// SPDX-License-Identifier: BSD-3-Clause
/******************************************************************************
 * Copyright (C) 2012-2018 Cadence Design Systems, Inc.
 * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
 *
 * lpddr4.c
 *
 *****************************************************************************
 */
#include "cps_drv_lpddr4.h"
#include "lpddr4_ctl_regs.h"
#include "lpddr4_if.h"
#include "lpddr4_private.h"
#include "lpddr4_sanity.h"
#include "lpddr4_structs_if.h"

#define LPDDR4_CUSTOM_TIMEOUT_DELAY 100000000U

/**
 * Internal Function:Poll for status of interrupt received by the Controller.
 * @param[in] pD Driver state info specific to this instance.
 * @param[in] irqBit Interrupt status bit to be checked.
 * @param[in] delay time delay.
 * @return CDN_EOK on success (Interrupt status high).
 * @return EIO on poll time out.
 * @return EINVAL checking status was not successful.
 */
static uint32_t lpddr4_pollctlirq(const lpddr4_privatedata * pd,
				  lpddr4_ctlinterrupt irqbit, uint32_t delay)
{

	uint32_t result = 0U;
	uint32_t timeout = 0U;
	bool irqstatus = false;

	/* Loop until irqStatus found to be 1 or if value of 'result' !=CDN_EOK */
	do {
		if (++timeout == delay) {
			result = EIO;
			break;
		}
		/* cps_delayns(10000000U); */
		result = lpddr4_checkctlinterrupt(pd, irqbit, &irqstatus);
	} while ((irqstatus == false) && (result == (uint32_t) CDN_EOK));

	return result;
}

/**
 * Internal Function:Poll for status of interrupt received by the PHY Independent Module.
 * @param[in] pD Driver state info specific to this instance.
 * @param[in] irqBit Interrupt status bit to be checked.
 * @param[in] delay time delay.
 * @return CDN_EOK on success (Interrupt status high).
 * @return EIO on poll time out.
 * @return EINVAL checking status was not successful.
 */
static uint32_t lpddr4_pollphyindepirq(const lpddr4_privatedata * pd,
				       lpddr4_phyindepinterrupt irqbit,
				       uint32_t delay)
{

	uint32_t result = 0U;
	uint32_t timeout = 0U;
	bool irqstatus = false;

	/* Loop until irqStatus found to be 1 or if value of 'result' !=CDN_EOK */
	do {
		if (++timeout == delay) {
			result = EIO;
			break;
		}
		/* cps_delayns(10000000U); */
		result = lpddr4_checkphyindepinterrupt(pd, irqbit, &irqstatus);
	} while ((irqstatus == false) && (result == (uint32_t) CDN_EOK));

	return result;
}

/**
 * Internal Function:Trigger function to poll and Ack IRQs
 * @param[in] pD Driver state info specific to this instance.
 * @return CDN_EOK on success (Interrupt status high).
 * @return EIO on poll time out.
 * @return EINVAL checking status was not successful.
 */
static uint32_t lpddr4_pollandackirq(const lpddr4_privatedata * pd)
{
	uint32_t result = 0U;

	/* Wait for PhyIndependent module to finish up ctl init sequence */
	result =
	    lpddr4_pollphyindepirq(pd, LPDDR4_PHY_INDEP_INIT_DONE_BIT,
				   LPDDR4_CUSTOM_TIMEOUT_DELAY);

	/* Ack to clear the PhyIndependent interrupt bit */
	if (result == (uint32_t) CDN_EOK) {
		result =
		    lpddr4_ackphyindepinterrupt(pd,
						LPDDR4_PHY_INDEP_INIT_DONE_BIT);
	}
	/* Wait for the CTL end of initialization */
	if (result == (uint32_t) CDN_EOK) {
		result =
		    lpddr4_pollctlirq(pd, LPDDR4_MC_INIT_DONE,
				      LPDDR4_CUSTOM_TIMEOUT_DELAY);
	}
	/* Ack to clear the Ctl interrupt bit */
	if (result == (uint32_t) CDN_EOK) {
		result = lpddr4_ackctlinterrupt(pd, LPDDR4_MC_INIT_DONE);
	}
	return result;
}

/**
 * Internal Function: Controller start sequence.
 * @param[in] pD Driver state info specific to this instance.
 * @return CDN_EOK on success.
 * @return EINVAL starting controller was not successful.
 */
static uint32_t lpddr4_startsequencecontroller(const lpddr4_privatedata * pd)
{
	uint32_t result = 0U;
	uint32_t regval = 0U;
	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
	lpddr4_infotype infotype;

	/* Set the PI_start to initiate leveling procedure */
	regval =
	    CPS_FLD_SET(LPDDR4__PI_START__FLD,
			CPS_REG_READ(&(ctlregbase->LPDDR4__PI_START__REG)));
	CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_START__REG)), regval);

	/* Set the Ctl_start  */
	regval =
	    CPS_FLD_SET(LPDDR4__START__FLD,
			CPS_REG_READ(&(ctlregbase->LPDDR4__START__REG)));
	CPS_REG_WRITE(&(ctlregbase->LPDDR4__START__REG), regval);

	if (pd->infohandler != NULL) {
		/* If a handler is registered, call it with the relevant information type */
		infotype = LPDDR4_DRV_SOC_PLL_UPDATE;
		pd->infohandler(pd, infotype);
	}

	result = lpddr4_pollandackirq(pd);

	return result;
}

/**
 * Internal Function: To add the offset to given address.
 * @param[in] addr Address to which the offset has to be added.
 * @param[in] regOffset The offset
 * @return regAddr The address value after the summation.
 */
static volatile uint32_t *lpddr4_addoffset(volatile uint32_t * addr,
					   uint32_t regoffset)
{

	volatile uint32_t *local_addr = addr;
	/* Declaring as array to add the offset value. */
	volatile uint32_t *regaddr = &local_addr[regoffset];
	return regaddr;
}

/**
 * Checks configuration object.
 * @param[in] config Driver/hardware configuration required.
 * @param[out] configSize Size of memory allocations required.
 * @return CDN_EOK on success (requirements structure filled).
 * @return ENOTSUP if configuration cannot be supported due to driver/hardware constraints.
 */
uint32_t lpddr4_probe(const lpddr4_config * config, uint16_t * configsize)
{
	uint32_t result;

	result = (uint32_t) (lpddr4_probesf(config, configsize));
	if (result == (uint32_t) CDN_EOK) {
		*configsize = (uint16_t) (sizeof(lpddr4_privatedata));
	}
	return result;
}

/**
 * Init function to be called after LPDDR4_probe() to set up the driver configuration.
 * Memory should be allocated for drv_data (using the size determined using LPDDR4_probe) before
 * calling  this API, init_settings should be initialized with base addresses for PHY Independent Module,
 * Controller and PHY before calling this function.
 * If callbacks are required for interrupt handling, these should also be configured in init_settings.
 * @param[in] pD Driver state info specific to this instance.
 * @param[in] cfg Specifies driver/hardware configuration.
 * @return CDN_EOK on success
 * @return EINVAL if illegal/inconsistent values in cfg.
 * @return ENOTSUP if hardware has an inconsistent configuration or doesn't support feature(s)
 * required by 'config' parameters.
 */
