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 20 void upower_apd_inst_isr(upwr_isr_callb txrx_isr, 21 upwr_isr_callb excp_isr) 22 { 23 /* Do nothing */ 24 } 25 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 53 void upower_wait_resp(void) 54 { 55 while (muptr->RSR.B.RF0 == 0) { 56 udelay(100); 57 } 58 upwr_txrx_isr(); 59 } 60 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 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 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 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 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 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