1 /*
2 * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <errno.h>
8
9 #include <common/debug.h>
10 #include <drivers/pmic/pmic_psc.h>
11 #include <drivers/spmi_api.h>
12 #include <lib/mtk_init/mtk_init.h>
13
14 #include "registers.h"
15
16 static struct spmi_device *sdev;
17
18 static const struct pmic_psc_reg mt6363_psc_regs[] = {
19 PMIC_PSC_REG(RG_PWRHOLD, MT6363_PPCCTL0, 0),
20 PMIC_PSC_REG(RG_CRST, MT6363_PPCCTL1, 0),
21 PMIC_PSC_REG(RG_SMART_RST_SDN_EN, MT6363_STRUP_CON12, 1),
22 PMIC_PSC_REG(RG_SMART_RST_MODE, MT6363_STRUP_CON12, 2),
23 };
24
mt6363_psc_read_field(uint32_t reg,uint32_t * val,uint32_t mask,uint32_t shift)25 static int mt6363_psc_read_field(uint32_t reg, uint32_t *val, uint32_t mask, uint32_t shift)
26 {
27 uint8_t rdata = 0;
28 int ret = 0;
29
30 if (!val)
31 return -EINVAL;
32 if (!sdev)
33 return -ENODEV;
34 ret = spmi_ext_register_readl(sdev, reg, &rdata, 1);
35 if (ret < 0)
36 return ret;
37
38 rdata &= (mask << shift);
39 *val = (rdata >> shift);
40
41 return 0;
42 }
43
mt6363_psc_write_field(uint32_t reg,uint32_t val,uint32_t mask,uint32_t shift)44 static int mt6363_psc_write_field(uint32_t reg, uint32_t val, uint32_t mask, uint32_t shift)
45 {
46 uint8_t org = 0;
47 int ret = 0;
48
49 if (!sdev)
50 return -ENODEV;
51 ret = spmi_ext_register_readl(sdev, reg, &org, 1);
52 if (ret < 0)
53 return ret;
54
55 org &= ~(mask << shift);
56 org |= (val << shift);
57
58 ret = spmi_ext_register_writel(sdev, reg, &org, 1);
59 return ret;
60 }
61
62 static const struct pmic_psc_config mt6363_psc_config = {
63 .read_field = mt6363_psc_read_field,
64 .write_field = mt6363_psc_write_field,
65 .regs = mt6363_psc_regs,
66 .reg_size = ARRAY_SIZE(mt6363_psc_regs),
67 };
68
mt6363_psc_init(void)69 static int mt6363_psc_init(void)
70 {
71 sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
72 if (!sdev)
73 ERROR("%s: get spmi device fail\n", __func__);
74 return pmic_psc_register(&mt6363_psc_config);
75 }
76
77 MTK_PLAT_SETUP_0_INIT(mt6363_psc_init);
78
79 #ifdef CONFIG_MTK_PMIC_SPT_SUPPORT
mt6363_spt_enable(void)80 static int mt6363_spt_enable(void)
81 {
82 /* Enable PMIC Self-Protection Timer(SPT) */
83 return mt6363_psc_write_field(MT6363_RG_SELFWDT_EN_ADDR, MT6363_RG_SELFWDT_EN_MASK,
84 MT6363_RG_SELFWDT_EN_MASK, 0);
85 }
86
87 MTK_PLAT_RUNTIME_INIT(mt6363_spt_enable);
88 #endif
89