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/
8 *****************************************************************************
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"
17 #define LPDDR4_CUSTOM_TIMEOUT_DELAY 100000000U
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.
28 static uint32_t lpddr4_pollctlirq(const lpddr4_privatedata * pd,
29 lpddr4_ctlinterrupt irqbit, uint32_t delay)
33 uint32_t timeout = 0U;
34 bool irqstatus = false;
36 /* Loop until irqStatus found to be 1 or if value of 'result' !=CDN_EOK */
38 if (++timeout == delay) {
42 /* cps_delayns(10000000U); */
43 result = lpddr4_checkctlinterrupt(pd, irqbit, &irqstatus);
44 } while ((irqstatus == false) && (result == (uint32_t) CDN_EOK));
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.
58 static uint32_t lpddr4_pollphyindepirq(const lpddr4_privatedata * pd,
59 lpddr4_phyindepinterrupt irqbit,
64 uint32_t timeout = 0U;
65 bool irqstatus = false;
67 /* Loop until irqStatus found to be 1 or if value of 'result' !=CDN_EOK */
69 if (++timeout == delay) {
73 /* cps_delayns(10000000U); */
74 result = lpddr4_checkphyindepinterrupt(pd, irqbit, &irqstatus);
75 } while ((irqstatus == false) && (result == (uint32_t) CDN_EOK));
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.
87 static uint32_t lpddr4_pollandackirq(const lpddr4_privatedata * pd)
91 /* Wait for PhyIndependent module to finish up ctl init sequence */
93 lpddr4_pollphyindepirq(pd, LPDDR4_PHY_INDEP_INIT_DONE_BIT,
94 LPDDR4_CUSTOM_TIMEOUT_DELAY);
96 /* Ack to clear the PhyIndependent interrupt bit */
97 if (result == (uint32_t) CDN_EOK) {
99 lpddr4_ackphyindepinterrupt(pd,
100 LPDDR4_PHY_INDEP_INIT_DONE_BIT);
102 /* Wait for the CTL end of initialization */
103 if (result == (uint32_t) CDN_EOK) {
105 lpddr4_pollctlirq(pd, LPDDR4_MC_INIT_DONE,
106 LPDDR4_CUSTOM_TIMEOUT_DELAY);
108 /* Ack to clear the Ctl interrupt bit */
109 if (result == (uint32_t) CDN_EOK) {
110 result = lpddr4_ackctlinterrupt(pd, LPDDR4_MC_INIT_DONE);
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.
121 static uint32_t lpddr4_startsequencecontroller(const lpddr4_privatedata * pd)
123 uint32_t result = 0U;
124 uint32_t regval = 0U;
125 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
126 lpddr4_infotype infotype;
128 /* Set the PI_start to initiate leveling procedure */
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);
134 /* Set the Ctl_start */
136 CPS_FLD_SET(LPDDR4__START__FLD,
137 CPS_REG_READ(&(ctlregbase->LPDDR4__START__REG)));
138 CPS_REG_WRITE(&(ctlregbase->LPDDR4__START__REG), regval);
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);
146 result = lpddr4_pollandackirq(pd);
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.
157 static volatile uint32_t *lpddr4_addoffset(volatile uint32_t * addr,
161 volatile uint32_t *local_addr = addr;
162 /* Declaring as array to add the offset value. */
163 volatile uint32_t *regaddr = &local_addr[regoffset];
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.
174 uint32_t lpddr4_probe(const lpddr4_config * config, uint16_t * configsize)
178 result = (uint32_t) (lpddr4_probesf(config, configsize));
179 if (result == (uint32_t) CDN_EOK) {
180 *configsize = (uint16_t) (sizeof(lpddr4_privatedata));
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.
198 uint32_t lpddr4_init(lpddr4_privatedata * pd, const lpddr4_config * cfg)
200 uint32_t result = 0U;
201 uint16_t productid = 0U;
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,
210 LPDDR4__CONTROLLER_ID__REG))));
211 if (productid == PRODUCT_ID) {
212 /* Populating configuration data to pD */
213 pd->ctlbase = ctlregbase;
215 (lpddr4_infocallback) cfg->infohandler;
216 pd->ctlinterrupthandler =
217 (lpddr4_ctlcallback) cfg->ctlinterrupthandler;
218 pd->phyindepinterrupthandler =
219 (lpddr4_phyindepcallback) cfg->
220 phyindepinterrupthandler;
222 /* Magic number validation failed - Driver doesn't support given IP version */
223 result = (uint32_t) EOPNOTSUPP;
231 * @param[in] pD Driver state info specific to this instance.
233 uint32_t lpddr4_start(const lpddr4_privatedata * pd)
235 uint32_t result = 0U;
236 uint32_t regval = 0U;
238 result = lpddr4_startsf(pd);
239 if (result == (uint32_t) CDN_EOK) {
240 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
242 /* Enable PI as the initiator for DRAM */
244 CPS_FLD_SET(LPDDR4__PI_INIT_LVL_EN__FLD,
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)),
252 /* Start PI init sequence. */
253 result = lpddr4_startsequencecontroller(pd);
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
267 uint32_t lpddr4_readreg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
268 uint32_t regoffset, uint32_t * regvalue)
270 uint32_t result = 0U;
272 result = lpddr4_readregsf(pd, cpp, regvalue);
273 if (result == (uint32_t) CDN_EOK) {
274 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
276 if (cpp == LPDDR4_CTL_REGS) {
277 if (regoffset >= LPDDR4_CTL_REG_COUNT) {
278 /* Return if user provider invalid register number */
282 CPS_REG_READ(lpddr4_addoffset
283 (&(ctlregbase->DENALI_CTL_0),
286 } else if (cpp == LPDDR4_PHY_REGS) {
287 if (regoffset >= LPDDR4_PHY_REG_COUNT) {
288 /* Return if user provider invalid register number */
292 CPS_REG_READ(lpddr4_addoffset
293 (&(ctlregbase->DENALI_PHY_0),
298 if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
299 /* Return if user provider invalid register number */
303 CPS_REG_READ(lpddr4_addoffset
304 (&(ctlregbase->DENALI_PI_0),
312 uint32_t lpddr4_writereg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
313 uint32_t regoffset, uint32_t regvalue)
315 uint32_t result = 0U;
317 result = lpddr4_writeregsf(pd, cpp);
318 if (result == (uint32_t) CDN_EOK) {
319 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
321 if (cpp == LPDDR4_CTL_REGS) {
322 if (regoffset >= LPDDR4_CTL_REG_COUNT) {
323 /* Return if user provider invalid register number */
326 CPS_REG_WRITE(lpddr4_addoffset
327 (&(ctlregbase->DENALI_CTL_0),
328 regoffset), regvalue);
330 } else if (cpp == LPDDR4_PHY_REGS) {
331 if (regoffset >= LPDDR4_PHY_REG_COUNT) {
332 /* Return if user provider invalid register number */
335 CPS_REG_WRITE(lpddr4_addoffset
336 (&(ctlregbase->DENALI_PHY_0),
337 regoffset), regvalue);
340 if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
341 /* Return if user provider invalid register number */
344 CPS_REG_WRITE(lpddr4_addoffset
345 (&(ctlregbase->DENALI_PI_0),
346 regoffset), regvalue);
354 static uint32_t lpddr4_checkmmrreaderror(const lpddr4_privatedata * pd,
360 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
361 uint32_t result = (uint32_t) CDN_EOK;
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. */
367 (uint8_t) CPS_FLD_READ(LPDDR4__MRR_ERROR_STATUS__FLD,
370 LPDDR4__MRR_ERROR_STATUS__REG)));
375 /* Mode register read was successful, read DATA */
379 LPDDR4__PERIPHERAL_MRR_DATA_0__REG));
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);
391 uint32_t lpddr4_getmmrregister(const lpddr4_privatedata * pd,
392 uint32_t readmoderegval, uint64_t * mmrvalue,
396 uint32_t result = 0U;
397 uint32_t tdelay = 1000U;
398 uint32_t regval = 0U;
400 result = lpddr4_getmmrregistersf(pd, mmrvalue, mmrstatus);
401 if (result == (uint32_t) CDN_EOK) {
403 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
405 /* Populate the calculated value to the register */
407 CPS_FLD_WRITE(LPDDR4__READ_MODEREG__FLD,
410 LPDDR4__READ_MODEREG__REG)),
412 CPS_REG_WRITE(&(ctlregbase->LPDDR4__READ_MODEREG__REG), regval);
414 /* Wait until the Read is done */
415 result = lpddr4_pollctlirq(pd, LPDDR4_MR_READ_DONE, tdelay);
417 if (result == (uint32_t) CDN_EOK) {
418 result = lpddr4_checkmmrreaderror(pd, mmrvalue, mmrstatus);
423 static uint32_t lpddr4_writemmrregister(const lpddr4_privatedata * pd,
424 uint32_t writemoderegval)
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;
432 /* Populate the calculated value to the register */
434 CPS_FLD_WRITE(LPDDR4__WRITE_MODEREG__FLD,
437 LPDDR4__WRITE_MODEREG__REG)),
439 CPS_REG_WRITE(&(ctlregbase->LPDDR4__WRITE_MODEREG__REG), regval);
441 result = lpddr4_pollctlirq(pd, LPDDR4_MR_WRITE_DONE, tdelay);
446 uint32_t lpddr4_setmmrregister(const lpddr4_privatedata * pd,
447 uint32_t writemoderegval, uint8_t * mrwstatus)
449 uint32_t result = 0U;
451 result = lpddr4_setmmrregistersf(pd, mrwstatus);
452 if (result == (uint32_t) CDN_EOK) {
454 /* Function call to trigger Mode register write */
455 result = lpddr4_writemmrregister(pd, writemoderegval);
457 if (result == (uint32_t) CDN_EOK) {
459 lpddr4_ackctlinterrupt(pd, LPDDR4_MR_WRITE_DONE);
461 /* Read the status of mode register write */
462 if (result == (uint32_t) CDN_EOK) {
463 lpddr4_ctlregs *ctlregbase =
464 (lpddr4_ctlregs *) pd->ctlbase;
466 (uint8_t) CPS_FLD_READ(LPDDR4__MRW_STATUS__FLD,
469 LPDDR4__MRW_STATUS__REG)));
470 if ((*mrwstatus) != 0U) {
479 uint32_t lpddr4_writectlconfig(const lpddr4_privatedata * pd,
480 const lpddr4_reginitdata * regvalues)
485 result = lpddr4_writectlconfigsf(pd, regvalues);
486 if (result == (uint32_t) CDN_EOK) {
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]) {
493 lpddr4_writereg(pd, LPDDR4_CTL_REGS, regnum,
494 (uint32_t) (regvalues->
503 uint32_t lpddr4_writephyindepconfig(const lpddr4_privatedata * pd,
504 const lpddr4_reginitdata * regvalues)
509 result = lpddr4_writephyindepconfigsf(pd, regvalues);
510 if (result == (uint32_t) CDN_EOK) {
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]) {
517 lpddr4_writereg(pd, LPDDR4_PHY_INDEP_REGS,
519 (uint32_t) (regvalues->
528 uint32_t lpddr4_writephyconfig(const lpddr4_privatedata * pd,
529 const lpddr4_reginitdata * regvalues)
534 result = lpddr4_writephyconfigsf(pd, regvalues);
535 if (result == (uint32_t) CDN_EOK) {
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]) {
542 lpddr4_writereg(pd, LPDDR4_PHY_REGS, regnum,
543 (uint32_t) (regvalues->
552 uint32_t lpddr4_readctlconfig(const lpddr4_privatedata * pd,
553 lpddr4_reginitdata * regvalues)
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]) {
564 lpddr4_readreg(pd, LPDDR4_CTL_REGS, regnum,
565 (uint32_t *) (®values->
574 uint32_t lpddr4_readphyindepconfig(const lpddr4_privatedata * pd,
575 lpddr4_reginitdata * regvalues)
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]) {
587 lpddr4_readreg(pd, LPDDR4_PHY_INDEP_REGS,
589 (uint32_t *) (®values->
598 uint32_t lpddr4_readphyconfig(const lpddr4_privatedata * pd,
599 lpddr4_reginitdata * regvalues)
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]) {
611 lpddr4_readreg(pd, LPDDR4_PHY_REGS, regnum,
612 (uint32_t *) (®values->
621 uint32_t lpddr4_getctlinterruptmask(const lpddr4_privatedata * pd,
624 uint32_t result = 0U;
625 uint64_t lowermask = 0U;
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 */
632 (uint64_t) (CPS_FLD_READ
633 (LPDDR4__INT_MASK_0__FLD,
636 LPDDR4__INT_MASK_0__REG))));
637 /* Reading the upper mask register */
639 (uint64_t) (CPS_FLD_READ
640 (LPDDR4__INT_MASK_1__FLD,
643 LPDDR4__INT_MASK_1__REG))));
644 /* Concatenate both register informations */
645 *mask = (uint64_t) ((*mask << WORD_SHIFT) | lowermask);
650 uint32_t lpddr4_setctlinterruptmask(const lpddr4_privatedata * pd,
651 const uint64_t * mask)
655 const uint64_t ui64one = 1ULL;
656 const uint32_t ui32irqcount = (uint32_t) LPDDR4_LOR_BITS + 1U;
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)) {
665 if (result == (uint32_t) CDN_EOK) {
666 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
668 /* Extracting the lower 32 bits and writing to lower mask register */
669 regval = (uint32_t) (*mask & WORD_MASK);
671 CPS_FLD_WRITE(LPDDR4__INT_MASK_0__FLD,
674 LPDDR4__INT_MASK_0__REG)),
676 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_0__REG), regval);
678 /* Extracting the upper 32 bits and writing to upper mask register */
679 regval = (uint32_t) ((*mask >> WORD_SHIFT) & WORD_MASK);
681 CPS_FLD_WRITE(LPDDR4__INT_MASK_1__FLD,
684 LPDDR4__INT_MASK_1__REG)),
686 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_1__REG), regval);
691 uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd,
692 lpddr4_ctlinterrupt intr, bool * irqstatus)
695 uint32_t ctlirqstatus = 0;
696 uint32_t fieldshift = 0;
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;
704 if ((uint32_t) intr >= WORD_SHIFT) {
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);
715 LPDDR4__INT_STATUS_0__REG));
716 /* The shift value remains same for lower interrupt register */
717 fieldshift = (uint32_t) intr;
720 /* MISRA compliance (Shifting operation) check */
721 if (fieldshift < WORD_SHIFT) {
722 if ((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) {
732 uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd,
733 lpddr4_ctlinterrupt intr)
737 uint32_t localinterrupt = (uint32_t) intr;
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;
745 /* Check if the requested bit is in upper register */
746 if (localinterrupt > WORD_SHIFT) {
748 (localinterrupt - (uint32_t) WORD_SHIFT);
749 regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
750 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
753 regval = (uint32_t)LPDDR4_BIT_MASK << localinterrupt;
754 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
762 uint32_t lpddr4_getphyindepinterruptmask(const lpddr4_privatedata * pd,
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 */
772 CPS_FLD_READ(LPDDR4__PI_INT_MASK__FLD,
775 LPDDR4__PI_INT_MASK__REG)));
780 uint32_t lpddr4_setphyindepinterruptmask(const lpddr4_privatedata * pd,
781 const uint32_t * mask)
785 const uint32_t ui32irqcount =
786 (uint32_t) LPDDR4_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT + 1U;
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)) {
795 if (result == (uint32_t) CDN_EOK) {
796 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
798 /* Writing to the user requested interrupt mask */
800 CPS_FLD_WRITE(LPDDR4__PI_INT_MASK__FLD,
803 LPDDR4__PI_INT_MASK__REG)),
805 CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_MASK__REG), regval);
810 uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd,
811 lpddr4_phyindepinterrupt intr,
815 uint32_t phyindepirqstatus = 0;
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;
822 /* Reading the requested bit to check interrupt status */
824 CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
826 !!((phyindepirqstatus >> (uint32_t)intr) & LPDDR4_BIT_MASK);
831 uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd,
832 lpddr4_phyindepinterrupt intr)
834 uint32_t result = 0U;
835 uint32_t regval = 0U;
836 uint32_t ui32shiftinterrupt = (uint32_t) intr;
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;
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);
851 /* Check for caTrainingError */
852 static void lpddr4_checkcatrainingerror(lpddr4_ctlregs * ctlregbase,
853 lpddr4_debuginfo * debuginfo,
858 uint32_t errbitmask = 0U;
860 volatile uint32_t *regaddress;
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
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;
878 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
882 /* Check for wrLvlError */
883 static void lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase,
884 lpddr4_debuginfo * debuginfo,
889 uint32_t errbitmask = 0U;
891 volatile uint32_t *regaddress;
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;
905 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
909 /* Check for GateLvlError */
910 static void lpddr4_checkgatelvlerror(lpddr4_ctlregs * ctlregbase,
911 lpddr4_debuginfo * debuginfo,
916 uint32_t errbitmask = 0U;
918 volatile uint32_t *regaddress;
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;
934 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
938 /* Check for ReadLvlError */
939 static void lpddr4_checkreadlvlerror(lpddr4_ctlregs * ctlregbase,
940 lpddr4_debuginfo * debuginfo,
945 uint32_t errbitmask = 0U;
947 volatile uint32_t *regaddress;
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;
962 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
966 /* Check for DqTrainingError */
967 static void lpddr4_checkdqtrainingerror(lpddr4_ctlregs * ctlregbase,
968 lpddr4_debuginfo * debuginfo,
973 uint32_t errbitmask = 0U;
975 volatile uint32_t *regaddress;
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;
989 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
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.
1001 static bool lpddr4_checklvlerrors(const lpddr4_privatedata * pd,
1002 lpddr4_debuginfo * debuginfo, bool errfound)
1005 bool localerrfound = errfound;
1007 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1009 if (localerrfound == false) {
1010 /* Check for ca training error */
1011 lpddr4_checkcatrainingerror(ctlregbase, debuginfo,
1015 if (localerrfound == false) {
1016 /* Check for Write leveling error */
1017 lpddr4_checkwrlvlerror(ctlregbase, debuginfo, &localerrfound);
1020 if (localerrfound == false) {
1021 /* Check for Gate leveling error */
1022 lpddr4_checkgatelvlerror(ctlregbase, debuginfo, &localerrfound);
1025 if (localerrfound == false) {
1026 /* Check for Read leveling error */
1027 lpddr4_checkreadlvlerror(ctlregbase, debuginfo, &localerrfound);
1030 if (localerrfound == false) {
1031 /* Check for DQ training error */
1032 lpddr4_checkdqtrainingerror(ctlregbase, debuginfo,
1035 return localerrfound;
1038 static bool lpddr4_seterror(volatile uint32_t * reg, uint32_t errbitmask,
1039 bool * errfoundptr, const uint32_t errorinfobits)
1042 uint32_t regval = 0U;
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;
1050 return *errfoundptr;
1053 static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,
1054 lpddr4_debuginfo * debuginfo, bool * errfoundptr)
1057 uint32_t errbitmask = (LPDDR4_BIT_MASK << 0x1U) | LPDDR4_BIT_MASK;
1058 /* Check PLL observation registers for PLL lock errors */
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);
1069 /* Check for IO Calibration errors */
1070 if (*errfoundptr == false) {
1071 debuginfo->iocaliberror =
1074 LPDDR4__PHY_CAL_RESULT_OBS_0__REG),
1075 IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
1077 if (*errfoundptr == false) {
1078 debuginfo->iocaliberror =
1081 LPDDR4__PHY_CAL_RESULT2_OBS_0__REG),
1082 IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
1084 if (*errfoundptr == false) {
1085 debuginfo->iocaliberror =
1088 LPDDR4__PHY_CAL_RESULT3_OBS_0__REG),
1089 IO_CALIB_FIELD, errfoundptr,
1094 static void lpddr4_setphysnapsettings(lpddr4_ctlregs * ctlregbase,
1095 const bool errorfound)
1099 volatile uint32_t *regaddress;
1100 uint32_t regval = 0U;
1102 /* Setting SC_PHY_SNAP_OBS_REGS_x to get a snapshot */
1103 if (errorfound == false) {
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++) {
1110 CPS_FLD_SET(LPDDR4__SC_PHY_SNAP_OBS_REGS_0__FLD,
1111 CPS_REG_READ(regaddress));
1112 CPS_REG_WRITE(regaddress, regval);
1114 lpddr4_addoffset(regaddress,
1115 (uint32_t) SLICE_WIDTH);
1120 static void lpddr4_setphyadrsnapsettings(lpddr4_ctlregs * ctlregbase,
1121 const bool errorfound)
1125 volatile uint32_t *regaddress;
1126 uint32_t regval = 0U;
1128 /* Setting SC_PHY ADR_SNAP_OBS_REGS_x to get a snapshot */
1129 if (errorfound == false) {
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++) {
1136 CPS_FLD_SET(LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__FLD,
1137 CPS_REG_READ(regaddress));
1138 CPS_REG_WRITE(regaddress, regval);
1140 lpddr4_addoffset(regaddress,
1141 (uint32_t) SLICE_WIDTH);
1146 static void lpddr4_setsettings(lpddr4_ctlregs * ctlregbase,
1147 const bool errorfound)
1150 /* Calling functions to enable snap shots of OBS registers */
1151 lpddr4_setphysnapsettings(ctlregbase, errorfound);
1152 lpddr4_setphyadrsnapsettings(ctlregbase, errorfound);
1155 static void lpddr4_setrxoffseterror(lpddr4_ctlregs * ctlregbase,
1156 lpddr4_debuginfo * debuginfo,
1160 volatile uint32_t *regaddress;
1162 uint32_t errbitmask = 0U;
1163 uint32_t regval = 0U;
1165 /* Check for rxOffsetError */
1166 if (*errorfound == false) {
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++) {
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;
1182 lpddr4_addoffset(regaddress,
1183 (uint32_t) SLICE_WIDTH);
1188 uint32_t lpddr4_getdebuginitinfo(const lpddr4_privatedata * pd,
1189 lpddr4_debuginfo * debuginfo)
1192 uint32_t result = 0U;
1193 bool errorfound = false;
1195 /* Calling Sanity Function to verify the input variables */
1196 result = lpddr4_getdebuginitinfosf(pd, debuginfo);
1197 if (result == (uint32_t) CDN_EOK) {
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);
1209 if (errorfound == true) {
1210 result = (uint32_t) EPROTO;
1216 static void readpdwakeup(const lpddr4_ctlfspnum * fspnum,
1217 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1220 /* Read the appropriate register, based on user given frequency. */
1221 if (*fspnum == LPDDR4_FSP_0) {
1223 CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
1226 LPDDR4__LPI_PD_WAKEUP_F0__REG)));
1227 } else if (*fspnum == LPDDR4_FSP_1) {
1229 CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
1232 LPDDR4__LPI_PD_WAKEUP_F1__REG)));
1234 /* Default register (sanity function already confirmed the variable value) */
1236 CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
1239 LPDDR4__LPI_PD_WAKEUP_F2__REG)));
1243 static void readsrshortwakeup(const lpddr4_ctlfspnum * fspnum,
1244 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1247 /* Read the appropriate register, based on user given frequency. */
1248 if (*fspnum == LPDDR4_FSP_0) {
1250 CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
1253 LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)));
1254 } else if (*fspnum == LPDDR4_FSP_1) {
1256 CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
1259 LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)));
1261 /* Default register (sanity function already confirmed the variable value) */
1263 CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
1266 LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)));
1270 static void readsrlongwakeup(const lpddr4_ctlfspnum * fspnum,
1271 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1274 /* Read the appropriate register, based on user given frequency. */
1275 if (*fspnum == LPDDR4_FSP_0) {
1277 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
1280 LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)));
1281 } else if (*fspnum == LPDDR4_FSP_1) {
1283 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
1286 LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)));
1288 /* Default register (sanity function already confirmed the variable value) */
1290 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
1293 LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)));
1297 static void readsrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1298 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1301 /* Read the appropriate register, based on user given frequency. */
1302 if (*fspnum == LPDDR4_FSP_0) {
1304 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1307 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
1308 } else if (*fspnum == LPDDR4_FSP_1) {
1310 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1313 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
1315 /* Default register (sanity function already confirmed the variable value) */
1317 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1320 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
1324 static void readsrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
1325 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1328 /* Read the appropriate register, based on user given frequency. */
1329 if (*fspnum == LPDDR4_FSP_0) {
1331 CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
1334 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)));
1335 } else if (*fspnum == LPDDR4_FSP_1) {
1337 CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
1340 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)));
1342 /* Default register (sanity function already confirmed the variable value) */
1344 CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
1347 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)));
1351 static void readsrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
1352 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1355 /* Read the appropriate register, based on user given frequency. */
1356 if (*fspnum == LPDDR4_FSP_0) {
1358 CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
1361 LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)));
1362 } else if (*fspnum == LPDDR4_FSP_1) {
1364 CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
1367 LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)));
1369 /* Default register (sanity function already confirmed the variable value) */
1371 CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
1374 LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)));
1378 static void readsrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1379 lpddr4_ctlregs * ctlregbase,
1383 /* Read the appropriate register, based on user given frequency. */
1384 if (*fspnum == LPDDR4_FSP_0) {
1387 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1390 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
1391 } else if (*fspnum == LPDDR4_FSP_1) {
1394 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1397 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
1399 /* Default register (sanity function already confirmed the variable value) */
1402 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1405 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
1410 static void lpddr4_readlpiwakeuptime(lpddr4_ctlregs * ctlregbase,
1411 const lpddr4_lpiwakeupparam *
1413 const lpddr4_ctlfspnum * fspnum,
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);
1432 /* Default function (sanity function already confirmed the variable value) */
1433 readsrdplonggatewakeup(fspnum, ctlregbase, cycles);
1437 uint32_t lpddr4_getlpiwakeuptime(const lpddr4_privatedata * pd,
1438 const lpddr4_lpiwakeupparam * lpiwakeupparam,
1439 const lpddr4_ctlfspnum * fspnum,
1443 uint32_t result = 0U;
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,
1455 static void writepdwakeup(const lpddr4_ctlfspnum * fspnum,
1456 lpddr4_ctlregs * ctlregbase, const uint32_t * cycles)
1459 uint32_t regval = 0U;
1460 /* Write to appropriate register ,based on user given frequency. */
1461 if (*fspnum == LPDDR4_FSP_0) {
1463 CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
1466 LPDDR4__LPI_PD_WAKEUP_F0__REG)),
1468 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG),
1470 } else if (*fspnum == LPDDR4_FSP_1) {
1472 CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
1475 LPDDR4__LPI_PD_WAKEUP_F1__REG)),
1477 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG),
1480 /* Default register (sanity function already confirmed the variable value) */
1482 CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
1485 LPDDR4__LPI_PD_WAKEUP_F2__REG)),
1487 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG),
1492 static void writesrshortwakeup(const lpddr4_ctlfspnum * fspnum,
1493 lpddr4_ctlregs * ctlregbase,
1494 const uint32_t * cycles)
1497 uint32_t regval = 0U;
1498 /* Write to appropriate register ,based on user given frequency. */
1499 if (*fspnum == LPDDR4_FSP_0) {
1501 CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
1504 LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)),
1507 (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG),
1509 } else if (*fspnum == LPDDR4_FSP_1) {
1511 CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
1514 LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)),
1517 (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG),
1520 /* Default register (sanity function already confirmed the variable value) */
1522 CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
1525 LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)),
1528 (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG),
1533 static void writesrlongwakeup(const lpddr4_ctlfspnum * fspnum,
1534 lpddr4_ctlregs * ctlregbase,
1535 const uint32_t * cycles)
1538 uint32_t regval = 0U;
1539 /* Write to appropriate register ,based on user given frequency. */
1540 if (*fspnum == LPDDR4_FSP_0) {
1542 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
1545 LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)),
1547 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG),
1549 } else if (*fspnum == LPDDR4_FSP_1) {
1551 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
1554 LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)),
1556 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG),
1559 /* Default register (sanity function already confirmed the variable value) */
1561 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
1564 LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)),
1566 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG),
1571 static void writesrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1572 lpddr4_ctlregs * ctlregbase,
1573 const uint32_t * cycles)
1576 uint32_t regval = 0U;
1577 /* Write to appropriate register ,based on user given frequency. */
1578 if (*fspnum == LPDDR4_FSP_0) {
1580 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1583 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
1587 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG),
1589 } else if (*fspnum == LPDDR4_FSP_1) {
1591 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1594 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
1598 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG),
1601 /* Default register (sanity function already confirmed the variable value) */
1603 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1606 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
1610 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG),
1615 static void writesrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
1616 lpddr4_ctlregs * ctlregbase,
1617 const uint32_t * cycles)
1620 uint32_t regval = 0U;
1621 /* Write to appropriate register ,based on user given frequency. */
1622 if (*fspnum == LPDDR4_FSP_0) {
1624 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
1627 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)),
1631 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG), regval);
1632 } else if (*fspnum == LPDDR4_FSP_1) {
1634 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
1637 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)),
1641 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG), regval);
1643 /* Default register (sanity function already confirmed the variable value) */
1645 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
1648 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)),
1652 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG), regval);
1656 static void writesrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
1657 lpddr4_ctlregs * ctlregbase,
1658 const uint32_t * cycles)
1661 uint32_t regval = 0U;
1662 /* Write to appropriate register ,based on user given frequency. */
1663 if (*fspnum == LPDDR4_FSP_0) {
1665 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
1668 LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)),
1672 LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG), regval);
1673 } else if (*fspnum == LPDDR4_FSP_1) {
1675 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
1678 LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)),
1682 LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG), regval);
1684 /* Default register (sanity function already confirmed the variable value) */
1686 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
1689 LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)),
1693 LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG), regval);
1697 static void writesrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1698 lpddr4_ctlregs * ctlregbase,
1699 const uint32_t * cycles)
1702 uint32_t regval = 0U;
1703 /* Write to appropriate register ,based on user given frequency. */
1704 if (*fspnum == LPDDR4_FSP_0) {
1707 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1710 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
1714 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG),
1716 } else if (*fspnum == LPDDR4_FSP_1) {
1719 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1722 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
1726 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG),
1729 /* Default register (sanity function already confirmed the variable value) */
1732 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1735 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
1739 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG),
1744 static void lpddr4_writelpiwakeuptime(lpddr4_ctlregs * ctlregbase,
1745 const lpddr4_lpiwakeupparam *
1747 const lpddr4_ctlfspnum * fspnum,
1748 const uint32_t * cycles)
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);
1766 /* Default function (sanity function already confirmed the variable value) */
1767 writesrdplonggatewakeup(fspnum, ctlregbase, 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)
1776 uint32_t result = 0U;
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) {
1786 if (result == (uint32_t) CDN_EOK) {
1787 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1788 lpddr4_writelpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
1794 uint32_t lpddr4_geteccenable(const lpddr4_privatedata * pd,
1795 lpddr4_eccenable * eccparam)
1797 uint32_t result = 0U;
1798 uint32_t fldval = 0U;
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;
1805 /* Reading the ECC_Enable field from the register. */
1807 CPS_FLD_READ(LPDDR4__ECC_ENABLE__FLD,
1810 LPDDR4__ECC_ENABLE__REG)));
1813 *eccparam = LPDDR4_ECC_ERR_DETECT_CORRECT;
1816 *eccparam = LPDDR4_ECC_ERR_DETECT;
1819 *eccparam = LPDDR4_ECC_ENABLED;
1822 /* Default ECC (Sanity function already confirmed the value to be in expected range.) */
1823 *eccparam = LPDDR4_ECC_DISABLED;
1830 uint32_t lpddr4_seteccenable(const lpddr4_privatedata * pd,
1831 const lpddr4_eccenable * eccparam)
1834 uint32_t result = 0U;
1835 uint32_t regval = 0U;
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;
1842 /* Updating the ECC_Enable field based on the user given value. */
1844 CPS_FLD_WRITE(LPDDR4__ECC_ENABLE__FLD,
1847 LPDDR4__ECC_ENABLE__REG)),
1849 CPS_REG_WRITE(&(ctlregbase->LPDDR4__ECC_ENABLE__REG), regval);
1854 uint32_t lpddr4_getreducmode(const lpddr4_privatedata * pd,
1855 lpddr4_reducmode * mode)
1857 uint32_t result = 0U;
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. */
1865 (LPDDR4__REDUC__FLD,
1866 CPS_REG_READ(&(ctlregbase->LPDDR4__REDUC__REG))) == 0U) {
1867 *mode = LPDDR4_REDUC_ON;
1869 *mode = LPDDR4_REDUC_OFF;
1875 uint32_t lpddr4_setreducmode(const lpddr4_privatedata * pd,
1876 const lpddr4_reducmode * mode)
1878 uint32_t result = 0U;
1879 uint32_t regval = 0U;
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. */
1887 CPS_FLD_WRITE(LPDDR4__REDUC__FLD,
1890 LPDDR4__REDUC__REG)), *mode);
1891 CPS_REG_WRITE(&(ctlregbase->LPDDR4__REDUC__REG), regval);
1896 uint32_t lpddr4_getdbireadmode(const lpddr4_privatedata * pd, bool * on_off)
1899 uint32_t result = 0U;
1901 /* Calling Sanity Function to verify the input variables */
1902 result = lpddr4_getdbireadmodesf(pd, on_off);
1904 if (result == (uint32_t) CDN_EOK) {
1905 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1906 /* Reading the field value from the register. */
1908 (LPDDR4__RD_DBI_EN__FLD,
1909 CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG))) ==
1919 uint32_t lpddr4_getdbiwritemode(const lpddr4_privatedata * pd, bool * on_off)
1922 uint32_t result = 0U;
1924 /* Calling Sanity Function to verify the input variables */
1925 result = lpddr4_getdbireadmodesf(pd, on_off);
1927 if (result == (uint32_t) CDN_EOK) {
1928 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1929 /* Reading the field value from the register. */
1931 (LPDDR4__WR_DBI_EN__FLD,
1932 CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG))) ==
1942 uint32_t lpddr4_setdbimode(const lpddr4_privatedata * pd,
1943 const lpddr4_dbimode * mode)
1946 uint32_t result = 0U;
1947 uint32_t regval = 0U;
1949 /* Calling Sanity Function to verify the input variables */
1950 result = lpddr4_setdbimodesf(pd, mode);
1952 if (result == (uint32_t) CDN_EOK) {
1953 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1955 /* Updating the appropriate field value based on the user given mode */
1956 if (*mode == LPDDR4_DBI_RD_ON) {
1958 CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
1961 LPDDR4__RD_DBI_EN__REG)),
1963 } else if (*mode == LPDDR4_DBI_RD_OFF) {
1965 CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
1968 LPDDR4__RD_DBI_EN__REG)),
1970 } else if (*mode == LPDDR4_DBI_WR_ON) {
1972 CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
1975 LPDDR4__WR_DBI_EN__REG)),
1978 /* Default field (Sanity function already confirmed the value to be in expected range.) */
1980 CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
1983 LPDDR4__WR_DBI_EN__REG)),
1986 CPS_REG_WRITE(&(ctlregbase->LPDDR4__RD_DBI_EN__REG), regval);
1991 uint32_t lpddr4_getrefreshrate(const lpddr4_privatedata * pd,
1992 const lpddr4_ctlfspnum * fspnum,
1995 uint32_t result = 0U;
1997 /* Calling Sanity Function to verify the input variables */
1998 result = lpddr4_getrefreshratesf(pd, fspnum, cycles);
2000 if (result == (uint32_t) CDN_EOK) {
2001 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2003 /* Selecting the appropriate register for the user requested Frequency */
2007 CPS_FLD_READ(LPDDR4__TREF_F2__FLD,
2010 LPDDR4__TREF_F2__REG)));
2014 CPS_FLD_READ(LPDDR4__TREF_F1__FLD,
2017 LPDDR4__TREF_F1__REG)));
2020 /* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
2022 CPS_FLD_READ(LPDDR4__TREF_F0__FLD,
2025 LPDDR4__TREF_F0__REG)));
2032 uint32_t lpddr4_setrefreshrate(const lpddr4_privatedata * pd,
2033 const lpddr4_ctlfspnum * fspnum,
2034 const uint32_t * cycles)
2036 uint32_t result = 0U;
2037 uint32_t regval = 0U;
2039 /* Calling Sanity Function to verify the input variables */
2040 result = lpddr4_setrefreshratesf(pd, fspnum, cycles);
2042 if (result == (uint32_t) CDN_EOK) {
2043 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2045 /* Selecting the appropriate register for the user requested Frequency */
2049 CPS_FLD_WRITE(LPDDR4__TREF_F2__FLD,
2052 LPDDR4__TREF_F2__REG)),
2054 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F2__REG),
2059 CPS_FLD_WRITE(LPDDR4__TREF_F1__FLD,
2062 LPDDR4__TREF_F1__REG)),
2064 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F1__REG),
2068 /* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
2070 CPS_FLD_WRITE(LPDDR4__TREF_F0__FLD,
2073 LPDDR4__TREF_F0__REG)),
2075 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F0__REG),
2083 uint32_t lpddr4_refreshperchipselect(const lpddr4_privatedata * pd,
2084 const uint32_t trefinterval)
2086 uint32_t result = 0U;
2087 uint32_t regval = 0U;
2089 /* Calling Sanity Function to verify the input variables */
2090 result = lpddr4_refreshperchipselectsf(pd);
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. */
2096 CPS_FLD_WRITE(LPDDR4__TREF_INTERVAL__FLD,
2099 LPDDR4__TREF_INTERVAL__REG)),
2101 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_INTERVAL__REG),