rockchip: enable or disable auto power down base on frequency

add auto_pd_dis_freq parameter, we can pass a frequency from kernel
to disable or enable ddr auto power down function.

Change-Id: Ie30914701336c59047c380381c6b75dd76a89562
diff --git a/plat/rockchip/rk3399/drivers/dram/dram.c b/plat/rockchip/rk3399/drivers/dram/dram.c
index 3b39e8b..ddae84d 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram.c
+++ b/plat/rockchip/rk3399/drivers/dram/dram.c
@@ -90,6 +90,7 @@
 struct rk3399_dram_status {
 	uint32_t current_index;
 	uint32_t index_freq[2];
+	uint32_t low_power_stat;
 	struct timing_related_config timing_config;
 	struct drv_odt_lp_config drv_odt_lp_cfg;
 };
@@ -2215,9 +2216,6 @@
 			continue;
 
 		/* exit stdby mode */
-		low_power |=
-		    ((read_32(&rk3399_ddr_cic->cic_ctrl1) >>
-		      channel) & 0x1) << (3 + 8 * channel);
 		write_32(&rk3399_ddr_cic->cic_ctrl1,
 			 (1 << (channel + 16)) | (0 << channel));
 		/* exit external self-refresh */
@@ -2229,9 +2227,7 @@
 				(1 << channel)))
 			;
 		/* exit auto low-power */
-		low_power |= (read_32(&ddr_pctl_regs->denali_ctl[101]) &
-				      0xf) << (8 * channel);
-		clrbits_32(&ddr_pctl_regs->denali_ctl[101], 0xf);
+		clrbits_32(&ddr_pctl_regs->denali_ctl[101], 0x7);
 		/* lp_cmd to exit */
 		if (((read_32(&ddr_pctl_regs->denali_ctl[100]) >> 24) &
 			      0x7f) != 0x40) {
@@ -2266,7 +2262,7 @@
 		val = (low_power >> (4 + 8 * channel)) & 0x1;
 		setbits_32(PMU_BASE + PMU_SFT_CON, val << tmp);
 		/* resume auto low-power */
-		val = (low_power >> (8 * channel)) & 0xf;
+		val = (low_power >> (8 * channel)) & 0x7;
 		setbits_32(&ddr_pctl_regs->denali_ctl[101], val);
 		/* resume stdby mode */
 		val = (low_power >> (3 + 8 * channel)) & 0x1;
@@ -2329,6 +2325,7 @@
 	uint32_t tmp, tmp1, i;
 	uint32_t ch_cnt = rk3399_dram_status.timing_config.ch_cnt;
 	uint32_t dram_type = rk3399_dram_status.timing_config.dram_type;
+	uint32_t *low_power = &rk3399_dram_status.low_power_stat;
 
 	if (dram_type == LPDDR4)
 		tmp = (lp_config->srpd_lite_idle << 16) |
@@ -2341,6 +2338,8 @@
 	else
 		tmp1 = (3 << 16) | (0x7 << 8) | 7;
 
+	*low_power = 0;
+
 	for (i = 0; i < ch_cnt; i++) {
 		write_32(&rk3399_ddr_pctl[i]->denali_ctl[102], tmp);
 		clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[103], 0xffff,
@@ -2348,6 +2347,7 @@
 			      lp_config->sr_idle);
 		clrsetbits_32(&rk3399_ddr_pctl[i]->denali_ctl[101],
 			      0x70f0f, tmp1);
+		*low_power |= (7 << (8 * i));
 	}
 
 	/* standby idle */
@@ -2358,20 +2358,24 @@
 		write_32(GRF_BASE + GRF_DDRC1_CON1,
 			 (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) |
 			 ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7)));
-		if (lp_config->standby_idle)
+		if (lp_config->standby_idle) {
 			tmp = 0x002a002a;
-		else
+			*low_power |= (1 << 11);
+		} else {
 			tmp = 0;
+		}
 		write_32(&rk3399_ddr_cic->cic_ctrl1, tmp);
 	}
 
 	write_32(GRF_BASE + GRF_DDRC0_CON1,
 		 (((0x1<<4) | (0x1<<5) | (0x1<<6) | (0x1<<7)) << 16) |
 		 ((0x1<<4) | (0x0<<5) | (0x1<<6) | (0x1<<7)));
