/*
 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <debug.h>
#include <arch_helpers.h>
#include <platform_def.h>
#include <plat_private.h>
#include <dram.h>
#include <pmu_regs.h>
#include <rk3399_def.h>
#include <soc.h>
#include <suspend.h>

#define PMUGRF_OS_REG0			0x300
#define PMUGRF_OS_REG1			0x304
#define PMUGRF_OS_REG2			0x308
#define PMUGRF_OS_REG3			0x30c

#define CRU_SFTRST_DDR_CTRL(ch, n)	((0x1 << (8 + 16 + (ch) * 4)) | \
					 ((n) << (8 + (ch) * 4)))
#define CRU_SFTRST_DDR_PHY(ch, n)	((0x1 << (9 + 16 + (ch) * 4)) | \
					 ((n) << (9 + (ch) * 4)))

#define FBDIV_ENC(n)			((n) << 16)
#define FBDIV_DEC(n)			(((n) >> 16) & 0xfff)
#define POSTDIV2_ENC(n)			((n) << 12)
#define POSTDIV2_DEC(n)			(((n) >> 12) & 0x7)
#define POSTDIV1_ENC(n)			((n) << 8)
#define POSTDIV1_DEC(n)			(((n) >> 8) & 0x7)
#define REFDIV_ENC(n)			(n)
#define REFDIV_DEC(n)			((n) & 0x3f)

/* PMU CRU */
#define PMUCRU_RSTNHOLD_CON0		0x120
#define PMUCRU_RSTNHOLD_CON1		0x124

#define PRESET_GPIO0_HOLD(n)		(((n) << 7) | WMSK_BIT(7))
#define PRESET_GPIO1_HOLD(n)		(((n) << 8) | WMSK_BIT(8))

#define SYS_COUNTER_FREQ_IN_MHZ		(SYS_COUNTER_FREQ_IN_TICKS / 1000000)

/*
 * Copy @num registers from @src to @dst
 */
__sramfunc void sram_regcpy(uintptr_t dst, uintptr_t src, uint32_t num)
{
	while (num--) {
		mmio_write_32(dst, mmio_read_32(src));
		dst += sizeof(uint32_t);
		src += sizeof(uint32_t);
	}
}

static __sramfunc uint32_t sram_get_timer_value(void)
{
	/*
	 * Generic delay timer implementation expects the timer to be a down
	 * counter. We apply bitwise NOT operator to the tick values returned
	 * by read_cntpct_el0() to simulate the down counter.
	 */
	return (uint32_t)(~read_cntpct_el0());
}

static __sramfunc void sram_udelay(uint32_t usec)
{
	uint32_t start, cnt, delta, delta_us;

	/* counter is decreasing */
	start = sram_get_timer_value();
	do {
		cnt = sram_get_timer_value();
		if (cnt > start) {
			delta = UINT32_MAX - cnt;
			delta += start;
		} else
			delta = start - cnt;
		delta_us = (delta * SYS_COUNTER_FREQ_IN_MHZ);
	} while (delta_us < usec);
}

static __sramfunc void configure_sgrf(void)
{
	/*
	 * SGRF_DDR_RGN_DPLL_CLK and SGRF_DDR_RGN_RTC_CLK:
	 * IC ECO bug, need to set this register.
	 *
	 * SGRF_DDR_RGN_BYPS:
	 * After the PD_CENTER suspend/resume, the DDR region
	 * related registers in the SGRF will be reset, we
	 * need to re-initialize them.
	 */
	mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
		      SGRF_DDR_RGN_DPLL_CLK |
		      SGRF_DDR_RGN_RTC_CLK |
		      SGRF_DDR_RGN_BYPS);
}

static __sramfunc void rkclk_ddr_reset(uint32_t channel, uint32_t ctl,
		uint32_t phy)
{
	channel &= 0x1;
	ctl &= 0x1;
	phy &= 0x1;
	mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(4),
		      CRU_SFTRST_DDR_CTRL(channel, ctl) |
		      CRU_SFTRST_DDR_PHY(channel, phy));
}