uint32_t lpddr4_init(lpddr4_privatedata * pd, const lpddr4_config * cfg)
{
	uint32_t result = 0U;
	uint16_t productid = 0U;
	uint32_t version[2] = { 0, 0 };

	result = lpddr4_initsf(pd, cfg);
	if (result == (uint32_t) CDN_EOK) {
		/* Validate Magic number */
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) cfg->ctlbase;
		productid = (uint16_t) (CPS_FLD_READ(LPDDR4__CONTROLLER_ID__FLD,
						     CPS_REG_READ(&
								  (ctlregbase->
								   LPDDR4__CONTROLLER_ID__REG))));
		version[0] =
		    (uint32_t) (CPS_FLD_READ
				(LPDDR4__CONTROLLER_VERSION_0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__CONTROLLER_VERSION_0__REG))));
		version[1] =
		    (uint32_t) (CPS_FLD_READ
				(LPDDR4__CONTROLLER_VERSION_1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__CONTROLLER_VERSION_1__REG))));
		if ((productid == PRODUCT_ID) && (version[0] == VERSION_0)
		    && (version[1] == VERSION_1)) {
			/* Populating configuration data to pD */
			pd->ctlbase = ctlregbase;
			pd->infohandler =
			    (lpddr4_infocallback) cfg->infohandler;
			pd->ctlinterrupthandler =
			    (lpddr4_ctlcallback) cfg->ctlinterrupthandler;
			pd->phyindepinterrupthandler =
			    (lpddr4_phyindepcallback) cfg->
			    phyindepinterrupthandler;
		} else {
			/* Magic number validation failed - Driver doesn't support given IP version */
			result = (uint32_t) EOPNOTSUPP;
		}
	}
	return result;
}

/**
 * Start the driver.
 * @param[in] pD Driver state info specific to this instance.
 */
uint32_t lpddr4_start(const lpddr4_privatedata * pd)
{
	uint32_t result = 0U;
	uint32_t regval = 0U;

	result = lpddr4_startsf(pd);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Enable PI as the initiator for DRAM */
		regval =
		    CPS_FLD_SET(LPDDR4__PI_INIT_LVL_EN__FLD,
				CPS_REG_READ(&
					     (ctlregbase->
					      LPDDR4__PI_INIT_LVL_EN__REG)));
		regval = CPS_FLD_SET(LPDDR4__PI_NORMAL_LVL_SEQ__FLD, regval);
		CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_INIT_LVL_EN__REG)),
			      regval);

		/* Start PI init sequence. */
		result = lpddr4_startsequencecontroller(pd);
	}
	return result;
}

/**
 * Read a register from the controller, PHY or PHY Independent Module
 * @param[in] pD Driver state info specific to this instance.
 * @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
 * @param[in] regOffset Register offset
 * @param[out] regValue Register value read
 * @return CDN_EOK on success.
 * @return EINVAL if regOffset if out of range or regValue is NULL
 */
uint32_t lpddr4_readreg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
			uint32_t regoffset, uint32_t * regvalue)
{
	uint32_t result = 0U;

	result = lpddr4_readregsf(pd, cpp, regvalue);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		if (cpp == LPDDR4_CTL_REGS) {
			if (regoffset >= LPDDR4_CTL_REG_COUNT) {
				/* Return if user provider invalid register number */
				result = EINVAL;
			} else {
				*regvalue =
				    CPS_REG_READ(lpddr4_addoffset
						 (&(ctlregbase->DENALI_CTL_0),
						  regoffset));
			}
		} else if (cpp == LPDDR4_PHY_REGS) {
			if (regoffset >= LPDDR4_PHY_REG_COUNT) {
				/* Return if user provider invalid register number */
				result = EINVAL;
			} else {
				*regvalue =
				    CPS_REG_READ(lpddr4_addoffset
						 (&(ctlregbase->DENALI_PHY_0),
						  regoffset));
			}

		} else {
			if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
				/* Return if user provider invalid register number */
				result = EINVAL;
			} else {
				*regvalue =
				    CPS_REG_READ(lpddr4_addoffset
						 (&(ctlregbase->DENALI_PI_0),
						  regoffset));
			}
		}
	}
	return result;
}

uint32_t lpddr4_writereg(const lpddr4_privatedata * pd, lpddr4_regblock cpp,
			 uint32_t regoffset, uint32_t regvalue)
{
	uint32_t result = 0U;

	result = lpddr4_writeregsf(pd, cpp);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		if (cpp == LPDDR4_CTL_REGS) {
			if (regoffset >= LPDDR4_CTL_REG_COUNT) {
				/* Return if user provider invalid register number */
				result = EINVAL;
			} else {
				CPS_REG_WRITE(lpddr4_addoffset
					      (&(ctlregbase->DENALI_CTL_0),
					       regoffset), regvalue);
			}
		} else if (cpp == LPDDR4_PHY_REGS) {
			if (regoffset >= LPDDR4_PHY_REG_COUNT) {
				/* Return if user provider invalid register number */
				result = EINVAL;
			} else {
				CPS_REG_WRITE(lpddr4_addoffset
					      (&(ctlregbase->DENALI_PHY_0),
					       regoffset), regvalue);
			}
		} else {
			if (regoffset >= LPDDR4_PHY_INDEP_REG_COUNT) {
				/* Return if user provider invalid register number */
				result = EINVAL;
			} else {
				CPS_REG_WRITE(lpddr4_addoffset
					      (&(ctlregbase->DENALI_PI_0),
					       regoffset), regvalue);
			}
		}
	}

	return result;
}

static uint32_t lpddr4_checkmmrreaderror(const lpddr4_privatedata * pd,
					 uint64_t * mmrvalue,
					 uint8_t * mrrstatus)
{

	uint64_t lowerdata;
	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
	uint32_t result = (uint32_t) CDN_EOK;

	/* Check if mode register read error interrupt occurred */
	if (lpddr4_pollctlirq(pd, LPDDR4_MRR_ERROR, 100) == 0U) {
		/* Mode register read error interrupt, read MRR status register and return. */
		*mrrstatus =
		    (uint8_t) CPS_FLD_READ(LPDDR4__MRR_ERROR_STATUS__FLD,
					   CPS_REG_READ(&
							(ctlregbase->
							 LPDDR4__MRR_ERROR_STATUS__REG)));
		*mmrvalue = 0;
		result = EIO;
	} else {
		*mrrstatus = 0;
		/* Mode register read was successful, read DATA */
		lowerdata =
		    CPS_REG_READ(&
				 (ctlregbase->
				  LPDDR4__PERIPHERAL_MRR_DATA_0__REG));
		*mmrvalue =
		    CPS_REG_READ(&
				 (ctlregbase->
				  LPDDR4__PERIPHERAL_MRR_DATA_1__REG));
		*mmrvalue = (uint64_t) ((*mmrvalue << WORD_SHIFT) | lowerdata);
		/* Acknowledge MR_READ_DONE interrupt to clear it */
		result = lpddr4_ackctlinterrupt(pd, LPDDR4_MR_READ_DONE);
	}
	return result;
}

