1 // SPDX-License-Identifier: BSD-3-Clause
2 /******************************************************************************
3  * Copyright (C) 2012-2018 Cadence Design Systems, Inc.
4  * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * lpddr4.c
7  *
8  *****************************************************************************
9  */
10 #include "cps_drv_lpddr4.h"
11 #include "lpddr4_ctl_regs.h"
12 #include "lpddr4_if.h"
13 #include "lpddr4_private.h"
14 #include "lpddr4_sanity.h"
15 #include "lpddr4_structs_if.h"
16 
17 #define LPDDR4_CUSTOM_TIMEOUT_DELAY 100000000U
18 
19 /**
20  * Internal Function:Poll for status of interrupt received by the Controller.
21  * @param[in] pD Driver state info specific to this instance.
22  * @param[in] irqBit Interrupt status bit to be checked.
23  * @param[in] delay time delay.
24  * @return CDN_EOK on success (Interrupt status high).
25  * @return EIO on poll time out.
26  * @return EINVAL checking status was not successful.
27  */
lpddr4_pollctlirq(const lpddr4_privatedata * pd,lpddr4_ctlinterrupt irqbit,uint32_t delay)28 static uint32_t lpddr4_pollctlirq(const lpddr4_privatedata * pd,
29 				  lpddr4_ctlinterrupt irqbit, uint32_t delay)
30 {
31 
32 	uint32_t result = 0U;
33 	uint32_t timeout = 0U;
34 	bool irqstatus = false;
35 
36 	/* Loop until irqStatus found to be 1 or if value of 'result' !=CDN_EOK */
37 	do {
38 		if (++timeout == delay) {
39 			result = EIO;
40 			break;
41 		}
42 		/* cps_delayns(10000000U); */
43 		result = lpddr4_checkctlinterrupt(pd, irqbit, &irqstatus);
44 	} while ((irqstatus == false) && (result == (uint32_t) CDN_EOK));
45 
46 	return result;
47 }
48 
49 /**
50  * Internal Function:Poll for status of interrupt received by the PHY Independent Module.
51  * @param[in] pD Driver state info specific to this instance.
52  * @param[in] irqBit Interrupt status bit to be checked.
53  * @param[in] delay time delay.
54  * @return CDN_EOK on success (Interrupt status high).
55  * @return EIO on poll time out.
56  * @return EINVAL checking status was not successful.
57  */
lpddr4_pollphyindepirq(const lpddr4_privatedata * pd,lpddr4_phyindepinterrupt irqbit,uint32_t delay)58 static uint32_t lpddr4_pollphyindepirq(const lpddr4_privatedata * pd,
59 				       lpddr4_phyindepinterrupt irqbit,
60 				       uint32_t delay)
61 {
62 
63 	uint32_t result = 0U;
64 	uint32_t timeout = 0U;
65 	bool irqstatus = false;
66 
67 	/* Loop until irqStatus found to be 1 or if value of 'result' !=CDN_EOK */
68 	do {
69 		if (++timeout == delay) {
70 			result = EIO;
71 			break;
72 		}
73 		/* cps_delayns(10000000U); */
74 		result = lpddr4_checkphyindepinterrupt(pd, irqbit, &irqstatus);
75 	} while ((irqstatus == false) && (result == (uint32_t) CDN_EOK));
76 
77 	return result;
78 }
79 
80 /**
81  * Internal Function:Trigger function to poll and Ack IRQs
82  * @param[in] pD Driver state info specific to this instance.
83  * @return CDN_EOK on success (Interrupt status high).
84  * @return EIO on poll time out.
85  * @return EINVAL checking status was not successful.
86  */
lpddr4_pollandackirq(const lpddr4_privatedata * pd)87 static uint32_t lpddr4_pollandackirq(const lpddr4_privatedata * pd)
88 {
89 	uint32_t result = 0U;
90 
91 	/* Wait for PhyIndependent module to finish up ctl init sequence */
92 	result =
93 	    lpddr4_pollphyindepirq(pd, LPDDR4_PHY_INDEP_INIT_DONE_BIT,
94 				   LPDDR4_CUSTOM_TIMEOUT_DELAY);
95 
96 	/* Ack to clear the PhyIndependent interrupt bit */
97 	if (result == (uint32_t) CDN_EOK) {
98 		result =
99 		    lpddr4_ackphyindepinterrupt(pd,
100 						LPDDR4_PHY_INDEP_INIT_DONE_BIT);
101 	}
102 	/* Wait for the CTL end of initialization */
103 	if (result == (uint32_t) CDN_EOK) {
104 		result =
105 		    lpddr4_pollctlirq(pd, LPDDR4_MC_INIT_DONE,
106 				      LPDDR4_CUSTOM_TIMEOUT_DELAY);
107 	}
108 	/* Ack to clear the Ctl interrupt bit */
109 	if (result == (uint32_t) CDN_EOK) {
110 		result = lpddr4_ackctlinterrupt(pd, LPDDR4_MC_INIT_DONE);
111 	}
112 	return result;
113 }
114 
115 /**
116  * Internal Function: Controller start sequence.
117  * @param[in] pD Driver state info specific to this instance.
118  * @return CDN_EOK on success.
119  * @return EINVAL starting controller was not successful.
120  */
lpddr4_startsequencecontroller(const lpddr4_privatedata * pd)121 static uint32_t lpddr4_startsequencecontroller(const lpddr4_privatedata * pd)
122 {
123 	uint32_t result = 0U;
124 	uint32_t regval = 0U;
125 	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
126 	lpddr4_infotype infotype;
127 
128 	/* Set the PI_start to initiate leveling procedure */
129 	regval =
130 	    CPS_FLD_SET(LPDDR4__PI_START__FLD,
131 			CPS_REG_READ(&(ctlregbase->LPDDR4__PI_START__REG)));
132 	CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_START__REG)), regval);
133 
134 	/* Set the Ctl_start  */
135 	regval =
136 	    CPS_FLD_SET(LPDDR4__START__FLD,
137 			CPS_REG_READ(&(ctlregbase->LPDDR4__START__REG)));
138 	CPS_REG_WRITE(&(ctlregbase->LPDDR4__START__REG), regval);
139 
140 	if (pd->infohandler != NULL) {
141 		/* If a handler is registered, call it with the relevant information type */
142 		infotype = LPDDR4_DRV_SOC_PLL_UPDATE;
143 		pd->infohandler(pd, infotype);
144 	}
145 
146 	result = lpddr4_pollandackirq(pd);
147 
148 	return result;
149 }
150 
151 /**
152  * Internal Function: To add the offset to given address.
153  * @param[in] addr Address to which the offset has to be added.
154  * @param[in] regOffset The offset
155  * @return regAddr The address value after the summation.
156  */
lpddr4_addoffset(volatile uint32_t * addr,uint32_t regoffset)157 static volatile uint32_t *lpddr4_addoffset(volatile uint32_t * addr,
158 					   uint32_t regoffset)
159 {
160 
161 	volatile uint32_t *local_addr = addr;
162 	/* Declaring as array to add the offset value. */
163 	volatile uint32_t *regaddr = &local_addr[regoffset];
164 	return regaddr;
165 }
166 
167 /**
168  * Checks configuration object.
169  * @param[in] config Driver/hardware configuration required.
170  * @param[out] configSize Size of memory allocations required.
171  * @return CDN_EOK on success (requirements structure filled).
172  * @return ENOTSUP if configuration cannot be supported due to driver/hardware constraints.
173  */
lpddr4_probe(const lpddr4_config * config,uint16_t * configsize)174 uint32_t lpddr4_probe(const lpddr4_config * config, uint16_t * configsize)
175 {
176 	uint32_t result;
177 
178 	result = (uint32_t) (lpddr4_probesf(config, configsize));
179 	if (result == (uint32_t) CDN_EOK) {
180 		*configsize = (uint16_t) (sizeof(lpddr4_privatedata));
181 	}
182 	return result;
183 }
184 
185 /**
186  * Init function to be called after LPDDR4_probe() to set up the driver configuration.
187  * Memory should be allocated for drv_data (using the size determined using LPDDR4_probe) before
188  * calling  this API, init_settings should be initialized with base addresses for PHY Independent Module,
189  * Controller and PHY before calling this function.
190  * If callbacks are required for interrupt handling, these should also be configured in init_settings.
191  * @param[in] pD Driver state info specific to this instance.
192  * @param[in] cfg Specifies driver/hardware configuration.
193  * @return CDN_EOK on success
194  * @return EINVAL if illegal/inconsistent values in cfg.
195  * @return ENOTSUP if hardware has an inconsistent configuration or doesn't support feature(s)
196  * required by 'config' parameters.
197  */
lpddr4_init(lpddr4_privatedata * pd,const lpddr4_config * cfg)198 uint32_t lpddr4_init(lpddr4_privatedata * pd, const lpddr4_config * cfg)
199 {
200 	uint32_t result = 0U;
201 	uint16_t productid = 0U;
202 
203 	result = lpddr4_initsf(pd, cfg);
204 	if (result == (uint32_t) CDN_EOK) {
205 		/* Validate Magic number */
206 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) cfg->ctlbase;
207 		productid = (uint16_t) (CPS_FLD_READ(LPDDR4__CONTROLLER_ID__FLD,
208 						     CPS_REG_READ(&
209 								  (ctlregbase->
210 								   LPDDR4__CONTROLLER_ID__REG))));
211 		if (productid == PRODUCT_ID) {
212 			/* Populating configuration data to pD */
213 			pd->ctlbase = ctlregbase;
214 			pd->infohandler =
215 			    (lpddr4_infocallback) cfg->infohandler;
216 			pd->ctlinterrupthandler =
217 			    (lpddr4_ctlcallback) cfg->ctlinterrupthandler;
218 			pd->phyindepinterrupthandler =
219 			    (lpddr4_phyindepcallback) cfg->
220 			    phyindepinterrupthandler;
221 		} else {
222 			/* Magic number validation failed - Driver doesn't support given IP version */
223 			result = (uint32_t) EOPNOTSUPP;
224 		}
225 	}
226 	return result;
227 }
228 
229 /**
230  * Start the driver.
231  * @param[in] pD Driver state info specific to this instance.
232  */
lpddr4_start(const lpddr4_privatedata * pd)233 uint32_t lpddr4_start(const lpddr4_privatedata * pd)
234 {
235 	uint32_t result = 0U;
236 	uint32_t regval = 0U;
237 
238 	result = lpddr4_startsf(pd);
239 	if (result == (uint32_t) CDN_EOK) {
240 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
241 
242 		/* Enable PI as the initiator for DRAM */
243 		regval =
244 		    CPS_FLD_SET(LPDDR4__PI_INIT_LVL_EN__FLD,
245 				CPS_REG_READ(&
246 					     (ctlregbase->
247 					      LPDDR4__PI_INIT_LVL_EN__REG)));
248 		regval = CPS_FLD_SET(LPDDR4__PI_NORMAL_LVL_SEQ__FLD, regval);
249 		CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_INIT_LVL_EN__REG)),
250 			      regval);
251 
252 		/* Start PI init sequence. */
253 		result = lpddr4_startsequencecontroller(pd);
254 	}
255 	return result;
256 }
257 
258 /**
259  * Read a register from the controller, PHY or PHY Independent Module
260  * @param[in] pD Driver state info specific to this instance.
261  * @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
262  * @param[in] regOffset Register offset
263  * @param[out] regValue Register value read
264  * @return CDN_EOK on success.
265  * @return EINVAL if regOffset if out of range or regValue is NULL
266  */
lpddr4_readreg(const lpddr4_privatedata * pd,lpddr4_regblock cpp,uint32_t regoffset,uint32_t * regvalue)267 uint32_t lpddr4_readreg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
268 			uint32_t regoffset, uint32_t * regvalue)
269 {
270 	uint32_t result = 0U;
271 
272 	result = lpddr4_readregsf(pd, cpp, regvalue);
273 	if (result == (uint32_t) CDN_EOK) {
274 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
275 
276 		if (cpp == LPDDR4_CTL_REGS) {
277 			if (regoffset >= LPDDR4_CTL_REG_COUNT) {
278 				/* Return if user provider invalid register number */
279 				result = EINVAL;
280 			} else {
281 				*regvalue =
282 				    CPS_REG_READ(lpddr4_addoffset
283 						 (&(ctlregbase->DENALI_CTL_0),
284 						  regoffset));
285 			}
286 		} else if (cpp == LPDDR4_PHY_REGS) {
287 			if (regoffset >= LPDDR4_PHY_REG_COUNT) {
288 				/* Return if user provider invalid register number */
289 				result = EINVAL;
290 			} else {
291 				*regvalue =
292 				    CPS_REG_READ(lpddr4_addoffset
293 						 (&(ctlregbase->DENALI_PHY_0),
294 						  regoffset));
295 			}
296 
297 		} else {
298 			if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
299 				/* Return if user provider invalid register number */
300 				result = EINVAL;
301 			} else {
302 				*regvalue =
303 				    CPS_REG_READ(lpddr4_addoffset
304 						 (&(ctlregbase->DENALI_PI_0),
305 						  regoffset));
306 			}
307 		}
308 	}
309 	return result;
310 }
311 
lpddr4_writereg(const lpddr4_privatedata * pd,lpddr4_regblock cpp,uint32_t regoffset,uint32_t regvalue)312 uint32_t lpddr4_writereg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
313 			 uint32_t regoffset, uint32_t regvalue)
314 {
315 	uint32_t result = 0U;
316 
317 	result = lpddr4_writeregsf(pd, cpp);
318 	if (result == (uint32_t) CDN_EOK) {
319 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
320 
321 		if (cpp == LPDDR4_CTL_REGS) {
322 			if (regoffset >= LPDDR4_CTL_REG_COUNT) {
323 				/* Return if user provider invalid register number */
324 				result = EINVAL;
325 			} else {
326 				CPS_REG_WRITE(lpddr4_addoffset
327 					      (&(ctlregbase->DENALI_CTL_0),
328 					       regoffset), regvalue);
329 			}
330 		} else if (cpp == LPDDR4_PHY_REGS) {
331 			if (regoffset >= LPDDR4_PHY_REG_COUNT) {
332 				/* Return if user provider invalid register number */
333 				result = EINVAL;
334 			} else {
335 				CPS_REG_WRITE(lpddr4_addoffset
336 					      (&(ctlregbase->DENALI_PHY_0),
337 					       regoffset), regvalue);
338 			}
339 		} else {
340 			if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
341 				/* Return if user provider invalid register number */
342 				result = EINVAL;
343 			} else {
344 				CPS_REG_WRITE(lpddr4_addoffset
345 					      (&(ctlregbase->DENALI_PI_0),
346 					       regoffset), regvalue);
347 			}
348 		}
349 	}
350 
351 	return result;
352 }
353 
lpddr4_checkmmrreaderror(const lpddr4_privatedata * pd,uint64_t * mmrvalue,uint8_t * mrrstatus)354 static uint32_t lpddr4_checkmmrreaderror(const lpddr4_privatedata * pd,
355 					 uint64_t * mmrvalue,
356 					 uint8_t * mrrstatus)
357 {
358 
359 	uint64_t lowerdata;
360 	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
361 	uint32_t result = (uint32_t) CDN_EOK;
362 
363 	/* Check if mode register read error interrupt occurred */
364 	if (lpddr4_pollctlirq(pd, LPDDR4_MRR_ERROR, 100) == 0U) {
365 		/* Mode register read error interrupt, read MRR status register and return. */
366 		*mrrstatus =
367 		    (uint8_t) CPS_FLD_READ(LPDDR4__MRR_ERROR_STATUS__FLD,
368 					   CPS_REG_READ(&
369 							(ctlregbase->
370 							 LPDDR4__MRR_ERROR_STATUS__REG)));
371 		*mmrvalue = 0;
372 		result = EIO;
373 	} else {
374 		*mrrstatus = 0;
375 		/* Mode register read was successful, read DATA */
376 		lowerdata =
377 		    CPS_REG_READ(&
378 				 (ctlregbase->
379 				  LPDDR4__PERIPHERAL_MRR_DATA_0__REG));
380 		*mmrvalue =
381 		    CPS_REG_READ(&
382 				 (ctlregbase->
383 				  LPDDR4__PERIPHERAL_MRR_DATA_1__REG));
384 		*mmrvalue = (uint64_t) ((*mmrvalue << WORD_SHIFT) | lowerdata);
385 		/* Acknowledge MR_READ_DONE interrupt to clear it */
386 		result = lpddr4_ackctlinterrupt(pd, LPDDR4_MR_READ_DONE);
387 	}
388 	return result;
389 }
390 
lpddr4_getmmrregister(const lpddr4_privatedata * pd,uint32_t readmoderegval,uint64_t * mmrvalue,uint8_t * mmrstatus)391 uint32_t lpddr4_getmmrregister(const lpddr4_privatedata * pd,
392 			       uint32_t readmoderegval, uint64_t * mmrvalue,
393 			       uint8_t * mmrstatus)
394 {
395 
396 	uint32_t result = 0U;
397 	uint32_t tdelay = 1000U;
398 	uint32_t regval = 0U;
399 
400 	result = lpddr4_getmmrregistersf(pd, mmrvalue, mmrstatus);
401 	if (result == (uint32_t) CDN_EOK) {
402 
403 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
404 
405 		/* Populate the calculated value to the register  */
406 		regval =
407 		    CPS_FLD_WRITE(LPDDR4__READ_MODEREG__FLD,
408 				  CPS_REG_READ(&
409 					       (ctlregbase->
410 						LPDDR4__READ_MODEREG__REG)),
411 				  readmoderegval);
412 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__READ_MODEREG__REG), regval);
413 
414 		/* Wait until the Read is done */
415 		result = lpddr4_pollctlirq(pd, LPDDR4_MR_READ_DONE, tdelay);
416 	}
417 	if (result == (uint32_t) CDN_EOK) {
418 		result = lpddr4_checkmmrreaderror(pd, mmrvalue, mmrstatus);
419 	}
420 	return result;
421 }
422 
lpddr4_writemmrregister(const lpddr4_privatedata * pd,uint32_t writemoderegval)423 static uint32_t lpddr4_writemmrregister(const lpddr4_privatedata * pd,
424 					uint32_t writemoderegval)
425 {
426 
427 	uint32_t result = (uint32_t) CDN_EOK;
428 	uint32_t tdelay = 1000U;
429 	uint32_t regval = 0U;
430 	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
431 
432 	/* Populate the calculated value to the register  */
433 	regval =
434 	    CPS_FLD_WRITE(LPDDR4__WRITE_MODEREG__FLD,
435 			  CPS_REG_READ(&
436 				       (ctlregbase->
437 					LPDDR4__WRITE_MODEREG__REG)),
438 			  writemoderegval);
439 	CPS_REG_WRITE(&(ctlregbase->LPDDR4__WRITE_MODEREG__REG), regval);
440 
441 	result = lpddr4_pollctlirq(pd, LPDDR4_MR_WRITE_DONE, tdelay);
442 
443 	return result;
444 }
445 
lpddr4_setmmrregister(const lpddr4_privatedata * pd,uint32_t writemoderegval,uint8_t * mrwstatus)446 uint32_t lpddr4_setmmrregister(const lpddr4_privatedata * pd,
447 			       uint32_t writemoderegval, uint8_t * mrwstatus)
448 {
449 	uint32_t result = 0U;
450 
451 	result = lpddr4_setmmrregistersf(pd, mrwstatus);
452 	if (result == (uint32_t) CDN_EOK) {
453 
454 		/* Function call to trigger Mode register write */
455 		result = lpddr4_writemmrregister(pd, writemoderegval);
456 
457 		if (result == (uint32_t) CDN_EOK) {
458 			result =
459 			    lpddr4_ackctlinterrupt(pd, LPDDR4_MR_WRITE_DONE);
460 		}
461 		/* Read the status of mode register write */
462 		if (result == (uint32_t) CDN_EOK) {
463 			lpddr4_ctlregs *ctlregbase =
464 			    (lpddr4_ctlregs *) pd->ctlbase;
465 			*mrwstatus =
466 			    (uint8_t) CPS_FLD_READ(LPDDR4__MRW_STATUS__FLD,
467 						   CPS_REG_READ(&
468 								(ctlregbase->
469 								 LPDDR4__MRW_STATUS__REG)));
470 			if ((*mrwstatus) != 0U) {
471 				result = EIO;
472 			}
473 		}
474 	}
475 
476 	return result;
477 }
478 
lpddr4_writectlconfig(const lpddr4_privatedata * pd,const lpddr4_reginitdata * regvalues)479 uint32_t lpddr4_writectlconfig(const lpddr4_privatedata * pd,
480 			       const lpddr4_reginitdata * regvalues)
481 {
482 	uint32_t result;
483 	uint32_t regnum;
484 
485 	result = lpddr4_writectlconfigsf(pd, regvalues);
486 	if (result == (uint32_t) CDN_EOK) {
487 
488 		/* Iterate through CTL register numbers. */
489 		for (regnum = 0; regnum < LPDDR4_CTL_REG_COUNT; regnum++) {
490 			/* Check if the user has requested update */
491 			if (regvalues->updatectlreg[regnum]) {
492 				result =
493 				    lpddr4_writereg(pd, LPDDR4_CTL_REGS, regnum,
494 						    (uint32_t) (regvalues->
495 								denalictlreg
496 								[regnum]));
497 			}
498 		}
499 	}
500 	return result;
501 }
502 
lpddr4_writephyindepconfig(const lpddr4_privatedata * pd,const lpddr4_reginitdata * regvalues)503 uint32_t lpddr4_writephyindepconfig(const lpddr4_privatedata * pd,
504 				    const lpddr4_reginitdata * regvalues)
505 {
506 	uint32_t result;
507 	uint32_t regnum;
508 
509 	result = lpddr4_writephyindepconfigsf(pd, regvalues);
510 	if (result == (uint32_t) CDN_EOK) {
511 
512 		/* Iterate through PHY Independent module register numbers. */
513 		for (regnum = 0; regnum < LPDDR4_PHY_INDEP_REG_COUNT; regnum++) {
514 			/* Check if the user has requested update */
515 			if (regvalues->updatephyindepreg[regnum]) {
516 				result =
517 				    lpddr4_writereg(pd, LPDDR4_PHY_INDEP_REGS,
518 						    regnum,
519 						    (uint32_t) (regvalues->
520 								denaliphyindepreg
521 								[regnum]));
522 			}
523 		}
524 	}
525 	return result;
526 }
527 
lpddr4_writephyconfig(const lpddr4_privatedata * pd,const lpddr4_reginitdata * regvalues)528 uint32_t lpddr4_writephyconfig(const lpddr4_privatedata * pd,
529 			       const lpddr4_reginitdata * regvalues)
530 {
531 	uint32_t result;
532 	uint32_t regnum;
533 
534 	result = lpddr4_writephyconfigsf(pd, regvalues);
535 	if (result == (uint32_t) CDN_EOK) {
536 
537 		/* Iterate through PHY register numbers. */
538 		for (regnum = 0; regnum < LPDDR4_PHY_REG_COUNT; regnum++) {
539 			/* Check if the user has requested update */
540 			if (regvalues->updatephyreg[regnum]) {
541 				result =
542 				    lpddr4_writereg(pd, LPDDR4_PHY_REGS, regnum,
543 						    (uint32_t) (regvalues->
544 								denaliphyreg
545 								[regnum]));
546 			}
547 		}
548 	}
549 	return result;
550 }
551 
lpddr4_readctlconfig(const lpddr4_privatedata * pd,lpddr4_reginitdata * regvalues)552 uint32_t lpddr4_readctlconfig(const lpddr4_privatedata * pd,
553 			      lpddr4_reginitdata * regvalues)
554 {
555 	uint32_t result;
556 	uint32_t regnum;
557 	result = lpddr4_readctlconfigsf(pd, regvalues);
558 	if (result == (uint32_t) CDN_EOK) {
559 		/* Iterate through CTL register numbers. */
560 		for (regnum = 0; regnum < LPDDR4_CTL_REG_COUNT; regnum++) {
561 			/* Check if the user has requested read (updateCtlReg=1) */
562 			if (regvalues->updatectlreg[regnum]) {
563 				result =
564 				    lpddr4_readreg(pd, LPDDR4_CTL_REGS, regnum,
565 						   (uint32_t *) (&regvalues->
566 								 denalictlreg
567 								 [regnum]));
568 			}
569 		}
570 	}
571 	return result;
572 }
573 
lpddr4_readphyindepconfig(const lpddr4_privatedata * pd,lpddr4_reginitdata * regvalues)574 uint32_t lpddr4_readphyindepconfig(const lpddr4_privatedata * pd,
575 				   lpddr4_reginitdata * regvalues)
576 {
577 	uint32_t result;
578 	uint32_t regnum;
579 
580 	result = lpddr4_readphyindepconfigsf(pd, regvalues);
581 	if (result == (uint32_t) CDN_EOK) {
582 		/* Iterate through PHY Independent module register numbers. */
583 		for (regnum = 0; regnum < LPDDR4_PHY_INDEP_REG_COUNT; regnum++) {
584 			/* Check if the user has requested read (updateCtlReg=1) */
585 			if (regvalues->updatephyindepreg[regnum]) {
586 				result =
587 				    lpddr4_readreg(pd, LPDDR4_PHY_INDEP_REGS,
588 						   regnum,
589 						   (uint32_t *) (&regvalues->
590 								 denaliphyindepreg
591 								 [regnum]));
592 			}
593 		}
594 	}
595 	return result;
596 }
597 
lpddr4_readphyconfig(const lpddr4_privatedata * pd,lpddr4_reginitdata * regvalues)598 uint32_t lpddr4_readphyconfig(const lpddr4_privatedata * pd,
599 			      lpddr4_reginitdata * regvalues)
600 {
601 	uint32_t result;
602 	uint32_t regnum;
603 
604 	result = lpddr4_readphyconfigsf(pd, regvalues);
605 	if (result == (uint32_t) CDN_EOK) {
606 		/* Iterate through PHY register numbers. */
607 		for (regnum = 0; regnum < LPDDR4_PHY_REG_COUNT; regnum++) {
608 			/* Check if the user has requested read (updateCtlReg=1) */
609 			if (regvalues->updatephyreg[regnum]) {
610 				result =
611 				    lpddr4_readreg(pd, LPDDR4_PHY_REGS, regnum,
612 						   (uint32_t *) (&regvalues->
613 								 denaliphyreg
614 								 [regnum]));
615 			}
616 		}
617 	}
618 	return result;
619 }
620 
lpddr4_getctlinterruptmask(const lpddr4_privatedata * pd,uint64_t * mask)621 uint32_t lpddr4_getctlinterruptmask(const lpddr4_privatedata * pd,
622 				    uint64_t * mask)
623 {
624 	uint32_t result = 0U;
625 	uint64_t lowermask = 0U;
626 
627 	result = lpddr4_getctlinterruptmasksf(pd, mask);
628 	if (result == (uint32_t) CDN_EOK) {
629 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
630 		/* Reading the lower mask register */
631 		lowermask =
632 		    (uint64_t) (CPS_FLD_READ
633 				(LPDDR4__INT_MASK_0__FLD,
634 				 CPS_REG_READ(&
635 					      (ctlregbase->
636 					       LPDDR4__INT_MASK_0__REG))));
637 		/* Reading the upper mask register */
638 		*mask =
639 		    (uint64_t) (CPS_FLD_READ
640 				(LPDDR4__INT_MASK_1__FLD,
641 				 CPS_REG_READ(&
642 					      (ctlregbase->
643 					       LPDDR4__INT_MASK_1__REG))));
644 		/* Concatenate both register informations */
645 		*mask = (uint64_t) ((*mask << WORD_SHIFT) | lowermask);
646 	}
647 	return result;
648 }
649 
lpddr4_setctlinterruptmask(const lpddr4_privatedata * pd,const uint64_t * mask)650 uint32_t lpddr4_setctlinterruptmask(const lpddr4_privatedata * pd,
651 				    const uint64_t * mask)
652 {
653 	uint32_t result;
654 	uint32_t regval = 0;
655 	const uint64_t ui64one = 1ULL;
656 	const uint32_t ui32irqcount = (uint32_t) LPDDR4_LOR_BITS + 1U;
657 
658 	result = lpddr4_setctlinterruptmasksf(pd, mask);
659 	if ((result == (uint32_t) CDN_EOK) && (ui32irqcount < 64U)) {
660 		/* Return if the user given value is higher than the field width */
661 		if (*mask >= (ui64one << ui32irqcount)) {
662 			result = EINVAL;
663 		}
664 	}
665 	if (result == (uint32_t) CDN_EOK) {
666 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
667 
668 		/* Extracting the lower 32 bits and writing to lower mask register */
669 		regval = (uint32_t) (*mask & WORD_MASK);
670 		regval =
671 		    CPS_FLD_WRITE(LPDDR4__INT_MASK_0__FLD,
672 				  CPS_REG_READ(&
673 					       (ctlregbase->
674 						LPDDR4__INT_MASK_0__REG)),
675 				  regval);
676 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_0__REG), regval);
677 
678 		/* Extracting the upper 32 bits and writing to upper mask register */
679 		regval = (uint32_t) ((*mask >> WORD_SHIFT) & WORD_MASK);
680 		regval =
681 		    CPS_FLD_WRITE(LPDDR4__INT_MASK_1__FLD,
682 				  CPS_REG_READ(&
683 					       (ctlregbase->
684 						LPDDR4__INT_MASK_1__REG)),
685 				  regval);
686 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_1__REG), regval);
687 	}
688 	return result;
689 }
690 
lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd,lpddr4_ctlinterrupt intr,bool * irqstatus)691 uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd,
692 				  lpddr4_ctlinterrupt intr, bool * irqstatus)
693 {
694 	uint32_t result;
695 	uint32_t ctlirqstatus = 0;
696 	uint32_t fieldshift = 0;
697 
698 	/* NOTE:This function assume irq status is mentioned in NOT more than 2 registers.
699 	 * Value of 'interrupt' should be less than 64 */
700 	result = lpddr4_checkctlinterruptsf(pd, intr, irqstatus);
701 	if (result == (uint32_t) CDN_EOK) {
702 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
703 
704 		if ((uint32_t) intr >= WORD_SHIFT) {
705 			ctlirqstatus =
706 			    CPS_REG_READ(&
707 					 (ctlregbase->
708 					  LPDDR4__INT_STATUS_1__REG));
709 			/* Reduce the shift value as we are considering upper register */
710 			fieldshift = (uint32_t) intr - ((uint32_t) WORD_SHIFT);
711 		} else {
712 			ctlirqstatus =
713 			    CPS_REG_READ(&
714 					 (ctlregbase->
715 					  LPDDR4__INT_STATUS_0__REG));
716 			/* The shift value remains same for lower interrupt register */
717 			fieldshift = (uint32_t) intr;
718 		}
719 
720 		/* MISRA compliance (Shifting operation) check */
721 		if (fieldshift < WORD_SHIFT) {
722 			if ((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) {
723 				*irqstatus = true;
724 			} else {
725 				*irqstatus = false;
726 			}
727 		}
728 	}
729 	return result;
730 }
731 
lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd,lpddr4_ctlinterrupt intr)732 uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd,
733 				lpddr4_ctlinterrupt intr)
734 {
735 	uint32_t result = 0;
736 	uint32_t regval = 0;
737 	uint32_t localinterrupt = (uint32_t) intr;
738 
739 	/* NOTE:This function assume irq status is mentioned in NOT more than 2 registers.
740 	 * Value of 'interrupt' should be less than 64 */
741 	result = lpddr4_ackctlinterruptsf(pd, intr);
742 	if (result == (uint32_t) CDN_EOK) {
743 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
744 
745 		/* Check if the requested bit is in upper register */
746 		if (localinterrupt > WORD_SHIFT) {
747 			localinterrupt =
748 			    (localinterrupt - (uint32_t) WORD_SHIFT);
749 			regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
750 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
751 				      regval);
752 		} else {
753 			regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
754 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
755 				      regval);
756 		}
757 	}
758 
759 	return result;
760 }
761 
lpddr4_getphyindepinterruptmask(const lpddr4_privatedata * pd,uint32_t * mask)762 uint32_t lpddr4_getphyindepinterruptmask(const lpddr4_privatedata * pd,
763 					 uint32_t * mask)
764 {
765 	uint32_t result;
766 
767 	result = lpddr4_getphyindepinterruptmsf(pd, mask);
768 	if (result == (uint32_t) CDN_EOK) {
769 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
770 		/* Reading mask register */
771 		*mask =
772 		    CPS_FLD_READ(LPDDR4__PI_INT_MASK__FLD,
773 				 CPS_REG_READ(&
774 					      (ctlregbase->
775 					       LPDDR4__PI_INT_MASK__REG)));
776 	}
777 	return result;
778 }
779 
lpddr4_setphyindepinterruptmask(const lpddr4_privatedata * pd,const uint32_t * mask)780 uint32_t lpddr4_setphyindepinterruptmask(const lpddr4_privatedata * pd,
781 					 const uint32_t * mask)
782 {
783 	uint32_t result;
784 	uint32_t regval = 0;
785 	const uint32_t ui32irqcount =
786 	    (uint32_t) LPDDR4_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT + 1U;
787 
788 	result = lpddr4_setphyindepinterruptmsf(pd, mask);
789 	if ((result == (uint32_t) CDN_EOK) && (ui32irqcount < WORD_SHIFT)) {
790 		/* Return if the user given value is higher than the field width */
791 		if (*mask >= (1U << ui32irqcount)) {
792 			result = EINVAL;
793 		}
794 	}
795 	if (result == (uint32_t) CDN_EOK) {
796 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
797 
798 		/* Writing to the user requested interrupt mask */
799 		regval =
800 		    CPS_FLD_WRITE(LPDDR4__PI_INT_MASK__FLD,
801 				  CPS_REG_READ(&
802 					       (ctlregbase->
803 						LPDDR4__PI_INT_MASK__REG)),
804 				  *mask);
805 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_MASK__REG), regval);
806 	}
807 	return result;
808 }
809 
lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd,lpddr4_phyindepinterrupt intr,bool * irqstatus)810 uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd,
811 				       lpddr4_phyindepinterrupt intr,
812 				       bool * irqstatus)
813 {
814 	uint32_t result = 0;
815 	uint32_t phyindepirqstatus = 0;
816 
817 	result = lpddr4_checkphyindepinterrupsf(pd, intr, irqstatus);
818 	/* Confirming that the value of interrupt is less than register width */
819 	if ((result == (uint32_t) CDN_EOK) && ((uint32_t) intr < WORD_SHIFT)) {
820 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
821 
822 		/* Reading the requested bit to check interrupt status */
823 		phyindepirqstatus =
824 		    CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
825 		*irqstatus =
826 		    !!((phyindepirqstatus >> (uint32_t)intr) & LPDDR4_BIT_MASK);
827 	}
828 	return result;
829 }
830 
lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd,lpddr4_phyindepinterrupt intr)831 uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd,
832 				     lpddr4_phyindepinterrupt intr)
833 {
834 	uint32_t result = 0U;
835 	uint32_t regval = 0U;
836 	uint32_t ui32shiftinterrupt = (uint32_t) intr;
837 
838 	result = lpddr4_ackphyindepinterruptsf(pd, intr);
839 	/* Confirming that the value of interrupt is less than register width */
840 	if ((result == (uint32_t) CDN_EOK) && (ui32shiftinterrupt < WORD_SHIFT)) {
841 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
842 
843 		/* Write 1 to the requested bit to ACk the interrupt */
844 		regval = (uint32_t)LPDDR4_BIT_MASK << ui32shiftinterrupt;
845 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
846 	}
847 
848 	return result;
849 }
850 
851 /* Check for caTrainingError */
lpddr4_checkcatrainingerror(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errfoundptr)852 static void lpddr4_checkcatrainingerror(lpddr4_ctlregs * ctlregbase,
853 					lpddr4_debuginfo * debuginfo,
854 					bool * errfoundptr)
855 {
856 
857 	uint32_t regval;
858 	uint32_t errbitmask = 0U;
859 	uint32_t snum;
860 	volatile uint32_t *regaddress;
861 
862 	regaddress =
863 	    (volatile uint32_t
864 	     *)(&(ctlregbase->LPDDR4__PHY_ADR_CALVL_OBS1_0__REG));
865 	errbitmask = (CA_TRAIN_RL) | (NIBBLE_MASK);
866 	/* PHY_ADR_CALVL_OBS1[4] – Right found
867 	   PHY_ADR_CALVL_OBS1[5] – left found
868 	   both the above fields should be high and below field should be zero.
869 	   PHY_ADR_CALVL_OBS1[3:0] – calvl_state
870 	 */
871 	for (snum = 0U; snum < ASLICE_NUM; snum++) {
872 		regval = CPS_REG_READ(regaddress);
873 		if ((regval & errbitmask) != CA_TRAIN_RL) {
874 			debuginfo->catraingerror = true;
875 			*errfoundptr = true;
876 		}
877 		regaddress =
878 		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
879 	}
880 }
881 
882 /* Check for  wrLvlError */
lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errfoundptr)883 static void lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase,
884 				   lpddr4_debuginfo * debuginfo,
885 				   bool * errfoundptr)
886 {
887 
888 	uint32_t regval;
889 	uint32_t errbitmask = 0U;
890 	uint32_t snum;
891 	volatile uint32_t *regaddress;
892 
893 	regaddress =
894 	    (volatile uint32_t
895 	     *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG));
896 	/* PHY_WRLVL_ERROR_OBS_X[1:0] should be zero */
897 	errbitmask = (LPDDR4_BIT_MASK << 1) | LPDDR4_BIT_MASK;
898 	for (snum = 0U; snum < DSLICE_NUM; snum++) {
899 		regval = CPS_REG_READ(regaddress);
900 		if ((regval & errbitmask) != 0U) {
901 			debuginfo->wrlvlerror = true;
902 			*errfoundptr = true;
903 		}
904 		regaddress =
905 		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
906 	}
907 }
908 
909 /* Check for  GateLvlError */
lpddr4_checkgatelvlerror(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errfoundptr)910 static void lpddr4_checkgatelvlerror(lpddr4_ctlregs * ctlregbase,
911 				     lpddr4_debuginfo * debuginfo,
912 				     bool * errfoundptr)
913 {
914 
915 	uint32_t regval;
916 	uint32_t errbitmask = 0U;
917 	uint32_t snum;
918 	volatile uint32_t *regaddress;
919 
920 	regaddress =
921 	    (volatile uint32_t
922 	     *)(&(ctlregbase->LPDDR4__PHY_GTLVL_STATUS_OBS_0__REG));
923 	/* PHY_GTLVL_STATUS_OBS[6] – gate_level min error
924 	 * PHY_GTLVL_STATUS_OBS[7] – gate_level max error
925 	 * All the above bit fields should be zero */
926 	errbitmask = GATE_LVL_ERROR_FIELDS;
927 	for (snum = 0U; snum < DSLICE_NUM; snum++) {
928 		regval = CPS_REG_READ(regaddress);
929 		if ((regval & errbitmask) != 0U) {
930 			debuginfo->gatelvlerror = true;
931 			*errfoundptr = true;
932 		}
933 		regaddress =
934 		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
935 	}
936 }
937 
938 /* Check for  ReadLvlError */
lpddr4_checkreadlvlerror(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errfoundptr)939 static void lpddr4_checkreadlvlerror(lpddr4_ctlregs * ctlregbase,
940 				     lpddr4_debuginfo * debuginfo,
941 				     bool * errfoundptr)
942 {
943 
944 	uint32_t regval;
945 	uint32_t errbitmask = 0U;
946 	uint32_t snum;
947 	volatile uint32_t *regaddress;
948 
949 	regaddress =
950 	    (volatile uint32_t
951 	     *)(&(ctlregbase->LPDDR4__PHY_RDLVL_STATUS_OBS_0__REG));
952 	/* PHY_RDLVL_STATUS_OBS[23:16] – failed bits : should be zero.
953 	   PHY_RDLVL_STATUS_OBS[31:28] – rdlvl_state : should be zero */
954 	errbitmask = READ_LVL_ERROR_FIELDS;
955 	for (snum = 0U; snum < DSLICE_NUM; snum++) {
956 		regval = CPS_REG_READ(regaddress);
957 		if ((regval & errbitmask) != 0U) {
958 			debuginfo->readlvlerror = true;
959 			*errfoundptr = true;
960 		}
961 		regaddress =
962 		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
963 	}
964 }
965 
966 /* Check for  DqTrainingError */
lpddr4_checkdqtrainingerror(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errfoundptr)967 static void lpddr4_checkdqtrainingerror(lpddr4_ctlregs * ctlregbase,
968 					lpddr4_debuginfo * debuginfo,
969 					bool * errfoundptr)
970 {
971 
972 	uint32_t regval;
973 	uint32_t errbitmask = 0U;
974 	uint32_t snum;
975 	volatile uint32_t *regaddress;
976 
977 	regaddress =
978 	    (volatile uint32_t
979 	     *)(&(ctlregbase->LPDDR4__PHY_WDQLVL_STATUS_OBS_0__REG));
980 	/* PHY_WDQLVL_STATUS_OBS[26:18] should all be zero. */
981 	errbitmask = DQ_LVL_STATUS;
982 	for (snum = 0U; snum < DSLICE_NUM; snum++) {
983 		regval = CPS_REG_READ(regaddress);
984 		if ((regval & errbitmask) != 0U) {
985 			debuginfo->dqtrainingerror = true;
986 			*errfoundptr = true;
987 		}
988 		regaddress =
989 		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
990 	}
991 }
992 
993 /**
994  * Internal Function:For checking errors in training/levelling sequence.
995  * @param[in] pD Driver state info specific to this instance.
996  * @param[in] debugInfo pointer to debug information.
997  * @param[out] errFoundPtr pointer to return if error found.
998  * @return CDN_EOK on success (Interrupt status high).
999  * @return EINVAL checking or unmasking was not successful.
1000  */
lpddr4_checklvlerrors(const lpddr4_privatedata * pd,lpddr4_debuginfo * debuginfo,bool errfound)1001 static bool lpddr4_checklvlerrors(const lpddr4_privatedata * pd,
1002 				  lpddr4_debuginfo * debuginfo, bool errfound)
1003 {
1004 
1005 	bool localerrfound = errfound;
1006 
1007 	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1008 
1009 	if (localerrfound == false) {
1010 		/* Check for ca training error */
1011 		lpddr4_checkcatrainingerror(ctlregbase, debuginfo,
1012 					    &localerrfound);
1013 	}
1014 
1015 	if (localerrfound == false) {
1016 		/* Check for Write leveling error */
1017 		lpddr4_checkwrlvlerror(ctlregbase, debuginfo, &localerrfound);
1018 	}
1019 
1020 	if (localerrfound == false) {
1021 		/* Check for Gate leveling error */
1022 		lpddr4_checkgatelvlerror(ctlregbase, debuginfo, &localerrfound);
1023 	}
1024 
1025 	if (localerrfound == false) {
1026 		/* Check for Read leveling error */
1027 		lpddr4_checkreadlvlerror(ctlregbase, debuginfo, &localerrfound);
1028 	}
1029 
1030 	if (localerrfound == false) {
1031 		/* Check for DQ training error */
1032 		lpddr4_checkdqtrainingerror(ctlregbase, debuginfo,
1033 					    &localerrfound);
1034 	}
1035 	return localerrfound;
1036 }
1037 
lpddr4_seterror(volatile uint32_t * reg,uint32_t errbitmask,bool * errfoundptr,const uint32_t errorinfobits)1038 static bool lpddr4_seterror(volatile uint32_t * reg, uint32_t errbitmask,
1039 			    bool * errfoundptr, const uint32_t errorinfobits)
1040 {
1041 
1042 	uint32_t regval = 0U;
1043 
1044 	/* Read the respective observation register */
1045 	regval = CPS_REG_READ(reg);
1046 	/* Compare the error bit values */
1047 	if ((regval & errbitmask) != errorinfobits) {
1048 		*errfoundptr = true;
1049 	}
1050 	return *errfoundptr;
1051 }
1052 
lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errfoundptr)1053 static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,
1054 			     lpddr4_debuginfo * debuginfo, bool * errfoundptr)
1055 {
1056 
1057 	uint32_t errbitmask = (LPDDR4_BIT_MASK << 0x1U) | LPDDR4_BIT_MASK;
1058 	/* Check PLL observation registers for PLL lock errors */
1059 
1060 	debuginfo->pllerror =
1061 	    lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_0__REG),
1062 			    errbitmask, errfoundptr, PLL_READY);
1063 	if (*errfoundptr == false) {
1064 		debuginfo->pllerror =
1065 		    lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_1__REG),
1066 				    errbitmask, errfoundptr, PLL_READY);
1067 	}
1068 
1069 	/* Check for IO Calibration errors */
1070 	if (*errfoundptr == false) {
1071 		debuginfo->iocaliberror =
1072 		    lpddr4_seterror(&
1073 				    (ctlregbase->
1074 				     LPDDR4__PHY_CAL_RESULT_OBS_0__REG),
1075 				    IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
1076 	}
1077 	if (*errfoundptr == false) {
1078 		debuginfo->iocaliberror =
1079 		    lpddr4_seterror(&
1080 				    (ctlregbase->
1081 				     LPDDR4__PHY_CAL_RESULT2_OBS_0__REG),
1082 				    IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
1083 	}
1084 	if (*errfoundptr == false) {
1085 		debuginfo->iocaliberror =
1086 		    lpddr4_seterror(&
1087 				    (ctlregbase->
1088 				     LPDDR4__PHY_CAL_RESULT3_OBS_0__REG),
1089 				    IO_CALIB_FIELD, errfoundptr,
1090 				    IO_CALIB_STATE);
1091 	}
1092 }
1093 
lpddr4_setphysnapsettings(lpddr4_ctlregs * ctlregbase,const bool errorfound)1094 static void lpddr4_setphysnapsettings(lpddr4_ctlregs * ctlregbase,
1095 				      const bool errorfound)
1096 {
1097 
1098 	uint32_t snum = 0U;
1099 	volatile uint32_t *regaddress;
1100 	uint32_t regval = 0U;
1101 
1102 	/* Setting SC_PHY_SNAP_OBS_REGS_x to get a snapshot */
1103 	if (errorfound == false) {
1104 		regaddress =
1105 		    (volatile uint32_t
1106 		     *)(&(ctlregbase->LPDDR4__SC_PHY_SNAP_OBS_REGS_0__REG));
1107 		/* Iterate through each PHY Data Slice */
1108 		for (snum = 0U; snum < DSLICE_NUM; snum++) {
1109 			regval =
1110 			    CPS_FLD_SET(LPDDR4__SC_PHY_SNAP_OBS_REGS_0__FLD,
1111 					CPS_REG_READ(regaddress));
1112 			CPS_REG_WRITE(regaddress, regval);
1113 			regaddress =
1114 			    lpddr4_addoffset(regaddress,
1115 					     (uint32_t) SLICE_WIDTH);
1116 		}
1117 	}
1118 }
1119 
lpddr4_setphyadrsnapsettings(lpddr4_ctlregs * ctlregbase,const bool errorfound)1120 static void lpddr4_setphyadrsnapsettings(lpddr4_ctlregs * ctlregbase,
1121 					 const bool errorfound)
1122 {
1123 
1124 	uint32_t snum = 0U;
1125 	volatile uint32_t *regaddress;
1126 	uint32_t regval = 0U;
1127 
1128 	/* Setting SC_PHY ADR_SNAP_OBS_REGS_x to get a snapshot */
1129 	if (errorfound == false) {
1130 		regaddress =
1131 		    (volatile uint32_t
1132 		     *)(&(ctlregbase->LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__REG));
1133 		/* Iterate through each PHY Address Slice */
1134 		for (snum = 0U; snum < ASLICE_NUM; snum++) {
1135 			regval =
1136 			    CPS_FLD_SET(LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__FLD,
1137 					CPS_REG_READ(regaddress));
1138 			CPS_REG_WRITE(regaddress, regval);
1139 			regaddress =
1140 			    lpddr4_addoffset(regaddress,
1141 					     (uint32_t) SLICE_WIDTH);
1142 		}
1143 	}
1144 }
1145 
lpddr4_setsettings(lpddr4_ctlregs * ctlregbase,const bool errorfound)1146 static void lpddr4_setsettings(lpddr4_ctlregs * ctlregbase,
1147 			       const bool errorfound)
1148 {
1149 
1150 	/* Calling functions to enable snap shots of OBS registers */
1151 	lpddr4_setphysnapsettings(ctlregbase, errorfound);
1152 	lpddr4_setphyadrsnapsettings(ctlregbase, errorfound);
1153 }
1154 
lpddr4_setrxoffseterror(lpddr4_ctlregs * ctlregbase,lpddr4_debuginfo * debuginfo,bool * errorfound)1155 static void lpddr4_setrxoffseterror(lpddr4_ctlregs * ctlregbase,
1156 				    lpddr4_debuginfo * debuginfo,
1157 				    bool * errorfound)
1158 {
1159 
1160 	volatile uint32_t *regaddress;
1161 	uint32_t snum = 0U;
1162 	uint32_t errbitmask = 0U;
1163 	uint32_t regval = 0U;
1164 
1165 	/* Check for rxOffsetError */
1166 	if (*errorfound == false) {
1167 		regaddress =
1168 		    (volatile uint32_t
1169 		     *)(&(ctlregbase->LPDDR4__PHY_RX_CAL_LOCK_OBS_0__REG));
1170 		errbitmask = (RX_CAL_DONE) | (NIBBLE_MASK);
1171 		/* PHY_RX_CAL_LOCK_OBS_x[4] – RX_CAL_DONE : should be high
1172 		   phy_rx_cal_lock_obs_x[3:0] – RX_CAL_STATE : should be zero. */
1173 		for (snum = 0U; snum < DSLICE_NUM; snum++) {
1174 			regval =
1175 			    CPS_FLD_READ(LPDDR4__PHY_RX_CAL_LOCK_OBS_0__FLD,
1176 					 CPS_REG_READ(regaddress));
1177 			if ((regval & errbitmask) != RX_CAL_DONE) {
1178 				debuginfo->rxoffseterror = true;
1179 				*errorfound = true;
1180 			}
1181 			regaddress =
1182 			    lpddr4_addoffset(regaddress,
1183 					     (uint32_t) SLICE_WIDTH);
1184 		}
1185 	}
1186 }
1187 
lpddr4_getdebuginitinfo(const lpddr4_privatedata * pd,lpddr4_debuginfo * debuginfo)1188 uint32_t lpddr4_getdebuginitinfo(const lpddr4_privatedata * pd,
1189 				 lpddr4_debuginfo * debuginfo)
1190 {
1191 
1192 	uint32_t result = 0U;
1193 	bool errorfound = false;
1194 
1195 	/* Calling Sanity Function to verify the input variables */
1196 	result = lpddr4_getdebuginitinfosf(pd, debuginfo);
1197 	if (result == (uint32_t) CDN_EOK) {
1198 
1199 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1200 		lpddr4_seterrors(ctlregbase, debuginfo, &errorfound);
1201 		/* Function to setup Snap for OBS registers */
1202 		lpddr4_setsettings(ctlregbase, errorfound);
1203 		/* Function to check for Rx offset error */
1204 		lpddr4_setrxoffseterror(ctlregbase, debuginfo, &errorfound);
1205 		/* Function Check various levelling errors */
1206 		errorfound = lpddr4_checklvlerrors(pd, debuginfo, errorfound);
1207 	}
1208 
1209 	if (errorfound == true) {
1210 		result = (uint32_t) EPROTO;
1211 	}
1212 
1213 	return result;
1214 }
1215 
readpdwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1216 static void readpdwakeup(const lpddr4_ctlfspnum * fspnum,
1217 			 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1218 {
1219 
1220 	/* Read the appropriate register, based on user given frequency. */
1221 	if (*fspnum == LPDDR4_FSP_0) {
1222 		*cycles =
1223 		    CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
1224 				 CPS_REG_READ(&
1225 					      (ctlregbase->
1226 					       LPDDR4__LPI_PD_WAKEUP_F0__REG)));
1227 	} else if (*fspnum == LPDDR4_FSP_1) {
1228 		*cycles =
1229 		    CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
1230 				 CPS_REG_READ(&
1231 					      (ctlregbase->
1232 					       LPDDR4__LPI_PD_WAKEUP_F1__REG)));
1233 	} else {
1234 		/* Default register (sanity function already confirmed the variable value) */
1235 		*cycles =
1236 		    CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
1237 				 CPS_REG_READ(&
1238 					      (ctlregbase->
1239 					       LPDDR4__LPI_PD_WAKEUP_F2__REG)));
1240 	}
1241 }
1242 
readsrshortwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1243 static void readsrshortwakeup(const lpddr4_ctlfspnum * fspnum,
1244 			      lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1245 {
1246 
1247 	/* Read the appropriate register, based on user given frequency. */
1248 	if (*fspnum == LPDDR4_FSP_0) {
1249 		*cycles =
1250 		    CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
1251 				 CPS_REG_READ(&
1252 					      (ctlregbase->
1253 					       LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)));
1254 	} else if (*fspnum == LPDDR4_FSP_1) {
1255 		*cycles =
1256 		    CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
1257 				 CPS_REG_READ(&
1258 					      (ctlregbase->
1259 					       LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)));
1260 	} else {
1261 		/* Default register (sanity function already confirmed the variable value) */
1262 		*cycles =
1263 		    CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
1264 				 CPS_REG_READ(&
1265 					      (ctlregbase->
1266 					       LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)));
1267 	}
1268 }
1269 
readsrlongwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1270 static void readsrlongwakeup(const lpddr4_ctlfspnum * fspnum,
1271 			     lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1272 {
1273 
1274 	/* Read the appropriate register, based on user given frequency. */
1275 	if (*fspnum == LPDDR4_FSP_0) {
1276 		*cycles =
1277 		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
1278 				 CPS_REG_READ(&
1279 					      (ctlregbase->
1280 					       LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)));
1281 	} else if (*fspnum == LPDDR4_FSP_1) {
1282 		*cycles =
1283 		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
1284 				 CPS_REG_READ(&
1285 					      (ctlregbase->
1286 					       LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)));
1287 	} else {
1288 		/* Default register (sanity function already confirmed the variable value) */
1289 		*cycles =
1290 		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
1291 				 CPS_REG_READ(&
1292 					      (ctlregbase->
1293 					       LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)));
1294 	}
1295 }
1296 
readsrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1297 static void readsrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1298 				 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1299 {
1300 
1301 	/* Read the appropriate register, based on user given frequency. */
1302 	if (*fspnum == LPDDR4_FSP_0) {
1303 		*cycles =
1304 		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1305 				 CPS_REG_READ(&
1306 					      (ctlregbase->
1307 					       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
1308 	} else if (*fspnum == LPDDR4_FSP_1) {
1309 		*cycles =
1310 		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1311 				 CPS_REG_READ(&
1312 					      (ctlregbase->
1313 					       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
1314 	} else {
1315 		/* Default register (sanity function already confirmed the variable value) */
1316 		*cycles =
1317 		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1318 				 CPS_REG_READ(&
1319 					      (ctlregbase->
1320 					       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
1321 	}
1322 }
1323 
readsrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1324 static void readsrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
1325 				lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1326 {
1327 
1328 	/* Read the appropriate register, based on user given frequency. */
1329 	if (*fspnum == LPDDR4_FSP_0) {
1330 		*cycles =
1331 		    CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
1332 				 CPS_REG_READ(&
1333 					      (ctlregbase->
1334 					       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)));
1335 	} else if (*fspnum == LPDDR4_FSP_1) {
1336 		*cycles =
1337 		    CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
1338 				 CPS_REG_READ(&
1339 					      (ctlregbase->
1340 					       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)));
1341 	} else {
1342 		/* Default register (sanity function already confirmed the variable value) */
1343 		*cycles =
1344 		    CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
1345 				 CPS_REG_READ(&
1346 					      (ctlregbase->
1347 					       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)));
1348 	}
1349 }
1350 
readsrdplongwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1351 static void readsrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
1352 			       lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1353 {
1354 
1355 	/* Read the appropriate register, based on user given frequency. */
1356 	if (*fspnum == LPDDR4_FSP_0) {
1357 		*cycles =
1358 		    CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
1359 				 CPS_REG_READ(&
1360 					      (ctlregbase->
1361 					       LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)));
1362 	} else if (*fspnum == LPDDR4_FSP_1) {
1363 		*cycles =
1364 		    CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
1365 				 CPS_REG_READ(&
1366 					      (ctlregbase->
1367 					       LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)));
1368 	} else {
1369 		/* Default register (sanity function already confirmed the variable value) */
1370 		*cycles =
1371 		    CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
1372 				 CPS_REG_READ(&
1373 					      (ctlregbase->
1374 					       LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)));
1375 	}
1376 }
1377 
readsrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,uint32_t * cycles)1378 static void readsrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1379 				   lpddr4_ctlregs * ctlregbase,
1380 				   uint32_t * cycles)
1381 {
1382 
1383 	/* Read the appropriate register, based on user given frequency. */
1384 	if (*fspnum == LPDDR4_FSP_0) {
1385 		*cycles =
1386 		    CPS_FLD_READ
1387 		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1388 		     CPS_REG_READ(&
1389 				  (ctlregbase->
1390 				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
1391 	} else if (*fspnum == LPDDR4_FSP_1) {
1392 		*cycles =
1393 		    CPS_FLD_READ
1394 		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1395 		     CPS_REG_READ(&
1396 				  (ctlregbase->
1397 				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
1398 	} else {
1399 		/* Default register (sanity function already confirmed the variable value) */
1400 		*cycles =
1401 		    CPS_FLD_READ
1402 		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1403 		     CPS_REG_READ(&
1404 				  (ctlregbase->
1405 				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
1406 	}
1407 
1408 }
1409 
lpddr4_readlpiwakeuptime(lpddr4_ctlregs * ctlregbase,const lpddr4_lpiwakeupparam * lpiwakeupparam,const lpddr4_ctlfspnum * fspnum,uint32_t * cycles)1410 static void lpddr4_readlpiwakeuptime(lpddr4_ctlregs * ctlregbase,
1411 				     const lpddr4_lpiwakeupparam *
1412 				     lpiwakeupparam,
1413 				     const lpddr4_ctlfspnum * fspnum,
1414 				     uint32_t * cycles)
1415 {
1416 
1417 	/* Iterate through each of the Wake up parameter type */
1418 	if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN) {
1419 		/* Calling appropriate function for register read */
1420 		readpdwakeup(fspnum, ctlregbase, cycles);
1421 	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN) {
1422 		readsrshortwakeup(fspnum, ctlregbase, cycles);
1423 	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN) {
1424 		readsrlongwakeup(fspnum, ctlregbase, cycles);
1425 	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN) {
1426 		readsrlonggatewakeup(fspnum, ctlregbase, cycles);
1427 	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN) {
1428 		readsrdpshortwakeup(fspnum, ctlregbase, cycles);
1429 	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN) {
1430 		readsrdplongwakeup(fspnum, ctlregbase, cycles);
1431 	} else {
1432 		/* Default function (sanity function already confirmed the variable value) */
1433 		readsrdplonggatewakeup(fspnum, ctlregbase, cycles);
1434 	}
1435 }
1436 
lpddr4_getlpiwakeuptime(const lpddr4_privatedata * pd,const lpddr4_lpiwakeupparam * lpiwakeupparam,const lpddr4_ctlfspnum * fspnum,uint32_t * cycles)1437 uint32_t lpddr4_getlpiwakeuptime(const lpddr4_privatedata * pd,
1438 				 const lpddr4_lpiwakeupparam * lpiwakeupparam,
1439 				 const lpddr4_ctlfspnum * fspnum,
1440 				 uint32_t * cycles)
1441 {
1442 
1443 	uint32_t result = 0U;
1444 
1445 	/* Calling Sanity Function to verify the input variables */
1446 	result = lpddr4_getlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
1447 	if (result == (uint32_t) CDN_EOK) {
1448 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1449 		lpddr4_readlpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
1450 					 cycles);
1451 	}
1452 	return result;
1453 }
1454 
writepdwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1455 static void writepdwakeup(const lpddr4_ctlfspnum * fspnum,
1456 			  lpddr4_ctlregs * ctlregbase, const uint32_t * cycles)
1457 {
1458 
1459 	uint32_t regval = 0U;
1460 	/* Write to appropriate register ,based on user given frequency. */
1461 	if (*fspnum == LPDDR4_FSP_0) {
1462 		regval =
1463 		    CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
1464 				  CPS_REG_READ(&
1465 					       (ctlregbase->
1466 						LPDDR4__LPI_PD_WAKEUP_F0__REG)),
1467 				  *cycles);
1468 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG),
1469 			      regval);
1470 	} else if (*fspnum == LPDDR4_FSP_1) {
1471 		regval =
1472 		    CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
1473 				  CPS_REG_READ(&
1474 					       (ctlregbase->
1475 						LPDDR4__LPI_PD_WAKEUP_F1__REG)),
1476 				  *cycles);
1477 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG),
1478 			      regval);
1479 	} else {
1480 		/* Default register (sanity function already confirmed the variable value) */
1481 		regval =
1482 		    CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
1483 				  CPS_REG_READ(&
1484 					       (ctlregbase->
1485 						LPDDR4__LPI_PD_WAKEUP_F2__REG)),
1486 				  *cycles);
1487 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG),
1488 			      regval);
1489 	}
1490 }
1491 
writesrshortwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1492 static void writesrshortwakeup(const lpddr4_ctlfspnum * fspnum,
1493 			       lpddr4_ctlregs * ctlregbase,
1494 			       const uint32_t * cycles)
1495 {
1496 
1497 	uint32_t regval = 0U;
1498 	/* Write to appropriate register ,based on user given frequency. */
1499 	if (*fspnum == LPDDR4_FSP_0) {
1500 		regval =
1501 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
1502 				  CPS_REG_READ(&
1503 					       (ctlregbase->
1504 						LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)),
1505 				  *cycles);
1506 		CPS_REG_WRITE(&
1507 			      (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG),
1508 			      regval);
1509 	} else if (*fspnum == LPDDR4_FSP_1) {
1510 		regval =
1511 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
1512 				  CPS_REG_READ(&
1513 					       (ctlregbase->
1514 						LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)),
1515 				  *cycles);
1516 		CPS_REG_WRITE(&
1517 			      (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG),
1518 			      regval);
1519 	} else {
1520 		/* Default register (sanity function already confirmed the variable value) */
1521 		regval =
1522 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
1523 				  CPS_REG_READ(&
1524 					       (ctlregbase->
1525 						LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)),
1526 				  *cycles);
1527 		CPS_REG_WRITE(&
1528 			      (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG),
1529 			      regval);
1530 	}
1531 }
1532 
writesrlongwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1533 static void writesrlongwakeup(const lpddr4_ctlfspnum * fspnum,
1534 			      lpddr4_ctlregs * ctlregbase,
1535 			      const uint32_t * cycles)
1536 {
1537 
1538 	uint32_t regval = 0U;
1539 	/* Write to appropriate register ,based on user given frequency. */
1540 	if (*fspnum == LPDDR4_FSP_0) {
1541 		regval =
1542 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
1543 				  CPS_REG_READ(&
1544 					       (ctlregbase->
1545 						LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)),
1546 				  *cycles);
1547 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG),
1548 			      regval);
1549 	} else if (*fspnum == LPDDR4_FSP_1) {
1550 		regval =
1551 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
1552 				  CPS_REG_READ(&
1553 					       (ctlregbase->
1554 						LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)),
1555 				  *cycles);
1556 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG),
1557 			      regval);
1558 	} else {
1559 		/* Default register (sanity function already confirmed the variable value) */
1560 		regval =
1561 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
1562 				  CPS_REG_READ(&
1563 					       (ctlregbase->
1564 						LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)),
1565 				  *cycles);
1566 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG),
1567 			      regval);
1568 	}
1569 }
1570 
writesrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1571 static void writesrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1572 				  lpddr4_ctlregs * ctlregbase,
1573 				  const uint32_t * cycles)
1574 {
1575 
1576 	uint32_t regval = 0U;
1577 	/* Write to appropriate register ,based on user given frequency. */
1578 	if (*fspnum == LPDDR4_FSP_0) {
1579 		regval =
1580 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1581 				  CPS_REG_READ(&
1582 					       (ctlregbase->
1583 						LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
1584 				  *cycles);
1585 		CPS_REG_WRITE(&
1586 			      (ctlregbase->
1587 			       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG),
1588 			      regval);
1589 	} else if (*fspnum == LPDDR4_FSP_1) {
1590 		regval =
1591 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1592 				  CPS_REG_READ(&
1593 					       (ctlregbase->
1594 						LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
1595 				  *cycles);
1596 		CPS_REG_WRITE(&
1597 			      (ctlregbase->
1598 			       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG),
1599 			      regval);
1600 	} else {
1601 		/* Default register (sanity function already confirmed the variable value) */
1602 		regval =
1603 		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1604 				  CPS_REG_READ(&
1605 					       (ctlregbase->
1606 						LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
1607 				  *cycles);
1608 		CPS_REG_WRITE(&
1609 			      (ctlregbase->
1610 			       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG),
1611 			      regval);
1612 	}
1613 }
1614 
writesrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1615 static void writesrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
1616 				 lpddr4_ctlregs * ctlregbase,
1617 				 const uint32_t * cycles)
1618 {
1619 
1620 	uint32_t regval = 0U;
1621 	/* Write to appropriate register ,based on user given frequency. */
1622 	if (*fspnum == LPDDR4_FSP_0) {
1623 		regval =
1624 		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
1625 				  CPS_REG_READ(&
1626 					       (ctlregbase->
1627 						LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)),
1628 				  *cycles);
1629 		CPS_REG_WRITE(&
1630 			      (ctlregbase->
1631 			       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG), regval);
1632 	} else if (*fspnum == LPDDR4_FSP_1) {
1633 		regval =
1634 		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
1635 				  CPS_REG_READ(&
1636 					       (ctlregbase->
1637 						LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)),
1638 				  *cycles);
1639 		CPS_REG_WRITE(&
1640 			      (ctlregbase->
1641 			       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG), regval);
1642 	} else {
1643 		/* Default register (sanity function already confirmed the variable value) */
1644 		regval =
1645 		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
1646 				  CPS_REG_READ(&
1647 					       (ctlregbase->
1648 						LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)),
1649 				  *cycles);
1650 		CPS_REG_WRITE(&
1651 			      (ctlregbase->
1652 			       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG), regval);
1653 	}
1654 }
1655 
writesrdplongwakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1656 static void writesrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
1657 				lpddr4_ctlregs * ctlregbase,
1658 				const uint32_t * cycles)
1659 {
1660 
1661 	uint32_t regval = 0U;
1662 	/* Write to appropriate register ,based on user given frequency. */
1663 	if (*fspnum == LPDDR4_FSP_0) {
1664 		regval =
1665 		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
1666 				  CPS_REG_READ(&
1667 					       (ctlregbase->
1668 						LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)),
1669 				  *cycles);
1670 		CPS_REG_WRITE(&
1671 			      (ctlregbase->
1672 			       LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG), regval);
1673 	} else if (*fspnum == LPDDR4_FSP_1) {
1674 		regval =
1675 		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
1676 				  CPS_REG_READ(&
1677 					       (ctlregbase->
1678 						LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)),
1679 				  *cycles);
1680 		CPS_REG_WRITE(&
1681 			      (ctlregbase->
1682 			       LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG), regval);
1683 	} else {
1684 		/* Default register (sanity function already confirmed the variable value) */
1685 		regval =
1686 		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
1687 				  CPS_REG_READ(&
1688 					       (ctlregbase->
1689 						LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)),
1690 				  *cycles);
1691 		CPS_REG_WRITE(&
1692 			      (ctlregbase->
1693 			       LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG), regval);
1694 	}
1695 }
1696 
writesrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,lpddr4_ctlregs * ctlregbase,const uint32_t * cycles)1697 static void writesrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1698 				    lpddr4_ctlregs * ctlregbase,
1699 				    const uint32_t * cycles)
1700 {
1701 
1702 	uint32_t regval = 0U;
1703 	/* Write to appropriate register ,based on user given frequency. */
1704 	if (*fspnum == LPDDR4_FSP_0) {
1705 		regval =
1706 		    CPS_FLD_WRITE
1707 		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1708 		     CPS_REG_READ(&
1709 				  (ctlregbase->
1710 				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
1711 		     *cycles);
1712 		CPS_REG_WRITE(&
1713 			      (ctlregbase->
1714 			       LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG),
1715 			      regval);
1716 	} else if (*fspnum == LPDDR4_FSP_1) {
1717 		regval =
1718 		    CPS_FLD_WRITE
1719 		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1720 		     CPS_REG_READ(&
1721 				  (ctlregbase->
1722 				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
1723 		     *cycles);
1724 		CPS_REG_WRITE(&
1725 			      (ctlregbase->
1726 			       LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG),
1727 			      regval);
1728 	} else {
1729 		/* Default register (sanity function already confirmed the variable value) */
1730 		regval =
1731 		    CPS_FLD_WRITE
1732 		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1733 		     CPS_REG_READ(&
1734 				  (ctlregbase->
1735 				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
1736 		     *cycles);
1737 		CPS_REG_WRITE(&
1738 			      (ctlregbase->
1739 			       LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG),
1740 			      regval);
1741 	}
1742 }
1743 
lpddr4_writelpiwakeuptime(lpddr4_ctlregs * ctlregbase,const lpddr4_lpiwakeupparam * lpiwakeupparam,const lpddr4_ctlfspnum * fspnum,const uint32_t * cycles)1744 static void lpddr4_writelpiwakeuptime(lpddr4_ctlregs * ctlregbase,
1745 				      const lpddr4_lpiwakeupparam *
1746 				      lpiwakeupparam,
1747 				      const lpddr4_ctlfspnum * fspnum,
1748 				      const uint32_t * cycles)
1749 {
1750 
1751 	/* Iterate through each of the Wake up parameter type */
1752 	if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN) {
1753 		/* Calling appropriate function for register write */
1754 		writepdwakeup(fspnum, ctlregbase, cycles);
1755 	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN) {
1756 		writesrshortwakeup(fspnum, ctlregbase, cycles);
1757 	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN) {
1758 		writesrlongwakeup(fspnum, ctlregbase, cycles);
1759 	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN) {
1760 		writesrlonggatewakeup(fspnum, ctlregbase, cycles);
1761 	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN) {
1762 		writesrdpshortwakeup(fspnum, ctlregbase, cycles);
1763 	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN) {
1764 		writesrdplongwakeup(fspnum, ctlregbase, cycles);
1765 	} else {
1766 		/* Default function (sanity function already confirmed the variable value) */
1767 		writesrdplonggatewakeup(fspnum, ctlregbase, cycles);
1768 	}
1769 }
1770 
lpddr4_setlpiwakeuptime(const lpddr4_privatedata * pd,const lpddr4_lpiwakeupparam * lpiwakeupparam,const lpddr4_ctlfspnum * fspnum,const uint32_t * cycles)1771 uint32_t lpddr4_setlpiwakeuptime(const lpddr4_privatedata * pd,
1772 				 const lpddr4_lpiwakeupparam * lpiwakeupparam,
1773 				 const lpddr4_ctlfspnum * fspnum,
1774 				 const uint32_t * cycles)
1775 {
1776 	uint32_t result = 0U;
1777 
1778 	/* Calling Sanity Function to verify the input variables */
1779 	result = lpddr4_setlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
1780 	if (result == (uint32_t) CDN_EOK) {
1781 		/* Return if the user given value is higher than the field width */
1782 		if (*cycles > NIBBLE_MASK) {
1783 			result = EINVAL;
1784 		}
1785 	}
1786 	if (result == (uint32_t) CDN_EOK) {
1787 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1788 		lpddr4_writelpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
1789 					  cycles);
1790 	}
1791 	return result;
1792 }
1793 
lpddr4_geteccenable(const lpddr4_privatedata * pd,lpddr4_eccenable * eccparam)1794 uint32_t lpddr4_geteccenable(const lpddr4_privatedata * pd,
1795 			     lpddr4_eccenable * eccparam)
1796 {
1797 	uint32_t result = 0U;
1798 	uint32_t fldval = 0U;
1799 
1800 	/* Calling Sanity Function to verify the input variables */
1801 	result = lpddr4_geteccenablesf(pd, eccparam);
1802 	if (result == (uint32_t) CDN_EOK) {
1803 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1804 
1805 		/* Reading the ECC_Enable field  from the register. */
1806 		fldval =
1807 		    CPS_FLD_READ(LPDDR4__ECC_ENABLE__FLD,
1808 				 CPS_REG_READ(&
1809 					      (ctlregbase->
1810 					       LPDDR4__ECC_ENABLE__REG)));
1811 		switch (fldval) {
1812 		case 3:
1813 			*eccparam = LPDDR4_ECC_ERR_DETECT_CORRECT;
1814 			break;
1815 		case 2:
1816 			*eccparam = LPDDR4_ECC_ERR_DETECT;
1817 			break;
1818 		case 1:
1819 			*eccparam = LPDDR4_ECC_ENABLED;
1820 			break;
1821 		default:
1822 			/* Default ECC (Sanity function already confirmed the value to be in expected range.) */
1823 			*eccparam = LPDDR4_ECC_DISABLED;
1824 			break;
1825 		}
1826 	}
1827 	return result;
1828 }
1829 
lpddr4_seteccenable(const lpddr4_privatedata * pd,const lpddr4_eccenable * eccparam)1830 uint32_t lpddr4_seteccenable(const lpddr4_privatedata * pd,
1831 			     const lpddr4_eccenable * eccparam)
1832 {
1833 
1834 	uint32_t result = 0U;
1835 	uint32_t regval = 0U;
1836 
1837 	/* Calling Sanity Function to verify the input variables */
1838 	result = lpddr4_seteccenablesf(pd, eccparam);
1839 	if (result == (uint32_t) CDN_EOK) {
1840 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1841 
1842 		/* Updating the ECC_Enable field based on the user given value. */
1843 		regval =
1844 		    CPS_FLD_WRITE(LPDDR4__ECC_ENABLE__FLD,
1845 				  CPS_REG_READ(&
1846 					       (ctlregbase->
1847 						LPDDR4__ECC_ENABLE__REG)),
1848 				  *eccparam);
1849 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__ECC_ENABLE__REG), regval);
1850 	}
1851 	return result;
1852 }
1853 
lpddr4_getreducmode(const lpddr4_privatedata * pd,lpddr4_reducmode * mode)1854 uint32_t lpddr4_getreducmode(const lpddr4_privatedata * pd,
1855 			     lpddr4_reducmode * mode)
1856 {
1857 	uint32_t result = 0U;
1858 
1859 	/* Calling Sanity Function to verify the input variables */
1860 	result = lpddr4_getreducmodesf(pd, mode);
1861 	if (result == (uint32_t) CDN_EOK) {
1862 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1863 		/* Read the value of reduc parameter. */
1864 		if (CPS_FLD_READ
1865 		    (LPDDR4__REDUC__FLD,
1866 		     CPS_REG_READ(&(ctlregbase->LPDDR4__REDUC__REG))) == 0U) {
1867 			*mode = LPDDR4_REDUC_ON;
1868 		} else {
1869 			*mode = LPDDR4_REDUC_OFF;
1870 		}
1871 	}
1872 	return result;
1873 }
1874 
lpddr4_setreducmode(const lpddr4_privatedata * pd,const lpddr4_reducmode * mode)1875 uint32_t lpddr4_setreducmode(const lpddr4_privatedata * pd,
1876 			     const lpddr4_reducmode * mode)
1877 {
1878 	uint32_t result = 0U;
1879 	uint32_t regval = 0U;
1880 
1881 	/* Calling Sanity Function to verify the input variables */
1882 	result = lpddr4_setreducmodesf(pd, mode);
1883 	if (result == (uint32_t) CDN_EOK) {
1884 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1885 		/* Setting to enable Half data path. */
1886 		regval =
1887 		    CPS_FLD_WRITE(LPDDR4__REDUC__FLD,
1888 				  CPS_REG_READ(&
1889 					       (ctlregbase->
1890 						LPDDR4__REDUC__REG)), *mode);
1891 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__REDUC__REG), regval);
1892 	}
1893 	return result;
1894 }
1895 
lpddr4_getdbireadmode(const lpddr4_privatedata * pd,bool * on_off)1896 uint32_t lpddr4_getdbireadmode(const lpddr4_privatedata * pd, bool * on_off)
1897 {
1898 
1899 	uint32_t result = 0U;
1900 
1901 	/* Calling Sanity Function to verify the input variables */
1902 	result = lpddr4_getdbireadmodesf(pd, on_off);
1903 
1904 	if (result == (uint32_t) CDN_EOK) {
1905 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1906 		/* Reading the field value from the register. */
1907 		if (CPS_FLD_READ
1908 		    (LPDDR4__RD_DBI_EN__FLD,
1909 		     CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG))) ==
1910 		    0U) {
1911 			*on_off = false;
1912 		} else {
1913 			*on_off = true;
1914 		}
1915 	}
1916 	return result;
1917 }
1918 
lpddr4_getdbiwritemode(const lpddr4_privatedata * pd,bool * on_off)1919 uint32_t lpddr4_getdbiwritemode(const lpddr4_privatedata * pd, bool * on_off)
1920 {
1921 
1922 	uint32_t result = 0U;
1923 
1924 	/* Calling Sanity Function to verify the input variables */
1925 	result = lpddr4_getdbireadmodesf(pd, on_off);
1926 
1927 	if (result == (uint32_t) CDN_EOK) {
1928 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1929 		/* Reading the field value from the register. */
1930 		if (CPS_FLD_READ
1931 		    (LPDDR4__WR_DBI_EN__FLD,
1932 		     CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG))) ==
1933 		    0U) {
1934 			*on_off = false;
1935 		} else {
1936 			*on_off = true;
1937 		}
1938 	}
1939 	return result;
1940 }
1941 
lpddr4_setdbimode(const lpddr4_privatedata * pd,const lpddr4_dbimode * mode)1942 uint32_t lpddr4_setdbimode(const lpddr4_privatedata * pd,
1943 			   const lpddr4_dbimode * mode)
1944 {
1945 
1946 	uint32_t result = 0U;
1947 	uint32_t regval = 0U;
1948 
1949 	/* Calling Sanity Function to verify the input variables */
1950 	result = lpddr4_setdbimodesf(pd, mode);
1951 
1952 	if (result == (uint32_t) CDN_EOK) {
1953 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1954 
1955 		/* Updating the appropriate field value based on the user given mode */
1956 		if (*mode == LPDDR4_DBI_RD_ON) {
1957 			regval =
1958 			    CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
1959 					  CPS_REG_READ(&
1960 						       (ctlregbase->
1961 							LPDDR4__RD_DBI_EN__REG)),
1962 					  1U);
1963 		} else if (*mode == LPDDR4_DBI_RD_OFF) {
1964 			regval =
1965 			    CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
1966 					  CPS_REG_READ(&
1967 						       (ctlregbase->
1968 							LPDDR4__RD_DBI_EN__REG)),
1969 					  0U);
1970 		} else if (*mode == LPDDR4_DBI_WR_ON) {
1971 			regval =
1972 			    CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
1973 					  CPS_REG_READ(&
1974 						       (ctlregbase->
1975 							LPDDR4__WR_DBI_EN__REG)),
1976 					  1U);
1977 		} else {
1978 			/* Default field (Sanity function already confirmed the value to be in expected range.) */
1979 			regval =
1980 			    CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
1981 					  CPS_REG_READ(&
1982 						       (ctlregbase->
1983 							LPDDR4__WR_DBI_EN__REG)),
1984 					  0U);
1985 		}
1986 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__RD_DBI_EN__REG), regval);
1987 	}
1988 	return result;
1989 }
1990 
lpddr4_getrefreshrate(const lpddr4_privatedata * pd,const lpddr4_ctlfspnum * fspnum,uint32_t * cycles)1991 uint32_t lpddr4_getrefreshrate(const lpddr4_privatedata * pd,
1992 			       const lpddr4_ctlfspnum * fspnum,
1993 			       uint32_t * cycles)
1994 {
1995 	uint32_t result = 0U;
1996 
1997 	/* Calling Sanity Function to verify the input variables */
1998 	result = lpddr4_getrefreshratesf(pd, fspnum, cycles);
1999 
2000 	if (result == (uint32_t) CDN_EOK) {
2001 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2002 
2003 		/* Selecting the appropriate register for the user requested Frequency */
2004 		switch (*fspnum) {
2005 		case LPDDR4_FSP_2:
2006 			*cycles =
2007 			    CPS_FLD_READ(LPDDR4__TREF_F2__FLD,
2008 					 CPS_REG_READ(&
2009 						      (ctlregbase->
2010 						       LPDDR4__TREF_F2__REG)));
2011 			break;
2012 		case LPDDR4_FSP_1:
2013 			*cycles =
2014 			    CPS_FLD_READ(LPDDR4__TREF_F1__FLD,
2015 					 CPS_REG_READ(&
2016 						      (ctlregbase->
2017 						       LPDDR4__TREF_F1__REG)));
2018 			break;
2019 		default:
2020 			/* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
2021 			*cycles =
2022 			    CPS_FLD_READ(LPDDR4__TREF_F0__FLD,
2023 					 CPS_REG_READ(&
2024 						      (ctlregbase->
2025 						       LPDDR4__TREF_F0__REG)));
2026 			break;
2027 		}
2028 	}
2029 	return result;
2030 }
2031 
lpddr4_setrefreshrate(const lpddr4_privatedata * pd,const lpddr4_ctlfspnum * fspnum,const uint32_t * cycles)2032 uint32_t lpddr4_setrefreshrate(const lpddr4_privatedata * pd,
2033 			       const lpddr4_ctlfspnum * fspnum,
2034 			       const uint32_t * cycles)
2035 {
2036 	uint32_t result = 0U;
2037 	uint32_t regval = 0U;
2038 
2039 	/* Calling Sanity Function to verify the input variables */
2040 	result = lpddr4_setrefreshratesf(pd, fspnum, cycles);
2041 
2042 	if (result == (uint32_t) CDN_EOK) {
2043 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2044 
2045 		/* Selecting the appropriate register for the user requested Frequency */
2046 		switch (*fspnum) {
2047 		case LPDDR4_FSP_2:
2048 			regval =
2049 			    CPS_FLD_WRITE(LPDDR4__TREF_F2__FLD,
2050 					  CPS_REG_READ(&
2051 						       (ctlregbase->
2052 							LPDDR4__TREF_F2__REG)),
2053 					  *cycles);
2054 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F2__REG),
2055 				      regval);
2056 			break;
2057 		case LPDDR4_FSP_1:
2058 			regval =
2059 			    CPS_FLD_WRITE(LPDDR4__TREF_F1__FLD,
2060 					  CPS_REG_READ(&
2061 						       (ctlregbase->
2062 							LPDDR4__TREF_F1__REG)),
2063 					  *cycles);
2064 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F1__REG),
2065 				      regval);
2066 			break;
2067 		default:
2068 			/* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
2069 			regval =
2070 			    CPS_FLD_WRITE(LPDDR4__TREF_F0__FLD,
2071 					  CPS_REG_READ(&
2072 						       (ctlregbase->
2073 							LPDDR4__TREF_F0__REG)),
2074 					  *cycles);
2075 			CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F0__REG),
2076 				      regval);
2077 			break;
2078 		}
2079 	}
2080 	return result;
2081 }
2082 
lpddr4_refreshperchipselect(const lpddr4_privatedata * pd,const uint32_t trefinterval)2083 uint32_t lpddr4_refreshperchipselect(const lpddr4_privatedata * pd,
2084 				     const uint32_t trefinterval)
2085 {
2086 	uint32_t result = 0U;
2087 	uint32_t regval = 0U;
2088 
2089 	/* Calling Sanity Function to verify the input variables */
2090 	result = lpddr4_refreshperchipselectsf(pd);
2091 
2092 	if (result == (uint32_t) CDN_EOK) {
2093 		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2094 		/* Setting tref_interval parameter to enable/disable Refresh per chip select. */
2095 		regval =
2096 		    CPS_FLD_WRITE(LPDDR4__TREF_INTERVAL__FLD,
2097 				  CPS_REG_READ(&
2098 					       (ctlregbase->
2099 						LPDDR4__TREF_INTERVAL__REG)),
2100 				  trefinterval);
2101 		CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_INTERVAL__REG),
2102 			      regval);
2103 	}
2104 	return result;
2105 }
2106