static __sramfunc void phy_pctrl_reset(uint32_t ch)
{
	rkclk_ddr_reset(ch, 1, 1);
	sram_udelay(10);
	rkclk_ddr_reset(ch, 1, 0);
	sram_udelay(10);
	rkclk_ddr_reset(ch, 0, 0);
	sram_udelay(10);
}

static __sramfunc void phy_dll_bypass_set(uint32_t ch, uint32_t hz)
{
	if (hz <= 125 * MHz) {
		/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
		mmio_setbits_32(PHY_REG(ch, 86), (0x3 << 2) << 8);
		mmio_setbits_32(PHY_REG(ch, 214), (0x3 << 2) << 8);
		mmio_setbits_32(PHY_REG(ch, 342), (0x3 << 2) << 8);
		mmio_setbits_32(PHY_REG(ch, 470), (0x3 << 2) << 8);
		/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
		mmio_setbits_32(PHY_REG(ch, 547), (0x3 << 2) << 16);
		mmio_setbits_32(PHY_REG(ch, 675), (0x3 << 2) << 16);
		mmio_setbits_32(PHY_REG(ch, 803), (0x3 << 2) << 16);
	} else {
		/* phy_sw_master_mode_X PHY_86/214/342/470 4bits offset_8 */
		mmio_clrbits_32(PHY_REG(ch, 86), (0x3 << 2) << 8);
		mmio_clrbits_32(PHY_REG(ch, 214), (0x3 << 2) << 8);
		mmio_clrbits_32(PHY_REG(ch, 342), (0x3 << 2) << 8);
		mmio_clrbits_32(PHY_REG(ch, 470), (0x3 << 2) << 8);
		/* phy_adrctl_sw_master_mode PHY_547/675/803 4bits offset_16 */
		mmio_clrbits_32(PHY_REG(ch, 547), (0x3 << 2) << 16);
		mmio_clrbits_32(PHY_REG(ch, 675), (0x3 << 2) << 16);
		mmio_clrbits_32(PHY_REG(ch, 803), (0x3 << 2) << 16);
	}
}

static __sramfunc void set_cs_training_index(uint32_t ch, uint32_t rank)
{
	/* PHY_8/136/264/392 phy_per_cs_training_index_X 1bit offset_24 */
	mmio_clrsetbits_32(PHY_REG(ch, 8), 0x1 << 24, rank << 24);
	mmio_clrsetbits_32(PHY_REG(ch, 136), 0x1 << 24, rank << 24);
	mmio_clrsetbits_32(PHY_REG(ch, 264), 0x1 << 24, rank << 24);
	mmio_clrsetbits_32(PHY_REG(ch, 392), 0x1 << 24, rank << 24);
}

static __sramfunc void select_per_cs_training_index(uint32_t ch, uint32_t rank)
{
	/* PHY_84 PHY_PER_CS_TRAINING_EN_0 1bit offset_16 */
	if ((mmio_read_32(PHY_REG(ch, 84)) >> 16) & 1)
		set_cs_training_index(ch, rank);
}

static void override_write_leveling_value(uint32_t ch)
{
	uint32_t byte;

	/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
	mmio_setbits_32(PHY_REG(ch, 896), 1);

	/*
	 * PHY_8/136/264/392
	 * phy_per_cs_training_multicast_en_X 1bit offset_16
	 */
	mmio_clrsetbits_32(PHY_REG(ch, 8), 0x1 << 16, 1 << 16);
	mmio_clrsetbits_32(PHY_REG(ch, 136), 0x1 << 16, 1 << 16);
	mmio_clrsetbits_32(PHY_REG(ch, 264), 0x1 << 16, 1 << 16);
	mmio_clrsetbits_32(PHY_REG(ch, 392), 0x1 << 16, 1 << 16);

	for (byte = 0; byte < 4; byte++)
		mmio_clrsetbits_32(PHY_REG(ch, 63 + (128 * byte)),
				   0xffff << 16,
				   0x200 << 16);

	/* PHY_896 PHY_FREQ_SEL_MULTICAST_EN 1bit offset_0 */
	mmio_clrbits_32(PHY_REG(ch, 896), 1);

	/* CTL_200 ctrlupd_req 1bit offset_8 */
	mmio_clrsetbits_32(CTL_REG(ch, 200), 0x1 << 8, 0x1 << 8);
}

