/*
 * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
 * Copyright 2017-2018 NXP
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch.h>
#include <arch_helpers.h>
#include <debug.h>
#include <ddrc.h>
#include <mmio.h>
#include <platform_def.h>
#include <spinlock.h>
#include <soc.h>

#include "lpddr4_dvfs.h"

#define SRC_IPS_BASE_ADDR       0x30390000
#define SRC_DDRC_RCR_ADDR	(SRC_IPS_BASE_ADDR + 0x1000)

#define GPC_PU_PWRHSK		(IMX_GPC_BASE + 0x01FC)  //added by baoxye
#define CCM_SRC_CTRL_OFFSET     (IMX_CCM_BASE + 0x800)
#define CCM_CCGR_OFFSET         (IMX_CCM_BASE + 0x4000)
#define CCM_SRC_CTRL(n)		(CCM_SRC_CTRL_OFFSET + 0x10 * n)
#define CCM_CCGR(n)		(CCM_CCGR_OFFSET + 0x10 * n)

static bool trained_csr_saved = false;

void lpddr4_save_umctl2(void);
void lpddr4_phy_save_phy(void);

void ddrc_enter_retention(void)
{
	unsigned int tmp, tmp_t, i;

	/* only need be save once */
	if (!trained_csr_saved) {
		lpddr4_save_umctl2();
		lpddr4_phy_save_phy();
		trained_csr_saved = true;
	}

	INFO("enter lpddr4_retention\n");
	/* wait DBGCAM to be empty */
	do{
		tmp = mmio_read_32(DDRC_DBGCAM(0));
	} while (tmp != 0x36000000);

	/* Blocks AXI ports from taking anymore transactions */
	mmio_write_32(DDRC_PCTRL_0(0), 0x00000000);

	/* Waits unit all AXI ports are idle */
	do {
		tmp = mmio_read_32(DDRC_PSTAT(0));
	} while (tmp & 0x10001);

	/* enters self refresh */
	mmio_write_32(DDRC_PWRCTL(0), 0x000000aa);

	tmp=0;
	while (tmp!=0x223) {
		tmp  = 0x33f & (mmio_read_32((DDRC_STAT(0))));
	}

	mmio_write_32(DDRC_DFIMISC(0), 0x00000000);

	/* set SWCTL.sw_done to disable quasi-dynamic register programming outside reset. */
	mmio_write_32(DDRC_SWCTL(0), 0x00000000);

	mmio_write_32(DDRC_DFIMISC(0), 0x00001f00);
	mmio_write_32(DDRC_DFIMISC(0), 0x00001f20);

	/* wait DFISTAT.dfi_init_complete to 0 */
	tmp_t = 0;
	while (tmp_t==1) {
		tmp  = mmio_read_32(DDRC_DFISTAT(0));
		tmp_t = tmp & 0x01;
	}

	mmio_write_32(DDRC_DFIMISC(0), 0x00001f00);

	/* wait DFISTAT.dfi_init_complete to 1 */
	tmp_t = 0;
	while (tmp_t==0) {
		 tmp  = mmio_read_32(DDRC_DFISTAT(0));
		tmp_t = tmp & 0x01;
	}

	/* set SWCTL.sw_done to enable quasi-dynamic register programming outside reset. */
	mmio_write_32(DDRC_SWCTL(0), 0x00000001);

	/* should check PhyInLP3 pub reg */
	dwc_ddrphy_apb_wr(0xd0000,0x0);
	tmp = dwc_ddrphy_apb_rd(0x90028);
	tmp = tmp & 0x1;
	if (tmp)
		INFO("C: PhyInLP3 = 1\n");
	else
		INFO("FAILED\n");

	dwc_ddrphy_apb_wr(0xd0000,0x1);

	for (i=0; i<20; i++);

	/* pwrdnreqn_async adbm/adbs of ddr */
	mmio_clrbits_32(GPC_PU_PWRHSK, (1 << 1));
	do {
	        tmp = mmio_read_32(GPC_PU_PWRHSK);
		 INFO("C: wait pwrdnackn_async clr\n");
	} while (tmp & (0x1<<18));/* wait untill pwrdnackn_async=0 */
	mmio_setbits_32(GPC_PU_PWRHSK, (1 << 1));

	/* remove PowerOk */
	mmio_write_32(SRC_DDRC_RCR_ADDR, 0x8F000008);

	for (i=0; i<20; i++);

	mmio_write_32(CCM_CCGR(5),0);
	mmio_write_32(CCM_SRC_CTRL(15),2);

	for (i=0; i<20; i++);

	/* enable the phy iso */
	mmio_setbits_32(0x303a0d40, 0x1);
	mmio_setbits_32(0x303a0104, (1 << 5));
}

