feat(mt8196): add PMIC driver

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>
This commit is contained in:
Hope Wang 2024-12-13 16:04:57 +08:00 committed by Wenzhen Yu
parent b8ac81c7e6
commit d4e6f98d7f
18 changed files with 5724 additions and 4 deletions

View file

@ -0,0 +1,88 @@
/*
* 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>
#include <drivers/spmi_api.h>
#include <lib/mtk_init/mtk_init.h>
#include "registers.h"
static struct spmi_device *sdev;
static const struct pmic_psc_reg mt6363_psc_regs[] = {
PMIC_PSC_REG(RG_PWRHOLD, MT6363_PPCCTL0, 0),
PMIC_PSC_REG(RG_CRST, MT6363_PPCCTL1, 0),
PMIC_PSC_REG(RG_SMART_RST_SDN_EN, MT6363_STRUP_CON12, 1),
PMIC_PSC_REG(RG_SMART_RST_MODE, MT6363_STRUP_CON12, 2),
};
static int mt6363_psc_read_field(uint32_t reg, uint32_t *val, uint32_t mask, uint32_t shift)
{
uint8_t rdata = 0;
int ret = 0;
if (!val)
return -EINVAL;
if (!sdev)
return -ENODEV;
ret = spmi_ext_register_readl(sdev, reg, &rdata, 1);
if (ret < 0)
return ret;
rdata &= (mask << shift);
*val = (rdata >> shift);
return 0;
}
static int mt6363_psc_write_field(uint32_t reg, uint32_t val, uint32_t mask, uint32_t shift)
{
uint8_t org = 0;
int ret = 0;
if (!sdev)
return -ENODEV;
ret = spmi_ext_register_readl(sdev, reg, &org, 1);
if (ret < 0)
return ret;
org &= ~(mask << shift);
org |= (val << shift);
ret = spmi_ext_register_writel(sdev, reg, &org, 1);
return ret;
}
static const struct pmic_psc_config mt6363_psc_config = {
.read_field = mt6363_psc_read_field,
.write_field = mt6363_psc_write_field,
.regs = mt6363_psc_regs,
.reg_size = ARRAY_SIZE(mt6363_psc_regs),
};
static int mt6363_psc_init(void)
{
sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
if (!sdev)
ERROR("%s: get spmi device fail\n", __func__);
return pmic_psc_register(&mt6363_psc_config);
}
MTK_PLAT_SETUP_0_INIT(mt6363_psc_init);
#ifdef CONFIG_MTK_PMIC_SPT_SUPPORT
static int mt6363_spt_enable(void)
{
/* Enable PMIC Self-Protection Timer(SPT) */
return mt6363_psc_write_field(MT6363_RG_SELFWDT_EN_ADDR, MT6363_RG_SELFWDT_EN_MASK,
MT6363_RG_SELFWDT_EN_MASK, 0);
}
MTK_PLAT_RUNTIME_INIT(mt6363_spt_enable);
#endif

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MT6363_REGISTER_H
#define MT6363_REGISTER_H
/* PMIC Registers for PSC */
#define MT6363_PPCCTL0 0xA08
#define MT6363_PPCCTL1 0xA09
#define MT6363_STRUP_CON12 0xA0F
#define MT6363_RG_SELFWDT_EN_ADDR 0xA14
#define MT6363_RG_SELFWDT_EN_MASK 0x1
#endif /* MT6363_REGISTER_H */

View file

@ -0,0 +1,17 @@
#
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
#Prologue, init variable
LOCAL_DIR := $(call GET_LOCAL_DIR)
#Define your module name
MODULE := mt6363
#Add your source code here
LOCAL_SRCS-y := $(LOCAL_DIR)/${PMIC_CHIP}_psc.c
#Epilogue, build as module
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))

View file

