feat(plat/mediatek/mt8195): add DCM driver

DCM means dynamic clock management, and it can dynamically
slow down or gate clocks during CPU or bus idle.

1. Add MCUSYS related DCM drivers.
2. Enable MCUSYS related DCM by default.

Change-Id: I3237199bc217bd3682f51d31284db5fd0324b396
Signed-off-by: Garmin Chang <garmin.chang@mediatek.com>
This commit is contained in:
Garmin Chang 2021-07-02 15:54:57 +08:00 committed by Rex-BC Chen
parent bc97629b74
commit 49d3bd8c4c
7 changed files with 630 additions and 2 deletions

View File

@ -19,6 +19,7 @@
#include <mt_gic_v3.h>
#include <mt_spm.h>
#include <mt_timer.h>
#include <mtk_dcm.h>
#include <mtgpio.h>
#include <plat_params.h>
#include <plat_private.h>
@ -84,6 +85,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
******************************************************************************/
void bl31_platform_setup(void)
{
/* Set dcm on */
if (!dcm_set_default()) {
ERROR("Failed to set default dcm on!!\n");
}
/* Initialize the GIC driver, CPU and distributor interfaces */
mt_gic_driver_init();
mt_gic_init();

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2021, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mtk_dcm.h>
#include <mtk_dcm_utils.h>
static void dcm_armcore(bool mode)
{
dcm_mp_cpusys_top_bus_pll_div_dcm(mode);
dcm_mp_cpusys_top_cpu_pll_div_0_dcm(mode);
dcm_mp_cpusys_top_cpu_pll_div_1_dcm(mode);
}
static void dcm_mcusys(bool on)
{
dcm_mp_cpusys_top_adb_dcm(on);
dcm_mp_cpusys_top_apb_dcm(on);
dcm_mp_cpusys_top_cpubiu_dcm(on);
dcm_mp_cpusys_top_misc_dcm(on);
dcm_mp_cpusys_top_mp0_qdcm(on);
dcm_cpccfg_reg_emi_wfifo(on);
dcm_mp_cpusys_top_last_cor_idle_dcm(on);
}
static void dcm_stall(bool on)
{
dcm_mp_cpusys_top_core_stall_dcm(on);
dcm_mp_cpusys_top_fcm_stall_dcm(on);
}
static bool check_dcm_state(void)
{
bool ret = true;
ret &= dcm_mp_cpusys_top_bus_pll_div_dcm_is_on();
ret &= dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on();
ret &= dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on();
ret &= dcm_mp_cpusys_top_adb_dcm_is_on();
ret &= dcm_mp_cpusys_top_apb_dcm_is_on();
ret &= dcm_mp_cpusys_top_cpubiu_dcm_is_on();
ret &= dcm_mp_cpusys_top_misc_dcm_is_on();
ret &= dcm_mp_cpusys_top_mp0_qdcm_is_on();
ret &= dcm_cpccfg_reg_emi_wfifo_is_on();
ret &= dcm_mp_cpusys_top_last_cor_idle_dcm_is_on();
ret &= dcm_mp_cpusys_top_core_stall_dcm_is_on();
ret &= dcm_mp_cpusys_top_fcm_stall_dcm_is_on();
return ret;
}
bool dcm_set_default(void)
{
dcm_armcore(true);
dcm_mcusys(true);
dcm_stall(true);
return check_dcm_state();
}

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2021, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MTK_DCM_H
#define MTK_DCM_H
#include <stdbool.h>
bool dcm_set_default(void);
#endif /* #ifndef MTK_DCM_H */

View File

@ -0,0 +1,483 @@
/*
* Copyright (c) 2021, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <lib/mmio.h>
#include <lib/utils_def.h>
#include <mtk_dcm_utils.h>
#define MP_CPUSYS_TOP_ADB_DCM_REG0_MASK (BIT(17))
#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK (BIT(15) | \
BIT(16) | \
BIT(17) | \
BIT(18) | \
BIT(21))
#define MP_CPUSYS_TOP_ADB_DCM_REG2_MASK (BIT(15) | \
BIT(16) | \
BIT(17) | \
BIT(18))
#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON (BIT(17))
#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON (BIT(15) | \
BIT(16) | \
BIT(17) | \
BIT(18) | \
BIT(21))
#define MP_CPUSYS_TOP_ADB_DCM_REG2_ON (BIT(15) | \
BIT(16) | \
BIT(17) | \
BIT(18))
#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF ((0x0 << 17))
#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF ((0x0 << 15) | \
(0x0 << 16) | \
(0x0 << 17) | \
(0x0 << 18) | \
(0x0 << 21))
#define MP_CPUSYS_TOP_ADB_DCM_REG2_OFF ((0x0 << 15) | \
(0x0 << 16) | \
(0x0 << 17) | \
(0x0 << 18))
bool dcm_mp_cpusys_top_adb_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0) &
MP_CPUSYS_TOP_ADB_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4) &
MP_CPUSYS_TOP_ADB_DCM_REG1_MASK) ==
(unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0) &
MP_CPUSYS_TOP_ADB_DCM_REG2_MASK) ==
(unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
return ret;
}
void dcm_mp_cpusys_top_adb_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_adb_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG2_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG0,
MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG0_OFF);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG1_OFF);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
MP_CPUSYS_TOP_ADB_DCM_REG2_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG2_OFF);
}
}
#define MP_CPUSYS_TOP_APB_DCM_REG0_MASK (BIT(5))
#define MP_CPUSYS_TOP_APB_DCM_REG1_MASK (BIT(8))
#define MP_CPUSYS_TOP_APB_DCM_REG2_MASK (BIT(16))
#define MP_CPUSYS_TOP_APB_DCM_REG0_ON (BIT(5))
#define MP_CPUSYS_TOP_APB_DCM_REG1_ON (BIT(8))
#define MP_CPUSYS_TOP_APB_DCM_REG2_ON (BIT(16))
#define MP_CPUSYS_TOP_APB_DCM_REG0_OFF ((0x0 << 5))
#define MP_CPUSYS_TOP_APB_DCM_REG1_OFF ((0x0 << 8))
#define MP_CPUSYS_TOP_APB_DCM_REG2_OFF ((0x0 << 16))
bool dcm_mp_cpusys_top_apb_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0) &
MP_CPUSYS_TOP_APB_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_APB_DCM_REG0_ON);
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0) &
MP_CPUSYS_TOP_APB_DCM_REG1_MASK) ==
(unsigned int) MP_CPUSYS_TOP_APB_DCM_REG1_ON);
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP0_DCM_CFG0) &
MP_CPUSYS_TOP_APB_DCM_REG2_MASK) ==
(unsigned int) MP_CPUSYS_TOP_APB_DCM_REG2_ON);
return ret;
}
void dcm_mp_cpusys_top_apb_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_apb_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
MP_CPUSYS_TOP_APB_DCM_REG0_ON);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
MP_CPUSYS_TOP_APB_DCM_REG1_ON);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
MP_CPUSYS_TOP_APB_DCM_REG2_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_apb_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
MP_CPUSYS_TOP_APB_DCM_REG0_MASK,
MP_CPUSYS_TOP_APB_DCM_REG0_OFF);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
MP_CPUSYS_TOP_APB_DCM_REG1_MASK,
MP_CPUSYS_TOP_APB_DCM_REG1_OFF);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
MP_CPUSYS_TOP_APB_DCM_REG2_MASK,
MP_CPUSYS_TOP_APB_DCM_REG2_OFF);
}
}
#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK (BIT(11) | \
BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON (BIT(11) | \
BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF ((0x0 << 11) | \
(0x0 << 24) | \
(0x0 << 25))
bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG) &
MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_bus_pll_div_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_MASK,
MP_CPUSYS_TOP_BUS_PLL_DIV_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK (BIT(0))
#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON (BIT(0))
#define MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF ((0x0 << 0))
bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP0_DCM_CFG7) &
MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_core_stall_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_core_stall_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_core_stall_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_MASK,
MP_CPUSYS_TOP_CORE_STALL_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK ((0xffff << 0))
#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON ((0xffff << 0))
#define MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF ((0x0 << 0))
bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MCSIC_DCM0) &
MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_cpubiu_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0,
MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
MP_CPUSYS_TOP_CPUBIU_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSIC_DCM0,
MP_CPUSYS_TOP_CPUBIU_DCM_REG0_MASK,
MP_CPUSYS_TOP_CPUBIU_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK (BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 24) | \
(0x0 << 25))
bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0) &
MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_0_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG0,
MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_MASK,
MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK (BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 24) | \
(0x0 << 25))
bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1) &
MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpu_pll_div_1_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_CPU_PLLDIV_CFG1,
MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_MASK,
MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK (BIT(4))
#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON (BIT(4))
#define MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF ((0x0 << 4))
bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP0_DCM_CFG7) &
MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_fcm_stall_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_fcm_stall_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_fcm_stall_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG7,
MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_MASK,
MP_CPUSYS_TOP_FCM_STALL_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK ((0x1U << 31))
#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON ((0x1U << 31))
#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF ((0x0U << 31))
bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG) &
MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_last_cor_idle_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_BUS_PLLDIV_CFG,
MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_MASK,
MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_MISC_DCM_REG0_MASK (BIT(1) | \
BIT(4))
#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(1) | \
BIT(4))
#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 1) | \
(0x0 << 4))
bool dcm_mp_cpusys_top_misc_dcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0) &
MP_CPUSYS_TOP_MISC_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_misc_dcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_misc_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
MP_CPUSYS_TOP_MISC_DCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_misc_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
MP_CPUSYS_TOP_MISC_DCM_REG0_MASK,
MP_CPUSYS_TOP_MISC_DCM_REG0_OFF);
}
}
#define MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK (BIT(3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK (BIT(0) | \
BIT(1) | \
BIT(2) | \
BIT(3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON (BIT(3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG1_ON (BIT(0) | \
BIT(1) | \
BIT(2) | \
BIT(3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF ((0x0 << 3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF ((0x0 << 0) | \
(0x0 << 1) | \
(0x0 << 2) | \
(0x0 << 3))
bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0) &
MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MP0_DCM_CFG0) &
MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK) ==
(unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
return ret;
}
void dcm_mp_cpusys_top_mp0_qdcm(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_mp0_qdcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
MP_CPUSYS_TOP_MP0_QDCM_REG1_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_MISC_DCM_CFG0,
MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
MP_CPUSYS_TOP_MP0_QDCM_REG1_MASK,
MP_CPUSYS_TOP_MP0_QDCM_REG1_OFF);
}
}
#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | \
BIT(1) | \
BIT(2) | \
BIT(3))
#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | \
BIT(1) | \
BIT(2) | \
BIT(3))
#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | \
(0x0 << 1) | \
(0x0 << 2) | \
(0x0 << 3))
bool dcm_cpccfg_reg_emi_wfifo_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(CPCCFG_REG_EMI_WFIFO) &
CPCCFG_REG_EMI_WFIFO_REG0_MASK) ==
(unsigned int) CPCCFG_REG_EMI_WFIFO_REG0_ON);
return ret;
}
void dcm_cpccfg_reg_emi_wfifo(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'cpccfg_reg_emi_wfifo'" */
mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO,
CPCCFG_REG_EMI_WFIFO_REG0_MASK,
CPCCFG_REG_EMI_WFIFO_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'cpccfg_reg_emi_wfifo'" */
mmio_clrsetbits_32(CPCCFG_REG_EMI_WFIFO,
CPCCFG_REG_EMI_WFIFO_REG0_MASK,
CPCCFG_REG_EMI_WFIFO_REG0_OFF);
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2021, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MTK_DCM_UTILS_H
#define MTK_DCM_UTILS_H
#include <stdbool.h>
#include <mtk_dcm.h>
#include <platform_def.h>
/* Base */
#define MP_CPUSYS_TOP_BASE (MCUCFG_BASE + 0x8000)
#define CPCCFG_REG_BASE (MCUCFG_BASE + 0xA800)
/* Register Definition */
#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG0 (MP_CPUSYS_TOP_BASE + 0x22a0)
#define MP_CPUSYS_TOP_CPU_PLLDIV_CFG1 (MP_CPUSYS_TOP_BASE + 0x22a4)
#define MP_CPUSYS_TOP_BUS_PLLDIV_CFG (MP_CPUSYS_TOP_BASE + 0x22e0)
#define MP_CPUSYS_TOP_MCSIC_DCM0 (MP_CPUSYS_TOP_BASE + 0x2440)
#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2500)
#define MP_CPUSYS_TOP_MP_ADB_DCM_CFG4 (MP_CPUSYS_TOP_BASE + 0x2510)
#define MP_CPUSYS_TOP_MP_MISC_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x2518)
#define MP_CPUSYS_TOP_MCUSYS_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x25c0)
#define CPCCFG_REG_EMI_WFIFO (CPCCFG_REG_BASE + 0x100)
#define MP_CPUSYS_TOP_MP0_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x4880)
#define MP_CPUSYS_TOP_MP0_DCM_CFG7 (MP_CPUSYS_TOP_BASE + 0x489c)
/* MP_CPUSYS_TOP */
bool dcm_mp_cpusys_top_adb_dcm_is_on(void);
void dcm_mp_cpusys_top_adb_dcm(bool on);
bool dcm_mp_cpusys_top_apb_dcm_is_on(void);
void dcm_mp_cpusys_top_apb_dcm(bool on);
bool dcm_mp_cpusys_top_bus_pll_div_dcm_is_on(void);
void dcm_mp_cpusys_top_bus_pll_div_dcm(bool on);
bool dcm_mp_cpusys_top_core_stall_dcm_is_on(void);
void dcm_mp_cpusys_top_core_stall_dcm(bool on);
bool dcm_mp_cpusys_top_cpubiu_dcm_is_on(void);
void dcm_mp_cpusys_top_cpubiu_dcm(bool on);
bool dcm_mp_cpusys_top_cpu_pll_div_0_dcm_is_on(void);
void dcm_mp_cpusys_top_cpu_pll_div_0_dcm(bool on);
bool dcm_mp_cpusys_top_cpu_pll_div_1_dcm_is_on(void);
void dcm_mp_cpusys_top_cpu_pll_div_1_dcm(bool on);
bool dcm_mp_cpusys_top_fcm_stall_dcm_is_on(void);
void dcm_mp_cpusys_top_fcm_stall_dcm(bool on);
bool dcm_mp_cpusys_top_last_cor_idle_dcm_is_on(void);
void dcm_mp_cpusys_top_last_cor_idle_dcm(bool on);
bool dcm_mp_cpusys_top_misc_dcm_is_on(void);
void dcm_mp_cpusys_top_misc_dcm(bool on);
bool dcm_mp_cpusys_top_mp0_qdcm_is_on(void);
void dcm_mp_cpusys_top_mp0_qdcm(bool on);
/* CPCCFG_REG */
bool dcm_cpccfg_reg_emi_wfifo_is_on(void);
void dcm_cpccfg_reg_emi_wfifo(bool on);
#endif

View File

@ -97,7 +97,7 @@ static struct pwr_ctrl suspend_ctrl = {
/* [4] */
.reg_spm_vrf18_req = 0,
/* [7] FIXME: default disable HW Auto S1*/
.reg_spm_ddr_en_req = 1,
.reg_spm_ddr_en_req = 0,
/* [8] */
.reg_spm_dvfs_req = 0,
/* [9] */

View File

@ -14,7 +14,8 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT}/common/drivers/timer/ \
-I${MTK_PLAT}/common/drivers/uart/ \
-I${MTK_PLAT}/common/lpm/ \
-I${MTK_PLAT_SOC}/drivers/dp/ \
-I${MTK_PLAT_SOC}/drivers/dcm \
-I${MTK_PLAT_SOC}/drivers/dp/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/mcdi/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
@ -56,6 +57,8 @@ BL31_SOURCES += common/desc_image_load.c \
${MTK_PLAT_SOC}/aarch64/platform_common.c \
${MTK_PLAT_SOC}/aarch64/plat_helpers.S \
${MTK_PLAT_SOC}/bl31_plat_setup.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \
${MTK_PLAT_SOC}/drivers/dp/mt_dp.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \