xref: /rk3399_ARM-atf/plat/rockchip/rk3368/drivers/ddr/ddr_rk3368.c (revision d0d0f171643a22bbc3d06f5b6dde40cc1d9d5d11)
16fba6e04STony Xie /*
26fba6e04STony Xie  * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
36fba6e04STony Xie  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
56fba6e04STony Xie  */
66fba6e04STony Xie 
709d40e0eSAntonio Nino Diaz #include <stdint.h>
809d40e0eSAntonio Nino Diaz #include <string.h>
909d40e0eSAntonio Nino Diaz 
106fba6e04STony Xie #include <platform_def.h>
1109d40e0eSAntonio Nino Diaz 
1209d40e0eSAntonio Nino Diaz #include <common/debug.h>
1309d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
1409d40e0eSAntonio Nino Diaz 
1509d40e0eSAntonio Nino Diaz #include <ddr_rk3368.h>
166fba6e04STony Xie #include <pmu.h>
176fba6e04STony Xie #include <rk3368_def.h>
186fba6e04STony Xie #include <soc.h>
196fba6e04STony Xie 
206fba6e04STony Xie /* GRF_SOC_STATUS0 */
216fba6e04STony Xie #define DPLL_LOCK		(0x1 << 2)
226fba6e04STony Xie 
236fba6e04STony Xie /* GRF_DDRC0_CON0 */
246fba6e04STony Xie #define GRF_DDR_16BIT_EN	(((0x1 << 3) << 16) | (0x1 << 3))
256fba6e04STony Xie #define GRF_DDR_32BIT_EN	(((0x1 << 3) << 16) | (0x0 << 3))
266fba6e04STony Xie #define GRF_MOBILE_DDR_EN	(((0x1 << 4) << 16) | (0x1 << 4))
276fba6e04STony Xie #define GRF_MOBILE_DDR_DISB	(((0x1 << 4) << 16) | (0x0 << 4))
286fba6e04STony Xie #define GRF_DDR3_EN		(((0x1 << 2) << 16) | (0x1 << 2))
296fba6e04STony Xie #define GRF_LPDDR2_3_EN		(((0x1 << 2) << 16) | (0x0 << 2))
306fba6e04STony Xie 
316fba6e04STony Xie /* PMUGRF_SOC_CON0 */
326fba6e04STony Xie #define ddrphy_bufferen_io_en(n)	((0x1 << (9 + 16)) | (n << 9))
336fba6e04STony Xie #define ddrphy_bufferen_core_en(n)	((0x1 << (8 + 16)) | (n << 8))
346fba6e04STony Xie 
356fba6e04STony Xie struct PCTRL_TIMING_TAG {
366fba6e04STony Xie 	uint32_t ddrfreq;
376fba6e04STony Xie 	uint32_t TOGCNT1U;
386fba6e04STony Xie 	uint32_t TINIT;
396fba6e04STony Xie 	uint32_t TRSTH;
406fba6e04STony Xie 	uint32_t TOGCNT100N;
416fba6e04STony Xie 	uint32_t TREFI;
426fba6e04STony Xie 	uint32_t TMRD;
436fba6e04STony Xie 	uint32_t TRFC;
446fba6e04STony Xie 	uint32_t TRP;
456fba6e04STony Xie 	uint32_t TRTW;
466fba6e04STony Xie 	uint32_t TAL;
476fba6e04STony Xie 	uint32_t TCL;
486fba6e04STony Xie 	uint32_t TCWL;
496fba6e04STony Xie 	uint32_t TRAS;
506fba6e04STony Xie 	uint32_t TRC;
516fba6e04STony Xie 	uint32_t TRCD;
526fba6e04STony Xie 	uint32_t TRRD;
536fba6e04STony Xie 	uint32_t TRTP;
546fba6e04STony Xie 	uint32_t TWR;
556fba6e04STony Xie 	uint32_t TWTR;
566fba6e04STony Xie 	uint32_t TEXSR;
576fba6e04STony Xie 	uint32_t TXP;
586fba6e04STony Xie 	uint32_t TXPDLL;
596fba6e04STony Xie 	uint32_t TZQCS;
606fba6e04STony Xie 	uint32_t TZQCSI;
616fba6e04STony Xie 	uint32_t TDQS;
626fba6e04STony Xie 	uint32_t TCKSRE;
636fba6e04STony Xie 	uint32_t TCKSRX;
646fba6e04STony Xie 	uint32_t TCKE;
656fba6e04STony Xie 	uint32_t TMOD;
666fba6e04STony Xie 	uint32_t TRSTL;
676fba6e04STony Xie 	uint32_t TZQCL;
686fba6e04STony Xie 	uint32_t TMRR;
696fba6e04STony Xie 	uint32_t TCKESR;
706fba6e04STony Xie 	uint32_t TDPD;
716fba6e04STony Xie 	uint32_t TREFI_MEM_DDR3;
726fba6e04STony Xie };
736fba6e04STony Xie 
746fba6e04STony Xie struct MSCH_SAVE_REG_TAG {
756fba6e04STony Xie 	uint32_t ddrconf;
766fba6e04STony Xie 	uint32_t ddrtiming;
776fba6e04STony Xie 	uint32_t ddrmode;
786fba6e04STony Xie 	uint32_t readlatency;
796fba6e04STony Xie 	uint32_t activate;
806fba6e04STony Xie 	uint32_t devtodev;
816fba6e04STony Xie };
826fba6e04STony Xie 
836fba6e04STony Xie /* ddr suspend need save reg */
846fba6e04STony Xie struct PCTL_SAVE_REG_TAG {
856fba6e04STony Xie 	uint32_t SCFG;
866fba6e04STony Xie 	uint32_t CMDTSTATEN;
876fba6e04STony Xie 	uint32_t MCFG1;
886fba6e04STony Xie 	uint32_t MCFG;
896fba6e04STony Xie 	uint32_t PPCFG;
906fba6e04STony Xie 	struct PCTRL_TIMING_TAG pctl_timing;
916fba6e04STony Xie 	/* DFI Control Registers */
926fba6e04STony Xie 	uint32_t DFITCTRLDELAY;
936fba6e04STony Xie 	uint32_t DFIODTCFG;
946fba6e04STony Xie 	uint32_t DFIODTCFG1;
956fba6e04STony Xie 	uint32_t DFIODTRANKMAP;
966fba6e04STony Xie 	/* DFI Write Data Registers */
976fba6e04STony Xie 	uint32_t DFITPHYWRDATA;
986fba6e04STony Xie 	uint32_t DFITPHYWRLAT;
996fba6e04STony Xie 	uint32_t DFITPHYWRDATALAT;
1006fba6e04STony Xie 	/* DFI Read Data Registers */
1016fba6e04STony Xie 	uint32_t DFITRDDATAEN;
1026fba6e04STony Xie 	uint32_t DFITPHYRDLAT;
1036fba6e04STony Xie 	/* DFI Update Registers */
1046fba6e04STony Xie 	uint32_t DFITPHYUPDTYPE0;
1056fba6e04STony Xie 	uint32_t DFITPHYUPDTYPE1;
1066fba6e04STony Xie 	uint32_t DFITPHYUPDTYPE2;
1076fba6e04STony Xie 	uint32_t DFITPHYUPDTYPE3;
1086fba6e04STony Xie 	uint32_t DFITCTRLUPDMIN;
1096fba6e04STony Xie 	uint32_t DFITCTRLUPDMAX;
1106fba6e04STony Xie 	uint32_t DFITCTRLUPDDLY;
1116fba6e04STony Xie 	uint32_t DFIUPDCFG;
1126fba6e04STony Xie 	uint32_t DFITREFMSKI;
1136fba6e04STony Xie 	uint32_t DFITCTRLUPDI;
1146fba6e04STony Xie 	/* DFI Status Registers */
1156fba6e04STony Xie 	uint32_t DFISTCFG0;
1166fba6e04STony Xie 	uint32_t DFISTCFG1;
1176fba6e04STony Xie 	uint32_t DFITDRAMCLKEN;
1186fba6e04STony Xie 	uint32_t DFITDRAMCLKDIS;
1196fba6e04STony Xie 	uint32_t DFISTCFG2;
1206fba6e04STony Xie 	/* DFI Low Power Register */
1216fba6e04STony Xie 	uint32_t DFILPCFG0;
1226fba6e04STony Xie };
1236fba6e04STony Xie 
1246fba6e04STony Xie struct DDRPHY_SAVE_REG_TAG {
1256fba6e04STony Xie 	uint32_t PHY_REG0;
1266fba6e04STony Xie 	uint32_t PHY_REG1;
1276fba6e04STony Xie 	uint32_t PHY_REGB;
1286fba6e04STony Xie 	uint32_t PHY_REGC;
1296fba6e04STony Xie 	uint32_t PHY_REG11;
1306fba6e04STony Xie 	uint32_t PHY_REG13;
1316fba6e04STony Xie 	uint32_t PHY_REG14;
1326fba6e04STony Xie 	uint32_t PHY_REG16;
1336fba6e04STony Xie 	uint32_t PHY_REG20;
1346fba6e04STony Xie 	uint32_t PHY_REG21;
1356fba6e04STony Xie 	uint32_t PHY_REG26;
1366fba6e04STony Xie 	uint32_t PHY_REG27;
1376fba6e04STony Xie 	uint32_t PHY_REG28;
1386fba6e04STony Xie 	uint32_t PHY_REG30;
1396fba6e04STony Xie 	uint32_t PHY_REG31;
1406fba6e04STony Xie 	uint32_t PHY_REG36;
1416fba6e04STony Xie 	uint32_t PHY_REG37;
1426fba6e04STony Xie 	uint32_t PHY_REG38;
1436fba6e04STony Xie 	uint32_t PHY_REG40;
1446fba6e04STony Xie 	uint32_t PHY_REG41;
1456fba6e04STony Xie 	uint32_t PHY_REG46;
1466fba6e04STony Xie 	uint32_t PHY_REG47;
1476fba6e04STony Xie 	uint32_t PHY_REG48;
1486fba6e04STony Xie 	uint32_t PHY_REG50;
1496fba6e04STony Xie 	uint32_t PHY_REG51;
1506fba6e04STony Xie 	uint32_t PHY_REG56;
1516fba6e04STony Xie 	uint32_t PHY_REG57;
1526fba6e04STony Xie 	uint32_t PHY_REG58;
1536fba6e04STony Xie 	uint32_t PHY_REGDLL;
1546fba6e04STony Xie 	uint32_t PHY_REGEC;
1556fba6e04STony Xie 	uint32_t PHY_REGED;
1566fba6e04STony Xie 	uint32_t PHY_REGEE;
1576fba6e04STony Xie 	uint32_t PHY_REGEF;
1586fba6e04STony Xie 	uint32_t PHY_REGFB;
1596fba6e04STony Xie 	uint32_t PHY_REGFC;
1606fba6e04STony Xie 	uint32_t PHY_REGFD;
1616fba6e04STony Xie 	uint32_t PHY_REGFE;
1626fba6e04STony Xie };
1636fba6e04STony Xie 
1646fba6e04STony Xie struct BACKUP_REG_TAG {
1656fba6e04STony Xie 	uint32_t tag;
1666fba6e04STony Xie 	uint32_t pctladdr;
1676fba6e04STony Xie 	struct PCTL_SAVE_REG_TAG pctl;
1686fba6e04STony Xie 	uint32_t phyaddr;
1696fba6e04STony Xie 	struct DDRPHY_SAVE_REG_TAG phy;
1706fba6e04STony Xie 	uint32_t nocaddr;
1716fba6e04STony Xie 	struct MSCH_SAVE_REG_TAG noc;
1726fba6e04STony Xie 	uint32_t pllselect;
1736fba6e04STony Xie 	uint32_t phypllockaddr;
1746fba6e04STony Xie 	uint32_t phyplllockmask;
1756fba6e04STony Xie 	uint32_t phyplllockval;
1766fba6e04STony Xie 	uint32_t pllpdstat;
1776fba6e04STony Xie 	uint32_t dpllmodeaddr;
1786fba6e04STony Xie 	uint32_t dpllslowmode;
1796fba6e04STony Xie 	uint32_t dpllnormalmode;
1806fba6e04STony Xie 	uint32_t dpllresetaddr;
1816fba6e04STony Xie 	uint32_t dpllreset;
1826fba6e04STony Xie 	uint32_t dplldereset;
1836fba6e04STony Xie 	uint32_t dpllconaddr;
1846fba6e04STony Xie 	uint32_t dpllcon[4];
1856fba6e04STony Xie 	uint32_t dplllockaddr;
1866fba6e04STony Xie 	uint32_t dplllockmask;
1876fba6e04STony Xie 	uint32_t dplllockval;
1886fba6e04STony Xie 	uint32_t ddrpllsrcdivaddr;
1896fba6e04STony Xie 	uint32_t ddrpllsrcdiv;
1906fba6e04STony Xie 	uint32_t retendisaddr;
1916fba6e04STony Xie 	uint32_t retendisval;
1926fba6e04STony Xie 	uint32_t grfregaddr;
1936fba6e04STony Xie 	uint32_t grfddrcreg;
1946fba6e04STony Xie 	uint32_t crupctlphysoftrstaddr;
1956fba6e04STony Xie 	uint32_t cruresetpctlphy;
1966fba6e04STony Xie 	uint32_t cruderesetphy;
1976fba6e04STony Xie 	uint32_t cruderesetpctlphy;
1986fba6e04STony Xie 	uint32_t physoftrstaddr;
1996fba6e04STony Xie 	uint32_t endtag;
2006fba6e04STony Xie };
2016fba6e04STony Xie 
ddr_get_phy_pll_freq(void)2026fba6e04STony Xie static uint32_t ddr_get_phy_pll_freq(void)
2036fba6e04STony Xie {
2046fba6e04STony Xie 	uint32_t ret = 0;
2056fba6e04STony Xie 	uint32_t fb_div, pre_div;
2066fba6e04STony Xie 
2076fba6e04STony Xie 	fb_div = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEC);
2086fba6e04STony Xie 	fb_div |= (mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGED) & 0x1) << 8;
2096fba6e04STony Xie 
2106fba6e04STony Xie 	pre_div = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEE) & 0xff;
2116fba6e04STony Xie 	ret = 2 * 24 * fb_div / (4 * pre_div);
2126fba6e04STony Xie 
2136fba6e04STony Xie 	return ret;
2146fba6e04STony Xie }
2156fba6e04STony Xie 
ddr_copy(uint32_t * pdest,uint32_t * psrc,uint32_t words)2166fba6e04STony Xie static void ddr_copy(uint32_t *pdest, uint32_t *psrc, uint32_t words)
2176fba6e04STony Xie {
2186fba6e04STony Xie 	uint32_t i;
2196fba6e04STony Xie 
2206fba6e04STony Xie 	for (i = 0; i < words; i++)
2216fba6e04STony Xie 		pdest[i] = psrc[i];
2226fba6e04STony Xie }
2236fba6e04STony Xie 
ddr_get_dpll_cfg(uint32_t * p)2246fba6e04STony Xie static void ddr_get_dpll_cfg(uint32_t *p)
2256fba6e04STony Xie {
2266fba6e04STony Xie 	uint32_t nmhz, NO, NF, NR;
2276fba6e04STony Xie 
2286fba6e04STony Xie 	nmhz = ddr_get_phy_pll_freq();
2296fba6e04STony Xie 	if (nmhz <= 150)
2306fba6e04STony Xie 		NO = 6;
2316fba6e04STony Xie 	else if (nmhz <= 250)
2326fba6e04STony Xie 		NO = 4;
2336fba6e04STony Xie 	else if (nmhz <= 500)
2346fba6e04STony Xie 		NO = 2;
2356fba6e04STony Xie 	else
2366fba6e04STony Xie 		NO = 1;
2376fba6e04STony Xie 
2386fba6e04STony Xie 	NR = 1;
2396fba6e04STony Xie 	NF = 2 * nmhz * NR * NO / 24;
2406fba6e04STony Xie 
2416fba6e04STony Xie 	p[0] = SET_NR(NR) | SET_NO(NO);
2426fba6e04STony Xie 	p[1] = SET_NF(NF);
2436fba6e04STony Xie 	p[2] = SET_NB(NF / 2);
2446fba6e04STony Xie }
2456fba6e04STony Xie 
ddr_reg_save(uint32_t pllpdstat,uint64_t base_addr)2466fba6e04STony Xie void ddr_reg_save(uint32_t pllpdstat, uint64_t base_addr)
2476fba6e04STony Xie {
2486fba6e04STony Xie 	struct BACKUP_REG_TAG *p_ddr_reg = (struct BACKUP_REG_TAG *)base_addr;
2496fba6e04STony Xie 	struct PCTL_SAVE_REG_TAG *pctl_tim = &p_ddr_reg->pctl;
2506fba6e04STony Xie 
2516fba6e04STony Xie 	p_ddr_reg->tag = 0x56313031;
2526fba6e04STony Xie 	p_ddr_reg->pctladdr = DDR_PCTL_BASE;
2536fba6e04STony Xie 	p_ddr_reg->phyaddr = DDR_PHY_BASE;
2546fba6e04STony Xie 	p_ddr_reg->nocaddr = SERVICE_BUS_BASE;
2556fba6e04STony Xie 
2566fba6e04STony Xie 	/* PCTLR */
2576fba6e04STony Xie 	ddr_copy((uint32_t *)&pctl_tim->pctl_timing.TOGCNT1U,
2586fba6e04STony Xie 		 (uint32_t *)(DDR_PCTL_BASE + DDR_PCTL_TOGCNT1U), 35);
2596fba6e04STony Xie 	pctl_tim->pctl_timing.TREFI |= DDR_UPD_REF_ENABLE;
2606fba6e04STony Xie 	pctl_tim->SCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_SCFG);
2616fba6e04STony Xie 	pctl_tim->CMDTSTATEN = mmio_read_32(DDR_PCTL_BASE +
2626fba6e04STony Xie 					    DDR_PCTL_CMDTSTATEN);
2636fba6e04STony Xie 	pctl_tim->MCFG1 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_MCFG1);
2646fba6e04STony Xie 	pctl_tim->MCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_MCFG);
2656fba6e04STony Xie 	pctl_tim->PPCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_PPCFG);
2666fba6e04STony Xie 	pctl_tim->pctl_timing.ddrfreq = mmio_read_32(DDR_PCTL_BASE +
2676fba6e04STony Xie 						     DDR_PCTL_TOGCNT1U * 2);
2686fba6e04STony Xie 	pctl_tim->DFITCTRLDELAY = mmio_read_32(DDR_PCTL_BASE +
2696fba6e04STony Xie 					       DDR_PCTL_DFITCTRLDELAY);
2706fba6e04STony Xie 	pctl_tim->DFIODTCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFIODTCFG);
2716fba6e04STony Xie 	pctl_tim->DFIODTCFG1 = mmio_read_32(DDR_PCTL_BASE +
2726fba6e04STony Xie 					    DDR_PCTL_DFIODTCFG1);
2736fba6e04STony Xie 	pctl_tim->DFIODTRANKMAP = mmio_read_32(DDR_PCTL_BASE +
2746fba6e04STony Xie 					       DDR_PCTL_DFIODTRANKMAP);
2756fba6e04STony Xie 	pctl_tim->DFITPHYWRDATA = mmio_read_32(DDR_PCTL_BASE +
2766fba6e04STony Xie 					       DDR_PCTL_DFITPHYWRDATA);
2776fba6e04STony Xie 	pctl_tim->DFITPHYWRLAT = mmio_read_32(DDR_PCTL_BASE +
2786fba6e04STony Xie 					      DDR_PCTL_DFITPHYWRLAT);
2796fba6e04STony Xie 	pctl_tim->DFITPHYWRDATALAT = mmio_read_32(DDR_PCTL_BASE +
2806fba6e04STony Xie 						  DDR_PCTL_DFITPHYWRDATALAT);
2816fba6e04STony Xie 	pctl_tim->DFITRDDATAEN = mmio_read_32(DDR_PCTL_BASE +
2826fba6e04STony Xie 					      DDR_PCTL_DFITRDDATAEN);
2836fba6e04STony Xie 	pctl_tim->DFITPHYRDLAT = mmio_read_32(DDR_PCTL_BASE +
2846fba6e04STony Xie 					      DDR_PCTL_DFITPHYRDLAT);
2856fba6e04STony Xie 	pctl_tim->DFITPHYUPDTYPE0 = mmio_read_32(DDR_PCTL_BASE +
2866fba6e04STony Xie 						 DDR_PCTL_DFITPHYUPDTYPE0);
2876fba6e04STony Xie 	pctl_tim->DFITPHYUPDTYPE1 = mmio_read_32(DDR_PCTL_BASE +
2886fba6e04STony Xie 						 DDR_PCTL_DFITPHYUPDTYPE1);
2896fba6e04STony Xie 	pctl_tim->DFITPHYUPDTYPE2 = mmio_read_32(DDR_PCTL_BASE +
2906fba6e04STony Xie 						 DDR_PCTL_DFITPHYUPDTYPE2);
2916fba6e04STony Xie 	pctl_tim->DFITPHYUPDTYPE3 = mmio_read_32(DDR_PCTL_BASE +
2926fba6e04STony Xie 						 DDR_PCTL_DFITPHYUPDTYPE3);
2936fba6e04STony Xie 	pctl_tim->DFITCTRLUPDMIN = mmio_read_32(DDR_PCTL_BASE +
2946fba6e04STony Xie 						DDR_PCTL_DFITCTRLUPDMIN);
2956fba6e04STony Xie 	pctl_tim->DFITCTRLUPDMAX = mmio_read_32(DDR_PCTL_BASE +
2966fba6e04STony Xie 						DDR_PCTL_DFITCTRLUPDMAX);
2976fba6e04STony Xie 	pctl_tim->DFITCTRLUPDDLY = mmio_read_32(DDR_PCTL_BASE +
2986fba6e04STony Xie 						DDR_PCTL_DFITCTRLUPDDLY);
2996fba6e04STony Xie 
3006fba6e04STony Xie 	pctl_tim->DFIUPDCFG = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFIUPDCFG);
3016fba6e04STony Xie 	pctl_tim->DFITREFMSKI = mmio_read_32(DDR_PCTL_BASE +
3026fba6e04STony Xie 					     DDR_PCTL_DFITREFMSKI);
3036fba6e04STony Xie 	pctl_tim->DFITCTRLUPDI = mmio_read_32(DDR_PCTL_BASE +
3046fba6e04STony Xie 					      DDR_PCTL_DFITCTRLUPDI);
3056fba6e04STony Xie 	pctl_tim->DFISTCFG0 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFISTCFG0);
3066fba6e04STony Xie 	pctl_tim->DFISTCFG1 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFISTCFG1);
3076fba6e04STony Xie 	pctl_tim->DFITDRAMCLKEN = mmio_read_32(DDR_PCTL_BASE +
3086fba6e04STony Xie 					       DDR_PCTL_DFITDRAMCLKEN);
3096fba6e04STony Xie 	pctl_tim->DFITDRAMCLKDIS = mmio_read_32(DDR_PCTL_BASE +
3106fba6e04STony Xie 						DDR_PCTL_DFITDRAMCLKDIS);
3116fba6e04STony Xie 	pctl_tim->DFISTCFG2 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFISTCFG2);
3126fba6e04STony Xie 	pctl_tim->DFILPCFG0 = mmio_read_32(DDR_PCTL_BASE + DDR_PCTL_DFILPCFG0);
3136fba6e04STony Xie 
3146fba6e04STony Xie 	/* PHY */
3156fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG0 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG0);
3166fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG1 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG1);
3176fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGB = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGB);
3186fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGC = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGC);
3196fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG11 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG11);
3206fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG13 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG13);
3216fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG14 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG14);
3226fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG16 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG16);
3236fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG20 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG20);
3246fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG21 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG21);
3256fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG26 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG26);
3266fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG27 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG27);
3276fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG28 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG28);
3286fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG30 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG30);
3296fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG31 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG31);
3306fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG36 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG36);
3316fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG37 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG37);
3326fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG38 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG38);
3336fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG40 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG40);
3346fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG41 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG41);
3356fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG46 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG46);
3366fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG47 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG47);
3376fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG48 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG48);
3386fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG50 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG50);
3396fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG51 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG51);
3406fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG56 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG56);
3416fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG57 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG57);
3426fba6e04STony Xie 	p_ddr_reg->phy.PHY_REG58 = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG58);
3436fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGDLL = mmio_read_32(DDR_PHY_BASE +
3446fba6e04STony Xie 						 DDR_PHY_REGDLL);
3456fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGEC = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEC);
3466fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGED = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGED);
3476fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGEE = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEE);
3486fba6e04STony Xie 	p_ddr_reg->phy.PHY_REGEF = 0;
3496fba6e04STony Xie 
3506fba6e04STony Xie 	if (mmio_read_32(DDR_PHY_BASE + DDR_PHY_REG2) & 0x2) {
3516fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFB = mmio_read_32(DDR_PHY_BASE +
3526fba6e04STony Xie 							DDR_PHY_REG2C);
3536fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFC = mmio_read_32(DDR_PHY_BASE +
3546fba6e04STony Xie 							DDR_PHY_REG3C);
3556fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFD = mmio_read_32(DDR_PHY_BASE +
3566fba6e04STony Xie 							DDR_PHY_REG4C);
3576fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFE = mmio_read_32(DDR_PHY_BASE +
3586fba6e04STony Xie 							DDR_PHY_REG5C);
3596fba6e04STony Xie 	} else {
3606fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFB = mmio_read_32(DDR_PHY_BASE +
3616fba6e04STony Xie 							DDR_PHY_REGFB);
3626fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFC = mmio_read_32(DDR_PHY_BASE +
3636fba6e04STony Xie 							DDR_PHY_REGFC);
3646fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFD = mmio_read_32(DDR_PHY_BASE +
3656fba6e04STony Xie 							DDR_PHY_REGFD);
3666fba6e04STony Xie 		p_ddr_reg->phy.PHY_REGFE = mmio_read_32(DDR_PHY_BASE +
3676fba6e04STony Xie 							DDR_PHY_REGFE);
3686fba6e04STony Xie 	}
3696fba6e04STony Xie 
3706fba6e04STony Xie 	/* NOC */
3716fba6e04STony Xie 	p_ddr_reg->noc.ddrconf = mmio_read_32(SERVICE_BUS_BASE + MSCH_DDRCONF);
3726fba6e04STony Xie 	p_ddr_reg->noc.ddrtiming = mmio_read_32(SERVICE_BUS_BASE +
3736fba6e04STony Xie 						MSCH_DDRTIMING);
3746fba6e04STony Xie 	p_ddr_reg->noc.ddrmode = mmio_read_32(SERVICE_BUS_BASE + MSCH_DDRMODE);
3756fba6e04STony Xie 	p_ddr_reg->noc.readlatency = mmio_read_32(SERVICE_BUS_BASE +
3766fba6e04STony Xie 						  MSCH_READLATENCY);
3776fba6e04STony Xie 	p_ddr_reg->noc.activate = mmio_read_32(SERVICE_BUS_BASE +
3786fba6e04STony Xie 					       MSCH_ACTIVATE);
3796fba6e04STony Xie 	p_ddr_reg->noc.devtodev = mmio_read_32(SERVICE_BUS_BASE +
3806fba6e04STony Xie 					       MSCH_DEVTODEV);
3816fba6e04STony Xie 
3826fba6e04STony Xie 	p_ddr_reg->pllselect = mmio_read_32(DDR_PHY_BASE + DDR_PHY_REGEE) * 0x1;
3836fba6e04STony Xie 	p_ddr_reg->phypllockaddr = GRF_BASE + GRF_SOC_STATUS0;
3846fba6e04STony Xie 	p_ddr_reg->phyplllockmask = GRF_DDRPHY_LOCK;
3856fba6e04STony Xie 	p_ddr_reg->phyplllockval = 0;
3866fba6e04STony Xie 
3876fba6e04STony Xie 	/* PLLPD */
3886fba6e04STony Xie 	p_ddr_reg->pllpdstat = pllpdstat;
3896fba6e04STony Xie 	/* DPLL */
3906fba6e04STony Xie 	p_ddr_reg->dpllmodeaddr = CRU_BASE + PLL_CONS(DPLL_ID, 3);
3916fba6e04STony Xie 	/* slow mode and power on */
3926fba6e04STony Xie 	p_ddr_reg->dpllslowmode = DPLL_WORK_SLOW_MODE | DPLL_POWER_DOWN;
3936fba6e04STony Xie 	p_ddr_reg->dpllnormalmode = DPLL_WORK_NORMAL_MODE;
3946fba6e04STony Xie 	p_ddr_reg->dpllresetaddr = CRU_BASE + PLL_CONS(DPLL_ID, 3);
3956fba6e04STony Xie 	p_ddr_reg->dpllreset = DPLL_RESET_CONTROL_NORMAL;
3966fba6e04STony Xie 	p_ddr_reg->dplldereset = DPLL_RESET_CONTROL_RESET;
3976fba6e04STony Xie 	p_ddr_reg->dpllconaddr = CRU_BASE + PLL_CONS(DPLL_ID, 0);
3986fba6e04STony Xie 
3996fba6e04STony Xie 	if (p_ddr_reg->pllselect == 0) {
4006fba6e04STony Xie 		p_ddr_reg->dpllcon[0] = (mmio_read_32(CRU_BASE +
4016fba6e04STony Xie 						      PLL_CONS(DPLL_ID, 0))
4026fba6e04STony Xie 							& 0xffff) |
403*79ca7807SJustin Chadwell 					(0xFFFFu << 16);
4046fba6e04STony Xie 		p_ddr_reg->dpllcon[1] = (mmio_read_32(CRU_BASE +
4056fba6e04STony Xie 						      PLL_CONS(DPLL_ID, 1))
4066fba6e04STony Xie 							& 0xffff);
4076fba6e04STony Xie 		p_ddr_reg->dpllcon[2] = (mmio_read_32(CRU_BASE +
4086fba6e04STony Xie 						      PLL_CONS(DPLL_ID, 2))
4096fba6e04STony Xie 							& 0xffff);
4106fba6e04STony Xie 		p_ddr_reg->dpllcon[3] = (mmio_read_32(CRU_BASE +
4116fba6e04STony Xie 						      PLL_CONS(DPLL_ID, 3))
4126fba6e04STony Xie 							& 0xffff) |
413*79ca7807SJustin Chadwell 					(0xFFFFu << 16);
4146fba6e04STony Xie 	} else {
4156fba6e04STony Xie 		ddr_get_dpll_cfg(&p_ddr_reg->dpllcon[0]);
4166fba6e04STony Xie 	}
4176fba6e04STony Xie 
4186fba6e04STony Xie 	p_ddr_reg->pllselect = 0;
4196fba6e04STony Xie 	p_ddr_reg->dplllockaddr = CRU_BASE + PLL_CONS(DPLL_ID, 1);
4206fba6e04STony Xie 	p_ddr_reg->dplllockmask = DPLL_STATUS_LOCK;
4216fba6e04STony Xie 	p_ddr_reg->dplllockval = DPLL_STATUS_LOCK;
4226fba6e04STony Xie 
4236fba6e04STony Xie 	/* SET_DDR_PLL_SRC */
4246fba6e04STony Xie 	p_ddr_reg->ddrpllsrcdivaddr = CRU_BASE + CRU_CLKSELS_CON(13);
4256fba6e04STony Xie 	p_ddr_reg->ddrpllsrcdiv = (mmio_read_32(CRU_BASE + CRU_CLKSELS_CON(13))
4266fba6e04STony Xie 					& DDR_PLL_SRC_MASK)
4276fba6e04STony Xie 					| (DDR_PLL_SRC_MASK << 16);
4286fba6e04STony Xie 	p_ddr_reg->retendisaddr = PMU_BASE + PMU_PWRMD_COM;
4296fba6e04STony Xie 	p_ddr_reg->retendisval = PD_PERI_PWRDN_ENABLE;
4306fba6e04STony Xie 	p_ddr_reg->grfregaddr = GRF_BASE + GRF_DDRC0_CON0;
4316fba6e04STony Xie 	p_ddr_reg->grfddrcreg = (mmio_read_32(GRF_BASE + GRF_DDRC0_CON0) &
4326fba6e04STony Xie 					      DDR_PLL_SRC_MASK) |
4336fba6e04STony Xie 				 (DDR_PLL_SRC_MASK << 16);
4346fba6e04STony Xie 
4356fba6e04STony Xie 	/* pctl phy soft reset */
4366fba6e04STony Xie 	p_ddr_reg->crupctlphysoftrstaddr = CRU_BASE + CRU_SOFTRSTS_CON(10);
4376fba6e04STony Xie 	p_ddr_reg->cruresetpctlphy = DDRCTRL0_PSRSTN_REQ(1) |
4386fba6e04STony Xie 				     DDRCTRL0_SRSTN_REQ(1) |
4396fba6e04STony Xie 				     DDRPHY0_PSRSTN_REQ(1) |
4406fba6e04STony Xie 				     DDRPHY0_SRSTN_REQ(1);
4416fba6e04STony Xie 	p_ddr_reg->cruderesetphy = DDRCTRL0_PSRSTN_REQ(1) |
4426fba6e04STony Xie 				   DDRCTRL0_SRSTN_REQ(1) |
4436fba6e04STony Xie 				   DDRPHY0_PSRSTN_REQ(0) |
4446fba6e04STony Xie 				   DDRPHY0_SRSTN_REQ(0);
4456fba6e04STony Xie 
4466fba6e04STony Xie 	p_ddr_reg->cruderesetpctlphy = DDRCTRL0_PSRSTN_REQ(0) |
4476fba6e04STony Xie 				       DDRCTRL0_SRSTN_REQ(0) |
4486fba6e04STony Xie 				       DDRPHY0_PSRSTN_REQ(0) |
4496fba6e04STony Xie 				       DDRPHY0_SRSTN_REQ(0);
4506fba6e04STony Xie 
4516fba6e04STony Xie 	p_ddr_reg->physoftrstaddr = DDR_PHY_BASE + DDR_PHY_REG0;
4526fba6e04STony Xie 
4536fba6e04STony Xie 	p_ddr_reg->endtag = 0xFFFFFFFF;
4546fba6e04STony Xie }
4556fba6e04STony Xie 
4566fba6e04STony Xie /*
4576fba6e04STony Xie  * "rk3368_ddr_reg_resume_V1.05.bin" is an executable bin which is generated
4586fba6e04STony Xie  * by ARM DS5 for resuming ddr controller. If the soc wakes up from system
4596fba6e04STony Xie  * suspend, ddr needs to be resumed and the resuming code needs to be run in
4606fba6e04STony Xie  * sram. But there is not a way to pointing the resuming code to the PMUSRAM
4616fba6e04STony Xie  * when linking .o files of bl31, so we use the
4626fba6e04STony Xie  * "rk3368_ddr_reg_resume_V1.05.bin" whose code is position-independent and
4636fba6e04STony Xie  * it can be loaded anywhere and run.
4646fba6e04STony Xie  */
4656fba6e04STony Xie static __aligned(4) unsigned int ddr_reg_resume[] = {
4666fba6e04STony Xie 	#include "rk3368_ddr_reg_resume_V1.05.bin"
4676fba6e04STony Xie };
4686fba6e04STony Xie 
ddr_get_resume_code_size(void)4696fba6e04STony Xie uint32_t ddr_get_resume_code_size(void)
4706fba6e04STony Xie {
4716fba6e04STony Xie 	return sizeof(ddr_reg_resume);
4726fba6e04STony Xie }
4736fba6e04STony Xie 
ddr_get_resume_data_size(void)4746fba6e04STony Xie uint32_t ddr_get_resume_data_size(void)
4756fba6e04STony Xie {
4766fba6e04STony Xie 	return sizeof(struct BACKUP_REG_TAG);
4776fba6e04STony Xie }
4786fba6e04STony Xie 
ddr_get_resume_code_base(void)4796fba6e04STony Xie uint32_t *ddr_get_resume_code_base(void)
4806fba6e04STony Xie {
4816fba6e04STony Xie 	return (unsigned int *)ddr_reg_resume;
4826fba6e04STony Xie }
483