xref: /rk3399_ARM-atf/plat/mediatek/drivers/pmic/pmic_psc.c (revision 52e486f6a6192bd18d36cdcbc35c59092eefc810)
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 #ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG
12 #include <drivers/pmic/pmic_shutdown_cfg.h>
13 #endif
14 
15 #define ERR_INVALID_ARGS	-EINVAL
16 #define ERR_NOT_CONFIGURED	-ENODEV
17 
18 static const struct pmic_psc_config *pmic_psc;
19 
20 static uint32_t read_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
21 {
22 	uint32_t val = 0;
23 	const struct pmic_psc_reg *reg;
24 
25 	if (reg_name >= pmic_psc->reg_size)
26 		return 0;
27 
28 	reg = &pmic_psc->regs[reg_name];
29 	pmic_psc->read_field(reg->reg_addr, &val, reg->reg_mask, reg->reg_shift);
30 	return val;
31 }
32 
33 static int set_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
34 {
35 	const struct pmic_psc_reg *reg;
36 
37 	if (reg_name >= pmic_psc->reg_size)
38 		return ERR_INVALID_ARGS;
39 
40 	reg = &pmic_psc->regs[reg_name];
41 	pmic_psc->write_field(reg->reg_addr, 1, reg->reg_mask, reg->reg_shift);
42 	return 0;
43 }
44 
45 static int clr_pmic_psc_reg(enum pmic_psc_reg_name reg_name)
46 {
47 	const struct pmic_psc_reg *reg;
48 
49 	if (reg_name >= pmic_psc->reg_size)
50 		return ERR_INVALID_ARGS;
51 
52 	reg = &pmic_psc->regs[reg_name];
53 	pmic_psc->write_field(reg->reg_addr, 0, reg->reg_mask, reg->reg_shift);
54 	return 0;
55 }
56 
57 int enable_pmic_smart_reset(bool enable)
58 {
59 	if (!pmic_psc)
60 		return ERR_NOT_CONFIGURED;
61 	if (enable)
62 		set_pmic_psc_reg(RG_SMART_RST_MODE);
63 	else
64 		clr_pmic_psc_reg(RG_SMART_RST_MODE);
65 	return 0;
66 }
67 
68 int enable_pmic_smart_reset_shutdown(bool enable)
69 {
70 	if (!pmic_psc)
71 		return ERR_NOT_CONFIGURED;
72 	if (enable)
73 		set_pmic_psc_reg(RG_SMART_RST_SDN_EN);
74 	else
75 		clr_pmic_psc_reg(RG_SMART_RST_SDN_EN);
76 	return 0;
77 }
78 
79 int platform_cold_reset(void)
80 {
81 	if (!pmic_psc)
82 		return ERR_NOT_CONFIGURED;
83 	/* Some PMICs may not support cold reset */
84 	if (!pmic_psc->regs[RG_CRST].reg_addr)
85 		return ERR_NOT_CONFIGURED;
86 	set_pmic_psc_reg(RG_CRST);
87 	return 0;
88 }
89 
90 int platform_power_hold(bool hold)
91 {
92 	int use_spmi_cmd_sdn = 0;
93 
94 	if (!pmic_psc)
95 		return ERR_NOT_CONFIGURED;
96 	if (hold)
97 		set_pmic_psc_reg(RG_PWRHOLD);
98 	else {
99 #ifdef CONFIG_MTK_PMIC_SHUTDOWN_CFG
100 		use_spmi_cmd_sdn = pmic_shutdown_cfg();
101 #endif
102 		if (use_spmi_cmd_sdn == 1)
103 			spmi_shutdown();
104 		else
105 			clr_pmic_psc_reg(RG_PWRHOLD);
106 	}
107 	return 0;
108 }
109 
110 int pmic_psc_register(const struct pmic_psc_config *psc)
111 {
112 	if (!psc || !psc->regs || !psc->read_field || !psc->write_field)
113 		return ERR_INVALID_ARGS;
114 	pmic_psc = psc;
115 	INFO("POWER_HOLD=0x%x\n", read_pmic_psc_reg(RG_PWRHOLD));
116 	return 0;
117 }
118