mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-27 07:15:20 +00:00

1. Add PMIC shutdown API 2. Add PMIC low power settings Change-Id: I634a60fa3e2a74a6031df9fe59e2f52956ef7114 Signed-off-by: Hope Wang <hope.wang@mediatek.corp-partner.google.com>
117 lines
2.4 KiB
C
117 lines
2.4 KiB
C
/*
|
|
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <errno.h>
|
|
|
|
#include <common/debug.h>
|
|
#include <drivers/pmic/pmic_psc.h>
|
|
#ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG
|
|
#include <drivers/pmic/pmic_shutdown_cfg.h>
|
|
#endif
|
|
|
|
#define ERR_INVALID_ARGS -EINVAL
|
|
#define ERR_NOT_CONFIGURED -ENODEV
|
|
|
|
static const struct pmic_psc_config *pmic_psc;
|
|
|
|
static uint32_t read_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
|
|
{
|
|
uint32_t val = 0;
|
|
const struct pmic_psc_reg *reg;
|
|
|
|
if (reg_name >= pmic_psc->reg_size)
|
|
return 0;
|
|
|
|
reg = &pmic_psc->regs[reg_name];
|
|
pmic_psc->read_field(reg->reg_addr, &val, reg->reg_mask, reg->reg_shift);
|
|
return val;
|
|
}
|
|
|
|
static int set_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
|
|
{
|
|
const struct pmic_psc_reg *reg;
|
|
|
|
if (reg_name >= pmic_psc->reg_size)
|
|
return ERR_INVALID_ARGS;
|
|
|
|
reg = &pmic_psc->regs[reg_name];
|
|
pmic_psc->write_field(reg->reg_addr, 1, reg->reg_mask, reg->reg_shift);
|
|
return 0;
|
|
}
|
|
|
|
static int clr_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
|
|
{
|
|
const struct pmic_psc_reg *reg;
|
|
|
|
if (reg_name >= pmic_psc->reg_size)
|
|
return ERR_INVALID_ARGS;
|
|
|
|
reg = &pmic_psc->regs[reg_name];
|
|
pmic_psc->write_field(reg->reg_addr, 0, reg->reg_mask, reg->reg_shift);
|
|
return 0;
|
|
}
|
|
|
|
int enable_pmic_smart_reset(bool enable)
|
|
{
|
|
if (!pmic_psc)
|
|
return ERR_NOT_CONFIGURED;
|
|
if (enable)
|
|
set_pmic_psc_reg(RG_SMART_RST_MODE);
|
|
else
|
|
clr_pmic_psc_reg(RG_SMART_RST_MODE);
|
|
return 0;
|
|
}
|
|
|
|
int enable_pmic_smart_reset_shutdown(bool enable)
|
|
{
|
|
if (!pmic_psc)
|
|
return ERR_NOT_CONFIGURED;
|
|
if (enable)
|
|
set_pmic_psc_reg(RG_SMART_RST_SDN_EN);
|
|
else
|
|
clr_pmic_psc_reg(RG_SMART_RST_SDN_EN);
|
|
return 0;
|
|
}
|
|
|
|
int platform_cold_reset(void)
|
|
{
|
|
if (!pmic_psc)
|
|
return ERR_NOT_CONFIGURED;
|
|
/* Some PMICs may not support cold reset */
|
|
if (!pmic_psc->regs[RG_CRST].reg_addr)
|
|
return ERR_NOT_CONFIGURED;
|
|
set_pmic_psc_reg(RG_CRST);
|
|
return 0;
|
|
}
|
|
|
|
int platform_power_hold(bool hold)
|
|
{
|
|
int use_spmi_cmd_sdn = 0;
|
|
|
|
if (!pmic_psc)
|
|
return ERR_NOT_CONFIGURED;
|
|
if (hold)
|
|
set_pmic_psc_reg(RG_PWRHOLD);
|
|
else {
|
|
#ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG
|
|
use_spmi_cmd_sdn = pmic_shutdown_cfg();
|
|
#endif
|
|
if (use_spmi_cmd_sdn == 1)
|
|
spmi_shutdown();
|
|
else
|
|
clr_pmic_psc_reg(RG_PWRHOLD);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int pmic_psc_register(const struct pmic_psc_config *psc)
|
|
{
|
|
if (!psc || !psc->regs || !psc->read_field || !psc->write_field)
|
|
return ERR_INVALID_ARGS;
|
|
pmic_psc = psc;
|
|
INFO("POWER_HOLD=0x%x\n", read_pmic_psc_reg(RG_PWRHOLD));
|
|
return 0;
|
|
}
|