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