static __sramfunc int data_training(uint32_t ch,
		struct rk3399_sdram_params *sdram_params,
		uint32_t training_flag)
{
	uint32_t obs_0, obs_1, obs_2, obs_3, obs_err = 0;
	uint32_t rank = sdram_params->ch[ch].rank;
	uint32_t rank_mask;
	uint32_t i, tmp;

	if (sdram_params->dramtype == LPDDR4)
		rank_mask = (rank == 1) ? 0x5 : 0xf;
	else
		rank_mask = (rank == 1) ? 0x1 : 0x3;

	/* PHY_927 PHY_PAD_DQS_DRIVE  RPULL offset_22 */
	mmio_setbits_32(PHY_REG(ch, 927), (1 << 22));

	if (training_flag == PI_FULL_TRAINING) {
		if (sdram_params->dramtype == LPDDR4) {
			training_flag = PI_WRITE_LEVELING |
					PI_READ_GATE_TRAINING |
					PI_READ_LEVELING |
					PI_WDQ_LEVELING;
		} else if (sdram_params->dramtype == LPDDR3) {
			training_flag = PI_CA_TRAINING | PI_WRITE_LEVELING |
					PI_READ_GATE_TRAINING;
		} else if (sdram_params->dramtype == DDR3) {
			training_flag = PI_WRITE_LEVELING |
					PI_READ_GATE_TRAINING |
					PI_READ_LEVELING;
		}
	}

	/* ca training(LPDDR4,LPDDR3 support) */
	if ((training_flag & PI_CA_TRAINING) == PI_CA_TRAINING) {
		for (i = 0; i < 4; i++) {
			if (!(rank_mask & (1 << i)))
				continue;

			select_per_cs_training_index(ch, i);
			/* PI_100 PI_CALVL_EN:RW:8:2 */
			mmio_clrsetbits_32(PI_REG(ch, 100), 0x3 << 8, 0x2 << 8);

			/* PI_92 PI_CALVL_REQ:WR:16:1,PI_CALVL_CS:RW:24:2 */
			mmio_clrsetbits_32(PI_REG(ch, 92),
					   (0x1 << 16) | (0x3 << 24),
					   (0x1 << 16) | (i << 24));
			while (1) {
				/* PI_174 PI_INT_STATUS:RD:8:18 */
				tmp = mmio_read_32(PI_REG(ch, 174)) >> 8;

				/*
				 * check status obs
				 * PHY_532/660/788 phy_adr_calvl_obs1_:0:32
				 */
				obs_0 = mmio_read_32(PHY_REG(ch, 532));
				obs_1 = mmio_read_32(PHY_REG(ch, 660));
				obs_2 = mmio_read_32(PHY_REG(ch, 788));
				if (((obs_0 >> 30) & 0x3) ||
				    ((obs_1 >> 30) & 0x3) ||
				    ((obs_2 >> 30) & 0x3))
					obs_err = 1;
				if ((((tmp >> 11) & 0x1) == 0x1) &&
				    (((tmp >> 13) & 0x1) == 0x1) &&
				    (((tmp >> 5) & 0x1) == 0x0) &&
				    (obs_err == 0))
					break;
				else if ((((tmp >> 5) & 0x1) == 0x1) ||
					 (obs_err == 1))
					return -1;
			}
			/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
			mmio_write_32(PI_REG(ch, 175), 0x00003f7c);
		}
		mmio_clrbits_32(PI_REG(ch, 100), 0x3 << 8);
	}

	/* write leveling(LPDDR4,LPDDR3,DDR3 support) */
	if ((training_flag & PI_WRITE_LEVELING) == PI_WRITE_LEVELING) {
		for (i = 0; i < rank; i++) {
			select_per_cs_training_index(ch, i);
			/* PI_60 PI_WRLVL_EN:RW:8:2 */
			mmio_clrsetbits_32(PI_REG(ch, 60), 0x3 << 8, 0x2 << 8);
			/* PI_59 PI_WRLVL_REQ:WR:8:1,PI_WRLVL_CS:RW:16:2 */
			mmio_clrsetbits_32(PI_REG(ch, 59),
					   (0x1 << 8) | (0x3 << 16),
					   (0x1 << 8) | (i << 16));

			while (1) {
				/* PI_174 PI_INT_STATUS:RD:8:18 */
				tmp = mmio_read_32(PI_REG(ch, 174)) >> 8;

				/*
				 * check status obs, if error maybe can not
				 * get leveling done PHY_40/168/296/424
				 * phy_wrlvl_status_obs_X:0:13
				 */
				obs_0 = mmio_read_32(PHY_REG(ch, 40));
				obs_1 = mmio_read_32(PHY_REG(ch, 168));
				obs_2 = mmio_read_32(PHY_REG(ch, 296));
				obs_3 = mmio_read_32(PHY_REG(ch, 424));
				if (((obs_0 >> 12) & 0x1) ||
				    ((obs_1 >> 12) & 0x1) ||
				    ((obs_2 >> 12) & 0x1) ||
				    ((obs_3 >> 12) & 0x1))
					obs_err = 1;
				if ((((tmp >> 10) & 0x1) == 0x1) &&
				    (((tmp >> 13) & 0x1) == 0x1) &&
				    (((tmp >> 4) & 0x1) == 0x0) &&
				    (obs_err == 0))
					break;
				else if ((((tmp >> 4) & 0x1) == 0x1) ||
					 (obs_err == 1))
					return -1;
			}

			/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
			mmio_write_32(PI_REG(ch, 175), 0x00003f7c);
		}
		override_write_leveling_value(ch);
		mmio_clrbits_32(PI_REG(ch, 60), 0x3 << 8);
	}

	/* read gate training(LPDDR4,LPDDR3,DDR3 support) */
	if ((training_flag & PI_READ_GATE_TRAINING) == PI_READ_GATE_TRAINING) {
		for (i = 0; i < rank; i++) {
			select_per_cs_training_index(ch, i);
			/* PI_80 PI_RDLVL_GATE_EN:RW:24:2 */
			mmio_clrsetbits_32(PI_REG(ch, 80), 0x3 << 24,
					   0x2 << 24);
			/*
			 * PI_74 PI_RDLVL_GATE_REQ:WR:16:1
			 * PI_RDLVL_CS:RW:24:2
			 */
			mmio_clrsetbits_32(PI_REG(ch, 74),
					   (0x1 << 16) | (0x3 << 24),
					   (0x1 << 16) | (i << 24));

			while (1) {
				/* PI_174 PI_INT_STATUS:RD:8:18 */
				tmp = mmio_read_32(PI_REG(ch, 174)) >> 8;

				/*
				 * check status obs
				 * PHY_43/171/299/427
				 *     PHY_GTLVL_STATUS_OBS_x:16:8
				 */
				obs_0 = mmio_read_32(PHY_REG(ch, 43));
				obs_1 = mmio_read_32(PHY_REG(ch, 171));
				obs_2 = mmio_read_32(PHY_REG(ch, 299));
				obs_3 = mmio_read_32(PHY_REG(ch, 427));
				if (((obs_0 >> (16 + 6)) & 0x3) ||
				    ((obs_1 >> (16 + 6)) & 0x3) ||
				    ((obs_2 >> (16 + 6)) & 0x3) ||
				    ((obs_3 >> (16 + 6)) & 0x3))
					obs_err = 1;
				if ((((tmp >> 9) & 0x1) == 0x1) &&
				    (((tmp >> 13) & 0x1) == 0x1) &&
				    (((tmp >> 3) & 0x1) == 0x0) &&
				    (obs_err == 0))
					break;
				else if ((((tmp >> 3) & 0x1) == 0x1) ||
					 (obs_err == 1))
					return -1;
			}
			/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
			mmio_write_32(PI_REG(ch, 175), 0x00003f7c);
		}
		mmio_clrbits_32(PI_REG(ch, 80), 0x3 << 24);
	}

	/* read leveling(LPDDR4,LPDDR3,DDR3 support) */
	if ((training_flag & PI_READ_LEVELING) == PI_READ_LEVELING) {
		for (i = 0; i < rank; i++) {
			select_per_cs_training_index(ch, i);
			/* PI_80 PI_RDLVL_EN:RW:16:2 */
			mmio_clrsetbits_32(PI_REG(ch, 80), 0x3 << 16,
					   0x2 << 16);
			/* PI_74 PI_RDLVL_REQ:WR:8:1,PI_RDLVL_CS:RW:24:2 */
			mmio_clrsetbits_32(PI_REG(ch, 74),
					   (0x1 << 8) | (0x3 << 24),
					   (0x1 << 8) | (i << 24));
			while (1) {
				/* PI_174 PI_INT_STATUS:RD:8:18 */
				tmp = mmio_read_32(PI_REG(ch, 174)) >> 8;

				/*
				 * make sure status obs not report error bit
				 * PHY_46/174/302/430
				 *     phy_rdlvl_status_obs_X:16:8
				 */
				if ((((tmp >> 8) & 0x1) == 0x1) &&
				    (((tmp >> 13) & 0x1) == 0x1) &&
				    (((tmp >> 2) & 0x1) == 0x0))
					break;
				else if (((tmp >> 2) & 0x1) == 0x1)
					return -1;
			}
			/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
			mmio_write_32(PI_REG(ch, 175), 0x00003f7c);
		}
		mmio_clrbits_32(PI_REG(ch, 80), 0x3 << 16);
	}

	/* wdq leveling(LPDDR4 support) */
	if ((training_flag & PI_WDQ_LEVELING) == PI_WDQ_LEVELING) {
		for (i = 0; i < 4; i++) {
			if (!(rank_mask & (1 << i)))
				continue;

			select_per_cs_training_index(ch, i);
			/*
			 * disable PI_WDQLVL_VREF_EN before wdq leveling?
			 * PI_181 PI_WDQLVL_VREF_EN:RW:8:1
			 */
			mmio_clrbits_32(PI_REG(ch, 181), 0x1 << 8);
			/* PI_124 PI_WDQLVL_EN:RW:16:2 */
			mmio_clrsetbits_32(PI_REG(ch, 124), 0x3 << 16,
					   0x2 << 16);
			/* PI_121 PI_WDQLVL_REQ:WR:8:1,PI_WDQLVL_CS:RW:16:2 */
			mmio_clrsetbits_32(PI_REG(ch, 121),
					   (0x1 << 8) | (0x3 << 16),
					   (0x1 << 8) | (i << 16));
			while (1) {
				/* PI_174 PI_INT_STATUS:RD:8:18 */
				tmp = mmio_read_32(PI_REG(ch, 174)) >> 8;
				if ((((tmp >> 12) & 0x1) == 0x1) &&
				    (((tmp >> 13) & 0x1) == 0x1) &&
				    (((tmp >> 6) & 0x1) == 0x0))
					break;
				else if (((tmp >> 6) & 0x1) == 0x1)
					return -1;
			}
			/* clear interrupt,PI_175 PI_INT_ACK:WR:0:17 */
			mmio_write_32(PI_REG(ch, 175), 0x00003f7c);
		}
		mmio_clrbits_32(PI_REG(ch, 124), 0x3 << 16);
	}

	/* PHY_927 PHY_PAD_DQS_DRIVE  RPULL offset_22 */
	mmio_clrbits_32(PHY_REG(ch, 927), (1 << 22));

	return 0;
}