uint32_t lpddr4_getmmrregister(const lpddr4_privatedata * pd,
			       uint32_t readmoderegval, uint64_t * mmrvalue,
			       uint8_t * mmrstatus)
{

	uint32_t result = 0U;
	uint32_t tdelay = 1000U;
	uint32_t regval = 0U;

	result = lpddr4_getmmrregistersf(pd, mmrvalue, mmrstatus);
	if (result == (uint32_t) CDN_EOK) {

		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Populate the calculated value to the register  */
		regval =
		    CPS_FLD_WRITE(LPDDR4__READ_MODEREG__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__READ_MODEREG__REG)),
				  readmoderegval);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__READ_MODEREG__REG), regval);

		/* Wait until the Read is done */
		result = lpddr4_pollctlirq(pd, LPDDR4_MR_READ_DONE, tdelay);
	}
	if (result == (uint32_t) CDN_EOK) {
		result = lpddr4_checkmmrreaderror(pd, mmrvalue, mmrstatus);
	}
	return result;
}

static uint32_t lpddr4_writemmrregister(const lpddr4_privatedata * pd,
					uint32_t writemoderegval)
{

	uint32_t result = (uint32_t) CDN_EOK;
	uint32_t tdelay = 1000U;
	uint32_t regval = 0U;
	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

	/* Populate the calculated value to the register  */
	regval =
	    CPS_FLD_WRITE(LPDDR4__WRITE_MODEREG__FLD,
			  CPS_REG_READ(&
				       (ctlregbase->
					LPDDR4__WRITE_MODEREG__REG)),
			  writemoderegval);
	CPS_REG_WRITE(&(ctlregbase->LPDDR4__WRITE_MODEREG__REG), regval);

	result = lpddr4_pollctlirq(pd, LPDDR4_MR_WRITE_DONE, tdelay);

	return result;
}

uint32_t lpddr4_setmmrregister(const lpddr4_privatedata * pd,
			       uint32_t writemoderegval, uint8_t * mrwstatus)
{
	uint32_t result = 0U;

	result = lpddr4_setmmrregistersf(pd, mrwstatus);
	if (result == (uint32_t) CDN_EOK) {

		/* Function call to trigger Mode register write */
		result = lpddr4_writemmrregister(pd, writemoderegval);

		if (result == (uint32_t) CDN_EOK) {
			result =
			    lpddr4_ackctlinterrupt(pd, LPDDR4_MR_WRITE_DONE);
		}
		/* Read the status of mode register write */
		if (result == (uint32_t) CDN_EOK) {
			lpddr4_ctlregs *ctlregbase =
			    (lpddr4_ctlregs *) pd->ctlbase;
			*mrwstatus =
			    (uint8_t) CPS_FLD_READ(LPDDR4__MRW_STATUS__FLD,
						   CPS_REG_READ(&
								(ctlregbase->
								 LPDDR4__MRW_STATUS__REG)));
			if ((*mrwstatus) != 0U) {
				result = EIO;
			}
		}
	}

	return result;
}

uint32_t lpddr4_writectlconfig(const lpddr4_privatedata * pd,
			       const lpddr4_reginitdata * regvalues)
{
	uint32_t result;
	uint32_t regnum;

	result = lpddr4_writectlconfigsf(pd, regvalues);
	if (result == (uint32_t) CDN_EOK) {

		/* Iterate through CTL register numbers. */
		for (regnum = 0; regnum < LPDDR4_CTL_REG_COUNT; regnum++) {
			/* Check if the user has requested update */
			if (regvalues->updatectlreg[regnum]) {
				result =
				    lpddr4_writereg(pd, LPDDR4_CTL_REGS, regnum,
						    (uint32_t) (regvalues->
								denalictlreg
								[regnum]));
			}
		}
	}
	return result;
}

uint32_t lpddr4_writephyindepconfig(const lpddr4_privatedata * pd,
				    const lpddr4_reginitdata * regvalues)
{
	uint32_t result;
	uint32_t regnum;

	result = lpddr4_writephyindepconfigsf(pd, regvalues);
	if (result == (uint32_t) CDN_EOK) {

		/* Iterate through PHY Independent module register numbers. */
		for (regnum = 0; regnum < LPDDR4_PHY_INDEP_REG_COUNT; regnum++) {
			/* Check if the user has requested update */
			if (regvalues->updatephyindepreg[regnum]) {
				result =
				    lpddr4_writereg(pd, LPDDR4_PHY_INDEP_REGS,
						    regnum,
						    (uint32_t) (regvalues->
								denaliphyindepreg
								[regnum]));
			}
		}
	}
	return result;
}

uint32_t lpddr4_writephyconfig(const lpddr4_privatedata * pd,
			       const lpddr4_reginitdata * regvalues)
{
	uint32_t result;
	uint32_t regnum;

	result = lpddr4_writephyconfigsf(pd, regvalues);
	if (result == (uint32_t) CDN_EOK) {

		/* Iterate through PHY register numbers. */
		for (regnum = 0; regnum < LPDDR4_PHY_REG_COUNT; regnum++) {
			/* Check if the user has requested update */
			if (regvalues->updatephyreg[regnum]) {
				result =
				    lpddr4_writereg(pd, LPDDR4_PHY_REGS, regnum,
						    (uint32_t) (regvalues->
								denaliphyreg
								[regnum]));
			}
		}
	}
	return result;
}

uint32_t lpddr4_readctlconfig(const lpddr4_privatedata * pd,
			      lpddr4_reginitdata * regvalues)
{
	uint32_t result;
	uint32_t regnum;
	result = lpddr4_readctlconfigsf(pd, regvalues);
	if (result == (uint32_t) CDN_EOK) {
		/* Iterate through CTL register numbers. */
		for (regnum = 0; regnum < LPDDR4_CTL_REG_COUNT; regnum++) {
			/* Check if the user has requested read (updateCtlReg=1) */
			if (regvalues->updatectlreg[regnum]) {
				result =
				    lpddr4_readreg(pd, LPDDR4_CTL_REGS, regnum,
						   (uint32_t *) (&regvalues->
								 denalictlreg
								 [regnum]));
			}
		}
	}
	return result;
}

uint32_t lpddr4_readphyindepconfig(const lpddr4_privatedata * pd,
				   lpddr4_reginitdata * regvalues)
{
	uint32_t result;
	uint32_t regnum;

	result = lpddr4_readphyindepconfigsf(pd, regvalues);
	if (result == (uint32_t) CDN_EOK) {
		/* Iterate through PHY Independent module register numbers. */
		for (regnum = 0; regnum < LPDDR4_PHY_INDEP_REG_COUNT; regnum++) {
			/* Check if the user has requested read (updateCtlReg=1) */
			if (regvalues->updatephyindepreg[regnum]) {
				result =
				    lpddr4_readreg(pd, LPDDR4_PHY_INDEP_REGS,
						   regnum,
						   (uint32_t *) (&regvalues->
								 denaliphyindepreg
								 [regnum]));
			}
		}
	}
	return result;
}

