1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /**
3  * Copyright 2019-2023 NXP
4  *
5  * KEYWORDS: micro-power uPower driver API
6  * -----------------------------------------------------------------------------
7  * PURPOSE: SoC-dependent uPower driver API #defines and typedefs shared
8  *          with the firmware
9  * -----------------------------------------------------------------------------
10  * PARAMETERS:
11  * PARAM NAME RANGE:DESCRIPTION:       DEFAULTS:                           UNITS
12  * -----------------------------------------------------------------------------
13  * REUSE ISSUES: no reuse issues
14  */
15 
16 #ifndef _UPWR_SOC_DEFS_H
17 #define _UPWR_SOC_DEFS_H
18 
19 #include <stdbool.h>
20 
21 #ifndef TYPES_LOCAL_H
22 #include <stdint.h>
23 #endif
24 
25 #ifdef _UPWR_DEFS_H
26 #error "upower_defs.h or upower_api.h included before upower_soc_defs.h"
27 #endif
28 
29 #define UPWR_MU_MSG_SIZE            (2U) /* words */
30 
31 #ifdef   NUM_PMC_SWT_WORDS
32 #define UPWR_PMC_SWT_WORDS          NUM_PMC_SWT_WORDS
33 #endif
34 
35 #ifdef   NUM_PMC_RAM_WORDS
36 #define UPWR_PMC_MEM_WORDS          NUM_PMC_RAM_WORDS
37 #endif
38 
39 #ifndef UPWR_DRAM_SHARED_BASE_ADDR
40 #define UPWR_DRAM_SHARED_BASE_ADDR      (0x28330000U)
41 #endif
42 
43 #ifndef UPWR_DRAM_SHARED_SIZE
44 #define UPWR_DRAM_SHARED_SIZE           (2048U)
45 #endif
46 
47 #define UPWR_DRAM_SHARED_ENDPLUS        (UPWR_DRAM_SHARED_BASE_ADDR+\
48 					 UPWR_DRAM_SHARED_SIZE)
49 
50 #ifndef UPWR_API_BUFFER_BASE
51 #define UPWR_API_BUFFER_BASE            (0x28330600U)
52 #endif
53 
54 #ifndef UPWR_API_BUFFER_ENDPLUS
55 #define UPWR_API_BUFFER_ENDPLUS         (UPWR_DRAM_SHARED_ENDPLUS - 64U)
56 #endif
57 
58 #ifndef UPWR_PMC_SWT_WORDS
59 #define UPWR_PMC_SWT_WORDS              (1U)
60 #endif
61 
62 #ifndef UPWR_PMC_MEM_WORDS
63 #define UPWR_PMC_MEM_WORDS              (2U)
64 #endif
65 
66 #define UPWR_OSC_HI_FREQ               (64U) // MHz
67 #define UPWR_OSC_LO_FREQ               (16U) // MHz
68 
69 #ifndef UPWR_I2C_FREQ
70 #define UPWR_I2C_FREQ                  (UPWR_OSC_HI_FREQ * 1000000U)
71 #endif
72 
73 /******************************************************************************
74  * i.MX8ULP-dependent uPower API Definition
75  *
76  * Copyright 2019-2023 NXP
77  *
78  * This chapter documents the API definitions that are specific to the
79  * i.MX8ULP SoC.
80  *
81  */
82 
83 /**---------------------------------------------------------------
84  * INITIALIZATION, CONFIGURATION
85  *
86  * i.MX8ULP provides only one Message Unit (MU) for each core domain:
87  * Real Time Domain (RTD) and Application Domain (APD), which has two A35 cores.
88  * Both A35 cores in APD must share the same API instance, meaning upwr_init
89  * must be called only once for each domain. The API does not provide any
90  * mutually exclusion or locking mechanism for concurrent accesses from both
91  * APD cores, so any API arbitration, if needed, must be implemented by the
92  * API user code.
93  *
94  * A domain must not go to Power Down (PD) or Deep Power Down (DPD) power modes
95  * with any service still pending (response not received).
96  *
97  * Next sections describe the i.MX8ULP particularities of service calls.
98  *
99  */
100 
101 /**+
102  * upwr_start()
103  *
104  * i.MX8ULP ROM firmware provides only the launch option 0, which has no
105  * power mode transition support and provides the following services:
106  * - upwr_xcp_config
107  * - upwr_xcp_sw_alarm
108  * - upwr_pwm_param
109  * - upwr_pwm_power_on
110  * - upwr_pwm_power-off
111  * - upwr_pwm_mem_retain
112  * - upwr_pwm_chng_dom_bias
113  * - upwr_pwm_chng_mem_bias
114  *
115  * i.MX8ULP RAM firmware provides 2 launch options:
116  *
117  * 1. starts all tasks, services and power mode ones;
118  *    this is the full-featured firmware option.
119  * 2. starts only the power mode tasks; services are not available with
120  *    this option, and futher calls to upwr_start (from either domain)
121  *    have no response; this option is mostly used to accelerate power mode
122  *    mixed-signal simulations, and not intended to be used with silicon.
123  *
124  * Note: option 0 is also available if the RAM firmware is loaded.
125  */
126 
127 /* service upwr_pwm_set_domain_pmic_rail message argument fields*/
128 typedef struct {
129 	uint32_t domain: 16U;
130 	uint32_t rail: 16U;
131 } upwr_pwm_dom_pmic_rail_args;
132 
133 /* service upwr_pwm_chng_dom_bias message argument fields */
134 
135 #define UPWR_DOMBIAS_MODE_BITS    (2U)
136 #define UPWR_DOMBIAS_RBB_BITS     (8U)
137 #define UPWR_DOMBIAS_RSV_BITS     (14U)
138 #define UPWR_DOMBIAS_ARG_BITS     (UPWR_DOMBIAS_RSV_BITS      + \
139                                    (2U * UPWR_DOMBIAS_MODE_BITS) + \
140                                    (4U * UPWR_DOMBIAS_RBB_BITS)  + 2U)
141 
142 typedef struct {
143 	uint32_t  :12U; /* TODO: find a way to use UPWR_HEADER_BITS */
144 	uint32_t dommode:UPWR_DOMBIAS_MODE_BITS;
145 	uint32_t avdmode:UPWR_DOMBIAS_MODE_BITS;
146 	uint32_t domapply:1U;
147 	uint32_t avdapply:1U;
148 	uint32_t rsv     :UPWR_DOMBIAS_RSV_BITS;
149 	uint32_t domrbbn :UPWR_DOMBIAS_RBB_BITS;/* RTD/APD back bias N-well */
150 	uint32_t domrbbp :UPWR_DOMBIAS_RBB_BITS;/* RTD/APD back bias P-well */
151 	uint32_t avdrbbn :UPWR_DOMBIAS_RBB_BITS;/* AVD     back bias N-well */
152 	uint32_t avdrbbp :UPWR_DOMBIAS_RBB_BITS;/* AVD     back bias P-well */
153 } upwr_pwm_dom_bias_args;
154 
155 #define UPWR_FILL_DOMBIAS_ARGS(dom, bias, args)           \
156 do {                                                      \
157 	(args).B.domapply = (args).B.avdapply = 0U;            \
158                                                           \
159 	switch ((bias)->apply) {                            \
160 		case BIAS_APPLY_RTD_AVD:                  \
161 			(args).B.avdapply = 1U;              \
162             /* fall through */                 \
163 		case BIAS_APPLY_RTD:                      \
164 			(dom) = (uint32_t)RTD_DOMAIN;       \
165 			(args).B.domapply = 1U;              \
166 			break;                            \
167 		case BIAS_APPLY_APD_AVD:                  \
168 			(args).B.avdapply = 1U;              \
169             /* fall through */                 \
170 		case BIAS_APPLY_APD:                      \
171 			(dom) = (uint32_t)APD_DOMAIN;       \
172 			(args).B.domapply = 1U;              \
173 			break;                            \
174 		case BIAS_APPLY_AVD:                      \
175 			(args).B.avdapply = 1U;              \
176 			break;                            \
177         default:                              \
178             break;                            \
179     }                                                 \
180 	(args).B.dommode = (uint32_t)((bias)->dommode);         \
181 	(args).B.avdmode = (uint32_t)((bias)->avdmode);         \
182 	uint32_t sat = UPWR_BIAS2MILIV((1UL << UPWR_DOMBIAS_RBB_BITS) - 1UL);\
183 	(args).B.domrbbn = ((bias)->dombias.rbbn > sat)? sat: \
184                      UPWR_BIAS_MILIV((bias)->dombias.rbbn); \
185 	(args).B.domrbbp = ((bias)->dombias.rbbp > sat)? sat: \
186                      UPWR_BIAS_MILIV((bias)->dombias.rbbp); \
187 	(args).B.avdrbbn = ((bias)->avdbias.rbbn > sat)? sat: \
188                      UPWR_BIAS_MILIV((bias)->avdbias.rbbn); \
189 	(args).B.avdrbbp = ((bias)->avdbias.rbbp > sat)? sat: \
190                      UPWR_BIAS_MILIV((bias)->avdbias.rbbp); \
191 } while (false)
192 
193 /* service upwr_pwm_chng_mem_bias message argument fields */
194 
195 typedef struct {
196 	uint32_t  :12U; /* TODO: find a way to use UPWR_HEADER_BITS */
197 	uint32_t en:1U;
198 	uint32_t rsv:19U;
199 } upwr_pwm_mem_bias_args;
200 
201 #define UPWR_FILL_MEMBIAS_ARGS(bias, args)                \
202 do {                                                      \
203 	(args).B.en = (bias)->en;                             \
204 } while (false)
205 
206 #include "upower_defs.h"
207 
208 #ifdef  __cplusplus
209 #ifndef UPWR_NAMESPACE /* extern "C" 'cancels' the effect of namespace */
210 extern "C" {
211 #endif
212 #endif
213 
214 #define UPWR_APD_CORES      (2U)
215 #define UPWR_RTD_CORES      (1U)
216 
217 #define RTD_DOMAIN (0U)
218 #define APD_DOMAIN (1U)
219 #define UPWR_MAIN_DOMAINS (2U)
220 #define AVD_DOMAIN (2U)
221 #define UPWR_DOMAIN_COUNT (3U)
222 #define PSD_DOMAIN (3U)
223 #define UPWR_ALL_DOMAINS (4U)
224 
225 typedef uint32_t soc_domain_t;
226 
227 /*=========================================================================
228  * UNIT CONVERSION MACROS
229  *   These macros convert physical units to the values passed as arguments
230  *   in API functions.
231  *=========================================================================*/
232 
233 #define UPWR_VOLT_MILIV(v) (v)        /* voltage in mV    to argument value */
234 #define UPWR_VOLT_MICROV(v)((v) / 1000U) /* voltage in uV    to argument value */
235 #define UPWR_BIAS_MILIV(v) (((v) + 49UL ) / 50UL)   /* bias voltage(mV) to argument value */
236 #define UPWR_BIAS2MILIV(v) ((v) * 50UL)   /* inverse of UPWR_BIAS_MILIV         */
237 #define UPWR_FREQ_KHZ(f)   (f)        /* frequency (kHz)  to argument value */
238 
239 #define UPWR_DOMBIAS_MAX_MV      (UPWR_BIAS2MILIV((1U << UPWR_DOMBIAS_RBB_BITS) - 1U))
240 
241 /**---------------------------------------------------------------
242  * EXCEPTION SERVICE GROUP
243  */
244 
245 /**+
246  * upwr_xcp_config()
247  *
248  * The i.MX8ULP uPower configuration struct contains the following bitfields:
249  *
250  *  - ALARM_INT (1 bit): tells which RTD MU interrupt should be used for alarms;
251  *    1= MU GPI1; 0= MU GPI0; APD alarms always use GPI0.
252  *  - CFG_IOMUX (1 bit): determintes if uPower configures i.MX8ULP IOMUX for
253  *    I2C and mode pins used to control an external PMIC;
254  *    1= uPower firmware or PMIC driver configures i.MX8ULP IOMUX and mode pins;
255  *    0= i.MX8ULP IOMUX and mode pins not configured by uPower;
256  *  - DGNBUFBITS (4 bits): determines the diagnostic buffer size according to
257  *    the formula: size = 2^(DGNBUFBITS+3) bytes;
258  *
259  *  Defaults are all zeroes; all other bits are reserved, and must be written 0.
260  */
261 
262 typedef union {
263 	uint32_t R;
264 	struct {
265 		uint32_t ALARM_INT   :1U; /* 1= use MU GPI1 for alarm interrupt;
266 					    0= use MU GPI0 for alarm interrupt;
267 					    this configuration is valid for
268 					    RTD only
269 					  */
270 		uint32_t CFG_IOMUX  : 1U; /* 1= tells uPower fw/PMIC driver to
271 					       config i.MX8ULP IOMUX for the PMIC
272 					       I2C and mode pins;
273 					    0= uPower fw/PMIC must not config
274 					       i.MX8ULP IOMUX, leave it to host
275 					  */
276 		uint32_t DGNBUFBITS : 4U; /* defines the diagnostic buffer size
277 					    according to the formula:
278 					    size = 2^(DGNBUFBITS+3) bytes */
279 		uint32_t RSV        :26U; /* reserved bits: should be all 0s  */
280 	} B;
281 } upwr_xcp_config_t;
282 
283 /**+
284  * upwr_xcp_sw_alarm()
285  *
286  * Argument code is defined by the enum upwr_alarm_t, with the values:
287  *  - UPWR_ALARM_INTERNAL: internal software error
288  *  - UPWR_ALARM_EXCEPTION: uPower core exception, either illegal instruction or
289  *    bus error
290  *  - UPWR_ALARM_SLACK: delay path too slow, meaning a timing violation occurred
291  *    or is iminent.
292  *  - UPWR_ALARM_VOLTAGE: one of the measured voltages is below safety margins.
293  *
294  * Note that this service emulates an alarm that would normally be issued by
295  * uPower when it detects one of the causes above. A request to alarm the APD
296  * domain when it is powered off returns success, but is ineffective.
297  *
298  */
299 
300 #define	UPWR_ALARM_INTERNAL   (0U)             /* internal error */
301 #define	UPWR_ALARM_EXCEPTION  (1U)             /* core exception */
302 #define	UPWR_ALARM_SLACK      (2U)             /* delay path too slow */
303 #define	UPWR_ALARM_VOLTAGE    (3U)             /* voltage drop */
304 #define	UPWR_ALARM_LAST       UPWR_ALARM_VOLTAGE
305 
306 typedef uint32_t upwr_alarm_t;
307 
308 /**---------------------------------------------------------------
309  * POWER MANAGEMENT SERVICE GROUP
310  */
311 
312                                      /* values in mV: */
313 
314 #define UPWR_RTD_RBBN_MAX     (1300U) /* max. RTD Reverse Back Bias N-Well */
315 #define UPWR_RTD_RBBN_MIN      (100U) /* min. RTD Reverse Back Bias N-Well */
316 
317 #define UPWR_RTD_RBBP_MAX     (1300U) /* max. RTD Reverse Back Bias P-Well */
318 #define UPWR_RTD_RBBP_MIN      (100U) /* min. RTD Reverse Back Bias P-Well */
319 
320 /* APD bias can only two values (mV): */
321 
322 #define UPWR_APD_RBBN_LO      (1000U) /* low  APD Reverse Back Bias N-Well */
323 #define UPWR_APD_RBBN_HI      (1300U) /* high APD Reverse Back Bias N-Well */
324 
325 #define UPWR_APD_RBBP_LO      (1000U) /* low  APD Reverse Back Bias P-Well */
326 #define UPWR_APD_RBBP_HI      (1300U) /* high APD Reverse Back Bias P-Well */
327 
328 /* AVD bias can only two values (mV): */
329 
330 #define UPWR_AVD_RBBN_LO      (1000U) /* low  AVD Reverse Back Bias N-Well */
331 #define UPWR_AVD_RBBN_HI      (1300U) /* high AVD Reverse Back Bias N-Well */
332 
333 #define UPWR_AVD_RBBP_LO      (1000U) /* low  AVD Reverse Back Bias P-Well */
334 #define UPWR_AVD_RBBP_HI      (1300U) /* high AVD Reverse Back Bias P-Well */
335 
336 /**+
337  * upwr_pwm_param()
338  *
339  * Argument param is defined by the struct/union upwr_pwm_param_t with the
340  * following i.MX8ULP-specific bitfields:
341  * - DPD_ALLOW (1 bit): 1= allows uPower power mode to go Deep Power Down (DPD);
342  *   uPower DPD also depends on other conditions, but if this bit is 0 uPower
343  *   won't go DPD even if those conditions are met; it can go either Sleep or
344  *   Deep Sleep (DSL) depending on the other configurations.
345  * - DSL_DIS (1 bit): if this bit is 1, uPower power mode won't go Deep Sleep
346  *   (DSL) even if the other conditions for that are met;
347  *   it may go Sleep instead.
348  * - SLP_ALLOW (1 bit): if this bit is 1, uPower power mode will go Sleep if
349  *   the conditions for Partial Active are met; it may also go Deep Sleep if bit
350  *   DSL_DIS=1.
351  * - DSL_BGAP_OFF (1 bit): 1= turns bandgap off when uPower goes Deep Sleep;
352  *   0= leaves bandgap on when uPower goes Deep Sleep (DSL).
353  * - DPD_BGAP_ON (1 bit): 1= leaves bandgap on when uPower goes Deep Power Down
354  *   (DPD); 0= powers off bandgap when uPower goes Deep Power Down (DPD).
355  *
356  *  Defaults are all zeroes; all other bits are reserved, and must be written 0.
357  */
358 
359 typedef union {
360 	uint32_t R;
361 	struct {
362 		uint32_t DPD_ALLOW   :1U; /* 1= uPower can go Deep Power Down */
363 		uint32_t DSL_DIS     :1U; /* 1= uPower won't go Deep Sleep    */
364 		uint32_t SLP_ALLOW   :1U; /* 1= uPower goes Sleep in the same
365 					       conditions as Active, and even
366 					       DSL if DSL_DIS=1  */
367 		uint32_t DSL_BGAP_OFF:1U; /* 1= turn bandgap off when uPower
368 					       goes Deep Sleep               */
369 		uint32_t DPD_BGAP_ON :1U; /* 1= leave bandgap on when uPower
370                                                goes Deep Power Down          */
371 		uint32_t RSV        :27U; /* reserved bits: should be all 0s  */
372 	} B;
373 } upwr_pwm_param_t;
374 
375 /**+
376  * upwr_pwm_chng_reg_voltage()
377  *
378  * Argument reg is defined by the enum upwr_pmc_reg_t, with regulator ids:
379  *  - RTD_PMC_REG: RTD regulator
380  *  - APD_PMC_REG: APD regulator
381  *  - RTD_BIAS_PMC_REG: RTD bias regulator
382  *  - APD_BIAS_PMC_REG: APD bias regulator
383  *  - RTD_LVD_PMC_MON: RTD LVD regulator
384  *  - APD_LVD_PMC_MON: APD LVD regulator
385  *  - AVD_LVD_PMC_MON: AVD LVD regulator
386  *
387  * Argument volt is defined by the formula:
388  *
389  * argument = 92.30797633*V - 55.000138, rounded to the nearest integer,
390  * where V is the value in Volts, with a minimum of 0.595833 V (argument = 0).
391  *
392  */
393 
394 /* Regulator ids */
395 
396 typedef enum {
397 	RTD_PMC_REG,
398 	APD_PMC_REG,
399 	RTD_BIAS_PMC_REG,
400 	APD_BIAS_PMC_REG,
401 	RTD_LVD_PMC_MON,
402 	APD_LVD_PMC_MON,
403 	AVD_LVD_PMC_MON
404 } upwr_pmc_reg_t;
405 
406 /**+
407  * upwr_pwm_freq_setup()
408  *
409  * Argument domain is either RTD_DOMAIN or APD_DOMAIN.
410  * Arguments nextfq and currfq are to be defined (TBD).
411  */
412 
413 /**+
414  * upwr_pwm_dom_power_on()
415  *
416  * The arguments must comply with the restrictions below, otherwise the service
417  * is not executed and returns error UPWR_RESP_BAD_REQ:
418  * - argument domain can only be APD_DOMAIN, because in i.MX8ULP it is not
419  *   possible APD powered on (calling the service) with RTD completely
420  *   powered off.
421  * - the call can only be made from the RTD domain, for the same reason.
422  * - argument boot can only be 1, because in i.MX8ULP it is not possible to
423  *   power on the APD domain without starting the core boot.
424  *
425  * If APD is already powered on and booting/booted when the service is called,
426  * it returns success without doing anything.
427  */
428 
429 /**+
430  * upwr_pwm_boot_start()
431  *
432  * The arguments must comply with the restrictions below, otherwise the service
433  * is not executed and returns error UPWR_RESP_BAD_REQ:
434  * - argument domain can only be APD_DOMAIN, because in i.MX8ULP it is not
435  *   possible APD powered on (calling the service) with RTD completely
436  *   powered off.
437  * - the call can only be made from the RTD domain, for the same reason.
438  *
439  * If APD is already booted when the service is called, it returns success
440  * without doing anything. Otherwise, it returns the error UPWR_RESP_BAD_STATE,
441  * because in i.MX8ULP APD cannot be booted separately from power on.
442  */
443 
444 /**+
445  * upwr_pwm_power_on(),
446  * upwr_pwm_power_off(),
447  * upwr_pwm_mem_retain()
448  *
449  * These three service functions use the same arguments:
450  *
451  * argument swt is an array of one 32-bit word: uint32_t swt[1];
452  * naturally the pointer to a single uint32_t variable may be passed.
453  * Each bit of the word correponds to a switch, according to the i.MX8ULP
454  * Reference Manual Rev B draft 2 table 64 Power switch reset state,
455  * and the following formula:
456  *
457  * if switch number < 10 bit number = switch number;
458  * if switch number >  9 bit number = switch number + 3;
459  *
460  * bits 9, 10, 11 and 12 must have the same value (corresponding to switch 9)
461  *
462  * Note: this argument is not used in upwr_pwm_mem_retain.
463  *
464  * argument mem is an array of two 32-bit words: uint32_t mem[2];
465  * naturally the pointer to a single uint64_t variable may be passed, since
466  * both ARM and RISC-V are little endian architectures.
467  * Each bit of the words correponds to a memory, according to the i.MX8ULP
468  * Reference Manual table "Memory Partitions".
469  *
470  * Turning a memory completely on (array and peripheral) will automatically
471  * turn on its power switch, even if not explicitely commanded.
472  * Turning a memory's power switch off will automatically turn off its array
473  * and peripheral beforehand, even if not explicitly commanded.
474  *
475  * Argument restrictions:
476  *
477  * The swt and mem arguments must comply with the restrictions below, otherwise
478  * the service is not executed (no switch/memory is changed) and returns error
479  * UPWR_RESP_BAD_REQ:
480  *  1. one must not put a memory in retention comming from an off state.
481  *  2. switches 9, 10, 11 and 12 must be turned on/off simultaneously.
482  *  3. an AVD switch can only be turned off if all AVD switches belong to the
483  *     domain requesting the service (as defined by registers SYSCTRL0,
484  *     LPAV_MASTER_ALLOC_CTRL and LPAV_SLAVE_ALLOC_CTRL);
485  *     there is no such restriction to turn the switch on.
486  *  4. an AVD memory can only be turned off or put in retention if all
487  *     AVD memories belong to the domain requesting the service
488  *     (as defined by registers SYSCTRL0, LPAV_MASTER_ALLOC_CTRL and
489  *      LPAV_SLAVE_ALLOC_CTRL); there is no such restriction to turn on the
490  *     memories.
491  *  5. EdgeLock RAMs must not be turned off, unless RTD domain is in
492  *     Deep Power Down (DPD).
493  *  6. Power Switch 19 must be on to turn on switches 17 (MIPI/DSI),
494  *     18 (MIPI/CSI), and all AVD power switches.
495  *
496  * Service Errors:
497  *
498  * Besides the error UPWR_RESP_BAD_REQ caused by violations of the restrictions
499  * above, the services may fail with error UPWR_RESP_RESOURCE if a power mode
500  * transition or a similar service is executing at the same time.
501  * This error should be interpreted as a "try later" response, as the service
502  * will succeed once those concurrent executions are done, and no other is
503  * started.
504  */
505 
506 /**+
507  * upwr_pwm_chng_switch_mem()
508  *
509  * The bit numbers in the argument struct mask and on/off state fields
510  * are the same as for services upwr_pwm_power_on, upwr_pwm_power_off and
511  * upwr_pwm_mem_retain.
512  *
513  * Turning a memory completely on (array and peripheral) will automatically
514  * turn on its power switch, even if not explicitely commanded.
515  *
516  * Argument restrictions:
517  *
518  * Same argument restrictions as services upwr_pwm_power_on, upwr_pwm_power_off
519  * and upwr_pwm_mem_retain, plus the following:
520  *
521  *  1. one must not turn a memory peripheral on and a memory array off.
522  *  2. one must not put a memory in retention and switch its power switch off.
523  *
524  * Service Errors:
525  *
526  * Besides the error UPWR_RESP_BAD_REQ caused by violations of the restrictions
527  * above, the service may fail with error UPWR_RESP_RESOURCE if a power mode
528  * transition or a similar service is executing at the same time.
529  * This error should be interpreted as a "try later" response, as the service
530  * will succeed once those concurrent executions are done, and no other is
531  * started.
532  */
533 
534 /**+
535  * upwr_pwm_pmode_config()
536  *
537  * The same power switch and memory restrictions of service
538  * upwr_pwm_chng_switch_mem apply between power modes, however they are not
539  * enforced by this service, that is, it does not return service error.
540  *
541  * The default power mode configurations for RTD and APD are documented in the
542  * i.MX8ULP Reference Manual sections "Power mode details (real-time domain)"
543  * and "Power mode details (application domain)", respectively.
544  * If those configurations are satisfactory, this service does not have
545  * to be called.
546  *
547  * Power Mode Configuration Structure:
548  *
549  * Follows a description of the power mode configuration structure elements.
550  * - dom_swts: the same switch configuration structures used in service
551  *             upwr_pwm_chng_switch_mem argument swt.
552  * - mem_swts: the same memory configuration structures used in service
553  *             upwr_pwm_chng_switch_mem argument mem.
554  * - regs: an array of structs base_reg_cfg_t (see upower_soc_defs.h),
555  *         one element for each regulator; base_reg_cfg_t has fields
556  *         mode (regulator-dependent), lvl (voltage level in uV),
557  *         comp (regulator-dependent complamentary info).
558  * - pads: pad configuration in low power; see pad_cfg_t definition below.
559  * - mons: domain monitors (LVD and HVD) configuration;
560  *         see mon_cfg_t definition below.
561  * - avd_mons: same as mons for the AVD domain; see mon_cfg_t definition below.
562  * - dom_bbias: back-bias configuration for the domain;
563  *              see base_bbias_cfg_t definition below.
564  * - avd_bbias: back-bias configuration for the AVD domain;
565  *              see base_bbias_cfg_t definition below.
566  * - mem_bbias: back-bias configuration for the memory;
567  *              see base_bbias_cfg_t definition below.
568  * - mem_fbias: forward-bias configuration for the memory;
569  *              see base_fbias_cfg_t definition below.
570  * - pmic: PMIC-specific configuration
571  *
572  * Structure pad_cfg_t:
573  *
574  * Pad control for low power modes (power off, etc), 1 bit per pad segment.
575  * - rst  : put pad segment in reset.
576  * - iso  : put pad segment in isolation.
577  * - compl: specific pad segment information.
578  * - msk  : select which pads will be updated.
579  *
580  * Structure mon_cfg_t:
581  *
582  * Configures a voltage monitor and its actions.
583  * There are monitors for RTD, APD and AVD, monitoring LVD and HVD.
584  * - lvl  : Voltage level (in uV).
585  * - mode : Mode of monitor (ON, OFF, LP, etc).
586  * - compl: Extra info for the monitor.
587  *
588  * Structure base_bbias_cfg_t:
589  *
590  * Configures back-bias (for domain or memory).
591  * - mode : Back bias mode (OFF, RBB, ARBB, etc).
592  * - p_lvl: Voltage level of p-well (in mV).
593  * - n_lvl: Voltage level of n-well (in mV).
594  * - compl: Complementary bias-specific (enable reset, interrupt, clamp, etc).
595  *
596  * Structure base_fbias_cfg_t:
597  *
598  * Configure memory forward bias for a memory segment.
599  *
600  * - mode : Forward bias mode (OFF, ON).
601  * - msk  : Selects which memory will be updated
602  *
603  */
604 
605 /*=========================================================================
606  * Domain bias
607  *=========================================================================*/
608 
609 /**+
610  * upwr_pwm_chng_dom_bias()
611  *
612  * Argument bias is a pointer to a struct with fields:
613  *  - apply: tells to which domains the bias must be applied;
614  *    options are RTD only (BIAS_APPLY_RTD), RTD and AVD (BIAS_APPLY_RTD_AVD),
615  *    APD only (BIAS_APPLY_APD), APD and AVD (BIAS_APPLY_APD_AVD),
616  *    AVD only (BIAS_APPLY_AVD)
617  *  - dommode: bias mode of the main domain (RTD or APD, determined by apply);
618  *    options are disabled (NBB_BIAS_MODE), reverse back bias (RBB_BIAS_MODE),
619  *    asymmetrical forward bias (AFBB_BIAS_MODE), asymmetrical reverse bias
620  *    (ARBB_BIAS_MODE).
621  *  - avdmode: bias mode of Audio-Video Domain (AVD);
622  *    options are the same as dommode.
623  *  - dombias: bias voltage level(s) for the main domain (RTD or APD,
624  *    determined by apply); it is a structure with 2 fields, rbbn and rbbp,
625  *    for the N-well and P-well voltages, respectively; values are in mV.
626  *  - avdbias: bias voltage level(s) for the Audio-Video Domain (AVD);
627  *    same fields as dombias;
628  *
629  * Argument restrictions:
630  *
631  * Voltage levels must comply with the #define-determined limits/options:
632  * between UPWR_RTD_RBBN_MIN and UPWR_RTD_RBBN_MAX (inclusive) for RTD N-well;
633  * between UPWR_RTD_RBBP_MIN and UPWR_RTD_RBBP_MAX (inclusive) for RTD P-well;
634  * either UPWR_APD_RBBN_LO or UPWR_APD_RBBN_HI for APD N-well;
635  * either UPWR_APD_RBBP_LO or UPWR_APD_RBBP_HI for APD P-well;
636  * either UPWR_AVD_RBBN_LO or UPWR_AVD_RBBN_HI for AVD N-well;
637  * either UPWR_AVD_RBBP_LO or UPWR_AVD_RBBP_HI for AVD P-well;
638  *
639  * But note that the limits/options above do not apply to all bias modes:
640  * rbbn is used and checked only in mode RBB_BIAS_MODE;
641  * rbbp is used and checked only in modes RBB_BIAS_MODE and ARBB_BIAS_MODE;
642  * modes AFBB_BIAS_MODE and NBB_BIAS_MODE use or check neither rbbn nor rbbp;
643  *
644  * Service error UPWR_RESP_BAD_REQ is returned if the voltage limits/options
645  * above are violated.
646  */
647 
648 /* argument struct for service upwr_pwm_chng_dom_bias:
649  */
650 
651 typedef enum {               /* bias modes (both domain and memory): */
652 	NBB_BIAS_MODE  = 0,  /* bias disabled */
653 	RBB_BIAS_MODE  = 1,  /* reverse back bias enabled */
654 	AFBB_BIAS_MODE = 2,  /* asymmetrical forward bias */
655 	ARBB_BIAS_MODE = 3   /* asymmetrical reverse bias */
656 } upwr_bias_mode_t;
657 
658 /* Domain Bias config (one per domain) */
659 
660 typedef enum {
661 	BIAS_APPLY_RTD,      /* apply to RTD only    */
662 	BIAS_APPLY_RTD_AVD,  /* apply to RTD and AVD */
663 	BIAS_APPLY_APD,      /* apply to APD only    */
664 	BIAS_APPLY_APD_AVD,  /* apply to APD and AVD */
665 	BIAS_APPLY_AVD,      /* apply to AVD only    */
666 	BIAS_APPLY_COUNT     /* number of apply options */
667 } upwr_bias_apply_t;
668 
669 typedef struct {
670 	uint16_t          rbbn;    /* reverse back bias N well (mV) */
671 	uint16_t          rbbp;    /* reverse back bias P well (mV) */
672 } upwr_rbb_t;
673 
674 struct upwr_dom_bias_cfg_t {
675 	upwr_bias_apply_t apply;   /* bias application option  */
676 	upwr_bias_mode_t  dommode; /* RTD/APD bias mode config */
677 	upwr_bias_mode_t  avdmode; /* AVD     bias mode config */
678 	upwr_rbb_t        dombias; /* RTD/APD reverse back bias */
679 	upwr_rbb_t        avdbias; /* AVD     reverse back bias */
680 };
681 
682 /* bias struct used in power mode config definitions */
683 
684 /**
685  *
686 
687  When write power mode transition program, please read below comments carefully.
688  The structure and logic is complex, There is a lot of extension and reuse.
689 
690  First, for mode, extend "uint32_t mode" to a union struct, add support for AVD:
691 typedef union {
692   uint32_t                  R;
693   struct {
694     uint32_t                  mode      : 8;
695     uint32_t                  rsrv_1    : 8;
696     uint32_t                  avd_mode  : 8;
697     uint32_t                  rsrv_2    : 8;
698   }                         B;
699 } dom_bias_mode_cfg_t;
700 
701   Second, if mode is AFBB mode, no need to configure rbbn and rbbp, uPower firmware will configure all SRAM_AFBB_0 or SRAM_AFBB_1 for corresponding domain.
702 
703   Third, if mode is RBB mode, extend "uint32_t rbbn" and "uint32_t rbbp" to a union struct, add support for AVD:
704   typedef union {
705   uint32_t                  R;
706   struct {
707     uint32_t                  lvl       : 8;
708     uint32_t                  rsrv_1    : 8;
709     uint32_t                  avd_lvl   : 8;
710     uint32_t                  rsrv_2    : 8;
711   }                         B;
712 } dom_bias_lvl_cfg_t;
713 
714  *
715  */
716 typedef struct {
717 	uint32_t mode; /* Domain bias mode config, extend to dom_bias_mode_cfg_t to support RTD, APD, AVD */
718 	uint32_t rbbn; /* reverse back bias N well */
719 	uint32_t rbbp; /* reverse back bias P well */
720 } UPWR_DOM_BIAS_CFG_T;
721 
722 /*=========================================================================
723  * Memory bias
724  *=========================================================================*/
725 
726 /**+
727  * upwr_pwm_chng_mem_bias()
728  *
729  * Argument struct contains only the field en, which can be either 1 (bias
730  * enabled) or 0 (bias disabled).
731  *
732  * Argument domain must be either RTD_DOMAIN (Real Time Domain) or APD_DOMAIN
733  * (Application Domain).
734  */
735 
736 /* Memory Bias config */
737 
738 struct upwr_mem_bias_cfg_t {
739 	uint32_t en; /* Memory bias enable config */
740 
741 };
742 
743 /* bias struct used in power mode config definitions */
744 
745 typedef struct {
746 	uint32_t en; /* Memory bias enable config */
747 } UPWR_MEM_BIAS_CFG_T;
748 
749 /* Split different Bias */
750 
751 struct upwr_pmc_bias_cfg_t {
752 	UPWR_DOM_BIAS_CFG_T dombias_cfg; /* Domain Bias config */
753 	UPWR_MEM_BIAS_CFG_T membias_cfg; /* Memory Bias config */
754 };
755 
756 /*=========================================================================
757  * Power modes
758  *=========================================================================*/
759 
760 typedef enum {/* from msb->lsb: Azure bit, dual boot bit, low power boot bit */
761 	SOC_BOOT_SINGLE   = 0,
762 	SOC_BOOT_LOW_PWR  = 1,
763 	SOC_BOOT_DUAL     = 2,
764 	SOC_BOOT_AZURE    = 4
765 } SOC_BOOT_TYPE_T;
766 
767 #ifdef UPWR_COMP_RAM
768 
769 /* Power modes for RTD domain  */
770 typedef enum {
771 	DPD_RTD_PWR_MODE, /* Real Time Deep Power Down mode */
772 	PD_RTD_PWR_MODE,  /* Real Time Power Down mode */
773 	DSL_RTD_PWR_MODE, /* Real Time Domain Deep Sleep Mode */
774 	HLD_RTD_PWR_MODE, /* Real Time Domain Hold Mode */
775 	SLP_RTD_PWR_MODE, /* Sleep Mode */
776 	ADMA_RTD_PWR_MODE,/* Active DMA Mode */
777 	ACT_RTD_PWR_MODE, /* Active Domain Mode */
778 	NUM_RTD_PWR_MODES
779 } upwr_ps_rtd_pwr_mode_t;
780 
781 /* Abstract power modes */
782 typedef enum {
783 	DPD_PWR_MODE,
784 	PD_PWR_MODE,
785 	PACT_PWR_MODE,
786 	DSL_PWR_MODE,
787 	HLD_PWR_MODE,
788 	SLP_PWR_MODE,
789 	ADMA_PWR_MODE,
790 	ACT_PWR_MODE,
791 	NUM_PWR_MODES,
792 	NUM_APD_PWR_MODES = NUM_PWR_MODES,
793 	TRANS_PWR_MODE    = NUM_PWR_MODES,
794 	INVALID_PWR_MODE  = TRANS_PWR_MODE + 1
795 } abs_pwr_mode_t;
796 
797 #else
798 
799 /* Power modes for RTD domain  */
800 #define	DPD_RTD_PWR_MODE   (0U)  /* Real Time Deep Power Down mode */
801 #define	PD_RTD_PWR_MODE    (1U)  /* Real Time Power Down mode */
802 #define	DSL_RTD_PWR_MODE   (2U)  /* Real Time Domain Deep Sleep Mode */
803 #define	HLD_RTD_PWR_MODE   (3U)  /* Real Time Domain Hold Mode */
804 #define	SLP_RTD_PWR_MODE   (4U)  /* Sleep Mode */
805 #define	ADMA_RTD_PWR_MODE  (5U)  /* Active DMA Mode */
806 #define	ACT_RTD_PWR_MODE   (6U)  /* Active Domain Mode */
807 #define	NUM_RTD_PWR_MODES  (7U)
808 
809 typedef uint32_t upwr_ps_rtd_pwr_mode_t;
810 
811 /* Abstract power modes */
812 #define	DPD_PWR_MODE       (0U)
813 #define	PD_PWR_MODE        (1U)
814 #define	PACT_PWR_MODE      (2U)
815 #define	DSL_PWR_MODE       (3U)
816 #define	HLD_PWR_MODE       (4U)
817 #define	SLP_PWR_MODE       (5U)
818 #define	ADMA_PWR_MODE      (6U)
819 #define	ACT_PWR_MODE       (7U)
820 #define	NUM_PWR_MODES      (8U)
821 #define	NUM_APD_PWR_MODES NUM_PWR_MODES
822 #define	TRANS_PWR_MODE    NUM_PWR_MODES
823 #define	INVALID_PWR_MODE  (TRANS_PWR_MODE + 1U)
824 
825 typedef uint32_t abs_pwr_mode_t;
826 
827 #endif
828 
829 typedef struct {
830 	abs_pwr_mode_t  mode;
831 	bool            ok;
832 } pch_trans_t;
833 
834 typedef pch_trans_t rtd_trans_t;
835 
836 typedef struct {
837 	abs_pwr_mode_t  mode;
838 	pch_trans_t     core[UPWR_APD_CORES];
839 } apd_trans_t;
840 
841 /* Codes for APD pwr mode as programmed in LPMODE reg */
842 typedef enum {
843 	ACT_APD_LPM,
844 	SLP_APD_LPM    = 1,
845 	DSL_APD_LPM    = 3,
846 	PACT_APD_LPM   = 7,
847 	PD_APD_LPM     = 15,
848 	DPD_APD_LPM    = 31,
849 	HLD_APD_LPM    = 63
850 } upwr_apd_lpm_t;
851 
852 /* PowerSys low power config */
853 
854 struct upwr_powersys_cfg_t {
855 	uint32_t lpm_mode; /* Powersys low power mode */
856 };
857 
858 /*=*************************************************************************
859  * RTD
860  *=*************************************************************************/
861 
862 /* Config pmc PADs */
863 
864 struct upwr_pmc_pad_cfg_t {
865 	uint32_t pad_close;   /* PMC PAD close config */
866 	uint32_t pad_reset;   /* PMC PAD reset config */
867 	uint32_t pad_tqsleep; /* PMC PAD TQ Sleep config */
868 };
869 
870 /* Config regulator (internal and external) */
871 
872 struct upwr_reg_cfg_t {
873 	uint32_t volt;  /* Regulator voltage config */
874 	uint32_t mode;  /* Regulator mode config */
875 };
876 
877 /* Config pmc monitors */
878 
879 struct  upwr_pmc_mon_cfg_t {
880 	uint32_t mon_hvd_en; /* PMC mon HVD */
881 	uint32_t mon_lvd_en; /* PMC mon LVD */
882 	uint32_t mon_lvdlvl; /* PMC mon LVDLVL */
883 };
884 
885 /* Same monitor config for RTD (for compatibility) */
886 
887 #define upwr_pmc_mon_rtd_cfg_t upwr_pmc_mon_cfg_t
888 
889 typedef swt_config_t ps_rtd_swt_cfgs_t[NUM_RTD_PWR_MODES];
890 typedef swt_config_t ps_apd_swt_cfgs_t[NUM_APD_PWR_MODES];
891 
892 /*=*************************************************************************
893  * APD
894  *=*************************************************************************/
895 
896 /* PowerSys PMIC config */
897 struct upwr_pmic_cfg_t {
898 	uint32_t                      volt;
899 	uint32_t                      mode;
900 	uint32_t                      mode_msk;
901 };
902 
903 typedef uint32_t offs_t;
904 
905 struct ps_apd_pwr_mode_cfg_t {
906 	#ifdef UPWR_SIMULATOR_ONLY
907 	struct upwr_switch_board_t*   swt_board_offs;
908 	struct upwr_mem_switches_t*   swt_mem_offs;
909 	#else
910 	offs_t                        swt_board_offs;
911 	offs_t                        swt_mem_offs;
912 	#endif
913 	struct upwr_pmic_cfg_t        pmic_cfg;
914 	struct upwr_pmc_pad_cfg_t     pad_cfg;
915 	struct upwr_pmc_bias_cfg_t    bias_cfg;
916 };
917 
918 /* Get the pointer to swt config */
919 static inline struct upwr_switch_board_t*
get_apd_swt_cfg(volatile struct ps_apd_pwr_mode_cfg_t * cfg)920 get_apd_swt_cfg(volatile struct ps_apd_pwr_mode_cfg_t *cfg)
921 {
922 	char  *ptr;
923 	ptr = (char*)cfg;
924 	ptr += (uint64_t)cfg->swt_board_offs;
925 	return (struct upwr_switch_board_t*)ptr;
926 }
927 
928 /* Get the pointer to mem config */
929 static inline struct upwr_mem_switches_t*
get_apd_mem_cfg(volatile struct ps_apd_pwr_mode_cfg_t * cfg)930 get_apd_mem_cfg(volatile struct ps_apd_pwr_mode_cfg_t *cfg)
931 {
932 	char  *ptr;
933 	ptr =  (char*)cfg;
934 	ptr += (uint64_t)cfg->swt_mem_offs;
935 	return (struct upwr_mem_switches_t*)ptr;
936 }
937 
938 /* Power Mode configuration */
939 
940 #define ps_rtd_pwr_mode_cfg_t upwr_power_mode_cfg_t
941 
942 /* these typedefs are just for RISC-V sizeof purpose */
943 typedef uint32_t swt_board_ptr_t;
944 typedef uint32_t swt_mem_ptr_t;
945 
946 struct upwr_power_mode_cfg_t {
947 	#ifdef UPWR_SIMULATOR_ONLY
948 	struct upwr_switch_board_t*   swt_board; /* Swt board for mem. */
949 	struct upwr_mem_switches_t*   swt_mem;   /* Swt to mem. arrays, perif */
950 	#else
951 	#ifdef __LP64__
952 	uint32_t                      swt_board;
953 	uint32_t                      swt_mem;
954 	#else
955 	struct upwr_switch_board_t*   swt_board; /* Swt board for mem. */
956 	struct upwr_mem_switches_t*   swt_mem;   /* Swt to mem. arrays, perif */
957 	#endif
958 	#endif
959 	struct upwr_reg_cfg_t         in_reg_cfg; /* internal regulator config*/
960 	struct upwr_reg_cfg_t         pmic_cfg;   /* external regulator - pmic*/
961 	struct upwr_pmc_pad_cfg_t     pad_cfg;  /* Pad conf for power trans*/
962 	struct upwr_pmc_mon_rtd_cfg_t mon_cfg;    /*monitor configuration */
963 	struct upwr_pmc_bias_cfg_t    bias_cfg;   /* Memomry/Domain Bias conf */
964 	struct upwr_powersys_cfg_t    pwrsys_lpm_cfg;/* pwrsys low power config*/
965 };
966 
upwr_sizeof_pmode_cfg(uint32_t domain)967 static inline int unsigned upwr_sizeof_pmode_cfg(uint32_t domain)
968 {
969 	switch (domain)
970 	{
971 		case RTD_DOMAIN:
972             {
973                 return sizeof(struct upwr_power_mode_cfg_t) +
974 					(sizeof(struct upwr_switch_board_t)*
975 					 UPWR_PMC_SWT_WORDS) +
976 					(sizeof(struct upwr_mem_switches_t)*
977 					 UPWR_PMC_MEM_WORDS) -
978 					2U * (sizeof(void*) - sizeof(swt_board_ptr_t));
979 
980                  /* fall through */
981             }
982 		case APD_DOMAIN:
983             {
984                 return sizeof(struct ps_apd_pwr_mode_cfg_t) +
985 					(sizeof(struct upwr_switch_board_t)*
986 					 UPWR_PMC_SWT_WORDS) +
987 					(sizeof(struct upwr_mem_switches_t)*
988 					 UPWR_PMC_MEM_WORDS);
989 
990                  /* fall through */
991             }
992         default:
993             break;
994 	}
995 
996 	return 0;
997 }
998 
999 /*=*************************************************************************
1000  * SIC
1001  *=*************************************************************************/
1002 
1003 /* SIC GPO according to Integration Guide */
1004 typedef union {
1005 	volatile uint32_t       R;
1006 	struct {
1007 		/* b[0] */
1008 		volatile uint32_t     PMODE         : 7;
1009 		volatile uint32_t     MODECHG       : 1;
1010 		/* b[1] */
1011 		volatile uint32_t     SNTL_RETN     : 1;
1012 		volatile uint32_t     rsrv_1        : 2;
1013 		volatile uint32_t     IRAM_RETN     : 1;
1014 		volatile uint32_t     DRAM_RETN     : 1;
1015 		volatile uint32_t     RTD_KEEP_RST  : 1;
1016 		volatile uint32_t     APD_KEEP_RST  : 1;
1017 		volatile uint32_t     RDY2PATCH     : 1;
1018 		/* b[2] */
1019 		volatile uint32_t     RTD_LLWU      : 1;
1020 		volatile uint32_t     APD_LLWU      : 1;
1021 		volatile uint32_t     rsrv_3        : 1;
1022 		volatile uint32_t     AVD_RST_HOLD  : 1;
1023 		volatile uint32_t     USB0_RETN     : 1;
1024 		volatile uint32_t     MIPI_DSI_ENA  : 1;
1025 		volatile uint32_t     DDR_RETN      : 1;
1026 		volatile uint32_t     PMIC_WAIT_DIS : 1;
1027 		/* b[3] */
1028 		volatile uint32_t     RTD_EARLY_REL : 1;
1029 		volatile uint32_t     RTD_ASYNC_REL : 1;
1030 		volatile uint32_t     RTD_CORE_REL  : 1;
1031 		volatile uint32_t     RTD_RST_HOLD  : 1;
1032 		volatile uint32_t     APD_EARLY_REL : 1;
1033 		volatile uint32_t     APD_ASYNC_REL : 1;
1034 		volatile uint32_t     APD_CORE_REL  : 1;
1035 		volatile uint32_t     APD_RST_HOLD  : 1;
1036 	}               B;
1037 	volatile uint8_t        b[4];
1038 } sic_gpor_t;
1039 
1040 /* SIC GPI according to Integration Guide */
1041 
1042 /* AVD domain power switches */
1043 #define AVD_PWR_SWITCH_MASK           ((1 <<  7)|\
1044                                        (1 <<  8)|\
1045                                        (1 <<  9)|\
1046                                        (1 << 10)|\
1047                                        (1 << 11)|\
1048                                        (1 << 12)|\
1049                                        (1 << 13)|\
1050                                        (1 << 14)|\
1051                                        (1 << 15)|\
1052                                        (1 << 16))
1053 
1054 typedef union {
1055 	volatile uint32_t          R;
1056 	struct {
1057 		/* AVD Slave */
1058 		volatile uint32_t       LPAV_MASTER         : 1;
1059 		volatile uint32_t       LPAV_SAI6           : 1;
1060 		volatile uint32_t       LPAV_SAI7           : 1;
1061 		volatile uint32_t       LPAV_SEMA42         : 1;
1062 		volatile uint32_t       LPAV_LPTMP8         : 1;
1063 		volatile uint32_t       LPAV_SPDIF          : 1;
1064 		volatile uint32_t       rsrv_1              : 2;
1065 		/* AVD Master */
1066 		volatile uint32_t       LPAV_PXP            : 1;
1067 		volatile uint32_t       LPAV_GPU2D          : 1;
1068 		volatile uint32_t       LPAV_GPU3D          : 1;
1069 		volatile uint32_t       LPAV_DCNANO         : 1;
1070 		volatile uint32_t       LPAV_MIPI_DSI       : 1;
1071 		volatile uint32_t       rsrv_2              : 1;
1072 		volatile uint32_t       LPAV_EPDC           : 1;
1073 		volatile uint32_t       LPAV_HIFI4          : 1;
1074 		/* APD LPMODE */
1075 		volatile uint32_t       APD_LPMODE          : 6;
1076 		volatile uint32_t       rsrv_3              : 2;
1077 		/* General */
1078 		volatile uint32_t       rsrv_4              : 4;
1079 		volatile uint32_t       SENT_BUSY           : 1;
1080 		volatile uint32_t       APD_RES_RTD         : 1;
1081 		volatile uint32_t       SENT_ACK            : 1;
1082 		volatile uint32_t       LDOEN               : 1;
1083 	} B;
1084 } sic_gpir_t;
1085 
1086 /* Mask the AVD peripherals in sic_gpir_t */
1087 #define AVD_PERIPH_OWNER_MSK          (0xffffUL & ~(0x3UL<<6) & ~(0x1UL<<13))
1088 
1089 /*=*************************************************************************
1090  * PMC
1091  *=*************************************************************************/
1092 
1093 /* Operating modes of devices */
1094 typedef enum {
1095 	OFF_PMC_MODE,
1096 	ON_PMC_MODE,
1097 	LP_PMC_MODE,
1098 	HP_PMC_MODE,
1099 	ENA_PMC_MODE,
1100 	DIS_PMC_MODE
1101 } pmc_dev_mode_t;
1102 
1103 /* Monitor Inputs types */
1104 typedef enum {
1105 	RTD_LVD_INP,
1106 	APD_LVD_INP,
1107 	AVD_LVD_INP,
1108 	RTD_HVD_INP,
1109 	APD_HVD_INP,
1110 	AVD_HVD_INP,
1111 	POR_INP,
1112 	LDOEN_INP
1113 } pmc_inp_t;
1114 
1115 typedef enum {
1116 	PAD_CLOSE_EVT,
1117 	PAD_RST_EVT,
1118 	PAD_TQSLEEP_EVT
1119 } pmc_pad_evt_t;
1120 
1121 
1122 /*=*************************************************************************
1123  * All configs
1124  *=*************************************************************************/
1125 
1126 /* LVD/HVD monitor config for a single domain */
1127 
1128 /* Domain + AVD monitor config
1129  * For RTD, mapped in mon_cfg.mon_hvd_en
1130  * For APD, mapped temporarily in pad_cfg.pad_tqsleep
1131  */
1132 typedef union upwr_mon_cfg_union_t {
1133 		volatile uint32_t         R;
1134 		struct {
1135 		/* Original config, not change */
1136 		volatile uint32_t          rsrv_1          : 8;
1137 		/* DOM */
1138 		volatile uint32_t          dom_lvd_irq_ena : 1;
1139 		volatile uint32_t          dom_lvd_rst_ena : 1;
1140 		volatile uint32_t          dom_hvd_irq_ena : 1;
1141 		volatile uint32_t          dom_hvd_rst_ena : 1;
1142 		volatile uint32_t          dom_lvd_lvl     : 4;
1143 		volatile uint32_t          dom_lvd_ena     : 1;
1144 		volatile uint32_t          dom_hvd_ena     : 1;
1145 		/* AVD */
1146 		volatile uint32_t          avd_lvd_irq_ena : 1;
1147 		volatile uint32_t          avd_lvd_rst_ena : 1;
1148 		volatile uint32_t          avd_hvd_irq_ena : 1;
1149 		volatile uint32_t          avd_hvd_rst_ena : 1;
1150 		volatile uint32_t          avd_lvd_lvl     : 4;
1151 		volatile uint32_t          avd_lvd_ena     : 1;
1152 		volatile uint32_t          avd_hvd_ena     : 1;
1153 	}                         B;
1154 } upwr_mon_cfg_t;
1155 
1156 /* Get the monitor config word from RAM (domaind and AVD) */
1157 
get_mon_cfg(uint8_t dom,void * mode_cfg)1158 static inline uint32_t get_mon_cfg(uint8_t dom, void *mode_cfg)
1159 {
1160 	if (dom == RTD_DOMAIN) {
1161 		return ((struct ps_rtd_pwr_mode_cfg_t*)mode_cfg)->mon_cfg.mon_hvd_en;
1162 	} else {
1163 		return ((struct ps_apd_pwr_mode_cfg_t*)mode_cfg)->pad_cfg.pad_tqsleep;
1164 	}
1165 }
1166 
1167 /* Set the monitor config word in RAM (domaind and AVD) */
1168 
set_mon_cfg(uint8_t dom,void * mode_cfg,upwr_mon_cfg_t mon_cfg)1169 static inline void  set_mon_cfg(uint8_t        dom,
1170 				void          *mode_cfg,
1171 				upwr_mon_cfg_t mon_cfg)
1172 {
1173 	uint32_t        *cfg;
1174 	if (dom == RTD_DOMAIN) {
1175 		cfg = (uint32_t*)&((struct ps_rtd_pwr_mode_cfg_t*)mode_cfg)->mon_cfg.mon_hvd_en;
1176 	} else {
1177 		cfg = (uint32_t*)&((struct ps_apd_pwr_mode_cfg_t*)mode_cfg)->pad_cfg.pad_tqsleep;
1178 	}
1179 
1180 	*cfg = mon_cfg.R;
1181 }
1182 
1183 #define PMIC_REG_VALID_TAG 0xAAU
1184 
1185 /**
1186  * limit the max pmic register->value count to 8
1187  * each data cost 4 Bytes, totally 32 Bytes
1188  */
1189 #define MAX_PMIC_REG_COUNT 0x8U
1190 
1191 /**
1192  * the configuration structure for PMIC register setting
1193  *
1194  * @ tag: The TAG number to judge if the data is valid or not, valid tag is PMIC_REG_VALID_TAG
1195  * @ power_mode : corresponding to each domain's power mode
1196  * RTD refer to upwr_ps_rtd_pwr_mode_t
1197  * APD refer to abs_pwr_mode_t
1198  * @ i2c_addr : i2c address
1199  * @ i2c_data : i2c data value
1200  */
1201 struct ps_pmic_reg_data_cfg_t{
1202     uint32_t tag : 8;
1203     uint32_t power_mode : 8;
1204     uint32_t i2c_addr : 8;
1205     uint32_t i2c_data : 8;
1206 };
1207 
1208 /* Uniformize access to PMIC cfg for RTD and APD */
1209 
1210 typedef union {
1211 	struct upwr_reg_cfg_t     RTD;
1212 	struct upwr_pmic_cfg_t    APD;
1213 } pmic_cfg_t;
1214 
1215 /* Access to PMIC mode mask and AVD mode */
1216 
1217 typedef union {
1218 	uint32_t                  R;
1219 	struct {
1220 		uint8_t                   mode;     /* Domain PMIC mode */
1221 		uint8_t                   msk;      /* Domain PMIC mode mask */
1222 		uint8_t                   avd_mode; /* AVD PMIC mode */
1223 		uint8_t                   avd_msk;  /* AVD PMIC mode mask */
1224 	}                         B;
1225 } pmic_mode_cfg_t;
1226 
1227 /* Access RTD, APD and AVD modes and masks */
1228 
get_pmic_mode_cfg(uint8_t dom,pmic_cfg_t * cfg)1229 static inline pmic_mode_cfg_t *get_pmic_mode_cfg(uint8_t dom, pmic_cfg_t *cfg)
1230 {
1231 	uint32_t *mode_cfg;
1232 
1233 	if (dom == RTD_DOMAIN) {
1234         mode_cfg = &cfg->RTD.mode;
1235     } else {
1236         mode_cfg = &cfg->APD.mode;
1237     }
1238 
1239 	return (pmic_mode_cfg_t*)mode_cfg;
1240 }
1241 
get_pmic_mode(uint8_t dom,pmic_cfg_t * cfg)1242 static inline uint8_t get_pmic_mode(uint8_t dom, pmic_cfg_t *cfg)
1243 {
1244 	return get_pmic_mode_cfg(dom, cfg)->B.mode;
1245 }
1246 
set_pmic_mode(uint8_t dom,pmic_cfg_t * cfg,uint8_t mode)1247 static inline void set_pmic_mode(uint8_t dom, pmic_cfg_t *cfg, uint8_t mode)
1248 {
1249 	get_pmic_mode_cfg(dom, cfg)->B.mode = mode;
1250 }
1251 
get_pmic_mode_msk(uint8_t dom,pmic_cfg_t * cfg)1252 static inline uint32_t get_pmic_mode_msk(uint8_t dom, pmic_cfg_t *cfg)
1253 {
1254 	pmic_mode_cfg_t   *mode_cfg;
1255 
1256 	if (dom == RTD_DOMAIN) {
1257 		mode_cfg = (pmic_mode_cfg_t*)&cfg->RTD.mode;
1258 		return mode_cfg->B.msk;
1259 	} else {
1260         return cfg->APD.mode_msk;
1261     }
1262 }
1263 
1264 /* Getters and setters for AVD mode and mask */
get_avd_pmic_mode(uint8_t dom,pmic_cfg_t * cfg)1265 static inline uint8_t get_avd_pmic_mode(uint8_t dom, pmic_cfg_t *cfg)
1266 {
1267 	return get_pmic_mode_cfg(dom, cfg)->B.avd_mode;
1268 }
1269 
set_avd_pmic_mode(uint8_t dom,pmic_cfg_t * cfg,uint8_t mode)1270 static inline void set_avd_pmic_mode(uint8_t dom, pmic_cfg_t *cfg, uint8_t mode)
1271 {
1272 	get_pmic_mode_cfg(dom, cfg)->B.avd_mode = mode;
1273 }
1274 
get_avd_pmic_mode_msk(uint8_t dom,pmic_cfg_t * cfg)1275 static inline uint8_t get_avd_pmic_mode_msk(uint8_t dom, pmic_cfg_t *cfg)
1276 {
1277 	return get_pmic_mode_cfg(dom, cfg)->B.avd_msk;
1278 }
1279 
set_avd_pmic_mode_msk(uint8_t dom,pmic_cfg_t * cfg,uint8_t msk)1280 static inline void set_avd_pmic_mode_msk(uint8_t     dom,
1281 					 pmic_cfg_t *cfg,
1282 					 uint8_t     msk)
1283 {
1284 	get_pmic_mode_cfg(dom, cfg)->B.avd_msk = msk;
1285 }
1286 
1287 struct ps_delay_cfg_t {
1288     uint32_t tag : 8U;
1289     uint32_t rsv : 8U;
1290     uint32_t exitdelay : 16U;   // exit delay in us
1291 };
1292 
1293 #define PS_DELAY_TAG 0xA5U
1294 
1295 // max exit delay = 0xffff = 65535 us = 65.5 ms (it is enought...)
1296 // with 8 bits, 256 -> not enought
1297 
1298 typedef struct ps_delay_cfg_t ps_rtd_delay_cfgs_t[NUM_RTD_PWR_MODES];
1299 typedef struct ps_delay_cfg_t ps_apd_delay_cfgs_t[NUM_APD_PWR_MODES];
1300 
1301 typedef struct ps_rtd_pwr_mode_cfg_t ps_rtd_pwr_mode_cfgs_t[NUM_RTD_PWR_MODES];
1302 typedef struct ps_apd_pwr_mode_cfg_t ps_apd_pwr_mode_cfgs_t[NUM_APD_PWR_MODES];
1303 typedef struct ps_pmic_reg_data_cfg_t ps_rtd_pmic_reg_data_cfgs_t[MAX_PMIC_REG_COUNT];
1304 typedef struct ps_pmic_reg_data_cfg_t ps_apd_pmic_reg_data_cfgs_t[MAX_PMIC_REG_COUNT];
1305 
1306 struct ps_pwr_mode_cfg_t {
1307 	ps_rtd_pwr_mode_cfgs_t  ps_rtd_pwr_mode_cfg;
1308 	ps_rtd_swt_cfgs_t       ps_rtd_swt_cfg;
1309 	ps_apd_pwr_mode_cfgs_t  ps_apd_pwr_mode_cfg ;
1310 	ps_apd_swt_cfgs_t       ps_apd_swt_cfg;
1311     ps_rtd_pmic_reg_data_cfgs_t ps_rtd_pmic_reg_data_cfg;
1312     ps_apd_pmic_reg_data_cfgs_t ps_apd_pmic_reg_data_cfg;
1313     ps_rtd_delay_cfgs_t    ps_rtd_delay_cfg;
1314     ps_apd_delay_cfgs_t    ps_apd_delay_cfg;
1315 
1316 };
1317 
1318 #define UPWR_XCP_MIN_ADDR   (0x28350000U)
1319 #define UPWR_XCP_MAX_ADDR   (0x2836FFFCU)
1320 
1321 struct upwr_reg_access_t {
1322 	uint32_t     addr;
1323 	uint32_t     data;
1324 	uint32_t     mask; /* mask=0 commands read */
1325 };
1326 
1327 typedef upwr_pointer_msg upwr_xcp_access_msg;
1328 
1329 /* unions for the shared memory buffer */
1330 
1331 typedef union {
1332 	struct upwr_reg_access_t            reg_access;
1333 } upwr_xcp_union_t;
1334 
1335 typedef union {
1336 	struct {
1337 		struct ps_rtd_pwr_mode_cfg_t rtd_struct;
1338 		struct upwr_switch_board_t   rtd_switch;
1339 		struct upwr_mem_switches_t   rtd_memory;
1340 	}                                                rtd_pwr_mode;
1341 	struct {
1342 		struct ps_apd_pwr_mode_cfg_t apd_struct;
1343 		struct upwr_switch_board_t   apd_switch;
1344 		struct upwr_mem_switches_t   apd_memory;
1345 	}                                                apd_pwr_mode;
1346 } upwr_pwm_union_t;
1347 
1348 #define MAX_SG_EXCEPT_MEM_SIZE sizeof(upwr_xcp_union_t)
1349 #define MAX_SG_PWRMGMT_MEM_SIZE sizeof(upwr_pwm_union_t)
1350 
1351 /**
1352  * VOLTM group need shared memory for PMIC IC configuration
1353  * 256 Bytes is enough for PMIC register array
1354  */
1355 #define MAX_SG_VOLTM_MEM_SIZE 256U
1356 
1357 #ifdef  __cplusplus
1358 #ifndef UPWR_NAMESPACE /* extern "C" 'cancels' the effect of namespace */
1359 } /* extern "C" */
1360 #endif
1361 #endif
1362 
1363 #endif /* #ifndef _UPWR_SOC_DEFS_H */
1364