static __sramfunc void set_ddrconfig(struct rk3399_sdram_params *sdram_params,
		unsigned char channel, uint32_t ddrconfig)
{
	/* only need to set ddrconfig */
	struct rk3399_sdram_channel *ch = &sdram_params->ch[channel];
	unsigned int cs0_cap = 0;
	unsigned int cs1_cap = 0;

	cs0_cap = (1 << (ch->cs0_row + ch->col + ch->bk + ch->bw - 20));
	if (ch->rank > 1)
		cs1_cap = cs0_cap >> (ch->cs0_row - ch->cs1_row);
	if (ch->row_3_4) {
		cs0_cap = cs0_cap * 3 / 4;
		cs1_cap = cs1_cap * 3 / 4;
	}

	mmio_write_32(MSCH_BASE(channel) + MSCH_DEVICECONF,
		      ddrconfig | (ddrconfig << 6));
	mmio_write_32(MSCH_BASE(channel) + MSCH_DEVICESIZE,
		      ((cs0_cap / 32) & 0xff) | (((cs1_cap / 32) & 0xff) << 8));
}

static __sramfunc void dram_all_config(struct rk3399_sdram_params *sdram_params)
{
	unsigned int i;

	for (i = 0; i < 2; i++) {
		struct rk3399_sdram_channel *info = &sdram_params->ch[i];
		struct rk3399_msch_timings *noc = &info->noc_timings;

		if (sdram_params->ch[i].col == 0)
			continue;

		mmio_write_32(MSCH_BASE(i) + MSCH_DDRTIMINGA0,
			      noc->ddrtiminga0.d32);
		mmio_write_32(MSCH_BASE(i) + MSCH_DDRTIMINGB0,
			      noc->ddrtimingb0.d32);
		mmio_write_32(MSCH_BASE(i) + MSCH_DDRTIMINGC0,
			      noc->ddrtimingc0.d32);
		mmio_write_32(MSCH_BASE(i) + MSCH_DEVTODEV0,
			      noc->devtodev0.d32);
		mmio_write_32(MSCH_BASE(i) + MSCH_DDRMODE, noc->ddrmode.d32);

		/* rank 1 memory clock disable (dfi_dram_clk_disable = 1) */
		if (sdram_params->ch[i].rank == 1)
			mmio_setbits_32(CTL_REG(i, 276), 1 << 17);
	}

	DDR_STRIDE(sdram_params->stride);

	/* reboot hold register set */
	mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
		      CRU_PMU_SGRF_RST_RLS |
		      PRESET_GPIO0_HOLD(1) |
		      PRESET_GPIO1_HOLD(1));
	mmio_clrsetbits_32(CRU_BASE + CRU_GLB_RST_CON, 0x3, 0x3);
}