@ -0,0 +1,73 @@
/*
* 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_set_lowpower.h>
#include <drivers/pmic/pmic_swap_api.h>
#include <drivers/spmi/spmi_common.h>
#include <lib/mtk_init/mtk_init.h>
#define MASTER_ID SPMI_MASTER_1
struct spmi_device *lowpower_sdev[SPMI_MAX_SLAVE_ID];
static const uint8_t lowpower_slvid_arr[] = {
MT6363_SLAVE,
MT6373_SLAVE,
MT6316_S6_SLAVE,
MT6316_S7_SLAVE,
MT6316_S8_SLAVE,
MT6316_S15_SLAVE,
};
static int pmic_lowpower_init(void)
{
uint8_t i, slvid;
for (i = 0; i < ARRAY_SIZE(lowpower_slvid_arr); i++) {
slvid = lowpower_slvid_arr[i];
lowpower_sdev[slvid] = get_spmi_device(MASTER_ID, slvid);
if (!lowpower_sdev[slvid])
return -ENODEV;
}
/* MT6363 Deep idle, SODI3 */
/* VREQ config by SCP owner in LK2 */
PMIC_BUCK_SET_LP(MT6363, VBUCK4, HW2, true, OP_MODE_LP, HW_LP);
PMIC_BUCK_SET_LP(MT6363, VBUCK4, RC9, true, OP_MODE_MU, HW_ON);
PMIC_BUCK_SET_LP(MT6363, VS2, HW2, true, OP_MODE_LP, HW_LP);
PMIC_BUCK_SET_LP(MT6363, VS2, RC9, true, OP_MODE_MU, HW_ON);
PMIC_BUCK_SET_LP(MT6363, VS3, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUB, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUB, RC9, true, OP_MODE_MU, HW_ON);
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUL, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VSRAM_CPUL, RC9, true, OP_MODE_MU, HW_ON);
PMIC_LDO_SET_LP(MT6363, VSRAM_APU, RC2, true, OP_MODE_MU, HW_OFF);
PMIC_LDO_SET_LP(MT6363, VSRAM_MODEM, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VSRAM_MODEM, RC9, true, OP_MODE_MU, HW_ON);
PMIC_LDO_SET_LP(MT6363, VA12_1, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VA12_1, RC9, true, OP_MODE_MU, HW_ON);
PMIC_LDO_SET_LP(MT6363, VA12_2, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VA12_2, RC9, true, OP_MODE_MU, HW_ON);
PMIC_LDO_SET_LP(MT6363, VUFS18, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6363, VUFS18, RC9, true, OP_MODE_MU, HW_ON);
PMIC_LDO_SET_LP(MT6363, VUFS12, HW2, true, OP_MODE_LP, HW_LP);
/* MT6373 Deep idle, SODI3 */
PMIC_BUCK_SET_LP(MT6373, VBUCK4, HW2, true, OP_MODE_LP, HW_OFF);
PMIC_BUCK_SET_LP(MT6373, VBUCK5, HW2, true, OP_MODE_LP, HW_OFF);
PMIC_BUCK_SET_LP(MT6373, VBUCK6, HW2, true, OP_MODE_LP, HW_LP);
PMIC_LDO_SET_LP(MT6373, VUSB, HW2, true, OP_MODE_LP, HW_LP);
/* MT6316 Deep idle, SODI3 */
PMIC_SLVID_BUCK_SET_LP(MT6316, S8, VBUCK1, HW2, true, OP_MODE_LP, HW_LP);
PMIC_SLVID_BUCK_SET_LP(MT6316, S6, VBUCK3, HW2, true, OP_MODE_LP, HW_ONLV);
return 0;
}
MTK_PLAT_SETUP_0_INIT(pmic_lowpower_init);

View file