uint32_t lpddr4_readphyconfig(const lpddr4_privatedata * pd,
			      lpddr4_reginitdata * regvalues)
{
	uint32_t result;
	uint32_t regnum;

	result = lpddr4_readphyconfigsf(pd, regvalues);
	if (result == (uint32_t) CDN_EOK) {
		/* Iterate through PHY register numbers. */
		for (regnum = 0; regnum < LPDDR4_PHY_REG_COUNT; regnum++) {
			/* Check if the user has requested read (updateCtlReg=1) */
			if (regvalues->updatephyreg[regnum]) {
				result =
				    lpddr4_readreg(pd, LPDDR4_PHY_REGS, regnum,
						   (uint32_t *) (&regvalues->
								 denaliphyreg
								 [regnum]));
			}
		}
	}
	return result;
}

uint32_t lpddr4_getctlinterruptmask(const lpddr4_privatedata * pd,
				    uint64_t * mask)
{
	uint32_t result = 0U;
	uint64_t lowermask = 0U;

	result = lpddr4_getctlinterruptmasksf(pd, mask);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Reading the lower mask register */
		lowermask =
		    (uint64_t) (CPS_FLD_READ
				(LPDDR4__INT_MASK_0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__INT_MASK_0__REG))));
		/* Reading the upper mask register */
		*mask =
		    (uint64_t) (CPS_FLD_READ
				(LPDDR4__INT_MASK_1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__INT_MASK_1__REG))));
		/* Concatenate both register informations */
		*mask = (uint64_t) ((*mask << WORD_SHIFT) | lowermask);
	}
	return result;
}

uint32_t lpddr4_setctlinterruptmask(const lpddr4_privatedata * pd,
				    const uint64_t * mask)
{
	uint32_t result;
	uint32_t regval = 0;
	const uint64_t ui64one = 1ULL;
	const uint32_t ui32irqcount = (uint32_t) LPDDR4_LOR_BITS + 1U;

	result = lpddr4_setctlinterruptmasksf(pd, mask);
	if ((result == (uint32_t) CDN_EOK) && (ui32irqcount < 64U)) {
		/* Return if the user given value is higher than the field width */
		if (*mask >= (ui64one << ui32irqcount)) {
			result = EINVAL;
		}
	}
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Extracting the lower 32 bits and writing to lower mask register */
		regval = (uint32_t) (*mask & WORD_MASK);
		regval =
		    CPS_FLD_WRITE(LPDDR4__INT_MASK_0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__INT_MASK_0__REG)),
				  regval);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_0__REG), regval);

		/* Extracting the upper 32 bits and writing to upper mask register */
		regval = (uint32_t) ((*mask >> WORD_SHIFT) & WORD_MASK);
		regval =
		    CPS_FLD_WRITE(LPDDR4__INT_MASK_1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__INT_MASK_1__REG)),
				  regval);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_1__REG), regval);
	}
	return result;
}

uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata * pd,
				  lpddr4_ctlinterrupt intr, bool * irqstatus)
{
	uint32_t result;
	uint32_t ctlirqstatus = 0;
	uint32_t fieldshift = 0;

	/* NOTE:This function assume irq status is mentioned in NOT more than 2 registers.
	 * Value of 'interrupt' should be less than 64 */
	result = lpddr4_checkctlinterruptsf(pd, intr, irqstatus);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		if ((uint32_t) intr >= WORD_SHIFT) {
			ctlirqstatus =
			    CPS_REG_READ(&
					 (ctlregbase->
					  LPDDR4__INT_STATUS_1__REG));
			/* Reduce the shift value as we are considering upper register */
			fieldshift = (uint32_t) intr - ((uint32_t) WORD_SHIFT);
		} else {
			ctlirqstatus =
			    CPS_REG_READ(&
					 (ctlregbase->
					  LPDDR4__INT_STATUS_0__REG));
			/* The shift value remains same for lower interrupt register */
			fieldshift = (uint32_t) intr;
		}

		/* MISRA compliance (Shifting operation) check */
		if (fieldshift < WORD_SHIFT) {
			if (((ctlirqstatus >> fieldshift) & BIT_MASK) > 0U) {
				*irqstatus = true;
			} else {
				*irqstatus = false;
			}
		}
	}
	return result;
}

uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata * pd,
				lpddr4_ctlinterrupt intr)
{
	uint32_t result = 0;
	uint32_t regval = 0;
	uint32_t localinterrupt = (uint32_t) intr;

	/* NOTE:This function assume irq status is mentioned in NOT more than 2 registers.
	 * Value of 'interrupt' should be less than 64 */
	result = lpddr4_ackctlinterruptsf(pd, intr);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Check if the requested bit is in upper register */
		if (localinterrupt > WORD_SHIFT) {
			localinterrupt =
			    (localinterrupt - (uint32_t) WORD_SHIFT);
			regval = ((uint32_t) BIT_MASK << localinterrupt);
			CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG),
				      regval);
		} else {
			regval = ((uint32_t) BIT_MASK << localinterrupt);
			CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG),
				      regval);
		}
	}

	return result;
}

uint32_t lpddr4_getphyindepinterruptmask(const lpddr4_privatedata * pd,
					 uint32_t * mask)
{
	uint32_t result;

	result = lpddr4_getphyindepinterruptmsf(pd, mask);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Reading mask register */
		*mask =
		    CPS_FLD_READ(LPDDR4__PI_INT_MASK__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__PI_INT_MASK__REG)));
	}
	return result;
}

uint32_t lpddr4_setphyindepinterruptmask(const lpddr4_privatedata * pd,
					 const uint32_t * mask)
{
	uint32_t result;
	uint32_t regval = 0;
	const uint32_t ui32irqcount =
	    (uint32_t) LPDDR4_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT + 1U;

	result = lpddr4_setphyindepinterruptmsf(pd, mask);
	if ((result == (uint32_t) CDN_EOK) && (ui32irqcount < WORD_SHIFT)) {
		/* Return if the user given value is higher than the field width */
		if (*mask >= (1U << ui32irqcount)) {
			result = EINVAL;
		}
	}
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Writing to the user requested interrupt mask */
		regval =
		    CPS_FLD_WRITE(LPDDR4__PI_INT_MASK__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__PI_INT_MASK__REG)),
				  *mask);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_MASK__REG), regval);
	}
	return result;
}

uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata * pd,
				       lpddr4_phyindepinterrupt intr,
				       bool * irqstatus)
{
	uint32_t result = 0;
	uint32_t phyindepirqstatus = 0;

	result = lpddr4_checkphyindepinterrupsf(pd, intr, irqstatus);
	/* Confirming that the value of interrupt is less than register width */
	if ((result == (uint32_t) CDN_EOK) && ((uint32_t) intr < WORD_SHIFT)) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Reading the requested bit to check interrupt status */
		phyindepirqstatus =
		    CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INT_STATUS__REG));
		*irqstatus =
		    (((phyindepirqstatus >> (uint32_t) intr) & BIT_MASK) > 0U);
	}
	return result;
}

uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata * pd,
				     lpddr4_phyindepinterrupt intr)
{
	uint32_t result = 0U;
	uint32_t regval = 0U;
	uint32_t ui32shiftinterrupt = (uint32_t) intr;

	result = lpddr4_ackphyindepinterruptsf(pd, intr);
	/* Confirming that the value of interrupt is less than register width */
	if ((result == (uint32_t) CDN_EOK) && (ui32shiftinterrupt < WORD_SHIFT)) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Write 1 to the requested bit to ACk the interrupt */
		regval = ((uint32_t) BIT_MASK << ui32shiftinterrupt);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__PI_INT_ACK__REG), regval);
	}

	return result;
}