static __sramfunc void pctl_cfg(uint32_t ch,
		struct rk3399_sdram_params *sdram_params)
{
	const uint32_t *params_ctl = sdram_params->pctl_regs.denali_ctl;
	const uint32_t *params_phy = sdram_params->phy_regs.denali_phy;
	const uint32_t *params_pi = sdram_params->pi_regs.denali_pi;
	uint32_t tmp, tmp1, tmp2;

	/*
	 * Workaround controller bug:
	 * Do not program DRAM_CLASS until NO_PHY_IND_TRAIN_INT is programmed
	 */
	sram_regcpy(CTL_REG(ch, 1), (uintptr_t)&params_ctl[1],
		    CTL_REG_NUM - 1);
	mmio_write_32(CTL_REG(ch, 0), params_ctl[0]);
	sram_regcpy(PI_REG(ch, 0), (uintptr_t)&params_pi[0],
		    PI_REG_NUM);

	mmio_write_32(PHY_REG(ch, 910), params_phy[910]);
	mmio_write_32(PHY_REG(ch, 911), params_phy[911]);
	mmio_write_32(PHY_REG(ch, 912), params_phy[912]);

	mmio_clrsetbits_32(CTL_REG(ch, 68), PWRUP_SREFRESH_EXIT,
				PWRUP_SREFRESH_EXIT);

