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;
202 uint32_t version[2] = { 0, 0 };
204 result = lpddr4_initsf(pd, cfg);
205 if (result == (uint32_t) CDN_EOK) {
206 /* Validate Magic number */
207 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) cfg->ctlbase;
208 productid = (uint16_t) (CPS_FLD_READ(LPDDR4__CONTROLLER_ID__FLD,
211 LPDDR4__CONTROLLER_ID__REG))));
213 (uint32_t) (CPS_FLD_READ
214 (LPDDR4__CONTROLLER_VERSION_0__FLD,
217 LPDDR4__CONTROLLER_VERSION_0__REG))));
219 (uint32_t) (CPS_FLD_READ
220 (LPDDR4__CONTROLLER_VERSION_1__FLD,
223 LPDDR4__CONTROLLER_VERSION_1__REG))));
224 if ((productid == PRODUCT_ID) && (version[0] == VERSION_0)
225 && (version[1] == VERSION_1)) {
226 /* Populating configuration data to pD */
227 pd->ctlbase = ctlregbase;
229 (lpddr4_infocallback) cfg->infohandler;
230 pd->ctlinterrupthandler =
231 (lpddr4_ctlcallback) cfg->ctlinterrupthandler;
232 pd->phyindepinterrupthandler =
233 (lpddr4_phyindepcallback) cfg->
234 phyindepinterrupthandler;
236 /* Magic number validation failed - Driver doesn't support given IP version */
237 result = (uint32_t) EOPNOTSUPP;
245 * @param[in] pD Driver state info specific to this instance.
247 uint32_t lpddr4_start(const lpddr4_privatedata * pd)
249 uint32_t result = 0U;
250 uint32_t regval = 0U;
252 result = lpddr4_startsf(pd);
253 if (result == (uint32_t) CDN_EOK) {
254 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
256 /* Enable PI as the initiator for DRAM */
258 CPS_FLD_SET(LPDDR4__PI_INIT_LVL_EN__FLD,
261 LPDDR4__PI_INIT_LVL_EN__REG)));
262 regval = CPS_FLD_SET(LPDDR4__PI_NORMAL_LVL_SEQ__FLD, regval);
263 CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_INIT_LVL_EN__REG)),
266 /* Start PI init sequence. */
267 result = lpddr4_startsequencecontroller(pd);
273 * Read a register from the controller, PHY or PHY Independent Module
274 * @param[in] pD Driver state info specific to this instance.
275 * @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
276 * @param[in] regOffset Register offset
277 * @param[out] regValue Register value read
278 * @return CDN_EOK on success.
279 * @return EINVAL if regOffset if out of range or regValue is NULL
281 uint32_t lpddr4_readreg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
282 uint32_t regoffset, uint32_t * regvalue)
284 uint32_t result = 0U;
286 result = lpddr4_readregsf(pd, cpp, regvalue);
287 if (result == (uint32_t) CDN_EOK) {
288 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
290 if (cpp == LPDDR4_CTL_REGS) {
291 if (regoffset >= LPDDR4_CTL_REG_COUNT) {
292 /* Return if user provider invalid register number */
296 CPS_REG_READ(lpddr4_addoffset
297 (&(ctlregbase->DENALI_CTL_0),
300 } else if (cpp == LPDDR4_PHY_REGS) {
301 if (regoffset >= LPDDR4_PHY_REG_COUNT) {
302 /* Return if user provider invalid register number */
306 CPS_REG_READ(lpddr4_addoffset
307 (&(ctlregbase->DENALI_PHY_0),
312 if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
313 /* Return if user provider invalid register number */
317 CPS_REG_READ(lpddr4_addoffset
318 (&(ctlregbase->DENALI_PI_0),
326 uint32_t lpddr4_writereg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
327 uint32_t regoffset, uint32_t regvalue)
329 uint32_t result = 0U;
331 result = lpddr4_writeregsf(pd, cpp);
332 if (result == (uint32_t) CDN_EOK) {
333 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
335 if (cpp == LPDDR4_CTL_REGS) {
336 if (regoffset >= LPDDR4_CTL_REG_COUNT) {
337 /* Return if user provider invalid register number */
340 CPS_REG_WRITE(lpddr4_addoffset
341 (&(ctlregbase->DENALI_CTL_0),
342 regoffset), regvalue);
344 } else if (cpp == LPDDR4_PHY_REGS) {
345 if (regoffset >= LPDDR4_PHY_REG_COUNT) {
346 /* Return if user provider invalid register number */
349 CPS_REG_WRITE(lpddr4_addoffset
350 (&(ctlregbase->DENALI_PHY_0),
351 regoffset), regvalue);
354 if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
355 /* Return if user provider invalid register number */
358 CPS_REG_WRITE(lpddr4_addoffset
359 (&(ctlregbase->DENALI_PI_0),
360 regoffset), regvalue);
368 static uint32_t lpddr4_checkmmrreaderror(const lpddr4_privatedata * pd,
374 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
375 uint32_t result = (uint32_t) CDN_EOK;
377 /* Check if mode register read error interrupt occurred */
378 if (lpddr4_pollctlirq(pd, LPDDR4_MRR_ERROR, 100) == 0U) {
379 /* Mode register read error interrupt, read MRR status register and return. */
381 (uint8_t) CPS_FLD_READ(LPDDR4__MRR_ERROR_STATUS__FLD,
384 LPDDR4__MRR_ERROR_STATUS__REG)));
389 /* Mode register read was successful, read DATA */
393 LPDDR4__PERIPHERAL_MRR_DATA_0__REG));
397 LPDDR4__PERIPHERAL_MRR_DATA_1__REG));
398 *mmrvalue = (uint64_t) ((*mmrvalue << WORD_SHIFT) | lowerdata);
399 /* Acknowledge MR_READ_DONE interrupt to clear it */
400 result = lpddr4_ackctlinterrupt(pd, LPDDR4_MR_READ_DONE);
405 uint32_t lpddr4_getmmrregister(const lpddr4_privatedata * pd,
406 uint32_t readmoderegval, uint64_t * mmrvalue,
410 uint32_t result = 0U;
411 uint32_t tdelay = 1000U;
412 uint32_t regval = 0U;
414 result = lpddr4_getmmrregistersf(pd, mmrvalue, mmrstatus);
415 if (result == (uint32_t) CDN_EOK) {
417 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
419 /* Populate the calculated value to the register */
421 CPS_FLD_WRITE(LPDDR4__READ_MODEREG__FLD,
424 LPDDR4__READ_MODEREG__REG)),
426 CPS_REG_WRITE(&(ctlregbase->LPDDR4__READ_MODEREG__REG), regval);
428 /* Wait until the Read is done */
429 result = lpddr4_pollctlirq(pd, LPDDR4_MR_READ_DONE, tdelay);
431 if (result == (uint32_t) CDN_EOK) {
432 result = lpddr4_checkmmrreaderror(pd, mmrvalue, mmrstatus);
437 static uint32_t lpddr4_writemmrregister(const lpddr4_privatedata * pd,
438 uint32_t writemoderegval)
441 uint32_t result = (uint32_t) CDN_EOK;
442 uint32_t tdelay = 1000U;
443 uint32_t regval = 0U;
444 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
446 /* Populate the calculated value to the register */
448 CPS_FLD_WRITE(LPDDR4__WRITE_MODEREG__FLD,
451 LPDDR4__WRITE_MODEREG__REG)),
453 CPS_REG_WRITE(&(ctlregbase->LPDDR4__WRITE_MODEREG__REG), regval);
455 result = lpddr4_pollctlirq(pd, LPDDR4_MR_WRITE_DONE, tdelay);
460 uint32_t lpddr4_setmmrregister(const lpddr4_privatedata * pd,
461 uint32_t writemoderegval, uint8_t * mrwstatus)
463 uint32_t result = 0U;
465 result = lpddr4_setmmrregistersf(pd, mrwstatus);
466 if (result == (uint32_t) CDN_EOK) {
468 /* Function call to trigger Mode register write */
469 result = lpddr4_writemmrregister(pd, writemoderegval);
471 if (result == (uint32_t) CDN_EOK) {
473 lpddr4_ackctlinterrupt(pd, LPDDR4_MR_WRITE_DONE);
475 /* Read the status of mode register write */
476 if (result == (uint32_t) CDN_EOK) {
477 lpddr4_ctlregs *ctlregbase =
478 (lpddr4_ctlregs *) pd->ctlbase;
480 (uint8_t) CPS_FLD_READ(LPDDR4__MRW_STATUS__FLD,
483 LPDDR4__MRW_STATUS__REG)));
484 if ((*mrwstatus) != 0U) {
493 uint32_t lpddr4_writectlconfig(const lpddr4_privatedata * pd,
494 const lpddr4_reginitdata * regvalues)
499 result = lpddr4_writectlconfigsf(pd, regvalues);
500 if (result == (uint32_t) CDN_EOK) {
502 /* Iterate through CTL register numbers. */
503 for (regnum = 0; regnum < LPDDR4_CTL_REG_COUNT; regnum++) {
504 /* Check if the user has requested update */
505 if (regvalues->updatectlreg[regnum]) {
507 lpddr4_writereg(pd, LPDDR4_CTL_REGS, regnum,
508 (uint32_t) (regvalues->
517 uint32_t lpddr4_writephyindepconfig(const lpddr4_privatedata * pd,
518 const lpddr4_reginitdata * regvalues)
523 result = lpddr4_writephyindepconfigsf(pd, regvalues);
524 if (result == (uint32_t) CDN_EOK) {
526 /* Iterate through PHY Independent module register numbers. */
527 for (regnum = 0; regnum < LPDDR4_PHY_INDEP_REG_COUNT; regnum++) {
528 /* Check if the user has requested update */
529 if (regvalues->updatephyindepreg[regnum]) {
531 lpddr4_writereg(pd, LPDDR4_PHY_INDEP_REGS,
533 (uint32_t) (regvalues->
542 uint32_t lpddr4_writephyconfig(const lpddr4_privatedata * pd,
543 const lpddr4_reginitdata * regvalues)
548 result = lpddr4_writephyconfigsf(pd, regvalues);
549 if (result == (uint32_t) CDN_EOK) {
551 /* Iterate through PHY register numbers. */
552 for (regnum = 0; regnum < LPDDR4_PHY_REG_COUNT; regnum++) {
553 /* Check if the user has requested update */
554 if (regvalues->updatephyreg[regnum]) {
556 lpddr4_writereg(pd, LPDDR4_PHY_REGS, regnum,
557 (uint32_t) (regvalues->
566 uint32_t lpddr4_readctlconfig(const lpddr4_privatedata * pd,
567 lpddr4_reginitdata * regvalues)
571 result = lpddr4_readctlconfigsf(pd, regvalues);
572 if (result == (uint32_t) CDN_EOK) {
573 /* Iterate through CTL register numbers. */
574 for (regnum = 0; regnum < LPDDR4_CTL_REG_COUNT; regnum++) {
575 /* Check if the user has requested read (updateCtlReg=1) */
576 if (regvalues->updatectlreg[regnum]) {
578 lpddr4_readreg(pd, LPDDR4_CTL_REGS, regnum,
579 (uint32_t *) (®values->
588 uint32_t lpddr4_readphyindepconfig(const lpddr4_privatedata * pd,
589 lpddr4_reginitdata * regvalues)
594 result = lpddr4_readphyindepconfigsf(pd, regvalues);
595 if (result == (uint32_t) CDN_EOK) {
596 /* Iterate through PHY Independent module register numbers. */
597 for (regnum = 0; regnum < LPDDR4_PHY_INDEP_REG_COUNT; regnum++) {
598 /* Check if the user has requested read (updateCtlReg=1) */
599 if (regvalues->updatephyindepreg[regnum]) {
601 lpddr4_readreg(pd, LPDDR4_PHY_INDEP_REGS,
603 (uint32_t *) (®values->
612 uint32_t lpddr4_readphyconfig(const lpddr4_privatedata * pd,
613 lpddr4_reginitdata * regvalues)
618 result = lpddr4_readphyconfigsf(pd, regvalues);
619 if (result == (uint32_t) CDN_EOK) {
620 /* Iterate through PHY register numbers. */
621 for (regnum = 0; regnum < LPDDR4_PHY_REG_COUNT; regnum++) {
622 /* Check if the user has requested read (updateCtlReg=1) */
623 if (regvalues->updatephyreg[regnum]) {
625 lpddr4_readreg(pd, LPDDR4_PHY_REGS, regnum,
626 (uint32_t *) (®values->
635 uint32_t lpddr4_getctlinterruptmask(const lpddr4_privatedata * pd,
638 uint32_t result = 0U;
639 uint64_t lowermask = 0U;
641 result = lpddr4_getctlinterruptmasksf(pd, mask);
642 if (result == (uint32_t) CDN_EOK) {
643 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
644 /* Reading the lower mask register */
646 (uint64_t) (CPS_FLD_READ
647 (LPDDR4__INT_MASK_0__FLD,
650 LPDDR4__INT_MASK_0__REG))));
651 /* Reading the upper mask register */
653 (uint64_t) (CPS_FLD_READ
654 (LPDDR4__INT_MASK_1__FLD,
657 LPDDR4__INT_MASK_1__REG))));
658 /* Concatenate both register informations */
659 *mask = (uint64_t) ((*mask << WORD_SHIFT) | lowermask);
664 uint32_t lpddr4_setctlinterruptmask(const lpddr4_privatedata * pd,
665 const uint64_t * mask)
669 const uint64_t ui64one = 1ULL;
670 const uint32_t ui32irqcount = (uint32_t) LPDDR4_LOR_BITS + 1U;
672 result = lpddr4_setctlinterruptmasksf(pd, mask);
673 if ((result == (uint32_t) CDN_EOK) && (ui32irqcount < 64U)) {
674 /* Return if the user given value is higher than the field width */
675 if (*mask >= (ui64one << ui32irqcount)) {
679 if (result == (uint32_t) CDN_EOK) {
680 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
682 /* Extracting the lower 32 bits and writing to lower mask register */
683 regval = (uint32_t) (*mask & WORD_MASK);
685 CPS_FLD_WRITE(LPDDR4__INT_MASK_0__FLD,
688 LPDDR4__INT_MASK_0__REG)),
690 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_0__REG), regval);
692 /* Extracting the upper 32 bits and writing to upper mask register */
693 regval = (uint32_t) ((*mask >> WORD_SHIFT) & WORD_MASK);
695 CPS_FLD_WRITE(LPDDR4__INT_MASK_1__FLD,
698 LPDDR4__INT_MASK_1__REG)),
700 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_1__REG), regval);
705 uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd,
706 lpddr4_ctlinterrupt intr, bool * irqstatus)
709 uint32_t ctlirqstatus = 0;
710 uint32_t fieldshift = 0;
712 /* NOTE:This function assume irq status is mentioned in NOT more than 2 registers.
713 * Value of 'interrupt' should be less than 64 */
714 result = lpddr4_checkctlinterruptsf(pd, intr, irqstatus);
715 if (result == (uint32_t) CDN_EOK) {
716 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
718 if ((uint32_t) intr >= WORD_SHIFT) {
722 LPDDR4__INT_STATUS_1__REG));
723 /* Reduce the shift value as we are considering upper register */
724 fieldshift = (uint32_t) intr - ((uint32_t) WORD_SHIFT);
729 LPDDR4__INT_STATUS_0__REG));
730 /* The shift value remains same for lower interrupt register */
731 fieldshift = (uint32_t) intr;
734 /* MISRA compliance (Shifting operation) check */
735 if (fieldshift < WORD_SHIFT) {
736 if (((ctlirqstatus >> fieldshift) & BIT_MASK) > 0U) {
746 uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd,
747 lpddr4_ctlinterrupt intr)
751 uint32_t localinterrupt = (uint32_t) intr;
753 /* NOTE:This function assume irq status is mentioned in NOT more than 2 registers.
754 * Value of 'interrupt' should be less than 64 */
755 result = lpddr4_ackctlinterruptsf(pd, intr);
756 if (result == (uint32_t) CDN_EOK) {
757 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
759 /* Check if the requested bit is in upper register */
760 if (localinterrupt > WORD_SHIFT) {
762 (localinterrupt - (uint32_t) WORD_SHIFT);
763 regval = ((uint32_t) BIT_MASK << localinterrupt);
764 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
767 regval = ((uint32_t) BIT_MASK << localinterrupt);
768 CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
776 uint32_t lpddr4_getphyindepinterruptmask(const lpddr4_privatedata * pd,
781 result = lpddr4_getphyindepinterruptmsf(pd, mask);
782 if (result == (uint32_t) CDN_EOK) {
783 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
784 /* Reading mask register */
786 CPS_FLD_READ(LPDDR4__PI_INT_MASK__FLD,
789 LPDDR4__PI_INT_MASK__REG)));
794 uint32_t lpddr4_setphyindepinterruptmask(const lpddr4_privatedata * pd,
795 const uint32_t * mask)
799 const uint32_t ui32irqcount =
800 (uint32_t) LPDDR4_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT + 1U;
802 result = lpddr4_setphyindepinterruptmsf(pd, mask);
803 if ((result == (uint32_t) CDN_EOK) && (ui32irqcount < WORD_SHIFT)) {
804 /* Return if the user given value is higher than the field width */
805 if (*mask >= (1U << ui32irqcount)) {
809 if (result == (uint32_t) CDN_EOK) {
810 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
812 /* Writing to the user requested interrupt mask */
814 CPS_FLD_WRITE(LPDDR4__PI_INT_MASK__FLD,
817 LPDDR4__PI_INT_MASK__REG)),
819 CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_MASK__REG), regval);
824 uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd,
825 lpddr4_phyindepinterrupt intr,
829 uint32_t phyindepirqstatus = 0;
831 result = lpddr4_checkphyindepinterrupsf(pd, intr, irqstatus);
832 /* Confirming that the value of interrupt is less than register width */
833 if ((result == (uint32_t) CDN_EOK) && ((uint32_t) intr < WORD_SHIFT)) {
834 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
836 /* Reading the requested bit to check interrupt status */
838 CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
840 (((phyindepirqstatus >> (uint32_t) intr) & BIT_MASK) > 0U);
845 uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd,
846 lpddr4_phyindepinterrupt intr)
848 uint32_t result = 0U;
849 uint32_t regval = 0U;
850 uint32_t ui32shiftinterrupt = (uint32_t) intr;
852 result = lpddr4_ackphyindepinterruptsf(pd, intr);
853 /* Confirming that the value of interrupt is less than register width */
854 if ((result == (uint32_t) CDN_EOK) && (ui32shiftinterrupt < WORD_SHIFT)) {
855 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
857 /* Write 1 to the requested bit to ACk the interrupt */
858 regval = ((uint32_t) BIT_MASK << ui32shiftinterrupt);
859 CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
865 /* Check for caTrainingError */
866 static void lpddr4_checkcatrainingerror(lpddr4_ctlregs * ctlregbase,
867 lpddr4_debuginfo * debuginfo,
872 uint32_t errbitmask = 0U;
874 volatile uint32_t *regaddress;
878 *)(&(ctlregbase->LPDDR4__PHY_ADR_CALVL_OBS1_0__REG));
879 errbitmask = (CA_TRAIN_RL) | (NIBBLE_MASK);
880 /* PHY_ADR_CALVL_OBS1[4] – Right found
881 PHY_ADR_CALVL_OBS1[5] – left found
882 both the above fields should be high and below field should be zero.
883 PHY_ADR_CALVL_OBS1[3:0] – calvl_state
885 for (snum = 0U; snum < ASLICE_NUM; snum++) {
886 regval = CPS_REG_READ(regaddress);
887 if ((regval & errbitmask) != CA_TRAIN_RL) {
888 debuginfo->catraingerror = true;
892 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
896 /* Check for wrLvlError */
897 static void lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase,
898 lpddr4_debuginfo * debuginfo,
903 uint32_t errbitmask = 0U;
905 volatile uint32_t *regaddress;
909 *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG));
910 /* PHY_WRLVL_ERROR_OBS_X[1:0] should be zero */
911 errbitmask = (BIT_MASK << 1) | (BIT_MASK);
912 for (snum = 0U; snum < DSLICE_NUM; snum++) {
913 regval = CPS_REG_READ(regaddress);
914 if ((regval & errbitmask) != 0U) {
915 debuginfo->wrlvlerror = true;
919 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
923 /* Check for GateLvlError */
924 static void lpddr4_checkgatelvlerror(lpddr4_ctlregs * ctlregbase,
925 lpddr4_debuginfo * debuginfo,
930 uint32_t errbitmask = 0U;
932 volatile uint32_t *regaddress;
936 *)(&(ctlregbase->LPDDR4__PHY_GTLVL_STATUS_OBS_0__REG));
937 /* PHY_GTLVL_STATUS_OBS[6] – gate_level min error
938 * PHY_GTLVL_STATUS_OBS[7] – gate_level max error
939 * All the above bit fields should be zero */
940 errbitmask = GATE_LVL_ERROR_FIELDS;
941 for (snum = 0U; snum < DSLICE_NUM; snum++) {
942 regval = CPS_REG_READ(regaddress);
943 if ((regval & errbitmask) != 0U) {
944 debuginfo->gatelvlerror = true;
948 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
952 /* Check for ReadLvlError */
953 static void lpddr4_checkreadlvlerror(lpddr4_ctlregs * ctlregbase,
954 lpddr4_debuginfo * debuginfo,
959 uint32_t errbitmask = 0U;
961 volatile uint32_t *regaddress;
965 *)(&(ctlregbase->LPDDR4__PHY_RDLVL_STATUS_OBS_0__REG));
966 /* PHY_RDLVL_STATUS_OBS[23:16] – failed bits : should be zero.
967 PHY_RDLVL_STATUS_OBS[31:28] – rdlvl_state : should be zero */
968 errbitmask = READ_LVL_ERROR_FIELDS;
969 for (snum = 0U; snum < DSLICE_NUM; snum++) {
970 regval = CPS_REG_READ(regaddress);
971 if ((regval & errbitmask) != 0U) {
972 debuginfo->readlvlerror = true;
976 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
980 /* Check for DqTrainingError */
981 static void lpddr4_checkdqtrainingerror(lpddr4_ctlregs * ctlregbase,
982 lpddr4_debuginfo * debuginfo,
987 uint32_t errbitmask = 0U;
989 volatile uint32_t *regaddress;
993 *)(&(ctlregbase->LPDDR4__PHY_WDQLVL_STATUS_OBS_0__REG));
994 /* PHY_WDQLVL_STATUS_OBS[26:18] should all be zero. */
995 errbitmask = DQ_LVL_STATUS;
996 for (snum = 0U; snum < DSLICE_NUM; snum++) {
997 regval = CPS_REG_READ(regaddress);
998 if ((regval & errbitmask) != 0U) {
999 debuginfo->dqtrainingerror = true;
1000 *errfoundptr = true;
1003 lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
1008 * Internal Function:For checking errors in training/levelling sequence.
1009 * @param[in] pD Driver state info specific to this instance.
1010 * @param[in] debugInfo pointer to debug information.
1011 * @param[out] errFoundPtr pointer to return if error found.
1012 * @return CDN_EOK on success (Interrupt status high).
1013 * @return EINVAL checking or unmasking was not successful.
1015 static bool lpddr4_checklvlerrors(const lpddr4_privatedata * pd,
1016 lpddr4_debuginfo * debuginfo, bool errfound)
1019 bool localerrfound = errfound;
1021 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1023 if (localerrfound == false) {
1024 /* Check for ca training error */
1025 lpddr4_checkcatrainingerror(ctlregbase, debuginfo,
1029 if (localerrfound == false) {
1030 /* Check for Write leveling error */
1031 lpddr4_checkwrlvlerror(ctlregbase, debuginfo, &localerrfound);
1034 if (localerrfound == false) {
1035 /* Check for Gate leveling error */
1036 lpddr4_checkgatelvlerror(ctlregbase, debuginfo, &localerrfound);
1039 if (localerrfound == false) {
1040 /* Check for Read leveling error */
1041 lpddr4_checkreadlvlerror(ctlregbase, debuginfo, &localerrfound);
1044 if (localerrfound == false) {
1045 /* Check for DQ training error */
1046 lpddr4_checkdqtrainingerror(ctlregbase, debuginfo,
1049 return localerrfound;
1052 static bool lpddr4_seterror(volatile uint32_t * reg, uint32_t errbitmask,
1053 bool * errfoundptr, const uint32_t errorinfobits)
1056 uint32_t regval = 0U;
1058 /* Read the respective observation register */
1059 regval = CPS_REG_READ(reg);
1060 /* Compare the error bit values */
1061 if ((regval & errbitmask) != errorinfobits) {
1062 *errfoundptr = true;
1064 return *errfoundptr;
1067 static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,
1068 lpddr4_debuginfo * debuginfo, bool * errfoundptr)
1071 uint32_t errbitmask = (BIT_MASK << 0x1U) | (BIT_MASK);
1072 /* Check PLL observation registers for PLL lock errors */
1074 debuginfo->pllerror =
1075 lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_0__REG),
1076 errbitmask, errfoundptr, PLL_READY);
1077 if (*errfoundptr == false) {
1078 debuginfo->pllerror =
1079 lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_1__REG),
1080 errbitmask, errfoundptr, PLL_READY);
1083 /* Check for IO Calibration errors */
1084 if (*errfoundptr == false) {
1085 debuginfo->iocaliberror =
1088 LPDDR4__PHY_CAL_RESULT_OBS_0__REG),
1089 IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
1091 if (*errfoundptr == false) {
1092 debuginfo->iocaliberror =
1095 LPDDR4__PHY_CAL_RESULT2_OBS_0__REG),
1096 IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
1098 if (*errfoundptr == false) {
1099 debuginfo->iocaliberror =
1102 LPDDR4__PHY_CAL_RESULT3_OBS_0__REG),
1103 IO_CALIB_FIELD, errfoundptr,
1108 static void lpddr4_setphysnapsettings(lpddr4_ctlregs * ctlregbase,
1109 const bool errorfound)
1113 volatile uint32_t *regaddress;
1114 uint32_t regval = 0U;
1116 /* Setting SC_PHY_SNAP_OBS_REGS_x to get a snapshot */
1117 if (errorfound == false) {
1120 *)(&(ctlregbase->LPDDR4__SC_PHY_SNAP_OBS_REGS_0__REG));
1121 /* Iterate through each PHY Data Slice */
1122 for (snum = 0U; snum < DSLICE_NUM; snum++) {
1124 CPS_FLD_SET(LPDDR4__SC_PHY_SNAP_OBS_REGS_0__FLD,
1125 CPS_REG_READ(regaddress));
1126 CPS_REG_WRITE(regaddress, regval);
1128 lpddr4_addoffset(regaddress,
1129 (uint32_t) SLICE_WIDTH);
1134 static void lpddr4_setphyadrsnapsettings(lpddr4_ctlregs * ctlregbase,
1135 const bool errorfound)
1139 volatile uint32_t *regaddress;
1140 uint32_t regval = 0U;
1142 /* Setting SC_PHY ADR_SNAP_OBS_REGS_x to get a snapshot */
1143 if (errorfound == false) {
1146 *)(&(ctlregbase->LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__REG));
1147 /* Iterate through each PHY Address Slice */
1148 for (snum = 0U; snum < ASLICE_NUM; snum++) {
1150 CPS_FLD_SET(LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__FLD,
1151 CPS_REG_READ(regaddress));
1152 CPS_REG_WRITE(regaddress, regval);
1154 lpddr4_addoffset(regaddress,
1155 (uint32_t) SLICE_WIDTH);
1160 static void lpddr4_setsettings(lpddr4_ctlregs * ctlregbase,
1161 const bool errorfound)
1164 /* Calling functions to enable snap shots of OBS registers */
1165 lpddr4_setphysnapsettings(ctlregbase, errorfound);
1166 lpddr4_setphyadrsnapsettings(ctlregbase, errorfound);
1169 static void lpddr4_setrxoffseterror(lpddr4_ctlregs * ctlregbase,
1170 lpddr4_debuginfo * debuginfo,
1174 volatile uint32_t *regaddress;
1176 uint32_t errbitmask = 0U;
1177 uint32_t regval = 0U;
1179 /* Check for rxOffsetError */
1180 if (*errorfound == false) {
1183 *)(&(ctlregbase->LPDDR4__PHY_RX_CAL_LOCK_OBS_0__REG));
1184 errbitmask = (RX_CAL_DONE) | (NIBBLE_MASK);
1185 /* PHY_RX_CAL_LOCK_OBS_x[4] – RX_CAL_DONE : should be high
1186 phy_rx_cal_lock_obs_x[3:0] – RX_CAL_STATE : should be zero. */
1187 for (snum = 0U; snum < DSLICE_NUM; snum++) {
1189 CPS_FLD_READ(LPDDR4__PHY_RX_CAL_LOCK_OBS_0__FLD,
1190 CPS_REG_READ(regaddress));
1191 if ((regval & errbitmask) != RX_CAL_DONE) {
1192 debuginfo->rxoffseterror = true;
1196 lpddr4_addoffset(regaddress,
1197 (uint32_t) SLICE_WIDTH);
1202 uint32_t lpddr4_getdebuginitinfo(const lpddr4_privatedata * pd,
1203 lpddr4_debuginfo * debuginfo)
1206 uint32_t result = 0U;
1207 bool errorfound = false;
1209 /* Calling Sanity Function to verify the input variables */
1210 result = lpddr4_getdebuginitinfosf(pd, debuginfo);
1211 if (result == (uint32_t) CDN_EOK) {
1213 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1214 lpddr4_seterrors(ctlregbase, debuginfo, &errorfound);
1215 /* Function to setup Snap for OBS registers */
1216 lpddr4_setsettings(ctlregbase, errorfound);
1217 /* Function to check for Rx offset error */
1218 lpddr4_setrxoffseterror(ctlregbase, debuginfo, &errorfound);
1219 /* Function Check various levelling errors */
1220 errorfound = lpddr4_checklvlerrors(pd, debuginfo, errorfound);
1223 if (errorfound == true) {
1224 result = (uint32_t) EPROTO;
1230 static void readpdwakeup(const lpddr4_ctlfspnum * fspnum,
1231 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1234 /* Read the appropriate register, based on user given frequency. */
1235 if (*fspnum == LPDDR4_FSP_0) {
1237 CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
1240 LPDDR4__LPI_PD_WAKEUP_F0__REG)));
1241 } else if (*fspnum == LPDDR4_FSP_1) {
1243 CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
1246 LPDDR4__LPI_PD_WAKEUP_F1__REG)));
1248 /* Default register (sanity function already confirmed the variable value) */
1250 CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
1253 LPDDR4__LPI_PD_WAKEUP_F2__REG)));
1257 static void readsrshortwakeup(const lpddr4_ctlfspnum * fspnum,
1258 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1261 /* Read the appropriate register, based on user given frequency. */
1262 if (*fspnum == LPDDR4_FSP_0) {
1264 CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
1267 LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)));
1268 } else if (*fspnum == LPDDR4_FSP_1) {
1270 CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
1273 LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)));
1275 /* Default register (sanity function already confirmed the variable value) */
1277 CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
1280 LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)));
1284 static void readsrlongwakeup(const lpddr4_ctlfspnum * fspnum,
1285 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1288 /* Read the appropriate register, based on user given frequency. */
1289 if (*fspnum == LPDDR4_FSP_0) {
1291 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
1294 LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)));
1295 } else if (*fspnum == LPDDR4_FSP_1) {
1297 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
1300 LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)));
1302 /* Default register (sanity function already confirmed the variable value) */
1304 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
1307 LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)));
1311 static void readsrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1312 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1315 /* Read the appropriate register, based on user given frequency. */
1316 if (*fspnum == LPDDR4_FSP_0) {
1318 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1321 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
1322 } else if (*fspnum == LPDDR4_FSP_1) {
1324 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1327 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
1329 /* Default register (sanity function already confirmed the variable value) */
1331 CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1334 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
1338 static void readsrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
1339 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1342 /* Read the appropriate register, based on user given frequency. */
1343 if (*fspnum == LPDDR4_FSP_0) {
1345 CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
1348 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)));
1349 } else if (*fspnum == LPDDR4_FSP_1) {
1351 CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
1354 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)));
1356 /* Default register (sanity function already confirmed the variable value) */
1358 CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
1361 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)));
1365 static void readsrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
1366 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
1369 /* Read the appropriate register, based on user given frequency. */
1370 if (*fspnum == LPDDR4_FSP_0) {
1372 CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
1375 LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)));
1376 } else if (*fspnum == LPDDR4_FSP_1) {
1378 CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
1381 LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)));
1383 /* Default register (sanity function already confirmed the variable value) */
1385 CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
1388 LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)));
1392 static void readsrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1393 lpddr4_ctlregs * ctlregbase,
1397 /* Read the appropriate register, based on user given frequency. */
1398 if (*fspnum == LPDDR4_FSP_0) {
1401 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1404 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
1405 } else if (*fspnum == LPDDR4_FSP_1) {
1408 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1411 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
1413 /* Default register (sanity function already confirmed the variable value) */
1416 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1419 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
1424 static void lpddr4_readlpiwakeuptime(lpddr4_ctlregs * ctlregbase,
1425 const lpddr4_lpiwakeupparam *
1427 const lpddr4_ctlfspnum * fspnum,
1431 /* Iterate through each of the Wake up parameter type */
1432 if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN) {
1433 /* Calling appropriate function for register read */
1434 readpdwakeup(fspnum, ctlregbase, cycles);
1435 } else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN) {
1436 readsrshortwakeup(fspnum, ctlregbase, cycles);
1437 } else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN) {
1438 readsrlongwakeup(fspnum, ctlregbase, cycles);
1439 } else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN) {
1440 readsrlonggatewakeup(fspnum, ctlregbase, cycles);
1441 } else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN) {
1442 readsrdpshortwakeup(fspnum, ctlregbase, cycles);
1443 } else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN) {
1444 readsrdplongwakeup(fspnum, ctlregbase, cycles);
1446 /* Default function (sanity function already confirmed the variable value) */
1447 readsrdplonggatewakeup(fspnum, ctlregbase, cycles);
1451 uint32_t lpddr4_getlpiwakeuptime(const lpddr4_privatedata * pd,
1452 const lpddr4_lpiwakeupparam * lpiwakeupparam,
1453 const lpddr4_ctlfspnum * fspnum,
1457 uint32_t result = 0U;
1459 /* Calling Sanity Function to verify the input variables */
1460 result = lpddr4_getlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
1461 if (result == (uint32_t) CDN_EOK) {
1462 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1463 lpddr4_readlpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
1469 static void writepdwakeup(const lpddr4_ctlfspnum * fspnum,
1470 lpddr4_ctlregs * ctlregbase, const uint32_t * cycles)
1473 uint32_t regval = 0U;
1474 /* Write to appropriate register ,based on user given frequency. */
1475 if (*fspnum == LPDDR4_FSP_0) {
1477 CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
1480 LPDDR4__LPI_PD_WAKEUP_F0__REG)),
1482 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG),
1484 } else if (*fspnum == LPDDR4_FSP_1) {
1486 CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
1489 LPDDR4__LPI_PD_WAKEUP_F1__REG)),
1491 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG),
1494 /* Default register (sanity function already confirmed the variable value) */
1496 CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
1499 LPDDR4__LPI_PD_WAKEUP_F2__REG)),
1501 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG),
1506 static void writesrshortwakeup(const lpddr4_ctlfspnum * fspnum,
1507 lpddr4_ctlregs * ctlregbase,
1508 const uint32_t * cycles)
1511 uint32_t regval = 0U;
1512 /* Write to appropriate register ,based on user given frequency. */
1513 if (*fspnum == LPDDR4_FSP_0) {
1515 CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
1518 LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)),
1521 (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG),
1523 } else if (*fspnum == LPDDR4_FSP_1) {
1525 CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
1528 LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)),
1531 (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG),
1534 /* Default register (sanity function already confirmed the variable value) */
1536 CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
1539 LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)),
1542 (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG),
1547 static void writesrlongwakeup(const lpddr4_ctlfspnum * fspnum,
1548 lpddr4_ctlregs * ctlregbase,
1549 const uint32_t * cycles)
1552 uint32_t regval = 0U;
1553 /* Write to appropriate register ,based on user given frequency. */
1554 if (*fspnum == LPDDR4_FSP_0) {
1556 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
1559 LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)),
1561 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG),
1563 } else if (*fspnum == LPDDR4_FSP_1) {
1565 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
1568 LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)),
1570 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG),
1573 /* Default register (sanity function already confirmed the variable value) */
1575 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
1578 LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)),
1580 CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG),
1585 static void writesrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1586 lpddr4_ctlregs * ctlregbase,
1587 const uint32_t * cycles)
1590 uint32_t regval = 0U;
1591 /* Write to appropriate register ,based on user given frequency. */
1592 if (*fspnum == LPDDR4_FSP_0) {
1594 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1597 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
1601 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG),
1603 } else if (*fspnum == LPDDR4_FSP_1) {
1605 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1608 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
1612 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG),
1615 /* Default register (sanity function already confirmed the variable value) */
1617 CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1620 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
1624 LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG),
1629 static void writesrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
1630 lpddr4_ctlregs * ctlregbase,
1631 const uint32_t * cycles)
1634 uint32_t regval = 0U;
1635 /* Write to appropriate register ,based on user given frequency. */
1636 if (*fspnum == LPDDR4_FSP_0) {
1638 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
1641 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)),
1645 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG), regval);
1646 } else if (*fspnum == LPDDR4_FSP_1) {
1648 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
1651 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)),
1655 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG), regval);
1657 /* Default register (sanity function already confirmed the variable value) */
1659 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
1662 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)),
1666 LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG), regval);
1670 static void writesrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
1671 lpddr4_ctlregs * ctlregbase,
1672 const uint32_t * cycles)
1675 uint32_t regval = 0U;
1676 /* Write to appropriate register ,based on user given frequency. */
1677 if (*fspnum == LPDDR4_FSP_0) {
1679 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
1682 LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)),
1686 LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG), regval);
1687 } else if (*fspnum == LPDDR4_FSP_1) {
1689 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
1692 LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)),
1696 LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG), regval);
1698 /* Default register (sanity function already confirmed the variable value) */
1700 CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
1703 LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)),
1707 LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG), regval);
1711 static void writesrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
1712 lpddr4_ctlregs * ctlregbase,
1713 const uint32_t * cycles)
1716 uint32_t regval = 0U;
1717 /* Write to appropriate register ,based on user given frequency. */
1718 if (*fspnum == LPDDR4_FSP_0) {
1721 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
1724 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
1728 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG),
1730 } else if (*fspnum == LPDDR4_FSP_1) {
1733 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
1736 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
1740 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG),
1743 /* Default register (sanity function already confirmed the variable value) */
1746 (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
1749 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
1753 LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG),
1758 static void lpddr4_writelpiwakeuptime(lpddr4_ctlregs * ctlregbase,
1759 const lpddr4_lpiwakeupparam *
1761 const lpddr4_ctlfspnum * fspnum,
1762 const uint32_t * cycles)
1765 /* Iterate through each of the Wake up parameter type */
1766 if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN) {
1767 /* Calling appropriate function for register write */
1768 writepdwakeup(fspnum, ctlregbase, cycles);
1769 } else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN) {
1770 writesrshortwakeup(fspnum, ctlregbase, cycles);
1771 } else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN) {
1772 writesrlongwakeup(fspnum, ctlregbase, cycles);
1773 } else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN) {
1774 writesrlonggatewakeup(fspnum, ctlregbase, cycles);
1775 } else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN) {
1776 writesrdpshortwakeup(fspnum, ctlregbase, cycles);
1777 } else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN) {
1778 writesrdplongwakeup(fspnum, ctlregbase, cycles);
1780 /* Default function (sanity function already confirmed the variable value) */
1781 writesrdplonggatewakeup(fspnum, ctlregbase, cycles);
1785 uint32_t lpddr4_setlpiwakeuptime(const lpddr4_privatedata * pd,
1786 const lpddr4_lpiwakeupparam * lpiwakeupparam,
1787 const lpddr4_ctlfspnum * fspnum,
1788 const uint32_t * cycles)
1790 uint32_t result = 0U;
1792 /* Calling Sanity Function to verify the input variables */
1793 result = lpddr4_setlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
1794 if (result == (uint32_t) CDN_EOK) {
1795 /* Return if the user given value is higher than the field width */
1796 if (*cycles > NIBBLE_MASK) {
1800 if (result == (uint32_t) CDN_EOK) {
1801 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1802 lpddr4_writelpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
1808 uint32_t lpddr4_geteccenable(const lpddr4_privatedata * pd,
1809 lpddr4_eccenable * eccparam)
1811 uint32_t result = 0U;
1812 uint32_t fldval = 0U;
1814 /* Calling Sanity Function to verify the input variables */
1815 result = lpddr4_geteccenablesf(pd, eccparam);
1816 if (result == (uint32_t) CDN_EOK) {
1817 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1819 /* Reading the ECC_Enable field from the register. */
1821 CPS_FLD_READ(LPDDR4__ECC_ENABLE__FLD,
1824 LPDDR4__ECC_ENABLE__REG)));
1827 *eccparam = LPDDR4_ECC_ERR_DETECT_CORRECT;
1830 *eccparam = LPDDR4_ECC_ERR_DETECT;
1833 *eccparam = LPDDR4_ECC_ENABLED;
1836 /* Default ECC (Sanity function already confirmed the value to be in expected range.) */
1837 *eccparam = LPDDR4_ECC_DISABLED;
1844 uint32_t lpddr4_seteccenable(const lpddr4_privatedata * pd,
1845 const lpddr4_eccenable * eccparam)
1848 uint32_t result = 0U;
1849 uint32_t regval = 0U;
1851 /* Calling Sanity Function to verify the input variables */
1852 result = lpddr4_seteccenablesf(pd, eccparam);
1853 if (result == (uint32_t) CDN_EOK) {
1854 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1856 /* Updating the ECC_Enable field based on the user given value. */
1858 CPS_FLD_WRITE(LPDDR4__ECC_ENABLE__FLD,
1861 LPDDR4__ECC_ENABLE__REG)),
1863 CPS_REG_WRITE(&(ctlregbase->LPDDR4__ECC_ENABLE__REG), regval);
1868 uint32_t lpddr4_getreducmode(const lpddr4_privatedata * pd,
1869 lpddr4_reducmode * mode)
1871 uint32_t result = 0U;
1873 /* Calling Sanity Function to verify the input variables */
1874 result = lpddr4_getreducmodesf(pd, mode);
1875 if (result == (uint32_t) CDN_EOK) {
1876 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1877 /* Read the value of reduc parameter. */
1879 (LPDDR4__REDUC__FLD,
1880 CPS_REG_READ(&(ctlregbase->LPDDR4__REDUC__REG))) == 0U) {
1881 *mode = LPDDR4_REDUC_ON;
1883 *mode = LPDDR4_REDUC_OFF;
1889 uint32_t lpddr4_setreducmode(const lpddr4_privatedata * pd,
1890 const lpddr4_reducmode * mode)
1892 uint32_t result = 0U;
1893 uint32_t regval = 0U;
1895 /* Calling Sanity Function to verify the input variables */
1896 result = lpddr4_setreducmodesf(pd, mode);
1897 if (result == (uint32_t) CDN_EOK) {
1898 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1899 /* Setting to enable Half data path. */
1901 CPS_FLD_WRITE(LPDDR4__REDUC__FLD,
1904 LPDDR4__REDUC__REG)), *mode);
1905 CPS_REG_WRITE(&(ctlregbase->LPDDR4__REDUC__REG), regval);
1910 uint32_t lpddr4_getdbireadmode(const lpddr4_privatedata * pd, bool * on_off)
1913 uint32_t result = 0U;
1915 /* Calling Sanity Function to verify the input variables */
1916 result = lpddr4_getdbireadmodesf(pd, on_off);
1918 if (result == (uint32_t) CDN_EOK) {
1919 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1920 /* Reading the field value from the register. */
1922 (LPDDR4__RD_DBI_EN__FLD,
1923 CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG))) ==
1933 uint32_t lpddr4_getdbiwritemode(const lpddr4_privatedata * pd, bool * on_off)
1936 uint32_t result = 0U;
1938 /* Calling Sanity Function to verify the input variables */
1939 result = lpddr4_getdbireadmodesf(pd, on_off);
1941 if (result == (uint32_t) CDN_EOK) {
1942 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1943 /* Reading the field value from the register. */
1945 (LPDDR4__WR_DBI_EN__FLD,
1946 CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG))) ==
1956 uint32_t lpddr4_setdbimode(const lpddr4_privatedata * pd,
1957 const lpddr4_dbimode * mode)
1960 uint32_t result = 0U;
1961 uint32_t regval = 0U;
1963 /* Calling Sanity Function to verify the input variables */
1964 result = lpddr4_setdbimodesf(pd, mode);
1966 if (result == (uint32_t) CDN_EOK) {
1967 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
1969 /* Updating the appropriate field value based on the user given mode */
1970 if (*mode == LPDDR4_DBI_RD_ON) {
1972 CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
1975 LPDDR4__RD_DBI_EN__REG)),
1977 } else if (*mode == LPDDR4_DBI_RD_OFF) {
1979 CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
1982 LPDDR4__RD_DBI_EN__REG)),
1984 } else if (*mode == LPDDR4_DBI_WR_ON) {
1986 CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
1989 LPDDR4__WR_DBI_EN__REG)),
1992 /* Default field (Sanity function already confirmed the value to be in expected range.) */
1994 CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
1997 LPDDR4__WR_DBI_EN__REG)),
2000 CPS_REG_WRITE(&(ctlregbase->LPDDR4__RD_DBI_EN__REG), regval);
2005 uint32_t lpddr4_getrefreshrate(const lpddr4_privatedata * pd,
2006 const lpddr4_ctlfspnum * fspnum,
2009 uint32_t result = 0U;
2011 /* Calling Sanity Function to verify the input variables */
2012 result = lpddr4_getrefreshratesf(pd, fspnum, cycles);
2014 if (result == (uint32_t) CDN_EOK) {
2015 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2017 /* Selecting the appropriate register for the user requested Frequency */
2021 CPS_FLD_READ(LPDDR4__TREF_F2__FLD,
2024 LPDDR4__TREF_F2__REG)));
2028 CPS_FLD_READ(LPDDR4__TREF_F1__FLD,
2031 LPDDR4__TREF_F1__REG)));
2034 /* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
2036 CPS_FLD_READ(LPDDR4__TREF_F0__FLD,
2039 LPDDR4__TREF_F0__REG)));
2046 uint32_t lpddr4_setrefreshrate(const lpddr4_privatedata * pd,
2047 const lpddr4_ctlfspnum * fspnum,
2048 const uint32_t * cycles)
2050 uint32_t result = 0U;
2051 uint32_t regval = 0U;
2053 /* Calling Sanity Function to verify the input variables */
2054 result = lpddr4_setrefreshratesf(pd, fspnum, cycles);
2056 if (result == (uint32_t) CDN_EOK) {
2057 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2059 /* Selecting the appropriate register for the user requested Frequency */
2063 CPS_FLD_WRITE(LPDDR4__TREF_F2__FLD,
2066 LPDDR4__TREF_F2__REG)),
2068 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F2__REG),
2073 CPS_FLD_WRITE(LPDDR4__TREF_F1__FLD,
2076 LPDDR4__TREF_F1__REG)),
2078 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F1__REG),
2082 /* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
2084 CPS_FLD_WRITE(LPDDR4__TREF_F0__FLD,
2087 LPDDR4__TREF_F0__REG)),
2089 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F0__REG),
2097 uint32_t lpddr4_refreshperchipselect(const lpddr4_privatedata * pd,
2098 const uint32_t trefinterval)
2100 uint32_t result = 0U;
2101 uint32_t regval = 0U;
2103 /* Calling Sanity Function to verify the input variables */
2104 result = lpddr4_refreshperchipselectsf(pd);
2106 if (result == (uint32_t) CDN_EOK) {
2107 lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
2108 /* Setting tref_interval parameter to enable/disable Refresh per chip select. */
2110 CPS_FLD_WRITE(LPDDR4__TREF_INTERVAL__FLD,
2113 LPDDR4__TREF_INTERVAL__REG)),
2115 CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_INTERVAL__REG),