mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-21 03:54:34 +00:00
feat(mt8196): add SPMI driver
Add SPMI and PMIF driver for PMIC communication Change-Id: Iad1d90381d6dad6b3e92fd9d6a3ce02fa11d15f1 Signed-off-by: Hope Wang <hope.wang@mediatek.corp-partner.google.com>
This commit is contained in:
parent
d4e6f98d7f
commit
adf73ae20a
12 changed files with 1012 additions and 1 deletions
plat/mediatek
drivers/spmi
include/drivers
mt8196
290
plat/mediatek/drivers/spmi/mt8196/platform_pmif_spmi.c
Normal file
290
plat/mediatek/drivers/spmi/mt8196/platform_pmif_spmi.c
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
#include <drivers/spmi/pmif_common.h>
|
||||
#include <drivers/spmi/pmif_v1/pmif.h>
|
||||
#include <drivers/spmi/spmi_common.h>
|
||||
#include <drivers/spmi/spmi_sw.h>
|
||||
#include <drivers/spmi_api.h>
|
||||
#include <lib/mtk_init/mtk_init.h>
|
||||
#include <mtk_mmap_pool.h>
|
||||
|
||||
#define SPMI_GROUP_ID 0xB
|
||||
#define SPMI_DEBUG 0
|
||||
|
||||
static const mmap_region_t pmif_spmi_mmap[] MTK_MMAP_SECTION = {
|
||||
MAP_REGION_FLAT(PMIF_SPMI_M_BASE, PMIF_SPMI_SIZE,
|
||||
MT_DEVICE | MT_RW | MT_NS),
|
||||
MAP_REGION_FLAT(SPMI_MST_M_BASE, SPMI_MST_SIZE,
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(PMIF_SPMI_P_BASE, PMIF_SPMI_SIZE,
|
||||
MT_DEVICE | MT_RW | MT_NS),
|
||||
{0}
|
||||
};
|
||||
DECLARE_MTK_MMAP_REGIONS(pmif_spmi_mmap);
|
||||
|
||||
static uint16_t mt6xxx_spmi_regs[] = {
|
||||
[SPMI_OP_ST_CTRL] = 0x0000,
|
||||
[SPMI_GRP_ID_EN] = 0x0004,
|
||||
[SPMI_OP_ST_STA] = 0x0008,
|
||||
[SPMI_MST_SAMPL] = 0x000C,
|
||||
[SPMI_MST_REQ_EN] = 0x0010,
|
||||
[SPMI_RCS_CTRL] = 0x0014,
|
||||
[SPMI_SLV_3_0_EINT] = 0x0020,
|
||||
[SPMI_SLV_7_4_EINT] = 0x0024,
|
||||
[SPMI_SLV_B_8_EINT] = 0x0028,
|
||||
[SPMI_SLV_F_C_EINT] = 0x002C,
|
||||
[SPMI_REC_CTRL] = 0x0040,
|
||||
[SPMI_REC0] = 0x0044,
|
||||
[SPMI_REC1] = 0x0048,
|
||||
[SPMI_REC2] = 0x004C,
|
||||
[SPMI_REC3] = 0x0050,
|
||||
[SPMI_REC4] = 0x0054,
|
||||
[SPMI_REC_CMD_DEC] = 0x005C,
|
||||
[SPMI_DEC_DBG] = 0x00F8,
|
||||
[SPMI_MST_DBG] = 0x00FC,
|
||||
};
|
||||
|
||||
static uint16_t mt6xxx_regs[] = {
|
||||
[PMIF_INIT_DONE] = 0x0000,
|
||||
[PMIF_INF_EN] = 0x0024,
|
||||
[PMIF_ARB_EN] = 0x0150,
|
||||
[PMIF_IRQ_EVENT_EN_0] = 0x0420,
|
||||
[PMIF_IRQ_FLAG_0] = 0x0428,
|
||||
[PMIF_IRQ_CLR_0] = 0x042C,
|
||||
[PMIF_IRQ_EVENT_EN_2] = 0x0440,
|
||||
[PMIF_IRQ_FLAG_2] = 0x0448,
|
||||
[PMIF_IRQ_CLR_2] = 0x044C,
|
||||
[PMIF_WDT_CTRL] = 0x0470,
|
||||
[PMIF_WDT_EVENT_EN_1] = 0x047C,
|
||||
[PMIF_WDT_FLAG_1] = 0x0480,
|
||||
[PMIF_SWINF_2_ACC] = 0x0880,
|
||||
[PMIF_SWINF_2_WDATA_31_0] = 0x0884,
|
||||
[PMIF_SWINF_2_WDATA_63_32] = 0x0888,
|
||||
[PMIF_SWINF_2_RDATA_31_0] = 0x0894,
|
||||
[PMIF_SWINF_2_RDATA_63_32] = 0x0898,
|
||||
[PMIF_SWINF_2_VLD_CLR] = 0x08A4,
|
||||
[PMIF_SWINF_2_STA] = 0x08A8,
|
||||
[PMIF_SWINF_3_ACC] = 0x08C0,
|
||||
[PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
|
||||
[PMIF_SWINF_3_WDATA_63_32] = 0x08C8,
|
||||
[PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
|
||||
[PMIF_SWINF_3_RDATA_63_32] = 0x08D8,
|
||||
[PMIF_SWINF_3_VLD_CLR] = 0x08E4,
|
||||
[PMIF_SWINF_3_STA] = 0x08E8,
|
||||
/* hw mpu */
|
||||
[PMIF_PMIC_ALL_RGN_EN_1] = 0x09B0,
|
||||
[PMIF_PMIC_ALL_RGN_EN_2] = 0x0D30,
|
||||
[PMIF_PMIC_ALL_RGN_0_START] = 0x09B4,
|
||||
[PMIF_PMIC_ALL_RGN_0_END] = 0x09B8,
|
||||
[PMIF_PMIC_ALL_RGN_1_START] = 0x09BC,
|
||||
[PMIF_PMIC_ALL_RGN_1_END] = 0x09C0,
|
||||
[PMIF_PMIC_ALL_RGN_2_START] = 0x09C4,
|
||||
[PMIF_PMIC_ALL_RGN_2_END] = 0x09C8,
|
||||
[PMIF_PMIC_ALL_RGN_3_START] = 0x09CC,
|
||||
[PMIF_PMIC_ALL_RGN_3_END] = 0x09D0,
|
||||
[PMIF_PMIC_ALL_RGN_31_START] = 0x0D34,
|
||||
[PMIF_PMIC_ALL_RGN_31_END] = 0x0D38,
|
||||
[PMIF_PMIC_ALL_INVLD_SLVID] = 0x0AAC,
|
||||
[PMIF_PMIC_ALL_RGN_0_PER0] = 0x0AB0,
|
||||
[PMIF_PMIC_ALL_RGN_0_PER1] = 0x0AB4,
|
||||
[PMIF_PMIC_ALL_RGN_1_PER0] = 0x0AB8,
|
||||
[PMIF_PMIC_ALL_RGN_2_PER0] = 0x0AC0,
|
||||
[PMIF_PMIC_ALL_RGN_3_PER0] = 0x0AC8,
|
||||
[PMIF_PMIC_ALL_RGN_31_PER0] = 0x0DB4,
|
||||
[PMIF_PMIC_ALL_RGN_31_PER1] = 0x0DB8,
|
||||
[PMIF_PMIC_ALL_RGN_OTHERS_PER0] = 0x0BA8,
|
||||
[PMIF_PMIC_ALL_RGN_OTHERS_PER1] = 0x0BAC,
|
||||
};
|
||||
|
||||
struct pmif pmif_spmi_arb[] = {
|
||||
{
|
||||
.base = (void *)PMIF_SPMI_M_BASE,
|
||||
.regs = mt6xxx_regs,
|
||||
.spmimst_base = (void *)SPMI_MST_M_BASE,
|
||||
.spmimst_regs = mt6xxx_spmi_regs,
|
||||
.mstid = SPMI_MASTER_0,
|
||||
.read_cmd = pmif_spmi_read_cmd,
|
||||
.write_cmd = pmif_spmi_write_cmd,
|
||||
}, {
|
||||
.base = (void *)PMIF_SPMI_M_BASE,
|
||||
.regs = mt6xxx_regs,
|
||||
.spmimst_base = (void *)SPMI_MST_M_BASE,
|
||||
.spmimst_regs = mt6xxx_spmi_regs,
|
||||
.mstid = SPMI_MASTER_1,
|
||||
.read_cmd = pmif_spmi_read_cmd,
|
||||
.write_cmd = pmif_spmi_write_cmd,
|
||||
}, {
|
||||
.base = (void *)PMIF_SPMI_P_BASE,
|
||||
.regs = mt6xxx_regs,
|
||||
.spmimst_base = (void *)SPMI_MST_P_BASE,
|
||||
.spmimst_regs = mt6xxx_spmi_regs,
|
||||
.mstid = SPMI_MASTER_P_1,
|
||||
.read_cmd = pmif_spmi_read_cmd,
|
||||
.write_cmd = pmif_spmi_write_cmd,
|
||||
},
|
||||
};
|
||||
|
||||
static struct spmi_device spmi_dev[] = {
|
||||
{
|
||||
.slvid = SPMI_SLAVE_4,
|
||||
.grpiden = 0x1 << SPMI_GROUP_ID,
|
||||
.mstid = SPMI_MASTER_1,
|
||||
.hwcid_addr = 0x09,
|
||||
.hwcid_val = 0x63,
|
||||
.swcid_addr = 0x0B,
|
||||
.swcid_val = 0x63,
|
||||
.wpk_key_addr = 0x3A7,
|
||||
.wpk_key_val = 0x9C,
|
||||
.wpk_key_h_val = 0x9C,
|
||||
.tma_key_addr = 0x39E,
|
||||
.tma_key_val = 0x9C,
|
||||
.tma_key_h_val = 0x9C,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_9,
|
||||
.grpiden = 0x1 << SPMI_GROUP_ID,
|
||||
.mstid = SPMI_MASTER_1,
|
||||
.hwcid_addr = 0x09,
|
||||
.hwcid_val = 0x85,
|
||||
.swcid_addr = 0x0B,
|
||||
.swcid_val = 0x85,
|
||||
.wpk_key_addr = 0x3AA,
|
||||
.wpk_key_val = 0x30,
|
||||
.wpk_key_h_val = 0x63,
|
||||
.tma_key_addr = 0x39E,
|
||||
.tma_key_val = 0x7A,
|
||||
.tma_key_h_val = 0x99,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_5,
|
||||
.grpiden = 0x800,
|
||||
.mstid = SPMI_MASTER_1,/* spmi-m */
|
||||
.hwcid_addr = 0x09,
|
||||
.hwcid_val = 0x73,
|
||||
.swcid_addr = 0x0B,
|
||||
.swcid_val = 0x73,
|
||||
.wpk_key_addr = 0x3A7,
|
||||
.wpk_key_val = 0x8C,
|
||||
.wpk_key_h_val = 0x9C,
|
||||
.tma_key_addr = 0x39E,
|
||||
.tma_key_val = 0x8C,
|
||||
.tma_key_h_val = 0x9C,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_14, /* MT6379 */
|
||||
.grpiden = 0x800,
|
||||
.mstid = SPMI_MASTER_1,/* spmi-m */
|
||||
.hwcid_addr = 0x00,
|
||||
.hwcid_val = 0x70,
|
||||
.hwcid_mask = 0xF0,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_6, /* MT6316 */
|
||||
.grpiden = 0x800,
|
||||
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||
.hwcid_addr = 0x209,
|
||||
.hwcid_val = 0x16,
|
||||
.swcid_addr = 0x20B,
|
||||
.swcid_val = 0x16,
|
||||
.wpk_key_addr = 0x3B1,
|
||||
.wpk_key_val = 0xE9,
|
||||
.wpk_key_h_val = 0xE6,
|
||||
.tma_key_addr = 0x3A8,
|
||||
.tma_key_val = 0xE9,
|
||||
.tma_key_h_val = 0xE6,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_7,
|
||||
.grpiden = 0x800,
|
||||
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||
.hwcid_addr = 0x209,
|
||||
.hwcid_val = 0x16,
|
||||
.swcid_addr = 0x20B,
|
||||
.swcid_val = 0x16,
|
||||
.wpk_key_addr = 0x3B1,
|
||||
.wpk_key_val = 0xE9,
|
||||
.wpk_key_h_val = 0xE6,
|
||||
.tma_key_addr = 0x3A8,
|
||||
.tma_key_val = 0xE9,
|
||||
.tma_key_h_val = 0xE6,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_8,
|
||||
.grpiden = 0x800,
|
||||
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||
.hwcid_addr = 0x209,
|
||||
.hwcid_val = 0x16,
|
||||
.swcid_addr = 0x20B,
|
||||
.swcid_val = 0x16,
|
||||
.wpk_key_addr = 0x3B1,
|
||||
.wpk_key_val = 0xE9,
|
||||
.wpk_key_h_val = 0xE6,
|
||||
.tma_key_addr = 0x3A8,
|
||||
.tma_key_val = 0xE9,
|
||||
.tma_key_h_val = 0xE6,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||
}, {
|
||||
.slvid = SPMI_SLAVE_15,
|
||||
.grpiden = 0x800,
|
||||
.mstid = SPMI_MASTER_P_1,/* spmi-m */
|
||||
.hwcid_addr = 0x209,
|
||||
.hwcid_val = 0x16,
|
||||
.swcid_addr = 0x20B,
|
||||
.swcid_val = 0x16,
|
||||
.wpk_key_addr = 0x3B1,
|
||||
.wpk_key_val = 0xE9,
|
||||
.wpk_key_h_val = 0xE6,
|
||||
.tma_key_addr = 0x3A8,
|
||||
.tma_key_val = 0xE9,
|
||||
.tma_key_h_val = 0xE6,
|
||||
.pmif_arb = &pmif_spmi_arb[SPMI_MASTER_P_1],
|
||||
},
|
||||
};
|
||||
|
||||
#if SPMI_DEBUG
|
||||
static void spmi_read_check(struct spmi_device *dev)
|
||||
{
|
||||
uint8_t rdata = 0;
|
||||
|
||||
spmi_ext_register_readl(dev, dev->hwcid_addr, &rdata, 1);
|
||||
|
||||
if (dev->hwcid_mask) {
|
||||
if ((rdata & dev->hwcid_mask) == (dev->hwcid_val & dev->hwcid_mask))
|
||||
SPMI_INFO("%s pass, slvid:%d rdata = 0x%x\n", __func__,
|
||||
dev->slvid, rdata);
|
||||
else
|
||||
SPMI_ERR("%s fail, slvid:%d rdata = 0x%x\n", __func__,
|
||||
dev->slvid, rdata);
|
||||
} else {
|
||||
if (rdata == dev->hwcid_val)
|
||||
SPMI_INFO("%s pass, slvid:%d rdata = 0x%x\n", __func__,
|
||||
dev->slvid, rdata);
|
||||
else
|
||||
SPMI_ERR("%s fail, slvid:%d rdata = 0x%x\n", __func__,
|
||||
dev->slvid, rdata);
|
||||
}
|
||||
}
|
||||
|
||||
void spmi_test(void)
|
||||
{
|
||||
for (int k = 0; k < ARRAY_SIZE(spmi_dev); k++)
|
||||
spmi_read_check(&spmi_dev[k]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int platform_pmif_spmi_init(void)
|
||||
{
|
||||
spmi_device_register(spmi_dev, ARRAY_SIZE(spmi_dev));
|
||||
|
||||
#if SPMI_DEBUG
|
||||
spmi_test();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
MTK_ARCH_INIT(platform_pmif_spmi_init);
|
173
plat/mediatek/drivers/spmi/pmif_common.c
Normal file
173
plat/mediatek/drivers/spmi/pmif_common.c
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/spinlock.h>
|
||||
|
||||
#include <pmif.h>
|
||||
#include "pmif_common.h"
|
||||
#include "spmi_common.h"
|
||||
#include "spmi_sw.h"
|
||||
|
||||
#define PMIF_CMD_REG_0 0
|
||||
#define PMIF_CMD_REG 1
|
||||
#define PMIF_CMD_EXT_REG 2
|
||||
#define PMIF_CMD_EXT_REG_LONG 3
|
||||
#define PMIF_READ_CMD_MIN 0x60
|
||||
#define PMIF_READ_CMD_MAX 0x7F
|
||||
#define PMIF_READ_CMD_EXT_MIN 0x20
|
||||
#define PMIF_READ_CMD_EXT_MAX 0x2F
|
||||
#define PMIF_READ_CMD_EXT_LONG_MIN 0x38
|
||||
#define PMIF_READ_CMD_EXT_LONG_MAX 0x3F
|
||||
#define PMIF_WRITE_CMD_MIN 0x40
|
||||
#define PMIF_WRITE_CMD_MAX 0x5F
|
||||
#define PMIF_WRITE_CMD_EXT_MAX 0xF
|
||||
#define PMIF_WRITE_CMD_EXT_LONG_MIN 0x30
|
||||
#define PMIF_WRITE_CMD_EXT_LONG_MAX 0x37
|
||||
#define PMIF_WRITE_CMD_0_MIN 0x80
|
||||
|
||||
/* macro for SWINF_FSM */
|
||||
#define SWINF_FSM_IDLE 0x00
|
||||
#define SWINF_FSM_REQ 0x02
|
||||
#define SWINF_FSM_WFDLE 0x04
|
||||
#define SWINF_FSM_WFVLDCLR 0x06
|
||||
|
||||
#define GET_SWINF_FSM(x) (((x) >> 1) & 0x7)
|
||||
#define GET_PMIF_INIT_DONE(x) (((x) >> 15) & 0x1)
|
||||
#define TIMEOUT_WAIT_IDLE_US 10000 /* 10ms */
|
||||
|
||||
#define PMIF_RW_CMD_SET(opc, rw, sid, bc, addr) \
|
||||
(((opc) << 30) | ((rw) << 29) | ((sid) << 24) | ((bc) << 16) | (addr))
|
||||
|
||||
static spinlock_t pmif_lock;
|
||||
|
||||
struct pmif *get_pmif_controller(int inf, int mstid)
|
||||
{
|
||||
return &pmif_spmi_arb[mstid];
|
||||
}
|
||||
|
||||
static int pmif_check_idle(int mstid)
|
||||
{
|
||||
struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
|
||||
unsigned int reg_rdata, offset = 0;
|
||||
|
||||
do {
|
||||
offset = arb->regs[PMIF_SWINF_3_STA];
|
||||
reg_rdata = mmio_read_32((uintptr_t)(arb->base + offset));
|
||||
} while (GET_SWINF_FSM(reg_rdata) != SWINF_FSM_IDLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pmif_check_vldclr(int mstid)
|
||||
{
|
||||
struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
|
||||
unsigned int reg_rdata, offset = 0;
|
||||
|
||||
do {
|
||||
offset = arb->regs[PMIF_SWINF_3_STA];
|
||||
reg_rdata = mmio_read_32((uintptr_t)(arb->base + offset));
|
||||
} while (GET_SWINF_FSM(reg_rdata) != SWINF_FSM_WFVLDCLR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pmif_spmi_read_cmd(struct pmif *arb, uint8_t opc, uint8_t sid,
|
||||
uint16_t addr, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
int ret;
|
||||
uint32_t offset = 0, data = 0;
|
||||
uint8_t bc = len - 1;
|
||||
|
||||
if (sid > SPMI_MAX_SLAVE_ID || len > PMIF_BYTECNT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check the opcode */
|
||||
if (opc >= PMIF_READ_CMD_MIN && opc <= PMIF_READ_CMD_MAX)
|
||||
opc = PMIF_CMD_REG;
|
||||
else if (opc >= PMIF_READ_CMD_EXT_MIN && opc <= PMIF_READ_CMD_EXT_MAX)
|
||||
opc = PMIF_CMD_EXT_REG;
|
||||
else if (opc >= PMIF_READ_CMD_EXT_LONG_MIN && opc <= PMIF_READ_CMD_EXT_LONG_MAX)
|
||||
opc = PMIF_CMD_EXT_REG_LONG;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&pmif_lock);
|
||||
|
||||
/* Wait for Software Interface FSM state to be IDLE. */
|
||||
ret = pmif_check_idle(arb->mstid);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
/* Send the command. */
|
||||
offset = arb->regs[PMIF_SWINF_3_ACC];
|
||||
mmio_write_32((uintptr_t)(arb->base + offset), PMIF_RW_CMD_SET(opc, 0, sid, bc, addr));
|
||||
/*
|
||||
* Wait for Software Interface FSM state to be WFVLDCLR,
|
||||
* read the data and clear the valid flag.
|
||||
*/
|
||||
ret = pmif_check_vldclr(arb->mstid);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
offset = arb->regs[PMIF_SWINF_3_RDATA_31_0];
|
||||
|
||||
data = mmio_read_32((uintptr_t)(arb->base + offset));
|
||||
memcpy(buf, &data, (bc & 3) + 1);
|
||||
|
||||
offset = arb->regs[PMIF_SWINF_3_VLD_CLR];
|
||||
mmio_write_32((uintptr_t)(arb->base + offset), 0x1);
|
||||
|
||||
done:
|
||||
spin_unlock(&pmif_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pmif_spmi_write_cmd(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr,
|
||||
const uint8_t *buf, uint8_t len)
|
||||
{
|
||||
int ret;
|
||||
uint32_t offset = 0, data = 0;
|
||||
uint8_t bc = len - 1;
|
||||
|
||||
if (sid > SPMI_MAX_SLAVE_ID || len > PMIF_BYTECNT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check the opcode */
|
||||
if (opc >= PMIF_WRITE_CMD_MIN && opc <= PMIF_WRITE_CMD_MAX)
|
||||
opc = PMIF_CMD_REG;
|
||||
else if (opc <= PMIF_WRITE_CMD_EXT_MAX)
|
||||
opc = PMIF_CMD_EXT_REG;
|
||||
else if (opc >= PMIF_WRITE_CMD_EXT_LONG_MIN && opc <= PMIF_WRITE_CMD_EXT_LONG_MAX)
|
||||
opc = PMIF_CMD_EXT_REG_LONG;
|
||||
else if (opc >= PMIF_WRITE_CMD_0_MIN)
|
||||
opc = PMIF_CMD_REG_0;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&pmif_lock);
|
||||
|
||||
/* Wait for Software Interface FSM state to be IDLE. */
|
||||
ret = pmif_check_idle(arb->mstid);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
/* Set the write data. */
|
||||
offset = arb->regs[PMIF_SWINF_3_WDATA_31_0];
|
||||
memcpy(&data, buf, (bc & 3) + 1);
|
||||
mmio_write_32((uintptr_t)(arb->base + offset), data);
|
||||
/* Send the command. */
|
||||
offset = arb->regs[PMIF_SWINF_3_ACC];
|
||||
mmio_write_32((uintptr_t)(arb->base + offset), PMIF_RW_CMD_SET(opc, 1, sid, bc, addr));
|
||||
|
||||
done:
|
||||
spin_unlock(&pmif_lock);
|
||||
return ret;
|
||||
}
|
42
plat/mediatek/drivers/spmi/pmif_common.h
Normal file
42
plat/mediatek/drivers/spmi/pmif_common.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PMIF_COMMON_H
|
||||
#define PMIF_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum {
|
||||
PMIF_CMD_REG_0,
|
||||
PMIF_CMD_REG,
|
||||
PMIF_CMD_EXT_REG,
|
||||
PMIF_CMD_EXT_REG_LONG,
|
||||
};
|
||||
|
||||
struct pmif {
|
||||
void *base;
|
||||
uint16_t *regs;
|
||||
void *spmimst_base;
|
||||
uint16_t *spmimst_regs;
|
||||
uint32_t mstid;
|
||||
int (*read_cmd)(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr, uint8_t *buf,
|
||||
uint8_t len);
|
||||
int (*write_cmd)(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr,
|
||||
const uint8_t *buf, uint8_t len);
|
||||
};
|
||||
|
||||
enum {
|
||||
PMIF_SPMI,
|
||||
PMIF_SPI
|
||||
};
|
||||
|
||||
int pmif_spmi_read_cmd(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr, uint8_t *buf,
|
||||
uint8_t len);
|
||||
int pmif_spmi_write_cmd(struct pmif *arb, uint8_t opc, uint8_t sid, uint16_t addr,
|
||||
const uint8_t *buf, uint8_t len);
|
||||
struct pmif *get_pmif_controller(int inf, int mstid);
|
||||
extern struct pmif pmif_spmi_arb[];
|
||||
#endif
|
68
plat/mediatek/drivers/spmi/pmif_v1/pmif.h
Normal file
68
plat/mediatek/drivers/spmi/pmif_v1/pmif.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef PMIF_H
|
||||
#define PMIF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <drivers/spmi/pmif_common.h>
|
||||
#include <drivers/spmi/spmi_common.h>
|
||||
|
||||
enum pmif_regs {
|
||||
PMIF_INIT_DONE,
|
||||
PMIF_INF_EN,
|
||||
PMIF_ARB_EN,
|
||||
PMIF_IRQ_EVENT_EN_0,
|
||||
PMIF_IRQ_FLAG_0,
|
||||
PMIF_IRQ_CLR_0,
|
||||
PMIF_IRQ_EVENT_EN_2,
|
||||
PMIF_IRQ_FLAG_2,
|
||||
PMIF_IRQ_CLR_2,
|
||||
PMIF_WDT_CTRL,
|
||||
PMIF_WDT_EVENT_EN_1,
|
||||
PMIF_WDT_FLAG_1,
|
||||
PMIF_SWINF_2_ACC,
|
||||
PMIF_SWINF_2_WDATA_31_0,
|
||||
PMIF_SWINF_2_WDATA_63_32,
|
||||
PMIF_SWINF_2_RDATA_31_0,
|
||||
PMIF_SWINF_2_RDATA_63_32,
|
||||
PMIF_SWINF_2_VLD_CLR,
|
||||
PMIF_SWINF_2_STA,
|
||||
PMIF_SWINF_3_ACC,
|
||||
PMIF_SWINF_3_WDATA_31_0,
|
||||
PMIF_SWINF_3_WDATA_63_32,
|
||||
PMIF_SWINF_3_RDATA_31_0,
|
||||
PMIF_SWINF_3_RDATA_63_32,
|
||||
PMIF_SWINF_3_VLD_CLR,
|
||||
PMIF_SWINF_3_STA,
|
||||
/* HW MPU */
|
||||
PMIF_PMIC_ALL_RGN_EN_1,
|
||||
PMIF_PMIC_ALL_RGN_EN_2,
|
||||
PMIF_PMIC_ALL_RGN_0_START,
|
||||
PMIF_PMIC_ALL_RGN_0_END,
|
||||
PMIF_PMIC_ALL_RGN_1_START,
|
||||
PMIF_PMIC_ALL_RGN_1_END,
|
||||
PMIF_PMIC_ALL_RGN_2_START,
|
||||
PMIF_PMIC_ALL_RGN_2_END,
|
||||
PMIF_PMIC_ALL_RGN_3_START,
|
||||
PMIF_PMIC_ALL_RGN_3_END,
|
||||
PMIF_PMIC_ALL_RGN_31_START,
|
||||
PMIF_PMIC_ALL_RGN_31_END,
|
||||
PMIF_PMIC_ALL_INVLD_SLVID,
|
||||
PMIF_PMIC_ALL_RGN_0_PER0,
|
||||
PMIF_PMIC_ALL_RGN_0_PER1,
|
||||
PMIF_PMIC_ALL_RGN_1_PER0,
|
||||
PMIF_PMIC_ALL_RGN_2_PER0,
|
||||
PMIF_PMIC_ALL_RGN_3_PER0,
|
||||
PMIF_PMIC_ALL_RGN_31_PER0,
|
||||
PMIF_PMIC_ALL_RGN_31_PER1,
|
||||
PMIF_PMIC_ALL_RGN_OTHERS_PER0,
|
||||
PMIF_PMIC_ALL_RGN_OTHERS_PER1,
|
||||
};
|
||||
#endif
|
19
plat/mediatek/drivers/spmi/rules.mk
Normal file
19
plat/mediatek/drivers/spmi/rules.mk
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
LOCAL_DIR := $(call GET_LOCAL_DIR)
|
||||
|
||||
MODULE := spmi
|
||||
|
||||
PLAT_INCLUDES += -I${MTK_PLAT}/drivers/spmi/pmif_v1
|
||||
|
||||
#Add your source code here
|
||||
LOCAL_SRCS-y := ${LOCAL_DIR}/pmif_common.c
|
||||
LOCAL_SRCS-y += ${LOCAL_DIR}/spmi_common.c
|
||||
LOCAL_SRCS-y += ${LOCAL_DIR}/${MTK_SOC}/platform_pmif_spmi.c
|
||||
|
||||
#Epilogue, build as module
|
||||
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
|
199
plat/mediatek/drivers/spmi/spmi_common.c
Normal file
199
plat/mediatek/drivers/spmi/spmi_common.c
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <lib/mmio.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#include "spmi_common.h"
|
||||
#include "spmi_sw.h"
|
||||
|
||||
/* SPMI Commands */
|
||||
#define SPMI_CMD_EXT_WRITE 0x00
|
||||
#define SPMI_CMD_EXT_READ 0x20
|
||||
#define SPMI_CMD_EXT_WRITEL 0x30
|
||||
#define SPMI_CMD_EXT_READL 0x38
|
||||
#define SPMI_CMD_WRITE 0x40
|
||||
#define SPMI_CMD_READ 0x60
|
||||
#define SPMI_CMD_ZERO_WRITE 0x80
|
||||
#define SPMI_READ_ADDR_MAX 0x1F
|
||||
|
||||
static struct spmi_device *spmi_dev[SPMI_MAX_SLAVE_ID];
|
||||
|
||||
int spmi_register_zero_write(struct spmi_device *dev, uint8_t data)
|
||||
{
|
||||
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_ZERO_WRITE,
|
||||
dev->slvid, 0, &data, 1);
|
||||
}
|
||||
|
||||
int spmi_register_read(struct spmi_device *dev, uint8_t addr, uint8_t *buf)
|
||||
{
|
||||
/* 5-bit register address */
|
||||
if (addr > SPMI_READ_ADDR_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_READ, dev->slvid, addr, buf, 1);
|
||||
}
|
||||
|
||||
int spmi_register_write(struct spmi_device *dev, uint8_t addr, uint8_t data)
|
||||
{
|
||||
/* 5-bit register address */
|
||||
if (addr > SPMI_READ_ADDR_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_WRITE,
|
||||
dev->slvid, addr, &data, 1);
|
||||
}
|
||||
|
||||
int spmi_ext_register_read(struct spmi_device *dev, uint8_t addr, uint8_t *buf,
|
||||
uint8_t len)
|
||||
{
|
||||
/* 8-bit register address, up to 16 bytes */
|
||||
if (len == 0 || len > 16)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READ,
|
||||
dev->slvid, addr, buf, len);
|
||||
}
|
||||
|
||||
int spmi_ext_register_write(struct spmi_device *dev, uint8_t addr,
|
||||
const uint8_t *buf, uint8_t len)
|
||||
{
|
||||
/* 8-bit register address, up to 16 bytes */
|
||||
if (len == 0 || len > 16)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITE,
|
||||
dev->slvid, addr, buf, len);
|
||||
}
|
||||
|
||||
int spmi_ext_register_readl(struct spmi_device *dev, uint16_t addr,
|
||||
uint8_t *buf, uint8_t len)
|
||||
{
|
||||
/* 8-bit register address, up to 16 bytes */
|
||||
if (len == 0 || len > 16)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READL,
|
||||
dev->slvid, addr, buf, len);
|
||||
}
|
||||
|
||||
int spmi_ext_register_writel(struct spmi_device *dev, uint16_t addr,
|
||||
const uint8_t *buf, uint8_t len)
|
||||
{
|
||||
/* 8-bit register address, up to 16 bytes */
|
||||
if (len == 0 || len > 16)
|
||||
return -EINVAL;
|
||||
|
||||
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITEL,
|
||||
dev->slvid, addr, buf, len);
|
||||
}
|
||||
|
||||
int spmi_ext_register_readl_field(struct spmi_device *dev, uint16_t addr,
|
||||
uint8_t *buf, uint16_t mask, uint16_t shift)
|
||||
{
|
||||
int ret;
|
||||
uint8_t rdata = 0;
|
||||
|
||||
ret = dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READL,
|
||||
dev->slvid, addr, &rdata, 1);
|
||||
if (!ret)
|
||||
*buf = (rdata >> shift) & mask;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spmi_ext_register_writel_field(struct spmi_device *dev, uint16_t addr,
|
||||
uint8_t data, uint16_t mask, uint16_t shift)
|
||||
{
|
||||
int ret;
|
||||
uint8_t tmp = 0;
|
||||
|
||||
ret = spmi_ext_register_readl(dev, addr, &tmp, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tmp &= ~(mask << shift);
|
||||
tmp |= (data << shift);
|
||||
return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITEL,
|
||||
dev->slvid, addr, &tmp, 1);
|
||||
}
|
||||
|
||||
struct spmi_device *get_spmi_device(int mstid, int slvid)
|
||||
{
|
||||
if (slvid >= SPMI_MAX_SLAVE_ID || slvid < 0) {
|
||||
SPMI_ERR("failed to get spmi_device with slave id %d\n", slvid);
|
||||
return NULL;
|
||||
}
|
||||
return spmi_dev[slvid];
|
||||
}
|
||||
|
||||
int spmi_device_register(struct spmi_device *platform_spmi_dev, unsigned int num_devs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!platform_spmi_dev || num_devs == 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < num_devs; i++) {
|
||||
if (platform_spmi_dev[i].slvid >= SPMI_MAX_SLAVE_ID ||
|
||||
platform_spmi_dev[i].slvid < 0) {
|
||||
SPMI_INFO("invalid slave id %d\n", platform_spmi_dev[i].slvid);
|
||||
continue;
|
||||
}
|
||||
if (!spmi_dev[platform_spmi_dev[i].slvid])
|
||||
spmi_dev[platform_spmi_dev[i].slvid] = &platform_spmi_dev[i];
|
||||
else {
|
||||
SPMI_INFO("duplicated slave id %d\n", platform_spmi_dev[i].slvid);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spmi_ctrl_op_st(int mstid, unsigned int grpiden, unsigned int sid,
|
||||
unsigned int cmd)
|
||||
{
|
||||
struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
|
||||
unsigned int rdata = 0x0;
|
||||
uintptr_t spmi_grp_id_en_addr =
|
||||
(uintptr_t)(arb->spmimst_base + arb->spmimst_regs[SPMI_GRP_ID_EN]);
|
||||
uintptr_t spmi_op_st_ctrl_addr =
|
||||
(uintptr_t)(arb->spmimst_base + arb->spmimst_regs[SPMI_OP_ST_CTRL]);
|
||||
uintptr_t spmi_op_st_sta_addr =
|
||||
(uintptr_t)(arb->spmimst_base + arb->spmimst_regs[SPMI_OP_ST_STA]);
|
||||
|
||||
/* gid is 0x800 */
|
||||
mmio_write_32(spmi_grp_id_en_addr, grpiden);
|
||||
|
||||
if (grpiden == (1 << SPMI_GROUP_ID))
|
||||
mmio_write_32(spmi_op_st_ctrl_addr, (cmd << 0x4) | SPMI_GROUP_ID);
|
||||
else
|
||||
mmio_write_32(spmi_op_st_ctrl_addr, (cmd << 0x4) | sid);
|
||||
|
||||
SPMI_INFO("%s 0x%x\n", __func__, mmio_read_32(spmi_op_st_ctrl_addr));
|
||||
|
||||
do {
|
||||
rdata = mmio_read_32(spmi_op_st_sta_addr);
|
||||
SPMI_INFO("%s 0x%x\n", __func__, rdata);
|
||||
|
||||
if (((rdata >> 0x1) & SPMI_OP_ST_NACK) == SPMI_OP_ST_NACK) {
|
||||
SPMI_ERR("SPMI_OP_ST_NACK occurs! OP_ST_STA = 0x%x\n", rdata);
|
||||
break;
|
||||
}
|
||||
} while ((rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spmi_command_shutdown(int mstid, struct spmi_device *dev, unsigned int grpiden)
|
||||
{
|
||||
if (grpiden != (1 << SPMI_GROUP_ID))
|
||||
dev->slvid = grpiden;
|
||||
|
||||
return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_SHUTDOWN);
|
||||
}
|
103
plat/mediatek/drivers/spmi/spmi_common.h
Normal file
103
plat/mediatek/drivers/spmi/spmi_common.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SPMI_COMMON_H
|
||||
#define SPMI_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include "pmif_common.h"
|
||||
|
||||
/* Read/write byte limitation */
|
||||
#define PMIF_BYTECNT_MAX 2
|
||||
|
||||
#define SPMI_GROUP_ID 0xB
|
||||
|
||||
/* enum marco for cmd/channel */
|
||||
enum spmi_master {
|
||||
SPMI_MASTER_0 = 0,
|
||||
SPMI_MASTER_1,
|
||||
SPMI_MASTER_P_1,
|
||||
SPMI_MASTER_MAX
|
||||
};
|
||||
|
||||
enum spmi_slave {
|
||||
SPMI_SLAVE_0 = 0,
|
||||
SPMI_SLAVE_1,
|
||||
SPMI_SLAVE_2,
|
||||
SPMI_SLAVE_3,
|
||||
SPMI_SLAVE_4,
|
||||
SPMI_SLAVE_5,
|
||||
SPMI_SLAVE_6,
|
||||
SPMI_SLAVE_7,
|
||||
SPMI_SLAVE_8,
|
||||
SPMI_SLAVE_9,
|
||||
SPMI_SLAVE_10,
|
||||
SPMI_SLAVE_11,
|
||||
SPMI_SLAVE_12,
|
||||
SPMI_SLAVE_13,
|
||||
SPMI_SLAVE_14,
|
||||
SPMI_SLAVE_15,
|
||||
SPMI_MAX_SLAVE_ID
|
||||
};
|
||||
|
||||
enum slv_type {
|
||||
BUCK_CPU,
|
||||
BUCK_GPU,
|
||||
BUCK_MD,
|
||||
BUCK_RF,
|
||||
MAIN_PMIC,
|
||||
BUCK_VPU,
|
||||
SUB_PMIC,
|
||||
CLOCK_PMIC,
|
||||
SECOND_PMIC,
|
||||
SLV_TYPE_MAX
|
||||
};
|
||||
|
||||
enum slv_type_id {
|
||||
BUCK_RF_ID = 1,
|
||||
BUCK_MD_ID = 3,
|
||||
MAIN_PMIC_ID = 5,
|
||||
BUCK_CPU_ID = 6,
|
||||
BUCK_GPU_ID = 7,
|
||||
BUCK_VPU_ID,
|
||||
SUB_PMIC_ID = 10,
|
||||
CLOCK_PMIC_ID = 11,
|
||||
SECOND_PMIC_ID = 12,
|
||||
SLV_TYPE_ID_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
SPMI_OP_ST_BUSY = 1,
|
||||
SPMI_OP_ST_ACK = 0,
|
||||
SPMI_OP_ST_NACK = 1
|
||||
};
|
||||
|
||||
struct spmi_device {
|
||||
int slvid;
|
||||
int grpiden;
|
||||
enum slv_type type;
|
||||
enum slv_type_id type_id;
|
||||
int mstid;
|
||||
uint16_t hwcid_addr;
|
||||
uint8_t hwcid_val;
|
||||
uint16_t hwcid_mask;
|
||||
uint16_t swcid_addr;
|
||||
uint8_t swcid_val;
|
||||
uint16_t wpk_key_addr;
|
||||
uint16_t wpk_key_val;
|
||||
uint16_t wpk_key_h_val;
|
||||
uint16_t tma_key_addr;
|
||||
uint16_t tma_key_val;
|
||||
uint16_t tma_key_h_val;
|
||||
uint16_t rcs_en_addr;
|
||||
uint16_t rcs_slvid_addr;
|
||||
struct pmif *pmif_arb;
|
||||
};
|
||||
|
||||
int spmi_command_shutdown(int mstid, struct spmi_device *dev, unsigned int grpiden);
|
||||
#endif
|
69
plat/mediatek/drivers/spmi/spmi_sw.h
Normal file
69
plat/mediatek/drivers/spmi/spmi_sw.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Mediatek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SPMI_SW_H
|
||||
#define SPMI_SW_H
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/delay_timer.h>
|
||||
#include <mt_timer.h>
|
||||
|
||||
enum spmi_regs {
|
||||
SPMI_OP_ST_CTRL,
|
||||
SPMI_GRP_ID_EN,
|
||||
SPMI_OP_ST_STA,
|
||||
SPMI_MST_SAMPL,
|
||||
SPMI_MST_REQ_EN,
|
||||
/* RCS support */
|
||||
SPMI_RCS_CTRL,
|
||||
SPMI_SLV_3_0_EINT,
|
||||
SPMI_SLV_7_4_EINT,
|
||||
SPMI_SLV_B_8_EINT,
|
||||
SPMI_SLV_F_C_EINT,
|
||||
SPMI_REC_CTRL,
|
||||
SPMI_REC0,
|
||||
SPMI_REC1,
|
||||
SPMI_REC2,
|
||||
SPMI_REC3,
|
||||
SPMI_REC4,
|
||||
SPMI_REC_CMD_DEC,
|
||||
SPMI_DEC_DBG,
|
||||
SPMI_MST_DBG
|
||||
};
|
||||
|
||||
/* DEBUG MARCO */
|
||||
#define SPMITAG "[SPMI] "
|
||||
#define SPMI_ERR(fmt, arg...) ERROR(SPMITAG fmt, ##arg)
|
||||
#define SPMI_ERRL(fmt, arg...) ERROR(fmt, ##arg)
|
||||
#define SPMI_INFO(fmt, arg...) INFO(SPMITAG fmt, ##arg)
|
||||
|
||||
#define wait_us(cond, timeout) \
|
||||
({ \
|
||||
uint64_t __now, __end, __ret; \
|
||||
\
|
||||
__end = sched_clock() + timeout; \
|
||||
for (;;) { \
|
||||
if (cond) { \
|
||||
__ret = timeout; \
|
||||
break; \
|
||||
} \
|
||||
__now = sched_clock(); \
|
||||
if (__end <= __now) { \
|
||||
__ret = 0; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
enum {
|
||||
SPMI_RESET = 0,
|
||||
SPMI_SLEEP,
|
||||
SPMI_SHUTDOWN,
|
||||
SPMI_WAKEUP
|
||||
};
|
||||
|
||||
#endif
|
33
plat/mediatek/include/drivers/spmi_api.h
Normal file
33
plat/mediatek/include/drivers/spmi_api.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2025, MediaTek Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef SPMI_API_H
|
||||
#define SPMI_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <drivers/spmi/spmi_common.h>
|
||||
|
||||
/* external API */
|
||||
int spmi_register_zero_write(struct spmi_device *dev, uint8_t data);
|
||||
int spmi_register_read(struct spmi_device *dev, uint8_t addr, uint8_t *buf);
|
||||
int spmi_register_write(struct spmi_device *dev, uint8_t addr, uint8_t data);
|
||||
int spmi_ext_register_read(struct spmi_device *dev, uint8_t addr, uint8_t *buf,
|
||||
uint8_t len);
|
||||
int spmi_ext_register_write(struct spmi_device *dev, uint8_t addr,
|
||||
const uint8_t *buf, uint8_t len);
|
||||
int spmi_ext_register_readl(struct spmi_device *dev, uint16_t addr,
|
||||
uint8_t *buf, uint8_t len);
|
||||
int spmi_ext_register_writel(struct spmi_device *dev, uint16_t addr,
|
||||
const uint8_t *buf, uint8_t len);
|
||||
int spmi_ext_register_readl_field(struct spmi_device *dev, uint16_t addr,
|
||||
uint8_t *buf, uint16_t mask, uint16_t shift);
|
||||
int spmi_ext_register_writel_field(struct spmi_device *dev, uint16_t addr,
|
||||
uint8_t data, uint16_t mask, uint16_t shift);
|
||||
struct spmi_device *get_spmi_device(int mstid, int slvid);
|
||||
int spmi_device_register(struct spmi_device *platform_spmi_dev, int num_devs);
|
||||
|
||||
#endif
|
|
@ -94,6 +94,20 @@
|
|||
#define UART0_BASE (IO_PHYS + 0x06000000)
|
||||
#define UART_BAUDRATE (115200)
|
||||
|
||||
/*******************************************************************************
|
||||
* PMIF address
|
||||
******************************************************************************/
|
||||
#define PMIF_SPMI_M_BASE (IO_PHYS + 0x0C01A000)
|
||||
#define PMIF_SPMI_P_BASE (IO_PHYS + 0x0C018000)
|
||||
#define PMIF_SPMI_SIZE 0x1000
|
||||
|
||||
/*******************************************************************************
|
||||
* SPMI address
|
||||
******************************************************************************/
|
||||
#define SPMI_MST_M_BASE (IO_PHYS + 0x0C01C000)
|
||||
#define SPMI_MST_P_BASE (IO_PHYS + 0x0C01C800)
|
||||
#define SPMI_MST_SIZE 0x1000
|
||||
|
||||
/*******************************************************************************
|
||||
* Infra IOMMU related constants
|
||||
******************************************************************************/
|
||||
|
|
|
@ -51,7 +51,7 @@ CONFIG_MTK_PMIC := y
|
|||
CONFIG_MTK_PMIC_LOWPOWER := y
|
||||
CONFIG_MTK_PMIC_SHUTDOWN_CFG := y
|
||||
CONFIG_MTK_PMIC_SPT_SUPPORT := n
|
||||
|
||||
CONFIG_MTK_SPMI := y
|
||||
PMIC_CHIP := mt6363
|
||||
|
||||
ENABLE_FEAT_AMU := 1
|
||||
|
|
|
@ -34,6 +34,7 @@ MODULES-y += $(MTK_PLAT)/drivers/vcp
|
|||
MODULES-y += $(MTK_PLAT)/helpers
|
||||
MODULES-y += $(MTK_PLAT)/topology
|
||||
MODULES-$(CONFIG_MTK_PMIC) += $(MTK_PLAT)/drivers/pmic
|
||||
MODULES-$(CONFIG_MTK_SPMI) += $(MTK_PLAT)/drivers/spmi
|
||||
|
||||
ifneq ($(MTKLIB_PATH),)
|
||||
LDFLAGS += -L $(dir $(MTKLIB_PATH))
|
||||
|
|
Loading…
Add table
Reference in a new issue