	/* PHY_DLL_RST_EN */
	mmio_clrsetbits_32(PHY_REG(ch, 957), 0x3 << 24, 1 << 24);
	dmbst();

	mmio_setbits_32(PI_REG(ch, 0), START);
	mmio_setbits_32(CTL_REG(ch, 0), START);

	/* wait lock */
	while (1) {
		tmp = mmio_read_32(PHY_REG(ch, 920));
		tmp1 = mmio_read_32(PHY_REG(ch, 921));
		tmp2 = mmio_read_32(PHY_REG(ch, 922));
		if ((((tmp >> 16) & 0x1) == 0x1) &&
		     (((tmp1 >> 16) & 0x1) == 0x1) &&
		     (((tmp1 >> 0) & 0x1) == 0x1) &&
		     (((tmp2 >> 0) & 0x1) == 0x1))
			break;
		/* if PLL bypass,don't need wait lock */
		if (mmio_read_32(PHY_REG(ch, 911)) & 0x1)
			break;
	}

	sram_regcpy(PHY_REG(ch, 896), (uintptr_t)&params_phy[896], 63);
	sram_regcpy(PHY_REG(ch, 0), (uintptr_t)&params_phy[0], 91);
	sram_regcpy(PHY_REG(ch, 128), (uintptr_t)&params_phy[128], 91);
	sram_regcpy(PHY_REG(ch, 256), (uintptr_t)&params_phy[256], 91);
	sram_regcpy(PHY_REG(ch, 384), (uintptr_t)&params_phy[384], 91);
	sram_regcpy(PHY_REG(ch, 512), (uintptr_t)&params_phy[512], 38);
	sram_regcpy(PHY_REG(ch, 640), (uintptr_t)&params_phy[640], 38);
	sram_regcpy(PHY_REG(ch, 768), (uintptr_t)&params_phy[768], 38);
}