@ -0,0 +1,291 @@
/*
* 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_shutdown_cfg.h>
#include <drivers/spmi/spmi_common.h>
#include <drivers/spmi_api.h>
#include <lib/mtk_init/mtk_init.h>
#define MASTER_ID SPMI_MASTER_1
#ifndef MT8678_PMIC_SUPPORT
/* MT6316 will automatically disable wdt in poffs */
#define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x408
#define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
#define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 1
#else
/* MT6319 will automatically disable wdt in poffs */
#define MT6319_TOP_RST_MISC_CLR 0x128
#define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x138
#define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
#define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 2
#endif
#define MT6373_TOP_RST_MISC1_CLR 0x13B
#define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x408
#define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
#define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 1
#define MT6685_TOP_RST_MISC_CLR 0x129
#define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR 0x408
#define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK 0x1
#define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT 1
struct spmi_device *sdev_arr[SPMI_MAX_SLAVE_ID];
struct cfg_t {
uint8_t slvid;
uint32_t addr;
uint32_t shutdown_src_addr;
uint32_t shutdown_src_mask;
uint32_t shutdown_src_shift;
uint8_t val;
};
#ifndef MT8678_PMIC_SUPPORT
static const struct cfg_t cfg_arr[] = {
{
.slvid = SPMI_SLAVE_6,
.addr = 0,
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_7,
.addr = 0,
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_8,
.addr = 0,
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_15,
.addr = 0,
.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_5,
.addr = MT6373_TOP_RST_MISC1_CLR,
.shutdown_src_addr = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_9,
.addr = MT6685_TOP_RST_MISC_CLR,
.shutdown_src_addr = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}
};
#else /* MT8678_PMIC_SUPPORT */
static const struct cfg_t cfg_arr[] = {
{
.slvid = SPMI_SLAVE_6,
.addr = MT6319_TOP_RST_MISC_CLR,
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_7,
.addr = MT6319_TOP_RST_MISC_CLR,
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_8,
.addr = MT6319_TOP_RST_MISC_CLR,
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_15,
.addr = MT6319_TOP_RST_MISC_CLR,
.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_5,
.addr = MT6373_TOP_RST_MISC1_CLR,
.shutdown_src_addr = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}, {
.slvid = SPMI_SLAVE_9,
.addr = MT6685_TOP_RST_MISC_CLR,
.shutdown_src_addr = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
.shutdown_src_mask = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
.shutdown_src_shift = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
.val = 0x1
}
};
#endif /* MT8678_PMIC_SUPPORT */
#define MT6316_TOP_ANA_KEY 0x3AA
#define MT6316_PMIC_RG_VI075_SINK_CUR_ADDR 0x994
#define MT6316_PMIC_RG_VI075_SINK_CUR_MASK 0xF
#define MT6316_PMIC_RG_VI075_SINK_CUR_SHIFT 4
#define MT6316_PMIC_RG_PSEQ_ELR_RSV2_ADDR 0xA2C
#define MT6316_PMIC_RG_PSEQ_ELR_RSV2_MASK 0x7
#define MT6316_PMIC_RG_PSEQ_ELR_RSV2_SHIFT 5
#define PSEQ_ELR_RSV2_VAL_MASK_1 0x3
#define PSEQ_ELR_RSV2_VAL_MASK_2 0x1
#define VI075_SINK_CUR_SOURCE_1 0x5
#define VI075_SINK_CUR_SOURCE_2 0
#define VI075_SINK_CUR_SOURCE_3 0xB
#define ARRAY_LENGTH_MAX 2
#ifndef MT8678_PMIC_SUPPORT
static void mt6316_key_lock_check(struct spmi_device *mt6316_dev, uint16_t key)
{
int i, ret;
uint16_t rdata;
uint8_t work_val[ARRAY_LENGTH_MAX];
uint8_t wdata[ARRAY_LENGTH_MAX];
for (i = 0; i < 2; i++) {
ret = spmi_ext_register_readl(mt6316_dev, key, &work_val[0], 2);
if (ret < 0) {
INFO("[%s]: read fail, addr = 0x%x, ret = %d\n"
, __func__, key, ret);
i = 0;
continue;
}
rdata = work_val[0] | (work_val[1] << 8);
if (rdata != 0) {
INFO("[%s] lock fail, addr = 0x%x, rdata = 0x%x.\n"
, __func__, key, rdata);
wdata[0] = 0;
wdata[1] = 0;
spmi_ext_register_writel(mt6316_dev, key, &wdata[0], 2);
i = 0;
}
}
}
static void wk_vio075_sink_cur(struct spmi_device *mt6316_dev, unsigned char en_seq_off)
{
uint8_t rval, wval;
int ret;
uint8_t buf[ARRAY_LENGTH_MAX];
ret = spmi_ext_register_readl(mt6316_dev, MT6316_PMIC_RG_PSEQ_ELR_RSV2_ADDR, &rval, 1);
if (ret < 0)
return;
rval = (rval >> MT6316_PMIC_RG_PSEQ_ELR_RSV2_SHIFT) & MT6316_PMIC_RG_PSEQ_ELR_RSV2_MASK;
if (!(rval & PSEQ_ELR_RSV2_VAL_MASK_1)) {
wval = VI075_SINK_CUR_SOURCE_1;
} else if (rval & PSEQ_ELR_RSV2_VAL_MASK_2) {
if (en_seq_off)
wval = VI075_SINK_CUR_SOURCE_2;
else
wval = VI075_SINK_CUR_SOURCE_3;
} else {
wval = VI075_SINK_CUR_SOURCE_2;
}
buf[0] = 0xDC;
buf[1] = 0xF1;
spmi_ext_register_writel(mt6316_dev,
MT6316_TOP_ANA_KEY,
&buf[0], 2); /* unlock TOP_ANA key */
spmi_ext_register_writel_field(mt6316_dev,
MT6316_PMIC_RG_VI075_SINK_CUR_ADDR, wval,
MT6316_PMIC_RG_VI075_SINK_CUR_MASK,
MT6316_PMIC_RG_VI075_SINK_CUR_SHIFT);
buf[0] = 0;
buf[1] = 0;
spmi_ext_register_writel(mt6316_dev,
MT6316_TOP_ANA_KEY,
&buf[0], 2); /* lock TOP_ANA key */
mt6316_key_lock_check(mt6316_dev, MT6316_TOP_ANA_KEY);
}
#endif
static int pmic_shutdown_cfg_init(void)
{
uint8_t i, slvid;
for (i = 0; i < ARRAY_SIZE(cfg_arr); i++) {
slvid = cfg_arr[i].slvid;
if (sdev_arr[slvid] != NULL)
continue;
sdev_arr[slvid] = get_spmi_device(MASTER_ID, slvid);
if (!sdev_arr[slvid])
return -ENODEV;
}
return 0;
}
MTK_PLAT_SETUP_0_INIT(pmic_shutdown_cfg_init);
int pmic_shutdown_cfg(void)
{
int ret;
uint8_t i, slvid;
uint32_t addr;
uint8_t val;
for (i = 0; i < ARRAY_SIZE(cfg_arr); i++) {
slvid = cfg_arr[i].slvid;
if (!sdev_arr[slvid])
return -ENODEV;
/* mt6316 vio075 sink current adjustment */
if ((slvid >= SPMI_SLAVE_6 && slvid <= SPMI_SLAVE_8) || slvid == SPMI_SLAVE_15)
wk_vio075_sink_cur(sdev_arr[slvid], 1);
addr = cfg_arr[i].addr;
val = cfg_arr[i].val;
/* Disable WDTRSTB_EN */
if (addr) {
ret = spmi_ext_register_writel(sdev_arr[slvid], addr, &val, 1);
if (ret < 0)
return ret;
}
/* set RG_SHUTDOWN_SRC_SEL to 1, shutdown PMIC by SPMI command */
spmi_ext_register_writel_field(sdev_arr[slvid],
cfg_arr[i].shutdown_src_addr, 1,
cfg_arr[i].shutdown_src_mask,
cfg_arr[i].shutdown_src_shift);
}
return 1; /* 1: use spmi_command_shutdown API */
}
/* shutdown PMIC by SPMI command */
int spmi_shutdown(void)
{
struct spmi_device *mt6363_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
if (!mt6363_sdev)
return -ENODEV;
/* set RG_SHUTDOWN_SRC_SEL to 1 */
spmi_ext_register_writel_field(mt6363_sdev, 0x408, 1, 0x1, 1);
spmi_command_shutdown(SPMI_MASTER_P_1, mt6363_sdev, 0x800);
spmi_command_shutdown(SPMI_MASTER_1, mt6363_sdev, 0x800);
return 0;
}

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>
#include <drivers/pmic/pmic_swap_api.h>
/* No need to check second pmic mt6373 */
bool is_second_pmic_pp_swap(void)
{
return false;
}

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdbool.h>
#include <drivers/pmic/pmic_swap_api.h>
#pragma weak is_second_pmic_pp_swap
bool is_second_pmic_pp_swap(void)
{
return false;
}