/* Check for caTrainingError */
static void lpddr4_checkcatrainingerror(lpddr4_ctlregs * ctlregbase,
					lpddr4_debuginfo * debuginfo,
					bool * errfoundptr)
{

	uint32_t regval;
	uint32_t errbitmask = 0U;
	uint32_t snum;
	volatile uint32_t *regaddress;

	regaddress =
	    (volatile uint32_t
	     *)(&(ctlregbase->LPDDR4__PHY_ADR_CALVL_OBS1_0__REG));
	errbitmask = (CA_TRAIN_RL) | (NIBBLE_MASK);
	/* PHY_ADR_CALVL_OBS1[4] – Right found
	   PHY_ADR_CALVL_OBS1[5] – left found
	   both the above fields should be high and below field should be zero.
	   PHY_ADR_CALVL_OBS1[3:0] – calvl_state
	 */
	for (snum = 0U; snum < ASLICE_NUM; snum++) {
		regval = CPS_REG_READ(regaddress);
		if ((regval & errbitmask) != CA_TRAIN_RL) {
			debuginfo->catraingerror = true;
			*errfoundptr = true;
		}
		regaddress =
		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
	}
}

/* Check for  wrLvlError */
static void lpddr4_checkwrlvlerror(lpddr4_ctlregs * ctlregbase,
				   lpddr4_debuginfo * debuginfo,
				   bool * errfoundptr)
{

	uint32_t regval;
	uint32_t errbitmask = 0U;
	uint32_t snum;
	volatile uint32_t *regaddress;

	regaddress =
	    (volatile uint32_t
	     *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG));
	/* PHY_WRLVL_ERROR_OBS_X[1:0] should be zero */
	errbitmask = (BIT_MASK << 1) | (BIT_MASK);
	for (snum = 0U; snum < DSLICE_NUM; snum++) {
		regval = CPS_REG_READ(regaddress);
		if ((regval & errbitmask) != 0U) {
			debuginfo->wrlvlerror = true;
			*errfoundptr = true;
		}
		regaddress =
		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
	}
}

/* Check for  GateLvlError */
static void lpddr4_checkgatelvlerror(lpddr4_ctlregs * ctlregbase,
				     lpddr4_debuginfo * debuginfo,
				     bool * errfoundptr)
{

	uint32_t regval;
	uint32_t errbitmask = 0U;
	uint32_t snum;
	volatile uint32_t *regaddress;

	regaddress =
	    (volatile uint32_t
	     *)(&(ctlregbase->LPDDR4__PHY_GTLVL_STATUS_OBS_0__REG));
	/* PHY_GTLVL_STATUS_OBS[6] – gate_level min error
	 * PHY_GTLVL_STATUS_OBS[7] – gate_level max error
	 * All the above bit fields should be zero */
	errbitmask = GATE_LVL_ERROR_FIELDS;
	for (snum = 0U; snum < DSLICE_NUM; snum++) {
		regval = CPS_REG_READ(regaddress);
		if ((regval & errbitmask) != 0U) {
			debuginfo->gatelvlerror = true;
			*errfoundptr = true;
		}
		regaddress =
		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
	}
}

/* Check for  ReadLvlError */
static void lpddr4_checkreadlvlerror(lpddr4_ctlregs * ctlregbase,
				     lpddr4_debuginfo * debuginfo,
				     bool * errfoundptr)
{

	uint32_t regval;
	uint32_t errbitmask = 0U;
	uint32_t snum;
	volatile uint32_t *regaddress;

	regaddress =
	    (volatile uint32_t
	     *)(&(ctlregbase->LPDDR4__PHY_RDLVL_STATUS_OBS_0__REG));
	/* PHY_RDLVL_STATUS_OBS[23:16] – failed bits : should be zero.
	   PHY_RDLVL_STATUS_OBS[31:28] – rdlvl_state : should be zero */
	errbitmask = READ_LVL_ERROR_FIELDS;
	for (snum = 0U; snum < DSLICE_NUM; snum++) {
		regval = CPS_REG_READ(regaddress);
		if ((regval & errbitmask) != 0U) {
			debuginfo->readlvlerror = true;
			*errfoundptr = true;
		}
		regaddress =
		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
	}
}

/* Check for  DqTrainingError */
static void lpddr4_checkdqtrainingerror(lpddr4_ctlregs * ctlregbase,
					lpddr4_debuginfo * debuginfo,
					bool * errfoundptr)
{

	uint32_t regval;
	uint32_t errbitmask = 0U;
	uint32_t snum;
	volatile uint32_t *regaddress;

	regaddress =
	    (volatile uint32_t
	     *)(&(ctlregbase->LPDDR4__PHY_WDQLVL_STATUS_OBS_0__REG));
	/* PHY_WDQLVL_STATUS_OBS[26:18] should all be zero. */
	errbitmask = DQ_LVL_STATUS;
	for (snum = 0U; snum < DSLICE_NUM; snum++) {
		regval = CPS_REG_READ(regaddress);
		if ((regval & errbitmask) != 0U) {
			debuginfo->dqtrainingerror = true;
			*errfoundptr = true;
		}
		regaddress =
		    lpddr4_addoffset(regaddress, (uint32_t) SLICE_WIDTH);
	}
}

/**
 * Internal Function:For checking errors in training/levelling sequence.
 * @param[in] pD Driver state info specific to this instance.
 * @param[in] debugInfo pointer to debug information.
 * @param[out] errFoundPtr pointer to return if error found.
 * @return CDN_EOK on success (Interrupt status high).
 * @return EINVAL checking or unmasking was not successful.
 */
static bool lpddr4_checklvlerrors(const lpddr4_privatedata * pd,
				  lpddr4_debuginfo * debuginfo, bool errfound)
{

	bool localerrfound = errfound;

	lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

	if (localerrfound == false) {
		/* Check for ca training error */
		lpddr4_checkcatrainingerror(ctlregbase, debuginfo,
					    &localerrfound);
	}

	if (localerrfound == false) {
		/* Check for Write leveling error */
		lpddr4_checkwrlvlerror(ctlregbase, debuginfo, &localerrfound);
	}

	if (localerrfound == false) {
		/* Check for Gate leveling error */
		lpddr4_checkgatelvlerror(ctlregbase, debuginfo, &localerrfound);
	}

	if (localerrfound == false) {
		/* Check for Read leveling error */
		lpddr4_checkreadlvlerror(ctlregbase, debuginfo, &localerrfound);
	}

	if (localerrfound == false) {
		/* Check for DQ training error */
		lpddr4_checkdqtrainingerror(ctlregbase, debuginfo,
					    &localerrfound);
	}
	return localerrfound;
}

static bool lpddr4_seterror(volatile uint32_t * reg, uint32_t errbitmask,
			    bool * errfoundptr, const uint32_t errorinfobits)
{

	uint32_t regval = 0U;

	/* Read the respective observation register */
	regval = CPS_REG_READ(reg);
	/* Compare the error bit values */
	if ((regval & errbitmask) != errorinfobits) {
		*errfoundptr = true;
	}
	return *errfoundptr;
}