static __sramfunc int dram_switch_to_next_index(
		struct rk3399_sdram_params *sdram_params)
{
	uint32_t ch, ch_count;
	uint32_t fn = ((mmio_read_32(CTL_REG(0, 111)) >> 16) + 1) & 0x1;

	mmio_write_32(CIC_BASE + CIC_CTRL0,
		      (((0x3 << 4) | (1 << 2) | 1) << 16) |
		      (fn << 4) | (1 << 2) | 1);
	while (!(mmio_read_32(CIC_BASE + CIC_STATUS0) & (1 << 2)))
		;

	mmio_write_32(CIC_BASE + CIC_CTRL0, 0x20002);
	while (!(mmio_read_32(CIC_BASE + CIC_STATUS0) & (1 << 0)))
		;

	ch_count = sdram_params->num_channels;

	/* LPDDR4 f2 cann't do training, all training will fail */
	for (ch = 0; ch < ch_count; ch++) {
		mmio_clrsetbits_32(PHY_REG(ch, 896), (0x3 << 8) | 1,
				   fn << 8);

		/* data_training failed */
		if (data_training(ch, sdram_params, PI_FULL_TRAINING))
			return -1;
	}

	return 0;
}

/*
 * Needs to be done for both channels at once in case of a shared reset signal
 * between channels.
 */
static __sramfunc int pctl_start(uint32_t channel_mask,
		struct rk3399_sdram_params *sdram_params)
{
	uint32_t count;

	mmio_setbits_32(CTL_REG(0, 68), PWRUP_SREFRESH_EXIT);
	mmio_setbits_32(CTL_REG(1, 68), PWRUP_SREFRESH_EXIT);

	/* need de-access IO retention before controller START */
	if (channel_mask & (1 << 0))
		mmio_setbits_32(PMU_BASE + PMU_PWRMODE_CON, (1 << 19));
	if (channel_mask & (1 << 1))
		mmio_setbits_32(PMU_BASE + PMU_PWRMODE_CON, (1 << 23));

	/* PHY_DLL_RST_EN */
	if (channel_mask & (1 << 0))
		mmio_clrsetbits_32(PHY_REG(0, 957), 0x3 << 24,
				   0x2 << 24);
	if (channel_mask & (1 << 1))
		mmio_clrsetbits_32(PHY_REG(1, 957), 0x3 << 24,
				   0x2 << 24);

	/* check ERROR bit */
	if (channel_mask & (1 << 0)) {
		count = 0;
		while (!(mmio_read_32(CTL_REG(0, 203)) & (1 << 3))) {
			/* CKE is low, loop 10ms */
			if (count > 100)
				return -1;

			sram_udelay(100);
			count++;
		}

		mmio_clrbits_32(CTL_REG(0, 68), PWRUP_SREFRESH_EXIT);
	}
	if (channel_mask & (1 << 1)) {
		count = 0;
		while (!(mmio_read_32(CTL_REG(1, 203)) & (1 << 3))) {
			/* CKE is low, loop 10ms */
			if (count > 100)
				return -1;

			sram_udelay(100);
			count++;
		}

		mmio_clrbits_32(CTL_REG(1, 68), PWRUP_SREFRESH_EXIT);
	}

	return 0;
}

