blob: 68043d7cb615c4b7fd6de79067fd1f538beee3d7 [file] [log] [blame]
Kevin Scholz3bb3f262019-10-07 19:26:36 +05301// 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 */
28static 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 */
58static 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 */
87static 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 */
121static 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 */
157static 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 */
174uint32_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 */
198uint32_t lpddr4_init(lpddr4_privatedata * pd, const lpddr4_config * cfg)
199{
200 uint32_t result = 0U;
201 uint16_t productid = 0U;
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530202
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))));
Lokesh Vutla6e802ef2020-08-05 22:44:26 +0530211 if (productid == PRODUCT_ID) {
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530212 /* 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 */
233uint32_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 */
267uint32_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
312uint32_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
354static 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
391uint32_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
423static 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
446uint32_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
479uint32_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
503uint32_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
528uint32_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
552uint32_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
574uint32_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
598uint32_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
621uint32_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
650uint32_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
691uint32_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) {
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +0100722 if ((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) {
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530723 *irqstatus = true;
724 } else {
725 *irqstatus = false;
726 }
727 }
728 }
729 return result;
730}
731
732uint32_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);
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +0100749 regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530750 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
751 regval);
752 } else {
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +0100753 regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530754 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
755 regval);
756 }
757 }
758
759 return result;
760}
761
762uint32_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
780uint32_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
810uint32_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 =
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +0100826 !!((phyindepirqstatus >> (uint32_t)intr) & LPDDR4_BIT_MASK);
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530827 }
828 return result;
829}
830
831uint32_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 */
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +0100844 regval = (uint32_t)LPDDR4_BIT_MASK << ui32shiftinterrupt;
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530845 CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
846 }
847
848 return result;
849}
850
851/* Check for caTrainingError */
852static 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 */
883static 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 */
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +0100897 errbitmask = (LPDDR4_BIT_MASK << 1) | LPDDR4_BIT_MASK;
Kevin Scholz3bb3f262019-10-07 19:26:36 +0530898 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 */
910static 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 */
939static 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 */
967static 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 */
1001static 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
1038static 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
1053static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,
1054 lpddr4_debuginfo * debuginfo, bool * errfoundptr)
1055{
1056
Heinrich Schuchardtf5abd8a2021-01-04 08:02:52 +01001057 uint32_t errbitmask = (LPDDR4_BIT_MASK << 0x1U) | LPDDR4_BIT_MASK;
Kevin Scholz3bb3f262019-10-07 19:26:36 +05301058 /* 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
1094static 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
1120static 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
1146static 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
1155static 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
1188uint32_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
1216static 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
1243static 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
1270static 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
1297static 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
1324static 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
1351static 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
1378static 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
1410static 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
1437uint32_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
1455static 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
1492static 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
1533static 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
1571static 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
1615static 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
1656static 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
1697static 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
1744static 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
1771uint32_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
1794uint32_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
1830uint32_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
1854uint32_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
1875uint32_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
1896uint32_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
1919uint32_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
1942uint32_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
1991uint32_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
2032uint32_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
2083uint32_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}