static void lpddr4_seterrors(lpddr4_ctlregs * ctlregbase,
			     lpddr4_debuginfo * debuginfo, bool * errfoundptr)
{

	uint32_t errbitmask = (BIT_MASK << 0x1U) | (BIT_MASK);
	/* Check PLL observation registers for PLL lock errors */

	debuginfo->pllerror =
	    lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_0__REG),
			    errbitmask, errfoundptr, PLL_READY);
	if (*errfoundptr == false) {
		debuginfo->pllerror =
		    lpddr4_seterror(&(ctlregbase->LPDDR4__PHY_PLL_OBS_1__REG),
				    errbitmask, errfoundptr, PLL_READY);
	}

	/* Check for IO Calibration errors */
	if (*errfoundptr == false) {
		debuginfo->iocaliberror =
		    lpddr4_seterror(&
				    (ctlregbase->
				     LPDDR4__PHY_CAL_RESULT_OBS_0__REG),
				    IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
	}
	if (*errfoundptr == false) {
		debuginfo->iocaliberror =
		    lpddr4_seterror(&
				    (ctlregbase->
				     LPDDR4__PHY_CAL_RESULT2_OBS_0__REG),
				    IO_CALIB_DONE, errfoundptr, IO_CALIB_DONE);
	}
	if (*errfoundptr == false) {
		debuginfo->iocaliberror =
		    lpddr4_seterror(&
				    (ctlregbase->
				     LPDDR4__PHY_CAL_RESULT3_OBS_0__REG),
				    IO_CALIB_FIELD, errfoundptr,
				    IO_CALIB_STATE);
	}
}

static void lpddr4_setphysnapsettings(lpddr4_ctlregs * ctlregbase,
				      const bool errorfound)
{

	uint32_t snum = 0U;
	volatile uint32_t *regaddress;
	uint32_t regval = 0U;

	/* Setting SC_PHY_SNAP_OBS_REGS_x to get a snapshot */
	if (errorfound == false) {
		regaddress =
		    (volatile uint32_t
		     *)(&(ctlregbase->LPDDR4__SC_PHY_SNAP_OBS_REGS_0__REG));
		/* Iterate through each PHY Data Slice */
		for (snum = 0U; snum < DSLICE_NUM; snum++) {
			regval =
			    CPS_FLD_SET(LPDDR4__SC_PHY_SNAP_OBS_REGS_0__FLD,
					CPS_REG_READ(regaddress));
			CPS_REG_WRITE(regaddress, regval);
			regaddress =
			    lpddr4_addoffset(regaddress,
					     (uint32_t) SLICE_WIDTH);
		}
	}
}

static void lpddr4_setphyadrsnapsettings(lpddr4_ctlregs * ctlregbase,
					 const bool errorfound)
{

	uint32_t snum = 0U;
	volatile uint32_t *regaddress;
	uint32_t regval = 0U;

	/* Setting SC_PHY ADR_SNAP_OBS_REGS_x to get a snapshot */
	if (errorfound == false) {
		regaddress =
		    (volatile uint32_t
		     *)(&(ctlregbase->LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__REG));
		/* Iterate through each PHY Address Slice */
		for (snum = 0U; snum < ASLICE_NUM; snum++) {
			regval =
			    CPS_FLD_SET(LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__FLD,
					CPS_REG_READ(regaddress));
			CPS_REG_WRITE(regaddress, regval);
			regaddress =
			    lpddr4_addoffset(regaddress,
					     (uint32_t) SLICE_WIDTH);
		}
	}
}

static void lpddr4_setsettings(lpddr4_ctlregs * ctlregbase,
			       const bool errorfound)
{

	/* Calling functions to enable snap shots of OBS registers */
	lpddr4_setphysnapsettings(ctlregbase, errorfound);
	lpddr4_setphyadrsnapsettings(ctlregbase, errorfound);
}

static void lpddr4_setrxoffseterror(lpddr4_ctlregs * ctlregbase,
				    lpddr4_debuginfo * debuginfo,
				    bool * errorfound)
{

	volatile uint32_t *regaddress;
	uint32_t snum = 0U;
	uint32_t errbitmask = 0U;
	uint32_t regval = 0U;

	/* Check for rxOffsetError */
	if (*errorfound == false) {
		regaddress =
		    (volatile uint32_t
		     *)(&(ctlregbase->LPDDR4__PHY_RX_CAL_LOCK_OBS_0__REG));
		errbitmask = (RX_CAL_DONE) | (NIBBLE_MASK);
		/* PHY_RX_CAL_LOCK_OBS_x[4] – RX_CAL_DONE : should be high
		   phy_rx_cal_lock_obs_x[3:0] – RX_CAL_STATE : should be zero. */
		for (snum = 0U; snum < DSLICE_NUM; snum++) {
			regval =
			    CPS_FLD_READ(LPDDR4__PHY_RX_CAL_LOCK_OBS_0__FLD,
					 CPS_REG_READ(regaddress));
			if ((regval & errbitmask) != RX_CAL_DONE) {
				debuginfo->rxoffseterror = true;
				*errorfound = true;
			}
			regaddress =
			    lpddr4_addoffset(regaddress,
					     (uint32_t) SLICE_WIDTH);
		}
	}
}

uint32_t lpddr4_getdebuginitinfo(const lpddr4_privatedata * pd,
				 lpddr4_debuginfo * debuginfo)
{

	uint32_t result = 0U;
	bool errorfound = false;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_getdebuginitinfosf(pd, debuginfo);
	if (result == (uint32_t) CDN_EOK) {

		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		lpddr4_seterrors(ctlregbase, debuginfo, &errorfound);
		/* Function to setup Snap for OBS registers */
		lpddr4_setsettings(ctlregbase, errorfound);
		/* Function to check for Rx offset error */
		lpddr4_setrxoffseterror(ctlregbase, debuginfo, &errorfound);
		/* Function Check various levelling errors */
		errorfound = lpddr4_checklvlerrors(pd, debuginfo, errorfound);
	}

	if (errorfound == true) {
		result = (uint32_t) EPROTO;
	}

	return result;
}

static void readpdwakeup(const lpddr4_ctlfspnum * fspnum,
			 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_PD_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_PD_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_PD_WAKEUP_F2__REG)));
	}
}

static void readsrshortwakeup(const lpddr4_ctlfspnum * fspnum,
			      lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)));
	}
}

static void readsrlongwakeup(const lpddr4_ctlfspnum * fspnum,
			     lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)));
	}
}

static void readsrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
				 lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
	}
}

static void readsrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
				lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)));
	}
}

static void readsrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
			       lpddr4_ctlregs * ctlregbase, uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)));
	}
}

