1 /*
2  * Copyright 2020-2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <common/debug.h>
10 #include <drivers/delay_timer.h>
11 #include <lib/mmio.h>
12 
13 #include "upower_api.h"
14 #include "upower_defs.h"
15 
16 #define UPOWER_AP_MU1_ADDR	U(0x29280000)
17 
18 struct MU_t *muptr = (struct MU_t *)UPOWER_AP_MU1_ADDR;
19 
upower_apd_inst_isr(upwr_isr_callb txrx_isr,upwr_isr_callb excp_isr)20 void upower_apd_inst_isr(upwr_isr_callb txrx_isr,
21 			 upwr_isr_callb excp_isr)
22 {
23 	/* Do nothing */
24 }
25 
upower_status(int status)26 int upower_status(int status)
27 {
28 	int ret = -1;
29 
30 	switch (status) {
31 	case 0:
32 		VERBOSE("finished successfully!\n");
33 		ret = 0;
34 		break;
35 	case -1:
36 		VERBOSE("memory allocation or resource failed!\n");
37 		break;
38 	case -2:
39 		VERBOSE("invalid argument!\n");
40 		break;
41 	case -3:
42 		VERBOSE("called in an invalid API state!\n");
43 		break;
44 	default:
45 		VERBOSE("invalid return status\n");
46 		break;
47 	}
48 
49 	return ret;
50 }
51 
52 
upower_wait_resp(void)53 void upower_wait_resp(void)
54 {
55 	while (muptr->RSR.B.RF0 == 0) {
56 		udelay(100);
57 	}
58 	upwr_txrx_isr();
59 }
60 
user_upwr_rdy_callb(uint32_t soc,uint32_t vmajor,uint32_t vminor)61 static void user_upwr_rdy_callb(uint32_t soc, uint32_t vmajor, uint32_t vminor)
62 {
63 	NOTICE("%s: soc=%x\n", __func__, soc);
64 	NOTICE("%s: RAM version:%d.%d\n", __func__, vmajor, vminor);
65 }
66 
upower_init(void)67 int upower_init(void)
68 {
69 	int status;
70 
71 	status = upwr_init(APD_DOMAIN, muptr, NULL, NULL, upower_apd_inst_isr, NULL);
72 	if (upower_status(status)) {
73 		ERROR("%s: upower init failure\n", __func__);
74 		return -EINVAL;
75 	}
76 
77 	NOTICE("%s: start uPower RAM service\n", __func__);
78 	status = upwr_start(1, user_upwr_rdy_callb);
79 	upower_wait_resp();
80 	/* poll status */
81 	if (upower_status(status)) {
82 		NOTICE("%s: upower init failure\n", __func__);
83 		return status;
84 	}
85 
86 	return 0;
87 }
88 
upower_pwm(int domain_id,bool pwr_on)89 int upower_pwm(int domain_id, bool pwr_on)
90 {
91 	int ret, ret_val;
92 	uint32_t swt;
93 
94 	if (domain_id == 9U || domain_id == 11U || domain_id == 12U) {
95 		swt = BIT_32(12) | BIT_32(11) | BIT_32(10) | BIT_32(9);
96 	} else {
97 		swt = BIT_32(domain_id);
98 	}
99 
100 	if (pwr_on) {
101 		ret = upwr_pwm_power_on(&swt, NULL, NULL);
102 	} else {
103 		ret = upwr_pwm_power_off(&swt, NULL, NULL);
104 	}
105 
106 	if (ret) {
107 		NOTICE("%s failed: ret: %d, pwr_on: %d\n", __func__, ret, pwr_on);
108 		return ret;
109 	}
110 	upower_wait_resp();
111 
112 	ret = upwr_poll_req_status(UPWR_SG_PWRMGMT, NULL, NULL, &ret_val, 1000);
113 	if (ret != UPWR_REQ_OK) {
114 		NOTICE("Failure %d, %s\n", ret, __func__);
115 		if (ret == UPWR_REQ_BUSY) {
116 			return -EBUSY;
117 		} else {
118 			return -EINVAL;
119 		}
120 	}
121 
122 	return 0;
123 }
124 
upower_read_temperature(uint32_t sensor_id,int32_t * temperature)125 int upower_read_temperature(uint32_t sensor_id, int32_t *temperature)
126 {
127 	int ret, ret_val;
128 	upwr_resp_t err_code;
129 	int64_t t;
130 
131 	ret = upwr_tpm_get_temperature(sensor_id, NULL);
132 	if (ret) {
133 		return ret;
134 	}
135 
136 	upower_wait_resp();
137 	ret = upwr_poll_req_status(UPWR_SG_TEMPM, NULL, &err_code, &ret_val, 1000);
138 	if (ret > UPWR_REQ_OK) {
139 		return ret;
140 	}
141 
142 	t = ret_val & 0xff;
143 	*temperature = (2673049 * t * t * t / 10000000 + 3734262 * t * t / 100000 +
144 			4487042 * t / 100 - 4698694) / 100000;
145 
146 	return 0;
147 }
148 
upower_pmic_i2c_write(uint32_t reg_addr,uint32_t reg_val)149 int upower_pmic_i2c_write(uint32_t reg_addr, uint32_t reg_val)
150 {
151 	int ret, ret_val;
152 	upwr_resp_t err_code;
153 
154 	ret = upwr_xcp_i2c_access(0x32, 1, 1, reg_addr, reg_val, NULL);
155 	if (ret) {
156 		WARN("pmic i2c read failed ret %d\n", ret);
157 		return ret;
158 	}
159 
160 	upower_wait_resp();
161 	ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
162 	if (ret != UPWR_REQ_OK) {
163 		WARN("i2c poll Failure %d, err_code %d, ret_val 0x%x\n",
164 		     ret, err_code, ret_val);
165 		return ret;
166 	}
167 
168 	VERBOSE("PMIC write reg[0x%x], val[0x%x]\n", reg_addr, reg_val);
169 
170 	return 0;
171 }
172 
upower_pmic_i2c_read(uint32_t reg_addr,uint32_t * reg_val)173 int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val)
174 {
175 	int ret, ret_val;
176 	upwr_resp_t err_code;
177 
178 	if (reg_val == NULL) {
179 		return -1;
180 	}
181 
182 	ret = upwr_xcp_i2c_access(0x32, -1, 1, reg_addr, 0, NULL);
183 	if (ret) {
184 		WARN("pmic i2c read failed ret %d\n", ret);
185 		return ret;
186 	}
187 
188 	upower_wait_resp();
189 	ret = upwr_poll_req_status(UPWR_SG_EXCEPT, NULL, &err_code, &ret_val, 1000);
190 	if (ret != UPWR_REQ_OK) {
191 		WARN("i2c poll Failure %d, err_code %d, ret_val 0x%x\n",
192 			ret, err_code, ret_val);
193 		return ret;
194 	}
195 
196 	*reg_val = ret_val;
197 
198 	VERBOSE("PMIC read reg[0x%x], val[0x%x]\n", reg_addr, *reg_val);
199 
200 	return 0;
201 }
202