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