feat(plat/mediatek/mt8186): 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.

TEST=build pass
BUG=b:202871018

Signed-off-by: Edward-JW Yang <edward-jw.yang@mediatek.corp-partner.google.com>
Change-Id: Idc669364c89cde0974d2940bd12987ee833d1965
This commit is contained in:
Edward-JW Yang 2021-11-01 20:20:18 +08:00 committed by Rex-BC Chen
parent af5a0c40af
commit 95ea87ffc2
6 changed files with 634 additions and 0 deletions

View File

@ -20,6 +20,7 @@
#include <mt_gic_v3.h>
#include <mt_timer.h>
#include <mtgpio.h>
#include <mtk_dcm.h>
#include <plat_params.h>
#include <plat_private.h>
@ -84,6 +85,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
******************************************************************************/
void bl31_platform_setup(void)
{
dcm_set_default();
/* Initialize the GIC driver, CPU and distributor interfaces */
mt_gic_driver_init();
mt_gic_init();

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2021, MediaTek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/debug.h>
#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_cpubiu_dbg_cg(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_cpubiu_dbg_cg_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;
}
void dcm_set_default(void)
{
dcm_armcore(true);
dcm_mcusys(true);
dcm_stall(true);
INFO("%s: %d", __func__, 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>
void dcm_set_default(void);
#endif /* #ifndef MTK_DCM_H */

View File

@ -0,0 +1,490 @@
/*
* 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(16) | \
BIT(17) | \
BIT(18) | \
BIT(21))
#define MP_CPUSYS_TOP_ADB_DCM_REG1_MASK (BIT(16) | \
BIT(17) | \
BIT(18))
#define MP_CPUSYS_TOP_ADB_DCM_REG0_ON (BIT(16) | \
BIT(17) | \
BIT(18) | \
BIT(21))
#define MP_CPUSYS_TOP_ADB_DCM_REG1_ON (BIT(16) | \
BIT(17) | \
BIT(18))
#define MP_CPUSYS_TOP_ADB_DCM_REG0_OFF ((0x0 << 16) | \
(0x0 << 17) | \
(0x0 << 18) | \
(0x0 << 21))
#define MP_CPUSYS_TOP_ADB_DCM_REG1_OFF ((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_CFG4) &
MP_CPUSYS_TOP_ADB_DCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0) &
MP_CPUSYS_TOP_ADB_DCM_REG1_MASK) ==
(unsigned int) MP_CPUSYS_TOP_ADB_DCM_REG1_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_CFG4,
MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG0_ON);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG1_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_adb_dcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP_ADB_DCM_CFG4,
MP_CPUSYS_TOP_ADB_DCM_REG0_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG0_OFF);
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCUSYS_DCM_CFG0,
MP_CPUSYS_TOP_ADB_DCM_REG1_MASK,
MP_CPUSYS_TOP_ADB_DCM_REG1_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_DBG_CG_REG0_MASK (BIT(0))
#define MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_ON ((0x0 << 0))
#define MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_OFF (BIT(0))
bool dcm_mp_cpusys_top_cpubiu_dbg_cg_is_on(void)
{
bool ret = true;
ret &= ((mmio_read_32(MP_CPUSYS_TOP_MCSI_CFG2) &
MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_ON);
return ret;
}
void dcm_mp_cpusys_top_cpubiu_dbg_cg(bool on)
{
if (on) {
/* TINFO = "Turn ON DCM 'mp_cpusys_top_cpubiu_dbg_cg'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSI_CFG2,
MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_MASK,
MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_cpubiu_dbg_cg'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MCSI_CFG2,
MP_CPUSYS_TOP_CPUBIU_DBG_CG_REG0_MASK,
MP_CPUSYS_TOP_CPUBIU_DBG_CG_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(11) | \
BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_ON (BIT(11) | \
BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_0_DCM_REG0_OFF ((0x0 << 11) | \
(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(11) | \
BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_ON (BIT(11) | \
BIT(24) | \
BIT(25))
#define MP_CPUSYS_TOP_CPU_PLL_DIV_1_DCM_REG0_OFF ((0x0 << 11) | \
(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 (BIT(31))
#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_ON (BIT(31))
#define MP_CPUSYS_TOP_LAST_COR_IDLE_DCM_REG0_OFF ((0x0 << 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(0) | \
BIT(1) | \
BIT(2) | \
BIT(3) | \
BIT(4))
#define MP_CPUSYS_TOP_MISC_DCM_REG0_ON (BIT(0) | \
BIT(1) | \
BIT(2) | \
BIT(3) | \
BIT(4))
#define MP_CPUSYS_TOP_MISC_DCM_REG0_OFF ((0x0 << 0) | \
(0x0 << 1) | \
(0x0 << 2) | \
(0x0 << 3) | \
(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(0) | \
BIT(1) | \
BIT(2) | \
BIT(3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG0_ON (BIT(0) | \
BIT(1) | \
BIT(2) | \
BIT(3))
#define MP_CPUSYS_TOP_MP0_QDCM_REG0_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_MP0_DCM_CFG0) &
MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK) ==
(unsigned int) MP_CPUSYS_TOP_MP0_QDCM_REG0_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_MP0_DCM_CFG0,
MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
MP_CPUSYS_TOP_MP0_QDCM_REG0_ON);
} else {
/* TINFO = "Turn OFF DCM 'mp_cpusys_top_mp0_qdcm'" */
mmio_clrsetbits_32(MP_CPUSYS_TOP_MP0_DCM_CFG0,
MP_CPUSYS_TOP_MP0_QDCM_REG0_MASK,
MP_CPUSYS_TOP_MP0_QDCM_REG0_OFF);
}
}
#define CPCCFG_REG_EMI_WFIFO_REG0_MASK (BIT(0) | BIT(2))
#define CPCCFG_REG_EMI_WFIFO_REG0_ON (BIT(0) | BIT(2))
#define CPCCFG_REG_EMI_WFIFO_REG0_OFF ((0x0 << 0) | (0x0 << 2))
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,58 @@
/*
* 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 0xc538000
#define CPCCFG_REG_BASE 0xc53a800
/* Register Definition */
#define CPCCFG_REG_EMI_WFIFO (CPCCFG_REG_BASE + 0x100)
#define MP_CPUSYS_TOP_BUS_PLLDIV_CFG (MP_CPUSYS_TOP_BASE + 0x22e0)
#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_MCSIC_DCM0 (MP_CPUSYS_TOP_BASE + 0x2440)
#define MP_CPUSYS_TOP_MCSI_CFG2 (MP_CPUSYS_TOP_BASE + 0x2418)
#define MP_CPUSYS_TOP_MCUSYS_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x25c0)
#define MP_CPUSYS_TOP_MP0_DCM_CFG0 (MP_CPUSYS_TOP_BASE + 0x4880)
#define MP_CPUSYS_TOP_MP0_DCM_CFG7 (MP_CPUSYS_TOP_BASE + 0x489c)
#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)
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_dbg_cg_is_on(void);
void dcm_mp_cpusys_top_cpubiu_dbg_cg(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);
bool dcm_cpccfg_reg_emi_wfifo_is_on(void);
void dcm_cpccfg_reg_emi_wfifo(bool on);
#endif

View File

@ -11,6 +11,7 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \
-I${MTK_PLAT}/common/drivers/gic600/ \
-I${MTK_PLAT}/common/drivers/gpio/ \
-I${MTK_PLAT}/common/drivers/timer/ \
-I${MTK_PLAT_SOC}/drivers/dcm/ \
-I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/pmic/ \
@ -46,6 +47,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/emi_mpu/emi_mpu.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
${MTK_PLAT_SOC}/drivers/pmic/pmic.c \