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