static void readsrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
				   lpddr4_ctlregs * ctlregbase,
				   uint32_t * cycles)
{

	/* Read the appropriate register, based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		*cycles =
		    CPS_FLD_READ
		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
		     CPS_REG_READ(&
				  (ctlregbase->
				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)));
	} else if (*fspnum == LPDDR4_FSP_1) {
		*cycles =
		    CPS_FLD_READ
		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
		     CPS_REG_READ(&
				  (ctlregbase->
				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)));
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		*cycles =
		    CPS_FLD_READ
		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
		     CPS_REG_READ(&
				  (ctlregbase->
				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)));
	}

}

static void lpddr4_readlpiwakeuptime(lpddr4_ctlregs * ctlregbase,
				     const lpddr4_lpiwakeupparam *
				     lpiwakeupparam,
				     const lpddr4_ctlfspnum * fspnum,
				     uint32_t * cycles)
{

	/* Iterate through each of the Wake up parameter type */
	if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN) {
		/* Calling appropriate function for register read */
		readpdwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN) {
		readsrshortwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN) {
		readsrlongwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN) {
		readsrlonggatewakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN) {
		readsrdpshortwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN) {
		readsrdplongwakeup(fspnum, ctlregbase, cycles);
	} else {
		/* Default function (sanity function already confirmed the variable value) */
		readsrdplonggatewakeup(fspnum, ctlregbase, cycles);
	}
}

uint32_t lpddr4_getlpiwakeuptime(const lpddr4_privatedata * pd,
				 const lpddr4_lpiwakeupparam * lpiwakeupparam,
				 const lpddr4_ctlfspnum * fspnum,
				 uint32_t * cycles)
{

	uint32_t result = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_getlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		lpddr4_readlpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
					 cycles);
	}
	return result;
}

static void writepdwakeup(const lpddr4_ctlfspnum * fspnum,
			  lpddr4_ctlregs * ctlregbase, const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_PD_WAKEUP_F0__REG)),
				  *cycles);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F0__REG),
			      regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_PD_WAKEUP_F1__REG)),
				  *cycles);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F1__REG),
			      regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_PD_WAKEUP_F2__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_PD_WAKEUP_F2__REG)),
				  *cycles);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_PD_WAKEUP_F2__REG),
			      regval);
	}
}

static void writesrshortwakeup(const lpddr4_ctlfspnum * fspnum,
			       lpddr4_ctlregs * ctlregbase,
			       const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F0__REG),
			      regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F1__REG),
			      regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_SHORT_WAKEUP_F2__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->LPDDR4__LPI_SR_SHORT_WAKEUP_F2__REG),
			      regval);
	}
}

static void writesrlongwakeup(const lpddr4_ctlfspnum * fspnum,
			      lpddr4_ctlregs * ctlregbase,
			      const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG)),
				  *cycles);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F0__REG),
			      regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG)),
				  *cycles);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F1__REG),
			      regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_WAKEUP_F2__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG)),
				  *cycles);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__LPI_SR_LONG_WAKEUP_F2__REG),
			      regval);
	}
}

static void writesrlonggatewakeup(const lpddr4_ctlfspnum * fspnum,
				  lpddr4_ctlregs * ctlregbase,
				  const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F0__REG),
			      regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F1__REG),
			      regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SR_LONG_MCCLK_GATE_WAKEUP_F2__REG),
			      regval);
	}
}

static void writesrdpshortwakeup(const lpddr4_ctlfspnum * fspnum,
				 lpddr4_ctlregs * ctlregbase,
				 const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F0__REG), regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F1__REG), regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_SHORT_WAKEUP_F2__REG), regval);
	}
}

static void writesrdplongwakeup(const lpddr4_ctlfspnum * fspnum,
				lpddr4_ctlregs * ctlregbase,
				const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_LONG_WAKEUP_F0__REG), regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_LONG_WAKEUP_F1__REG), regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE(LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG)),
				  *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_LONG_WAKEUP_F2__REG), regval);
	}
}

static void writesrdplonggatewakeup(const lpddr4_ctlfspnum * fspnum,
				    lpddr4_ctlregs * ctlregbase,
				    const uint32_t * cycles)
{

	uint32_t regval = 0U;
	/* Write to appropriate register ,based on user given frequency. */
	if (*fspnum == LPDDR4_FSP_0) {
		regval =
		    CPS_FLD_WRITE
		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__FLD,
		     CPS_REG_READ(&
				  (ctlregbase->
				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG)),
		     *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F0__REG),
			      regval);
	} else if (*fspnum == LPDDR4_FSP_1) {
		regval =
		    CPS_FLD_WRITE
		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__FLD,
		     CPS_REG_READ(&
				  (ctlregbase->
				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG)),
		     *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F1__REG),
			      regval);
	} else {
		/* Default register (sanity function already confirmed the variable value) */
		regval =
		    CPS_FLD_WRITE
		    (LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__FLD,
		     CPS_REG_READ(&
				  (ctlregbase->
				   LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG)),
		     *cycles);
		CPS_REG_WRITE(&
			      (ctlregbase->
			       LPDDR4__LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_F2__REG),
			      regval);
	}
}

static void lpddr4_writelpiwakeuptime(lpddr4_ctlregs * ctlregbase,
				      const lpddr4_lpiwakeupparam *
				      lpiwakeupparam,
				      const lpddr4_ctlfspnum * fspnum,
				      const uint32_t * cycles)
{

	/* Iterate through each of the Wake up parameter type */
	if (*lpiwakeupparam == LPDDR4_LPI_PD_WAKEUP_FN) {
		/* Calling appropriate function for register write */
		writepdwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_SHORT_WAKEUP_FN) {
		writesrshortwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_WAKEUP_FN) {
		writesrlongwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN) {
		writesrlonggatewakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN) {
		writesrdpshortwakeup(fspnum, ctlregbase, cycles);
	} else if (*lpiwakeupparam == LPDDR4_LPI_SRPD_LONG_WAKEUP_FN) {
		writesrdplongwakeup(fspnum, ctlregbase, cycles);
	} else {
		/* Default function (sanity function already confirmed the variable value) */
		writesrdplonggatewakeup(fspnum, ctlregbase, cycles);
	}
}

uint32_t lpddr4_setlpiwakeuptime(const lpddr4_privatedata * pd,
				 const lpddr4_lpiwakeupparam * lpiwakeupparam,
				 const lpddr4_ctlfspnum * fspnum,
				 const uint32_t * cycles)
{
	uint32_t result = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_setlpiwakeuptimesf(pd, lpiwakeupparam, fspnum, cycles);
	if (result == (uint32_t) CDN_EOK) {
		/* Return if the user given value is higher than the field width */
		if (*cycles > NIBBLE_MASK) {
			result = EINVAL;
		}
	}
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		lpddr4_writelpiwakeuptime(ctlregbase, lpiwakeupparam, fspnum,
					  cycles);
	}
	return result;
}

uint32_t lpddr4_geteccenable(const lpddr4_privatedata * pd,
			     lpddr4_eccenable * eccparam)
{
	uint32_t result = 0U;
	uint32_t fldval = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_geteccenablesf(pd, eccparam);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Reading the ECC_Enable field  from the register. */
		fldval =
		    CPS_FLD_READ(LPDDR4__ECC_ENABLE__FLD,
				 CPS_REG_READ(&
					      (ctlregbase->
					       LPDDR4__ECC_ENABLE__REG)));
		switch (fldval) {
		case 3:
			*eccparam = LPDDR4_ECC_ERR_DETECT_CORRECT;
			break;
		case 2:
			*eccparam = LPDDR4_ECC_ERR_DETECT;
			break;
		case 1:
			*eccparam = LPDDR4_ECC_ENABLED;
			break;
		default:
			/* Default ECC (Sanity function already confirmed the value to be in expected range.) */
			*eccparam = LPDDR4_ECC_DISABLED;
			break;
		}
	}
	return result;
}

