diff options
| author | Caesar Wang <wxt@rock-chips.com> | 2016-08-25 08:38:23 +0800 | 
|---|---|---|
| committer | Caesar Wang <wxt@rock-chips.com> | 2016-08-25 08:39:16 +0800 | 
| commit | 863edcea43425dd31168724710411a74b1f6c666 (patch) | |
| tree | 6571256605ac01352810fbac36c0dd32b9b69419 | |
| parent | fe877779ee7bfd1c244be5104a3c89c95ce039b0 (diff) | |
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
| -rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dram.c | 30 | ||||
| -rw-r--r-- | plat/rockchip/rk3399/drivers/dram/dram.h | 57 | 
2 files changed, 48 insertions, 39 deletions
| diff --git a/plat/rockchip/rk3399/drivers/dram/dram.c b/plat/rockchip/rk3399/drivers/dram/dram.c index 3b39e8b2..ddae84d3 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.c +++ b/plat/rockchip/rk3399/drivers/dram/dram.c @@ -90,6 +90,7 @@ static struct rk3399_ddr_publ_regs *const rk3399_ddr_publ[2] = {  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 @@ uint32_t exit_low_power(void)  			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 @@ uint32_t exit_low_power(void)  				(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 @@ void resume_low_power(uint32_t low_power)  		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 @@ static void dram_low_power_config(struct drv_odt_lp_config *lp_config)  	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 @@ static void dram_low_power_config(struct drv_odt_lp_config *lp_config)  	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 @@ static void dram_low_power_config(struct drv_odt_lp_config *lp_config)  			      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 @@ static void dram_low_power_config(struct drv_odt_lp_config *lp_config)  		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 @@ uint64_t ddr_set_rate(uint64_t hz)  		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 ad344e20..62c5170a 100644 --- a/plat/rockchip/rk3399/drivers/dram/dram.h +++ b/plat/rockchip/rk3399/drivers/dram/dram.h @@ -229,34 +229,35 @@ struct rk3399_sdram_default_config {  };  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;  }; | 