View file

@ -0,0 +1,117 @@
/*
* 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;
}

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2022, MediaTek Inc. All rights reserved.
# Copyright (c) 2022-2025, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -8,8 +8,24 @@ LOCAL_DIR := $(call GET_LOCAL_DIR)
MODULE := pmic
ifneq (${PMIC_CHIP}, mt6363)
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic.c
PLAT_INCLUDES += -I${LOCAL_DIR}/
else
LOCAL_SRCS-y := ${LOCAL_DIR}/pmic_psc.c
LOCAL_SRCS-y += ${LOCAL_DIR}/pmic_common_swap_api.c
LOCAL_SRCS-${CONFIG_MTK_PMIC_LOWPOWER} += ${LOCAL_DIR}/${MTK_SOC}/pmic_lowpower_init.c
LOCAL_SRCS-${CONFIG_MTK_PMIC_LOWPOWER} += ${LOCAL_DIR}/${MTK_SOC}/pmic_swap_api.c
LOCAL_SRCS-${CONFIG_MTK_PMIC_SHUTDOWN_CFG} += ${LOCAL_DIR}/${MTK_SOC}/pmic_shutdown_cfg.c
endif
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
$(eval $(call add_defined_option,CONFIG_MTK_PMIC_SPT_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_PMIC_SHUTDOWN_CFG))
#Include sub rules.mk
ifneq (${PMIC_CHIP},)
SUB_RULES-y := $(LOCAL_DIR)/$(PMIC_CHIP)
#Expand sub rules.mk
$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
endif

View file

@ -0,0 +1,263 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MT6316_LOWPOWER_REG_H
#define MT6316_LOWPOWER_REG_H
#define MT6316_RG_LDO_VDIG18_SW_OP_EN_ADDR 0x197
#define MT6316_RG_LDO_VDIG18_HW0_OP_EN_ADDR 0x197
#define MT6316_RG_LDO_VDIG18_HW2_OP_EN_ADDR 0x197
#define MT6316_RG_LDO_VDIG18_RC0_OP_EN_ADDR 0x197
#define MT6316_RG_LDO_VDIG18_BUCK_OP_EN_ADDR 0x197
#define MT6316_RG_LDO_VDIG18_HW0_OP_MODE_ADDR 0x198
#define MT6316_RG_LDO_VDIG18_HW2_OP_MODE_ADDR 0x198
#define MT6316_RG_LDO_VDIG18_RC0_OP_MODE_ADDR 0x198
#define MT6316_RG_LDO_VDIG18_BUCK_OP_MODE_ADDR 0x198
#define MT6316_RG_VDIG18_PWROFF_OP_EN_ADDR 0x199
#define MT6316_RG_LDO_VDIG12_SW_OP_EN_ADDR 0x19B
#define MT6316_RG_LDO_VDIG12_HW0_OP_EN_ADDR 0x19B
#define MT6316_RG_LDO_VDIG12_HW2_OP_EN_ADDR 0x19B
#define MT6316_RG_LDO_VDIG12_RC0_OP_EN_ADDR 0x19B
#define MT6316_RG_LDO_VDIG12_BUCK_OP_EN_ADDR 0x19B
#define MT6316_RG_LDO_VDIG12_HW0_OP_MODE_ADDR 0x19C
#define MT6316_RG_LDO_VDIG12_HW2_OP_MODE_ADDR 0x19C
#define MT6316_RG_LDO_VDIG12_RC0_OP_MODE_ADDR 0x19C
#define MT6316_RG_LDO_VDIG12_BUCK_OP_MODE_ADDR 0x19C
#define MT6316_RG_VDIG12_PWROFF_OP_EN_ADDR 0x19D
#define MT6316_RG_BUCK_VBUCK1_VOSEL_SLEEP_ADDR 0x148
#define MT6316_RG_BUCK_VBUCK1_ONLV_EN_ADDR 0x148
#define MT6316_RG_BUCK_VBUCK1_ONLV_EN_SHIFT 4
#define MT6316_RG_BUCK_VBUCK1_RC0_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC1_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC2_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC3_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC4_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC5_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC6_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC7_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC8_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC9_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC10_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC11_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC12_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC13_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW0_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW1_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW2_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW3_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_SW_OP_EN_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC0_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC1_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC2_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC3_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC4_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC5_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC6_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC7_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC8_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC9_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC10_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC11_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC12_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC13_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW0_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW1_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW2_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW3_OP_CFG_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC0_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC1_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC2_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC3_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC4_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC5_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC6_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC7_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC8_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC9_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC10_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC11_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC12_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_RC13_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW0_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW1_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW2_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK1_HW3_OP_MODE_ADDR 0x149
#define MT6316_RG_BUCK_VBUCK2_VOSEL_SLEEP_ADDR 0x150
#define MT6316_RG_BUCK_VBUCK2_ONLV_EN_ADDR 0x150
#define MT6316_RG_BUCK_VBUCK2_ONLV_EN_SHIFT 4
#define MT6316_RG_BUCK_VBUCK2_RC0_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC1_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC2_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC3_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC4_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC5_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC6_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC7_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC8_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC9_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC10_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC11_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC12_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC13_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW0_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW1_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW2_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW3_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_SW_OP_EN_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC0_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC1_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC2_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC3_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC4_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC5_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC6_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC7_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC8_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC9_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC10_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC11_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC12_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC13_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW0_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW1_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW2_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW3_OP_CFG_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC0_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC1_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC2_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC3_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC4_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC5_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC6_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC7_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC8_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC9_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC10_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC11_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC12_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_RC13_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW0_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW1_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW2_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK2_HW3_OP_MODE_ADDR 0x151
#define MT6316_RG_BUCK_VBUCK3_VOSEL_SLEEP_ADDR 0x158
#define MT6316_RG_BUCK_VBUCK3_ONLV_EN_ADDR 0x158
#define MT6316_RG_BUCK_VBUCK3_ONLV_EN_SHIFT 4
#define MT6316_RG_BUCK_VBUCK3_RC0_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC1_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC2_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC3_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC4_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC5_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC6_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC7_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC8_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC9_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC10_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC11_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC12_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC13_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW0_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW1_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW2_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW3_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_SW_OP_EN_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC0_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC1_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC2_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC3_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC4_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC5_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC6_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC7_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC8_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC9_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC10_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC11_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC12_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC13_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW0_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW1_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW2_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW3_OP_CFG_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC0_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC1_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC2_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC3_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC4_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC5_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC6_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC7_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC8_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC9_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC10_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC11_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC12_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_RC13_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW0_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW1_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW2_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK3_HW3_OP_MODE_ADDR 0x159
#define MT6316_RG_BUCK_VBUCK4_VOSEL_SLEEP_ADDR 0x160
#define MT6316_RG_BUCK_VBUCK4_ONLV_EN_ADDR 0x160
#define MT6316_RG_BUCK_VBUCK4_ONLV_EN_SHIFT 4
#define MT6316_RG_BUCK_VBUCK4_RC0_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC1_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC2_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC3_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC4_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC5_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC6_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC7_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC8_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC9_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC10_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC11_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC12_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC13_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW0_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW1_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW2_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW3_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_SW_OP_EN_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC0_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC1_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC2_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC3_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC4_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC5_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC6_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC7_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC8_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC9_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC10_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC11_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC12_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC13_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW0_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW1_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW2_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW3_OP_CFG_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC0_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC1_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC2_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC3_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC4_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC5_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC6_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC7_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC8_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC9_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC10_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC11_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC12_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_RC13_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW0_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW1_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW2_OP_MODE_ADDR 0x161
#define MT6316_RG_BUCK_VBUCK4_HW3_OP_MODE_ADDR 0x161
#endif /* MT6316_LOWPOWER_REG_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PMIC_PSC_H
#define PMIC_PSC_H
#include <stdint.h>
enum pmic_psc_reg_name {
RG_PWRHOLD,
RG_CRST,
RG_SMART_RST_SDN_EN,
RG_SMART_RST_MODE,
};
struct pmic_psc_reg {
uint16_t reg_addr;
uint16_t reg_mask;
uint16_t reg_shift;
};
struct pmic_psc_config {
int (*read_field)(uint32_t reg, uint32_t *val, uint32_t mask, uint32_t shift);
int (*write_field)(uint32_t reg, uint32_t val, uint32_t mask, uint32_t shift);
const struct pmic_psc_reg *regs;
const uint32_t reg_size;
};
#define PMIC_PSC_REG(_reg_name, addr, shift) \
[_reg_name] = { \
.reg_addr = addr, \
.reg_mask = 0x1, \
.reg_shift = shift, \
}
int enable_pmic_smart_reset(bool enable);
int enable_pmic_smart_reset_shutdown(bool enable);
int platform_cold_reset(void);
int platform_power_hold(bool hold);
int pmic_psc_register(const struct pmic_psc_config *psc);
#endif /* PMIC_PSC_H */