uint32_t lpddr4_seteccenable(const lpddr4_privatedata * pd,
			     const lpddr4_eccenable * eccparam)
{

	uint32_t result = 0U;
	uint32_t regval = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_seteccenablesf(pd, eccparam);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Updating the ECC_Enable field based on the user given value. */
		regval =
		    CPS_FLD_WRITE(LPDDR4__ECC_ENABLE__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__ECC_ENABLE__REG)),
				  *eccparam);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__ECC_ENABLE__REG), regval);
	}
	return result;
}

uint32_t lpddr4_getreducmode(const lpddr4_privatedata * pd,
			     lpddr4_reducmode * mode)
{
	uint32_t result = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_getreducmodesf(pd, mode);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Read the value of reduc parameter. */
		if (CPS_FLD_READ
		    (LPDDR4__REDUC__FLD,
		     CPS_REG_READ(&(ctlregbase->LPDDR4__REDUC__REG))) == 0U) {
			*mode = LPDDR4_REDUC_ON;
		} else {
			*mode = LPDDR4_REDUC_OFF;
		}
	}
	return result;
}

uint32_t lpddr4_setreducmode(const lpddr4_privatedata * pd,
			     const lpddr4_reducmode * mode)
{
	uint32_t result = 0U;
	uint32_t regval = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_setreducmodesf(pd, mode);
	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Setting to enable Half data path. */
		regval =
		    CPS_FLD_WRITE(LPDDR4__REDUC__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__REDUC__REG)), *mode);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__REDUC__REG), regval);
	}
	return result;
}

uint32_t lpddr4_getdbireadmode(const lpddr4_privatedata * pd, bool * on_off)
{

	uint32_t result = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_getdbireadmodesf(pd, on_off);

	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Reading the field value from the register. */
		if (CPS_FLD_READ
		    (LPDDR4__RD_DBI_EN__FLD,
		     CPS_REG_READ(&(ctlregbase->LPDDR4__RD_DBI_EN__REG))) ==
		    0U) {
			*on_off = false;
		} else {
			*on_off = true;
		}
	}
	return result;
}

uint32_t lpddr4_getdbiwritemode(const lpddr4_privatedata * pd, bool * on_off)
{

	uint32_t result = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_getdbireadmodesf(pd, on_off);

	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Reading the field value from the register. */
		if (CPS_FLD_READ
		    (LPDDR4__WR_DBI_EN__FLD,
		     CPS_REG_READ(&(ctlregbase->LPDDR4__WR_DBI_EN__REG))) ==
		    0U) {
			*on_off = false;
		} else {
			*on_off = true;
		}
	}
	return result;
}

uint32_t lpddr4_setdbimode(const lpddr4_privatedata * pd,
			   const lpddr4_dbimode * mode)
{

	uint32_t result = 0U;
	uint32_t regval = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_setdbimodesf(pd, mode);

	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Updating the appropriate field value based on the user given mode */
		if (*mode == LPDDR4_DBI_RD_ON) {
			regval =
			    CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__RD_DBI_EN__REG)),
					  1U);
		} else if (*mode == LPDDR4_DBI_RD_OFF) {
			regval =
			    CPS_FLD_WRITE(LPDDR4__RD_DBI_EN__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__RD_DBI_EN__REG)),
					  0U);
		} else if (*mode == LPDDR4_DBI_WR_ON) {
			regval =
			    CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__WR_DBI_EN__REG)),
					  1U);
		} else {
			/* Default field (Sanity function already confirmed the value to be in expected range.) */
			regval =
			    CPS_FLD_WRITE(LPDDR4__WR_DBI_EN__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__WR_DBI_EN__REG)),
					  0U);
		}
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__RD_DBI_EN__REG), regval);
	}
	return result;
}

uint32_t lpddr4_getrefreshrate(const lpddr4_privatedata * pd,
			       const lpddr4_ctlfspnum * fspnum,
			       uint32_t * cycles)
{
	uint32_t result = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_getrefreshratesf(pd, fspnum, cycles);

	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Selecting the appropriate register for the user requested Frequency */
		switch (*fspnum) {
		case LPDDR4_FSP_2:
			*cycles =
			    CPS_FLD_READ(LPDDR4__TREF_F2__FLD,
					 CPS_REG_READ(&
						      (ctlregbase->
						       LPDDR4__TREF_F2__REG)));
			break;
		case LPDDR4_FSP_1:
			*cycles =
			    CPS_FLD_READ(LPDDR4__TREF_F1__FLD,
					 CPS_REG_READ(&
						      (ctlregbase->
						       LPDDR4__TREF_F1__REG)));
			break;
		default:
			/* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
			*cycles =
			    CPS_FLD_READ(LPDDR4__TREF_F0__FLD,
					 CPS_REG_READ(&
						      (ctlregbase->
						       LPDDR4__TREF_F0__REG)));
			break;
		}
	}
	return result;
}

uint32_t lpddr4_setrefreshrate(const lpddr4_privatedata * pd,
			       const lpddr4_ctlfspnum * fspnum,
			       const uint32_t * cycles)
{
	uint32_t result = 0U;
	uint32_t regval = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_setrefreshratesf(pd, fspnum, cycles);

	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;

		/* Selecting the appropriate register for the user requested Frequency */
		switch (*fspnum) {
		case LPDDR4_FSP_2:
			regval =
			    CPS_FLD_WRITE(LPDDR4__TREF_F2__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__TREF_F2__REG)),
					  *cycles);
			CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F2__REG),
				      regval);
			break;
		case LPDDR4_FSP_1:
			regval =
			    CPS_FLD_WRITE(LPDDR4__TREF_F1__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__TREF_F1__REG)),
					  *cycles);
			CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F1__REG),
				      regval);
			break;
		default:
			/* FSP_0 is considered as the default (sanity check already confirmed it as valid FSP) */
			regval =
			    CPS_FLD_WRITE(LPDDR4__TREF_F0__FLD,
					  CPS_REG_READ(&
						       (ctlregbase->
							LPDDR4__TREF_F0__REG)),
					  *cycles);
			CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_F0__REG),
				      regval);
			break;
		}
	}
	return result;
}

uint32_t lpddr4_refreshperchipselect(const lpddr4_privatedata * pd,
				     const uint32_t trefinterval)
{
	uint32_t result = 0U;
	uint32_t regval = 0U;

	/* Calling Sanity Function to verify the input variables */
	result = lpddr4_refreshperchipselectsf(pd);

	if (result == (uint32_t) CDN_EOK) {
		lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *) pd->ctlbase;
		/* Setting tref_interval parameter to enable/disable Refresh per chip select. */
		regval =
		    CPS_FLD_WRITE(LPDDR4__TREF_INTERVAL__FLD,
				  CPS_REG_READ(&
					       (ctlregbase->
						LPDDR4__TREF_INTERVAL__REG)),
				  trefinterval);
		CPS_REG_WRITE(&(ctlregbase->LPDDR4__TREF_INTERVAL__REG),
			      regval);
	}
	return result;
}