void dmc_save(void)
{
	struct rk3399_sdram_params *sdram_params = &sdram_config;
	uint32_t *params_ctl;
	uint32_t *params_pi;
	uint32_t *params_phy;
	uint32_t refdiv, postdiv2, postdiv1, fbdiv;
	uint32_t tmp;

	params_ctl = sdram_params->pctl_regs.denali_ctl;
	params_pi = sdram_params->pi_regs.denali_pi;
	params_phy = sdram_params->phy_regs.denali_phy;

	fbdiv = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 0)) & 0xfff;
	tmp = mmio_read_32(CRU_BASE + CRU_PLL_CON(DPLL_ID, 1));
	postdiv2 = POSTDIV2_DEC(tmp);
	postdiv1 = POSTDIV1_DEC(tmp);
	refdiv = REFDIV_DEC(tmp);

	sdram_params->ddr_freq = ((fbdiv * 24) /
				(refdiv * postdiv1 * postdiv2)) * MHz;

	INFO("sdram_params->ddr_freq = %d\n", sdram_params->ddr_freq);
	sdram_params->odt = (((mmio_read_32(PHY_REG(0, 5)) >> 16) &
			       0x7) != 0) ? 1 : 0;

	/* copy the registers CTL PI and PHY */
	sram_regcpy((uintptr_t)&params_ctl[0], CTL_REG(0, 0), CTL_REG_NUM);

	/* mask DENALI_CTL_00_DATA.START, only copy here, will trigger later */
	params_ctl[0] &= ~(0x1 << 0);

	sram_regcpy((uintptr_t)&params_pi[0], PI_REG(0, 0),
		    PI_REG_NUM);

	/* mask DENALI_PI_00_DATA.START, only copy here, will trigger later*/
	params_pi[0] &= ~(0x1 << 0);

	sram_regcpy((uintptr_t)&params_phy[0], PHY_REG(0, 0), 91);
	sram_regcpy((uintptr_t)&params_phy[128], PHY_REG(0, 128), 91);
	sram_regcpy((uintptr_t)&params_phy[256], PHY_REG(0, 256), 91);
	sram_regcpy((uintptr_t)&params_phy[384], PHY_REG(0, 384), 91);
	sram_regcpy((uintptr_t)&params_phy[512], PHY_REG(0, 512), 38);
	sram_regcpy((uintptr_t)&params_phy[640], PHY_REG(0, 640), 38);
	sram_regcpy((uintptr_t)&params_phy[768], PHY_REG(0, 768), 38);
	sram_regcpy((uintptr_t)&params_phy[896], PHY_REG(0, 896), 63);

	/* set DENALI_PHY_957_DATA.PHY_DLL_RST_EN = 0x1 */
	params_phy[957] &= ~(0x3 << 24);
	params_phy[957] |= 1 << 24;
	params_phy[896] |= 1;
	params_phy[896] &= ~(0x3 << 8);
}

__sramfunc void dmc_restore(void)
{
	struct rk3399_sdram_params *sdram_params = &sdram_config;
	uint32_t channel_mask = 0;
	uint32_t channel;

	configure_sgrf();

retry:
	for (channel = 0; channel < sdram_params->num_channels; channel++) {
		phy_pctrl_reset(channel);
		phy_dll_bypass_set(channel, sdram_params->ddr_freq);
		if (channel >= sdram_params->num_channels)
			continue;

		pctl_cfg(channel, sdram_params);
	}

	for (channel = 0; channel < 2; channel++) {
		if (sdram_params->ch[channel].col)
			channel_mask |= 1 << channel;
	}

	if (pctl_start(channel_mask, sdram_params) < 0)
		goto retry;

	for (channel = 0; channel < sdram_params->num_channels; channel++) {
		/* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */
		if (sdram_params->dramtype == LPDDR3)
			sram_udelay(10);

		/* If traning fail, retry to do it again. */
		if (data_training(channel, sdram_params, PI_FULL_TRAINING))
			goto retry;

		set_ddrconfig(sdram_params, channel,
			      sdram_params->ch[channel].ddrconfig);
	}

	dram_all_config(sdram_params);

	/* Switch to index 1 and prepare for DDR frequency switch. */
	dram_switch_to_next_index(sdram_params);
}
