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 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 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 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 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 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 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 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 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 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