1 /*
2  * Copyright 2020-2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_UPOWER_H_
9 #define _FSL_UPOWER_H_
10 
11 #include "fsl_common.h"
12 #include "upower_soc_defs.h"
13 #include "upower_api.h"
14 
15 /*!
16  * @addtogroup upower
17  * @{
18  */
19 
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 
24 /*! @name Driver version */
25 /*@{*/
26 /*! @brief upower driver version (2.0.19.) */
27 #define FSL_UPOWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 19))
28 /*@}*/
29 
30 /*! @brief pmic rail id. */
31 #define PMIC_BUCK1 (0U)
32 #define PMIC_BUCK2 (1U)
33 #define PMIC_BUCK3 (2U)
34 #define PMIC_BUCK4 (3U)
35 #define PMIC_LDO1  (4U)
36 #define PMIC_LDO2  (5U)
37 #define PMIC_LDO3  (6U)
38 #define PMIC_LDO4  (7U)
39 #define PMIC_LSW1  (8U)
40 #define PMIC_LSW2  (9U)
41 #define PMIC_LSW3  (10U)
42 #define PMIC_LSW4  (11U)
43 
44 /*! @brief pmic voltage. */
45 /* 1.1 V */
46 #define PMIC_VOLTAGE_1_1V (1100 * 1000)
47 /* 1.0 V */
48 #define PMIC_VOLTAGE_1_0V (1000 * 1000)
49 /* 0.9 V */
50 #define PMIC_VOLTAGE_0_9V (900 * 1000)
51 
52 #define PMIC_I2C_ADDR           (0x32)
53 #define PMIC_WRITE_DATA_SIZE    (1)
54 #define PMIC_IC_WRITE_DATA_SIZE (1)
55 #define PMIC_READ_DATA_SIZE     (-1)
56 #define PMIC_IC_READ_DATA_SIZE  (1)
57 
58 /*! @brief PCA9460 register */
59 #define PCA9460_BUCK23_DVS_CFG1_ADDR     (0x12)
60 #define PCA9460_BUCK23_DVS_CFG2_ADDR     (0x13)
61 #define PCA9460_BUCK2CTRL_ADDR     (0x14)
62 #define PCA9460_BUCK2OUT_DVS0_ADDR (0x15)
63 #define PCA9460_BUCK2OUT_DVS1_ADDR (0x16)
64 #define PCA9460_BUCK2OUT_DVS2_ADDR (0x17)
65 #define PCA9460_BUCK2OUT_DVS3_ADDR (0x18)
66 #define PCA9460_BUCK2OUT_DVS4_ADDR (0x19)
67 #define PCA9460_BUCK2OUT_DVS5_ADDR (0x1A)
68 #define PCA9460_BUCK2OUT_DVS6_ADDR (0x1B)
69 #define PCA9460_BUCK2OUT_DVS7_ADDR (0x1C)
70 #define PCA9460_BUCK2OUT_STDBY_ADDR (0x1D)
71 #define PCA9460_BUCK2OUT_MAX_LIMIT_ADDR (0x1F)
72 #define PCA9460_BUCK2OUT_MIN_LIMIT_ADDR (0x20)
73 #define PCA9460_BUCK3CTRL_ADDR     (0x21)
74 #define PCA9460_BUCK3OUT_DVS0_ADDR (0x22)
75 #define PCA9460_LDO1_CFG_ADDR      (0x30)
76 #define PCA9460_LDO1_OUT_ADDR      (0x31)
77 
78 /*! Drive Mode: OD(Over Drive), ND(Nominal Drive), UD(Under Drive) */
79 typedef enum
80 {
81     DRIVE_MODE_UD = 0,
82     DRIVE_MODE_ND = 1,
83     DRIVE_MODE_OD  = 2,
84     DRIVE_MODE_NUM = 3,
85 } drive_mode_e;
86 
87 /*! PCA9460 BUCK23_DVS_CFG2 register */
88 #define BUCK23_DVS_CFG2_B2_DVS_CTRL_BITS (2)
89 #define BUCK23_DVS_CFG2_B3_DVS_CTRL_BITS (2)
90 #define BUCK23_DVS_CFG2_RSVD_BITS (4)
91 
92 /*! PCA9460 BUCK3CTRL register */
93 #define B3_RAMP_BITS   (2)
94 #define B3_LPMODE_BITS (2)
95 #define B3_AD_BITS     (1)
96 #define B3_FPWM_BITS   (1)
97 #define B3_ENMODE_BITS (2)
98 
99 #define BUCK_OUTPUT_TABLE_SIZE    (128)
100 #define BUCK2_BUCK3_VOLTAGE_STEPS (0.0125)
101 
102 /*! PCA9460 LDO1_CFG register */
103 #define L1_CSEL_BITS   (2)
104 #define L1_LLSEL_BITS  (2)
105 #define L1_LPMODE_BITS (2)
106 #define L1_ENMODE_BITS (2)
107 
108 typedef union
109 {
110     uint8_t val;
111     struct
112     {
113         uint8_t RSVD : BUCK23_DVS_CFG2_RSVD_BITS;
114         uint8_t B3_DVS_CTRL : BUCK23_DVS_CFG2_B3_DVS_CTRL_BITS;
115         uint8_t B2_DVS_CTRL : BUCK23_DVS_CFG2_B2_DVS_CTRL_BITS;
116     } reg;
117 } pca9460_buck23_dvs_cfg2_t;
118 
119 typedef union
120 {
121     uint8_t val;
122     struct
123     {
124         uint8_t B3_ENMODE : B3_ENMODE_BITS;
125         uint8_t B3_FPWM : B3_FPWM_BITS;
126         uint8_t B3_AD : B3_AD_BITS;
127         uint8_t B3_LPMODE : B3_LPMODE_BITS;
128         uint8_t B3_RAMP : B3_RAMP_BITS;
129     } reg;
130 } pca9460_buck3ctrl_t;
131 
132 typedef union
133 {
134     uint8_t val;
135     struct
136     {
137         uint8_t L1_ENMODE : L1_ENMODE_BITS;
138         uint8_t L1_LPMODE : L1_LPMODE_BITS;
139         uint8_t L1_LLSEL : L1_LLSEL_BITS;
140         uint8_t L1_CSEL : L1_CSEL_BITS;
141     } reg;
142 } pca9460_ldo1_cfg_t;
143 
144 /*! @brief upower power switch mask definition. */
145 typedef enum _upower_ps_mask
146 {
147     kUPOWER_PS_M33       = (1U << 0U), /*!< RTD: CM33 core complex/platform/peripherals */
148     kUPOWER_PS_FUSION    = (1U << 1U), /*!< RTD: Fusion core and peripherals */
149     kUPOWER_PS_A35_0     = (1U << 2U), /*!< AD: A35[0] core complex */
150     kUPOWER_PS_A35_1     = (1U << 3U), /*!< AD: A35[1] core complex */
151     kUPOWER_PS_L2_CACHE  = (1U << 4U), /*!< AD: 256KB L2 cache */
152     kUPOWER_PS_AD_NIC    = (1U << 5U), /*!< AD: A35 NIC_PER, NIC_AP */
153     kUPOWER_PS_AD_PER    = (1U << 6U), /*!< AD: A35 peripherals and croessbar */
154     kUPOWER_PS_GPU3D     = (1U << 7U), /*!< LPAV: 3DGPU */
155     kUPOWER_PS_HIFI4     = (1U << 8U), /*!< LPAV: HiFi4 complex */
156     kUPOWER_PS_DDRC      = (1U << 9U | 1U << 10U | 1U << 11U | 1U << 12U), /*!< LPAV: DDR controller */
157     kUPOWER_PS_PXP_EPDC  = (1U << 13U),                                    /*!< LPAV: PXP, EPDC */
158     kUPOWER_PS_MIPI_DSI  = (1U << 14U),                                    /*!< LPAV: MIPI DSI */
159     kUPOWER_PS_MIPI_CSI  = (1U << 15U),                                    /*!< LPAV: MIPI CSI */
160     kUPOWER_PS_AV_NIC    = (1U << 16U),                                    /*!< LPAV: NIC, System RAM2, DCNano */
161     kUPOWER_PS_FUSION_AO = (1U << 17U),                                    /*!< RTD: Fusion "Always ON" */
162     kUPOWER_PS_FUSES     = (1U << 18U),                                    /*!< RTD: Fuses */
163 } upower_ps_mask_t;
164 
165 /*! @brief upower memory partitions 0 mask definition. */
166 typedef enum _upower_mp0_mask
167 {
168     kUPOWER_MP0_A35_0       = (1U << 0U),  /*!< AD: A35 core0 */
169     kUPOWER_MP0_A35_1       = (1U << 1U),  /*!< AD: A35 core1 */
170     kUPOWER_MP0_A35_CORE_A  = (1U << 2U),  /*!< AD: A35 core0/1 */
171     kUPOWER_MP0_A35_CORE_B  = (1U << 3U),  /*!< AD: A35 core0/1 */
172     kUPOWER_MP0_A35_CORE_C  = (1U << 4U),  /*!< AD: A35 core0/1 */
173     kUPOWER_MP0_CAAM        = (1U << 5U),  /*!< AD: CAAM */
174     kUPOWER_MP0_DMA1        = (1U << 6U),  /*!< AD: DMA1 */
175     kUPOWER_MP0_FLEXSPI2    = (1U << 7U),  /*!< AD: FlexSPI2 */
176     kUPOWER_MP0_AD_SYSTEM_A = (1U << 8U),  /*!< AD: System */
177     kUPOWER_MP0_AD_SYSTEM_B = (1U << 9U),  /*!< AD: System */
178     kUPOWER_MP0_USB         = (1U << 10U), /*!< AD: USB */
179     kUPOWER_MP0_USDHC0      = (1U << 11U), /*!< AD: uSDHC0 */
180     kUPOWER_MP0_USDHC1      = (1U << 12U), /*!< AD: uSDHC1 */
181     kUPOWER_MP0_USDHC2      = (1U << 13U), /*!< AD: uSDHC2 */
182     kUPOWER_MP0_GIC         = (1U << 14U), /*!< AD: GIC */
183     kUPOWER_MP0_ENET        = (1U << 15U), /*!< AD: ENET */
184     kUPOWER_MP0_BRAINSHIFT  = (1U << 16U), /*!< AD: Brainshift */
185     kUPOWER_MP0_DCNANO_A    = (1U << 17U), /*!< LPAV: DCNano */
186     kUPOWER_MP0_DCNANO_B    = (1U << 18U), /*!< LPAV: DCNano */
187     kUPOWER_MP0_EPDC_A      = (1U << 19U), /*!< LPAV: EPDC */
188     kUPOWER_MP0_EPDC_B      = (1U << 20U), /*!< LPAV: EPDC */
189     kUPOWER_MP0_DMA2        = (1U << 21U), /*!< LPAV: DMA2 */
190     kUPOWER_MP0_GPU2D_A     = (1U << 22U), /*!< LPAV: GPU2D */
191     kUPOWER_MP0_GPU2D_B     = (1U << 23U), /*!< LPAV: GPU2D */
192     kUPOWER_MP0_GPU3D_A     = (1U << 24U), /*!< LPAV: GPU3D */
193     kUPOWER_MP0_GPU3D_B     = (1U << 25U), /*!< LPAV: GPU3D */
194     kUPOWER_MP0_HIFI4       = (1U << 26U), /*!< LPAV: Hi-Fi DSP */
195     kUPOWER_MP0_ISI         = (1U << 27U), /*!< LPAV: ISI */
196     kUPOWER_MP0_MIPI_CSI    = (1U << 28U), /*!< LPAV: MIPI CSI */
197     kUPOWER_MP0_MIPI_DSI    = (1U << 29U), /*!< LPAV: MIPI DSI */
198     kUPOWER_MP0_PXP         = (1U << 30U), /*!< LPAV: PXP */
199     kUPOWER_MP0_AV_SYSTEM   = (1U << 31U), /*!< LPAV: System */
200 } upower_mp0_mask_t;
201 
202 /*! @brief upower memory partitions 1 mask definition. */
203 typedef enum _upower_mp1_mask
204 {
205     kUPOWER_MP1_CASPER     = (1U << 0U),  /*!< RTD: Casper */
206     kUPOWER_MP1_DMA0       = (1U << 1U),  /*!< RTD: DMA0 */
207     kUPOWER_MP1_FLEXCAN    = (1U << 2U),  /*!< RTD: FlexCAN (CAN-FD) */
208     kUPOWER_MP1_FLEXSPI0   = (1U << 3U),  /*!< RTD: FlexSPI0 (OTFAD) */
209     kUPOWER_MP1_FLEXSPI1   = (1U << 4U),  /*!< RTD: FlexSPI1 */
210     kUPOWER_MP1_M33        = (1U << 5U),  /*!< RTD: M33 */
211     kUPOWER_MP1_POWERQUAD  = (1U << 6U),  /*!< RTD: PowerQuad */
212     kUPOWER_MP1_M33_ETF    = (1U << 7U),  /*!< RTD: M33-ETF */
213     kUPOWER_MP1_SENTINEL_A = (1U << 8U),  /*!< RTD: Sentinel */
214     kUPOWER_MP1_SENTINEL_B = (1U << 9U),  /*!< RTD: Sentinel */
215     kUPOWER_MP1_UPOWER_A   = (1U << 10U), /*!< RTD: uPower */
216     kUPOWER_MP1_UPOWER_B   = (1U << 11U), /*!< RTD: uPower */
217     kUPOWER_MP1_RTD_SYSTEM = (1U << 12U), /*!< RTD: System */
218     kUPOWER_MP1_SYSTEM0    = (1U << 13U), /*!< RTD: System[0] */
219     kUPOWER_MP1_SYSTEM1    = (1U << 14U), /*!< RTD: System[1] */
220     kUPOWER_MP1_SYSTEM2    = (1U << 15U), /*!< RTD: System[2] */
221     kUPOWER_MP1_SYSTEM3    = (1U << 16U), /*!< RTD: System[3] */
222     kUPOWER_MP1_SYSTEM4    = (1U << 17U), /*!< RTD: System[4] */
223     kUPOWER_MP1_SYSTEM5    = (1U << 18U), /*!< RTD: System[5] */
224     kUPOWER_MP1_SYSTEM6    = (1U << 19U), /*!< RTD: System[6] */
225     kUPOWER_MP1_SYSTEM7    = (1U << 20U), /*!< RTD: System[7] */
226     kUPOWER_MP1_SENTINEL_C = (1U << 21U), /*!< RTD: Sentinel */
227 } upower_mp1_mask_t;
228 
229 typedef struct _upower_version
230 {
231     uint32_t romMajor;
232     uint32_t romMinor;
233     uint32_t romFixes;
234     uint32_t ramMajor;
235     uint32_t ramMinor;
236     uint32_t ramFixes;
237 } upower_version_t;
238 
239 /*******************************************************************************
240  * API
241  ******************************************************************************/
242 #if defined(__cplusplus)
243 extern "C" {
244 #endif /*__cplusplus */
245 
246 /*!
247  * @brief Check status of current request to uPower.
248  *
249  * Will block till related callback function has been called
250  *
251  * @sg Indicate which Service Group that request point to
252  * @sgfptr: pointer to the variable that will hold the function id of the last request completed
253  * @errptr: pointer to the variable that will hold the error code
254  * @retptr: pointer to the variable that will hold the value returned by the last request completed (invalid if the last
255  * request completed didn't return any value)
256  * @attempts: maximum number of polling attempts; if attempts > 0 and is reached with no service response received,
257  * upwr_poll_req_status returns UPWR_REQ_BUSY and variables pointed by sgfptr, retptr and errptr are not updated; if
258  * attempts = 0, upwr_poll_req_status waits "forever".
259  */
260 void UPOWER_CheckReqWithArgs(upwr_sg_t sg, uint32_t *sgfptr, upwr_resp_t *errptr, int *retptr, uint32_t attempts);
261 
262 /*!
263  * @brief uPower specific IRQ handler.
264  *
265  */
266 void uPower_IRQHandler(void);
267 
268 /*!
269  * @brief Check status of current request to uPower.
270  *
271  * Will block till related callback function has been called
272  *
273  * @sg Indicate which Service Group that request point to
274  */
275 void UPOWER_CheckReq(upwr_sg_t sg);
276 
277 /*!
278  * @brief Initialize MU interface for uPower access.
279  *
280  * @param pVersion Pointer to the structure to save uPower ROM and RAM versions
281  */
282 void UPOWER_Init(upower_version_t *pVersion);
283 
284 /*!
285  * @brief Deinitialize MU interface for uPower access.
286  */
287 void UPOWER_Deinit(void);
288 
289 /*!
290  * @brief Power on certain domain without reset.
291  *
292  * @param domain Target domain to power on.
293  * @return 0 if ok, failure otherwise.
294  */
295 int UPOWER_PowerOnDomain(soc_domain_t domain);
296 
297 /*!
298  * @brief Reset and kick off certain domain.
299  *
300  * @param domain Target domain to boot.
301  * @return 0 if ok, failure otherwise.
302  */
303 int UPOWER_BootDomain(soc_domain_t domain);
304 
305 /*!
306  * @brief Power on power switches.
307  *
308  * @param mask Bits to define which switch should be turned on. The value should be ORed by @ref upower_ps_mask_t.
309  *             Bit value 1 means the switch is to be powered on; Value 0 means the switch keeps unchanged.
310  * @return 0 if ok, failure otherwise.
311  */
312 int UPOWER_PowerOnSwitches(upower_ps_mask_t mask);
313 
314 /*!
315  * @brief Power off power switches.
316  *
317  * @param mask Bits to define which switch should be turned off. The value should be ORed by @ref upower_ps_mask_t.
318  *             Bit value 1 means the switch is to be powered off; Value 0 means the switch keeps unchanged.
319  * @return 0 if ok, failure otherwise.
320  */
321 int UPOWER_PowerOffSwitches(upower_ps_mask_t mask);
322 
323 /*!
324  * @brief Power on memory partitions array/periphery logic. If a memory is requested to turn on, but the
325  * power switch that feeds that memory is not, the power switch will be turned on automatically.
326  *
327  * The parameter mask bits define which memory partition should be turned on. The value should be ORed by
328  * upower_mp0_mask_t or upower_mp1_mask_t. Mask bit value 1 means the switch is to be powered on; Value 0
329  * means the switch keeps unchanged.
330  *
331  * @param mask0 memory partition group 0 mask, see @ref upower_mp0_mask_t.
332  * @param mask1 memory partition group 1 mask, see @ref upower_mp1_mask_t.
333  * @return 0 if ok, failure otherwise.
334  */
335 int UPOWER_PowerOnMemPart(uint32_t mask0, uint32_t mask1);
336 
337 /*!
338  * @brief Power off memory partitions array/periphery logic.
339  *
340  * The parameter mask bits define which memory partition should be turned off. The value should be ORed by
341  * upower_mp0_mask_t and upower_mp1_mask_t. Mask bit value 1 means the switch is to be powered off; Value 0
342  * means the switch keeps unchanged.
343  *
344  * @param mask0 memory partition group 0 mask, see @ref upower_mp0_mask_t.
345  * @param mask1 memory partition group 1 mask, see @ref upower_mp1_mask_t.
346  * @return 0 if ok, failure otherwise.
347  */
348 int UPOWER_PowerOffMemPart(uint32_t mask0, uint32_t mask1);
349 
350 /*!
351  * @brief Power on memory partitions array logic and power off its periphery logic. If a memory array is
352  * requested to turn on, but the power switch that feeds that memory is not, the power switch will be turned
353  * on automatically.
354  *
355  * The parameter mask bits define which memory partition should be turned on. The value should be ORed by
356  * upower_mp0_mask_t or upower_mp1_mask_t. Mask bit value 1 means the switch is to be powered on; Value 0
357  * means the switch keeps unchanged.
358  *
359  * @param mask0 memory partition group 0 mask, see @ref upower_mp0_mask_t.
360  * @param mask1 memory partition group 1 mask, see @ref upower_mp1_mask_t.
361  * @return 0 if ok, failure otherwise.
362  */
363 int UPOWER_RetainMemPart(uint32_t mask0, uint32_t mask1);
364 
365 /*!
366  * @brief M33 call this API to inform uPower, M33 is using ddr.
367  *
368  * @param use_ddr not 0, true, means that RTD is using ddr. 0, false, means that, RTD is not using ddr.
369  * @return 0 if ok, failure otherwise(-1 if service group is busy, -3 if called in an invalid API state).
370  */
371 int UPOWER_SetRtdUseDdr(bool use_ddr);
372 
373 /*!
374  * @brief M33 call this API to Power On Application Domain when Application Domain is in Power Down/Deep Power Down
375  * mode. After upower get the msg, upower write a flag to registers according to msg. Then upower will get a WUU1
376  * interrupt request and upower change Power Down mode/Deep Power mode to Active mode when Application Domain is in
377  * Power Down/Deep Power Down mode.
378  *
379  * @return 0 if ok, failure otherwise.
380  */
381 int UPOWER_PowerOnADInPDMode(void);
382 
383 /*!
384  * @brief set sg powermanagement parameters of upower.
385  *
386  * please see upower_soc_defs.h file for struct upwr_pwm_param_t
387  *
388  * @param pcfg_in user's selection for powermanagement parameter of upower
389  * @return 0 if ok, failure otherwise.
390  */
391 int UPOWER_SetPwrMgmtParam(upwr_pwm_param_t *pcfg_in);
392 
393 /*!
394  * @brief Reduce Buck2 and Buck3 voltage in STANDBY mode.
395  *
396  * @return 0 if ok, failure otherwise.
397  */
398 int UPOWER_ReduceBuck23VoltInSTBY(void);
399 
400 /*!
401  * @brief Set DDR retention control bit.
402  *
403  * @param domain Target domain to power on.
404  * @param enable true means set ddr retention, false means clear ddr retention.
405  * @return 0 if ok, failure otherwise.
406  */
407 int UPOWER_SetDDRRetention(soc_domain_t domain, bool enable);
408 
409 /*!
410  * @brief Set LDO1 rail power.
411  *
412  * @param enable True means on, false means off.
413  * @return 0 if ok, failure otherwise.
414  */
415 int UPOWER_SetLDO1Power(bool enable);
416 
417 /*!
418  * @brief Set Buck3 rail power.
419  *
420  * @param enable True means on, false means off.
421  * @return 0 if ok, failure otherwise.
422  */
423 int UPOWER_SetBuck3Power(bool enable);
424 
425 /*
426  * @brief change PMIC voltage.
427  *
428  * @return 0 if ok, failure otherwise.
429  */
430 int UPOWER_ChngPmicVoltage(uint32_t rail, int voltage);
431 
432 /*!
433  * @brief Write PMIC registers by I2C.
434  *
435  * @param reg_addr means pmic ic target address.
436  * @param reg_val means write data, specific data can be found in PCA9460.
437  * @return 0 if ok, failure otherwise.
438  */
439 int UPOWER_SetPmicReg(uint32_t reg_addr, uint32_t reg_val);
440 
441 /*!
442  * @brief Read PMIC registers by I2C.
443  *
444  * @param reg_addr means pmic ic pca9460 target address.
445  * @param reg_val means value of register.
446  * @return 0 if ok, failure otherwise.
447  */
448 int UPOWER_ReadPmicReg(uint32_t reg_addr, uint8_t *reg_val);
449 
450 /*!
451  * @brief Init BUCK2 BUCK3 output voltage table.
452  */
453 void UPOWER_InitBuck2Buck3Table(void);
454 
455 /*!
456  * @brief get PMIC voltage.
457  *
458  * @return 0 if ok, failure otherwise.
459  */
460 int UPOWER_GetPmicVoltage(uint32_t rail, int *voltage);
461 
462 /*!
463  * @brief Change Bias Configuration(biasing options: NBB, RBB, ARBB, AFBB; Bias Voltage) for RTD
464  *
465  * @param  drive_mode Drive Mode: UD, ND, OD.
466  * @return 0 if ok, failure otherwise.
467  */
468 int UPOWER_ChngRTDDomBias(drive_mode_e drive_mode);
469 #if defined(__cplusplus)
470 }
471 #endif /*__cplusplus */
472 
473 /*! @} */
474 
475 #endif /* _FSL_UPOWER_H_ */
476