blob: 337857b74be3e08402b877b923cbddc0e9e8480c [file] [log] [blame]
Jacky Bai4d93d1d2020-07-02 14:39:58 +08001/*
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
18struct MU_t *muptr = (struct MU_t *)UPOWER_AP_MU1_ADDR;
19
20void upower_apd_inst_isr(upwr_isr_callb txrx_isr,
21 upwr_isr_callb excp_isr)
22{
23 /* Do nothing */
24}
25
26int 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
53void upower_wait_resp(void)
54{
55 while (muptr->RSR.B.RF0 == 0) {
56 udelay(100);
57 }
58 upwr_txrx_isr();
59}
60
61static 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
67int 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
89int 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
125int 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}
Jacky Bai8d07de32022-05-27 15:33:40 +0800148
149int 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
173int 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}