Peng Fan | ac2cb4d | 2021-08-07 16:01:10 +0800 | [diff] [blame] | 1 | /* SPDX-License-Identifier: BSD-3-Clause */ |
| 2 | /* |
| 3 | * Copyright 2020 NXP |
| 4 | */ |
| 5 | |
| 6 | enum soc_domain { |
| 7 | RTD_DOMAIN = 0, |
| 8 | APD_DOMAIN = 1, |
| 9 | UPWR_MAIN_DOMAINS, /* RTD, AVD */ |
| 10 | AVD_DOMAIN = UPWR_MAIN_DOMAINS, |
| 11 | UPWR_DOMAIN_COUNT, /* RTD, APD, AVD */ |
| 12 | PSD_DOMAIN = UPWR_DOMAIN_COUNT, |
| 13 | UPWR_ALL_DOMAINS /* RTD, APD, AVD, PSD */ |
| 14 | }; |
| 15 | |
| 16 | enum upwr_api_state { |
| 17 | UPWR_API_INIT_WAIT, /* waiting for ROM firmware initialization */ |
| 18 | UPWR_API_INITLZED, /* ROM firmware initialized */ |
| 19 | UPWR_API_START_WAIT, /* waiting for start services */ |
| 20 | UPWR_API_READY /* ready to receive service requests */ |
| 21 | }; |
| 22 | |
| 23 | enum upwr_sg { /* Service Groups in priority order, high to low */ |
| 24 | UPWR_SG_EXCEPT, /* 0 = exception */ |
| 25 | UPWR_SG_PWRMGMT, /* 1 = power management */ |
| 26 | UPWR_SG_DELAYM, /* 2 = delay measurement */ |
| 27 | UPWR_SG_VOLTM, /* 3 = voltage measurement */ |
| 28 | UPWR_SG_CURRM, /* 4 = current measurement */ |
| 29 | UPWR_SG_TEMPM, /* 5 = temperature measurement */ |
| 30 | UPWR_SG_DIAG, /* 6 = diagnostic */ |
| 31 | UPWR_SG_COUNT |
| 32 | }; |
| 33 | |
| 34 | enum upwr_xcp_f { /* Exception Functions */ |
| 35 | /* 0 = init msg (not a service request itself) */ |
| 36 | UPWR_XCP_INIT, |
| 37 | /* 0 = also ping request, since its response is an init msg */ |
| 38 | UPWR_XCP_PING = UPWR_XCP_INIT, |
| 39 | UPWR_XCP_START, /* 1 = service start: upwr_start (not a service request itself) */ |
| 40 | UPWR_XCP_SHUTDOWN, /* 2 = service shutdown: upwr_xcp_shutdown */ |
| 41 | UPWR_XCP_CONFIG, /* 3 = uPower configuration: upwr_xcp_config */ |
| 42 | UPWR_XCP_SW_ALARM, /* 4 = uPower software alarm: upwr_xcp_sw_alarm */ |
| 43 | UPWR_XCP_I2C, /* 5 = I2C access: upwr_xcp_i2c_access */ |
| 44 | UPWR_XCP_SPARE_6, /* 6 = spare */ |
| 45 | UPWR_XCP_SET_DDR_RETN, /* 7 = set/clear ddr retention */ |
| 46 | UPWR_XCP_SPARE_8, /* 8 = spare */ |
| 47 | UPWR_XCP_SPARE_9, /* 9 = spare */ |
| 48 | UPWR_XCP_SPARE_10, /* 10 = spare */ |
| 49 | UPWR_XCP_SPARE_11, /* 11 = spare */ |
| 50 | UPWR_XCP_SPARE_12, /* 12 = spare */ |
| 51 | UPWR_XCP_SPARE_13, /* 13 = spare */ |
| 52 | UPWR_XCP_SPARE_14, /* 14 = spare */ |
| 53 | UPWR_XCP_SPARE_15, /* 15 = spare */ |
| 54 | UPWR_XCP_F_COUNT |
| 55 | }; |
| 56 | |
| 57 | enum upwr_resp { /* response error codes */ |
| 58 | UPWR_RESP_OK = 0, /* no error */ |
| 59 | UPWR_RESP_SG_BUSY, /* service group is busy */ |
| 60 | UPWR_RESP_SHUTDOWN, /* services not up or shutting down */ |
| 61 | UPWR_RESP_BAD_REQ, /* invalid request */ |
| 62 | UPWR_RESP_BAD_STATE, /* system state doesn't allow perform the request */ |
| 63 | UPWR_RESP_UNINSTALLD, /* service or function not installed */ |
| 64 | UPWR_RESP_UNINSTALLED = |
| 65 | UPWR_RESP_UNINSTALLD, /* service or function not installed (alias) */ |
| 66 | UPWR_RESP_RESOURCE, /* resource not available */ |
| 67 | UPWR_RESP_TIMEOUT, /* service timeout */ |
| 68 | UPWR_RESP_COUNT |
| 69 | }; |
| 70 | |
| 71 | #define UPWR_SRVGROUP_BITS (4) |
| 72 | #define UPWR_FUNCTION_BITS (4) |
| 73 | #define UPWR_PWDOMAIN_BITS (4) |
| 74 | #define UPWR_HEADER_BITS (UPWR_SRVGROUP_BITS + UPWR_FUNCTION_BITS + UPWR_PWDOMAIN_BITS) |
| 75 | #define UPWR_ARG_BITS (32 - UPWR_HEADER_BITS) |
| 76 | |
| 77 | #define UPWR_DUAL_OFFSET_BITS ((UPWR_ARG_BITS + 32) >> 1) |
| 78 | |
| 79 | struct upwr_msg_hdr { |
| 80 | u32 domain :UPWR_PWDOMAIN_BITS; /* power domain */ |
| 81 | u32 srvgrp :UPWR_SRVGROUP_BITS; /* service group */ |
| 82 | u32 function :UPWR_FUNCTION_BITS; /* function */ |
| 83 | u32 arg :UPWR_ARG_BITS; /* function-specific argument */ |
| 84 | }; |
| 85 | |
| 86 | union upwr_down_1w_msg { |
| 87 | struct upwr_msg_hdr hdr; |
| 88 | u32 word; /* message first word */ |
| 89 | }; |
| 90 | |
| 91 | #define upwr_start_msg union upwr_down_1w_msg |
| 92 | #define upwr_xcp_ping_msg union upwr_down_1w_msg |
| 93 | |
| 94 | #define UPWR_RESP_ERR_BITS (4) |
| 95 | #define UPWR_RESP_HDR_BITS (UPWR_RESP_ERR_BITS + \ |
| 96 | UPWR_SRVGROUP_BITS + UPWR_FUNCTION_BITS) |
| 97 | #define UPWR_RESP_RET_BITS (32 - UPWR_RESP_HDR_BITS) |
| 98 | |
| 99 | struct upwr_resp_hdr { |
| 100 | u32 errcode :UPWR_RESP_ERR_BITS; |
| 101 | u32 srvgrp :UPWR_SRVGROUP_BITS; /* service group */ |
| 102 | u32 function:UPWR_FUNCTION_BITS; |
| 103 | u32 ret :UPWR_RESP_RET_BITS; /* return value, if any */ |
| 104 | }; |
| 105 | |
| 106 | struct upwr_up_2w_msg { |
| 107 | struct upwr_resp_hdr hdr; |
| 108 | u32 word2; /* message second word */ |
| 109 | }; |
| 110 | |
| 111 | #define upwr_up_max_msg struct upwr_up_2w_msg |
| 112 | |
| 113 | union upwr_2pointer_msg { |
| 114 | struct upwr_msg_hdr hdr; |
| 115 | struct { |
| 116 | u64:UPWR_HEADER_BITS; |
| 117 | u64 ptr0:UPWR_DUAL_OFFSET_BITS; |
| 118 | u64 ptr1:UPWR_DUAL_OFFSET_BITS; |
| 119 | } ptrs; |
| 120 | }; |
| 121 | |
| 122 | #define upwr_pwm_pwron_msg union upwr_2pointer_msg |
| 123 | |
| 124 | struct upwr_pointer_msg { |
| 125 | struct upwr_msg_hdr hdr; |
| 126 | u32 ptr; /* config struct offset */ |
| 127 | }; |
| 128 | |
| 129 | struct upwr_i2c_access { /* structure pointed by message upwr_xcp_i2c_msg */ |
| 130 | u16 addr; |
| 131 | s8 data_size; |
| 132 | u8 subaddr_size; |
| 133 | u32 subaddr; |
| 134 | u32 data; |
| 135 | }; |
| 136 | |
| 137 | enum upwr_req_status { |
| 138 | UPWR_REQ_OK, /* request succeeded */ |
| 139 | UPWR_REQ_ERR, /* request failed */ |
| 140 | UPWR_REQ_BUSY /* request execution ongoing */ |
| 141 | }; |
| 142 | |
| 143 | #define UPWR_SOC_BITS (7) |
| 144 | #define UPWR_VMINOR_BITS (4) |
| 145 | #define UPWR_VFIXES_BITS (4) |
| 146 | #define UPWR_VMAJOR_BITS \ |
| 147 | (32 - UPWR_HEADER_BITS - UPWR_SOC_BITS - UPWR_VMINOR_BITS - UPWR_VFIXES_BITS) |
| 148 | union upwr_init_msg { |
| 149 | struct upwr_resp_hdr hdr; |
| 150 | struct { |
| 151 | u32 rsv:UPWR_RESP_HDR_BITS; |
| 152 | u32 soc:UPWR_SOC_BITS; /* SoC identification */ |
| 153 | u32 vmajor:UPWR_VMAJOR_BITS; /* firmware major version */ |
| 154 | u32 vminor:UPWR_VMINOR_BITS; /* firmware minor version */ |
| 155 | u32 vfixes:UPWR_VFIXES_BITS; /* firmware fixes version */ |
| 156 | } args; |
| 157 | }; |
| 158 | |
| 159 | #define UPWR_RAM_VMINOR_BITS (7) |
| 160 | #define UPWR_RAM_VFIXES_BITS (6) |
| 161 | #define UPWR_RAM_VMAJOR_BITS (32 - UPWR_HEADER_BITS - UPWR_RAM_VFIXES_BITS - UPWR_RAM_VMINOR_BITS) |
| 162 | |
| 163 | union upwr_ready_msg { |
| 164 | struct upwr_resp_hdr hdr; |
| 165 | struct { |
| 166 | u32 rsv:UPWR_RESP_HDR_BITS; |
| 167 | u32 vmajor:UPWR_RAM_VMAJOR_BITS; /* RAM fw major version */ |
| 168 | u32 vminor:UPWR_RAM_VMINOR_BITS; /* RAM fw minor version */ |
| 169 | u32 vfixes:UPWR_RAM_VFIXES_BITS; /* RAM fw fixes version */ |
| 170 | } args; |
| 171 | }; |
| 172 | |
| 173 | struct upwr_reg_access_t { |
| 174 | u32 addr; |
| 175 | u32 data; |
| 176 | u32 mask; /* mask=0 commands read */ |
| 177 | }; |
| 178 | |
| 179 | union upwr_xcp_union { |
| 180 | struct upwr_reg_access_t reg_access; |
| 181 | }; |
| 182 | |
| 183 | enum { /* Power Management Functions */ |
| 184 | UPWR_PWM_REGCFG, /* 0 = regulator config: upwr_pwm_reg_config */ |
| 185 | UPWR_PWM_DEVMODE = UPWR_PWM_REGCFG, /* deprecated, for old compile */ |
| 186 | UPWR_PWM_VOLT, /* 1 = voltage change: upwr_pwm_chng_reg_voltage */ |
| 187 | UPWR_PWM_SWITCH, /* 2 = switch control: upwr_pwm_chng_switch_mem */ |
| 188 | UPWR_PWM_PWR_ON, /* 3 = switch/RAM/ROM power on: upwr_pwm_power_on */ |
| 189 | UPWR_PWM_PWR_OFF, /* 4 = switch/RAM/ROM power off: upwr_pwm_power_off */ |
| 190 | UPWR_PWM_RETAIN, /* 5 = retain memory array: upwr_pwm_mem_retain */ |
| 191 | UPWR_PWM_DOM_BIAS, /* 6 = Domain bias control: upwr_pwm_chng_dom_bias */ |
| 192 | UPWR_PWM_MEM_BIAS, /* 7 = Memory bias control: upwr_pwm_chng_mem_bias */ |
| 193 | UPWR_PWM_PMICCFG, /* 8 = PMIC configuration: upwr_pwm_pmic_config */ |
| 194 | UPWR_PWM_PMICMOD = UPWR_PWM_PMICCFG, /* deprecated, for old compile */ |
| 195 | UPWR_PWM_PES, /* 9 = Power Event Sequencer */ |
| 196 | UPWR_PWM_CONFIG, /* 10= apply power mode defined configuration */ |
| 197 | UPWR_PWM_CFGPTR, /* 11= configuration pointer */ |
| 198 | UPWR_PWM_DOM_PWRON, /* 12 = domain power on: upwr_pwm_dom_power_on */ |
| 199 | UPWR_PWM_BOOT, /* 13 = boot start: upwr_pwm_boot_start */ |
| 200 | UPWR_PWM_FREQ, /* 14 = domain frequency setup */ |
| 201 | UPWR_PWM_PARAM, /* 15 = power management parameters */ |
| 202 | UPWR_PWM_F_COUNT |
| 203 | }; |
| 204 | |
| 205 | #ifndef UPWR_PMC_SWT_WORDS |
| 206 | #define UPWR_PMC_SWT_WORDS (1) |
| 207 | #endif |
| 208 | |
| 209 | #ifndef UPWR_PMC_MEM_WORDS |
| 210 | #define UPWR_PMC_MEM_WORDS (2) |
| 211 | #endif |
| 212 | |
| 213 | #define UPWR_API_ASSERT(c) do { } while (0) |
| 214 | |
| 215 | struct upwr_code_vers { |
| 216 | u32 soc_id; |
| 217 | u32 vmajor; |
| 218 | u32 vminor; |
| 219 | u32 vfixes; |
| 220 | }; |
| 221 | |
| 222 | #define UPWR_MU_MSG_SIZE (2) |
| 223 | |
| 224 | #define UPWR_MU_TSR_EMPTY ((u32)((1 << UPWR_MU_MSG_SIZE) - 1)) |
| 225 | |
| 226 | #ifndef UPWR_DRAM_SHARED_BASE_ADDR |
| 227 | #define UPWR_DRAM_SHARED_BASE_ADDR (0x28330000) |
| 228 | #endif |
| 229 | |
| 230 | #ifndef UPWR_DRAM_SHARED_SIZE |
| 231 | #define UPWR_DRAM_SHARED_SIZE (2048) |
| 232 | #endif |
| 233 | |
| 234 | #define UPWR_DRAM_SHARED_ENDPLUS (UPWR_DRAM_SHARED_BASE_ADDR + UPWR_DRAM_SHARED_SIZE) |
| 235 | |
| 236 | #ifndef UPWR_API_BUFFER_BASE |
| 237 | #define UPWR_API_BUFFER_BASE (0x28330600) |
| 238 | #endif |
| 239 | |
| 240 | #ifndef UPWR_API_BUFFER_ENDPLUS |
| 241 | #define UPWR_API_BUFFER_ENDPLUS (UPWR_DRAM_SHARED_ENDPLUS - 64) |
| 242 | #endif |
| 243 | |
| 244 | typedef void (*upwr_rdy_callb)(u32 vmajor, u32 vminor, u32 vfixes); |
| 245 | typedef void (*upwr_callb)(enum upwr_sg sg, u32 func, enum upwr_resp errcode, int ret); |
| 246 | int upwr_init(enum soc_domain domain, struct mu_type *muptr); |
| 247 | int upwr_start(u32 launchopt, const upwr_rdy_callb rdycallb); |
| 248 | u32 upwr_rom_version(u32 *vmajor, u32 *vminor, u32 *vfixes); |
| 249 | typedef void (*UPWR_RX_CALLB_FUNC_T)(void); |
| 250 | |
| 251 | int upwr_xcp_set_ddr_retention(enum soc_domain domain, u32 enable, const upwr_callb callb); |
| 252 | int upwr_pwm_power_on(const u32 swton[], const u32 memon[], upwr_callb callb); |
| 253 | int upwr_xcp_i2c_access(u16 addr, s8 data_size, u8 subaddr_size, u32 subaddr, |
| 254 | u32 wdata, const upwr_callb callb); |
| 255 | enum upwr_req_status upwr_poll_req_status(enum upwr_sg sg, u32 *sgfptr, |
| 256 | enum upwr_resp *errptr, int *retptr, |
| 257 | u32 attempts); |
| 258 | void upwr_txrx_isr(void); |