void ddrc_exit_retention(void)
{
	volatile unsigned int tmp, tmp_t, i;
	INFO("exit lpddr4_retention\n");

	for (i=0; i<50; i++);

	for (i=0; i<50; i++);

	/* assert all reset */
	/* assert [0]src_system_rst_b! */
	mmio_write_32(SRC_DDRC_RCR_ADDR + 0x04, 0x8F000001);
	mmio_write_32(SRC_DDRC_RCR_ADDR, 0x8F00000F);
	/* release [0]src_system_rst_b! */
	mmio_write_32(SRC_DDRC_RCR_ADDR + 0x04, 0x8F000000);

	mmio_write_32(CCM_CCGR(5),2);
	mmio_write_32(CCM_SRC_CTRL(15),2);
	INFO("C: enable all DRAM clocks \n");

	/* change the clock source of dram_apb_clk_root */
	mmio_write_32(0x3038a088, (0x7<<24)|(0x7<<16));
	mmio_write_32(0x3038a084, (0x4<<24)|(0x3<<16));

	/* disable iso */
	/* mmio_write_32(0x303A00EC,0x0000ffff); //PGC_CPU_MAPPING */
	/* reg32setbit(0x303A00F8,5);//PU_PGC_SW_PUP_REQ */
	mmio_setbits_32(0x303a00f8, (1 << 5));

	/* release [0]ddr1_preset_n,  [3]ddr1_phy_pwrokin_n */
	mmio_write_32(SRC_DDRC_RCR_ADDR, 0x8F000006);

	lpddr4_cfg_umctl2();
	/* Skips the DRAM init routine and starts up in selfrefresh mode */
	/* Program INIT0.skip_dram_init = 2'b11 */
	mmio_write_32(DDRC_INIT0(0), 0xc0000000 | (mmio_read_32(DDRC_INIT0(0))));
	/* Keeps the controller in self-refresh mode */
	mmio_write_32(DDRC_PWRCTL(0), 0x000000aa);
	mmio_write_32(SRC_DDRC_RCR_ADDR, 0x8F000000); /* release all reset */
	mmio_write_32(DDRC_DBG1(0), 0x00000000);

	/* before write Dynamic reg, sw_done should be 0 */
	mmio_write_32(DDRC_SWCTL(0), 0x00000000);
	mmio_write_32(DDRC_DDR_SS_GPR0, 0x01);//LPDDR4 mode
	mmio_write_32(DDRC_DFIMISC(0), 0x00000000);

	lpddr4_phy_cfg();

	dwc_ddrphy_apb_wr(0xd0000,0x0);
	do {
		tmp_t = dwc_ddrphy_apb_rd(0x20097);
		INFO("C: Waiting for CalBusy = 0\n");
	} while(tmp_t != 0);
	dwc_ddrphy_apb_wr(0xd0000,0x1);

	/* before write Dynamic reg, sw_done should be 0 */
	mmio_write_32(DDRC_SWCTL(0), 0x00000000);
	mmio_write_32(DDRC_DFIMISC(0), 0x00000020); 

	/* wait DFISTAT.dfi_init_complete to 1 */
	tmp_t = 0;
	while(tmp_t==0){
		tmp  = mmio_read_32(DDRC_DFISTAT(0));
		tmp_t = tmp & 0x01;
		INFO("wait DFISTAT.dfi_init_complete to 1\n");
	}

	/* clear DFIMISC.dfi_init_start */
	mmio_write_32(DDRC_DFIMISC(0), 0x00000000);
	/* set DFIMISC.dfi_init_complete_en */
	mmio_write_32(DDRC_DFIMISC(0), 0x00000001);
	/* set SWCTL.sw_done to enable quasi-dynamic register programming outside reset. */
	mmio_write_32(DDRC_SWCTL(0), 0x00000001);

	/* wait SWSTAT.sw_done_ack to 1 */
	tmp_t = 0;
	while (tmp_t!=0x1) {
		tmp  = mmio_read_32(DDRC_SWSTAT(0));
		tmp_t = tmp & 0x1;
		INFO("1wait SWSTAT.sw_done_ack to 1\n");
	}

	mmio_write_32(DDRC_PWRCTL(0), 0x000000aa);
	mmio_write_32(DDRC_SWCTL(0), 0x00000000);
	mmio_write_32(DDRC_DFIMISC(0), 0x00000001);
	mmio_write_32(DDRC_SWCTL(0), 0x00000001);

	/* wait SWSTAT.sw_done_ack to 1 */
	tmp_t = 0;
	while (tmp_t!=0x1) {
		tmp  = mmio_read_32(DDRC_SWSTAT(0));
		tmp_t = tmp & 0x1;
		INFO("2wait SWSTAT.sw_done_ack to 1\n");
	}

	/* mmio_write_32(DDRC_PWRCTL(0), 0x0000008a); */
	mmio_write_32(DDRC_PWRCTL(0), 0x00000088);

	/* wait STAT to normal state */
	tmp_t = 0;
	while(tmp_t!=0x1){
		tmp  = mmio_read_32(DDRC_STAT(0));
		tmp_t = tmp & 0x7;
		INFO("wait STAT to normal state\n");
	}

	mmio_write_32(DDRC_DERATEEN(0), 0x00000302);

	mmio_write_32(DDRC_PCTRL_0(0), 0x00000001);
	/* dis_auto-refresh is set to 0 */
	mmio_write_32(DDRC_RFSHCTL3(0), 0x00000000);

	/* should check PhyInLP3 pub reg */
	dwc_ddrphy_apb_wr(0xd0000, 0x0);
	dwc_ddrphy_apb_rd(0x90028);
	tmp = tmp & 0x1;
	if(!tmp)
		 INFO("C: PhyInLP3 = 0\n");
	else
		INFO("FAILED\n");
	dwc_ddrphy_apb_wr(0xd0000, 0x1);
}