-	if (lp_config->standby_idle)
+	if (lp_config->standby_idle) {
 		tmp = 0x00150015;
-	else
+		*low_power |= (1 << 3);
+	} else {
 		tmp = 0;
+	}
 	write_32(&rk3399_ddr_cic->cic_ctrl1, tmp);
 }
 
@@ -2513,6 +2517,10 @@
 		gen_rk3399_set_odt(0);
 
 	rk3399_dram_status.current_index = index;
+
+	if (mhz < dts_parameter.auto_pd_dis_freq)
+		low_power |= rk3399_dram_status.low_power_stat;
+
 	resume_low_power(low_power);
 out:
 	return mhz;
diff --git a/plat/rockchip/rk3399/drivers/dram/dram.h b/plat/rockchip/rk3399/drivers/dram/dram.h
index ad344e2..62c5170 100644
--- a/plat/rockchip/rk3399/drivers/dram/dram.h
+++ b/plat/rockchip/rk3399/drivers/dram/dram.h
@@ -229,34 +229,35 @@
 };
 
 struct  ddr_dts_config_timing {
-	uint32_t ddr3_speed_bin;
-	uint32_t pd_idle;
-	uint32_t sr_idle;
-	uint32_t sr_mc_gate_idle;
-	uint32_t srpd_lite_idle;
-	uint32_t standby_idle;
-	uint32_t ddr3_dll_dis_freq;
-	uint32_t phy_dll_dis_freq;
-	uint32_t ddr3_odt_dis_freq;
-	uint32_t ddr3_drv;
-	uint32_t ddr3_odt;
-	uint32_t phy_ddr3_ca_drv;
-	uint32_t phy_ddr3_dq_drv;
-	uint32_t phy_ddr3_odt;
-	uint32_t lpddr3_odt_dis_freq;
-	uint32_t lpddr3_drv;
-	uint32_t lpddr3_odt;
-	uint32_t phy_lpddr3_ca_drv;
-	uint32_t phy_lpddr3_dq_drv;
-	uint32_t phy_lpddr3_odt;
-	uint32_t lpddr4_odt_dis_freq;
-	uint32_t lpddr4_drv;
-	uint32_t lpddr4_dq_odt;
-	uint32_t lpddr4_ca_odt;
-	uint32_t phy_lpddr4_ca_drv;
-	uint32_t phy_lpddr4_ck_cs_drv;
-	uint32_t phy_lpddr4_dq_drv;
-	uint32_t phy_lpddr4_odt;
+	unsigned int ddr3_speed_bin;
+	unsigned int pd_idle;
+	unsigned int sr_idle;
+	unsigned int sr_mc_gate_idle;
+	unsigned int srpd_lite_idle;
+	unsigned int standby_idle;
+	unsigned int auto_pd_dis_freq;
+	unsigned int ddr3_dll_dis_freq;
+	unsigned int phy_dll_dis_freq;
+	unsigned int ddr3_odt_dis_freq;
+	unsigned int ddr3_drv;
+	unsigned int ddr3_odt;
+	unsigned int phy_ddr3_ca_drv;
+	unsigned int phy_ddr3_dq_drv;
+	unsigned int phy_ddr3_odt;
+	unsigned int lpddr3_odt_dis_freq;
+	unsigned int lpddr3_drv;
+	unsigned int lpddr3_odt;
+	unsigned int phy_lpddr3_ca_drv;
+	unsigned int phy_lpddr3_dq_drv;
+	unsigned int phy_lpddr3_odt;
+	unsigned int lpddr4_odt_dis_freq;
+	unsigned int lpddr4_drv;
+	unsigned int lpddr4_dq_odt;
+	unsigned int lpddr4_ca_odt;
+	unsigned int phy_lpddr4_ca_drv;
+	unsigned int phy_lpddr4_ck_cs_drv;
+	unsigned int phy_lpddr4_dq_drv;
+	unsigned int phy_lpddr4_odt;
 	uint32_t available;
 };