View file

@ -0,0 +1,206 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PMIC_SET_LOWPOWER_H
#define PMIC_SET_LOWPOWER_H
#include <stdint.h>
#include <drivers/spmi_api.h>
#include "mt6316_lowpower_reg.h"
#include "mt6363_lowpower_reg.h"
#include "mt6373_lowpower_reg.h"
#define OP_MODE_MU 0
#define OP_MODE_LP 1
#define HW_OFF 0
#define HW_ON 0
#define HW_LP 1
#define HW_ONLV (0x10 | 1)
#define NORMAL_OP_CFG 0x10
enum {
RC0 = 0,
RC1,
RC2,
RC3,
RC4,
RC5,
RC6,
RC7,
RC8 = 0,
RC9,
RC10,
RC11,
RC12,
RC13,
HW0 = 0,
HW1,
HW2,
HW3,
HW4,
HW5,
HW6,
HW7,
HW8 = 0,
HW9,
HW10,
HW11,
HW12,
HW13,
};
#define VOTER_EN_SET 1
#define VOTER_EN_CLR 2
enum {
VOTER_EN_LO_BIT0 = 0,
VOTER_EN_LO_BIT1,
VOTER_EN_LO_BIT2,
VOTER_EN_LO_BIT3,
VOTER_EN_LO_BIT4,
VOTER_EN_LO_BIT5,
VOTER_EN_LO_BIT6,
VOTER_EN_LO_BIT7,
VOTER_EN_HI_BIT0 = 0,
VOTER_EN_HI_BIT1,
VOTER_EN_HI_BIT2,
VOTER_EN_HI_BIT3,
};
enum {
MT6363_SLAVE = SPMI_SLAVE_4,
MT6368_SLAVE = SPMI_SLAVE_5,
MT6369_SLAVE = SPMI_SLAVE_5,
MT6373_SLAVE = SPMI_SLAVE_5,
MT6316_S6_SLAVE = SPMI_SLAVE_6,
MT6316_S7_SLAVE = SPMI_SLAVE_7,
MT6316_S8_SLAVE = SPMI_SLAVE_8,
MT6316_S15_SLAVE = SPMI_SLAVE_15,
MT6319_S6_SLAVE = SPMI_SLAVE_6,
MT6319_S7_SLAVE = SPMI_SLAVE_7,
MT6319_S8_SLAVE = SPMI_SLAVE_8,
MT6319_S15_SLAVE = SPMI_SLAVE_15,
};
extern struct spmi_device *lowpower_sdev[SPMI_MAX_SLAVE_ID];
#define PMIC_BUCK_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
{ \
uint8_t val = 0; \
struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
if (sdev && \
!spmi_ext_register_readl(sdev, _chip##_RG_BUCK_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
!(val & NORMAL_OP_CFG)) {\
if ((_cfg) == HW_ONLV) { \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
(1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
(1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT)); \
} else if ((_cfg) == HW_LP) { \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
(1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
0); \
} \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
1 << (_user), \
((_cfg) & 0x1) ? 1 << (_user) : 0); \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
1 << (_user), \
(_mode) ? 1 << (_user) : 0); \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
1 << (_user), \
(_en) ? 1 << (_user) : 0); \
} \
}
#define PMIC_LDO_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
{ \
uint8_t val = 0; \
struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
if (sdev && \
!spmi_ext_register_readl(sdev, _chip##_RG_LDO_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
!(val & NORMAL_OP_CFG)) {\
if ((_cfg) == HW_ONLV) { \
pmic_spmi_update_bits(sdev, \
_chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
(1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
(1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT)); \
} else { \
pmic_spmi_update_bits(sdev, \
_chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
(1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
0); \
} \
pmic_spmi_update_bits(sdev, \
_chip##_RG_LDO_##_name##_##_user##_OP_CFG_ADDR, \
1 << (_user), \
((_cfg) & 0x1) ? 1 << (_user) : 0); \
pmic_spmi_update_bits(sdev, \
_chip##_RG_LDO_##_name##_##_user##_OP_MODE_ADDR, \
1 << (_user), \
(_mode) ? 1 << (_user) : 0); \
pmic_spmi_update_bits(sdev, \
_chip##_RG_LDO_##_name##_##_user##_OP_EN_ADDR, \
1 << (_user), \
(_en) ? 1 << (_user) : 0); \
} \
}
#define PMIC_SLVID_BUCK_SET_LP(_chip, _slvid, _name, _user, _en, _mode, _cfg) \
{ \
struct spmi_device *sdev = lowpower_sdev[_chip##_##_slvid##_SLAVE]; \
if (sdev) {\
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
1 << (_user), \
(_cfg) ? 1 << (_user) : 0); \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
1 << (_user), \
(_mode) ? 1 << (_user) : 0); \
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
1 << (_user), \
(_en) ? 1 << (_user) : 0); \
} \
}
#define PMIC_BUCK_VOTER_EN(_chip, _name, _user, _cfg) \
{ \
struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
if (sdev) {\
pmic_spmi_update_bits(sdev, \
_chip##_RG_BUCK_##_name##_##_user##_ADDR + (_cfg), \
1 << (_user), \
1 << (_user)); \
} \
}
static inline int pmic_spmi_update_bits(struct spmi_device *sdev, uint16_t reg,
uint8_t mask, uint8_t val)
{
uint8_t org = 0;
int ret = 0;
ret = spmi_ext_register_readl(sdev, reg, &org, 1);
if (ret < 0)
return ret;
org &= ~mask;
org |= val & mask;
ret = spmi_ext_register_writel(sdev, reg, &org, 1);
return ret;
}
#endif /* PMIC_SET_LOWPOWER_H */

View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PMIC_SHUTDOWN_CFG_H
#define PMIC_SHUTDOWN_CFG_H
#pragma weak spmi_shutdown
int spmi_shutdown(void);
int pmic_shutdown_cfg(void);
#endif /* PMIC_SHUTDOWN_CFG_H */

View file

@ -0,0 +1,16 @@
/*
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef PMIC_SWAP_API_H
#define PMIC_SWAP_API_H
#include <stdbool.h>
#include <drivers/spmi_api.h>
bool is_second_pmic_pp_swap(void);
#endif /* PMIC_SWAP_API_H */

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2024, MediaTek Inc. All rights reserved.
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -47,6 +47,12 @@ CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND := y
CONFIG_MTK_TINYSYS_VCP := y
CPU_PM_TINYSYS_SUPPORT := y
MTK_PUBEVENT_ENABLE := y
CONFIG_MTK_PMIC := y
CONFIG_MTK_PMIC_LOWPOWER := y
CONFIG_MTK_PMIC_SHUTDOWN_CFG := y
CONFIG_MTK_PMIC_SPT_SUPPORT := n
PMIC_CHIP := mt6363
ENABLE_FEAT_AMU := 1
ENABLE_FEAT_ECV := 1

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2024, MediaTek Inc. All rights reserved.
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@ -33,6 +33,7 @@ MODULES-y += $(MTK_PLAT)/drivers/timer
MODULES-y += $(MTK_PLAT)/drivers/vcp
MODULES-y += $(MTK_PLAT)/helpers
MODULES-y += $(MTK_PLAT)/topology
MODULES-$(CONFIG_MTK_PMIC) += $(MTK_PLAT)/drivers/pmic
ifneq ($(MTKLIB_PATH),)
LDFLAGS += -L $(dir $(MTKLIB_PATH))