Re: [U-Boot] [PATCH v2 2/3] rk3288: sdram: auto-detect the capacity
Hi Simon, On 09/23/2016 10:53 AM, Simon Glass wrote: Hi Kever, On 19 September 2016 at 21:28, Kever Yang wrote: Add support for rk3288 dram capacity auto detect, support DDR3 and LPDDR3, DDR2 is not supported. The program will automatically detect: - channel number - rank number - column address number - row address number The dts file do not need to describe those info after apply this patch. Signed-off-by: Kever Yang --- Changes in v2: - update code for OF_PLATDATA enabled - bug fix for ddrconfig arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 244 ++- 1 file changed, 202 insertions(+), 42 deletions(-) Tested on firefly-rk3288: Tested-by: Simon Glass Thanks for your test. diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c index cf9ef2e..b3dc251 100644 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c @@ -57,6 +57,10 @@ struct rk3288_sdram_params { struct regmap *map; }; +#define TEST_PATTEN0x5aa5f00f +#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4) +#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4) + #ifdef CONFIG_SPL_BUILD static void copy_to_reg(u32 *dest, const u32 *src, u32 n) { @@ -214,7 +218,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel, } static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, -const struct rk3288_sdram_params *sdram_params, +struct rk3288_sdram_params *sdram_params, struct rk3288_grf *grf) { unsigned int burstlen; @@ -264,7 +268,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, } static void phy_cfg(const struct chan_info *chan, u32 channel, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; struct rk3288_msch *msch = chan->msch; @@ -446,7 +450,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel, } static int data_training(const struct chan_info *chan, u32 channel, -const struct rk3288_sdram_params *sdram_params) +struct rk3288_sdram_params *sdram_params) { unsigned int j; int ret = 0; @@ -549,7 +553,7 @@ static void move_to_access_state(const struct chan_info *chan) } static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, -const struct rk3288_sdram_params *sdram_params) +struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; @@ -563,7 +567,7 @@ static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, } static void dram_all_config(const struct dram_info *dram, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { unsigned int chan; u32 sys_reg = 0; @@ -589,9 +593,173 @@ static void dram_all_config(const struct dram_info *dram, writel(sys_reg, &dram->pmu->sys_reg[2]); rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); } +const int ddrconf_table[] = { + /* row col,bw */ + 0, + ((1 << 4) | 1), + ((2 << 4) | 1), + ((3 << 4) | 1), + ((4 << 4) | 1), + ((1 << 4) | 2), + ((2 << 4) | 2), + ((3 << 4) | 2), + ((1 << 4) | 0), + ((2 << 4) | 0), + ((3 << 4) | 0), + 0, + 0, + 0, + 0, + ((4 << 4) | 2), +}; + +static int sdram_rank_bw_detect(struct dram_info *dram, int channel, + struct rk3288_sdram_params *sdram_params) +{ + int reg; + int need_trainig = 0; + const struct chan_info *chan = &dram->chan[channel]; + struct rk3288_ddr_publ *publ = chan->publ; + + if (-1 == data_training(chan, channel, sdram_params)) { + reg = readl(&publ->datx8[0].dxgsr[0]); + /* Check the result for rank 0 */ + if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { + debug("data training fail!\n"); + return -EIO; + } else if ((channel == 1) && + (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { + sdram_params->num_channels = 1; + } + + /* Check the result for rank 1 */ + if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { + sdram_params->ch[channel].rank = 1; + clrsetbits_le32(&publ->pgcr, 0xF << 18, + sdram_params->ch[channel].rank << 18); + need_trainig = 1; + } + reg = readl(&publ->datx8[2].dxgsr[0]); + if (reg & (1 << 4))
Re: [U-Boot] [PATCH v2 2/3] rk3288: sdram: auto-detect the capacity
On 2016-09-19, Kever Yang wrote: > Add support for rk3288 dram capacity auto detect, support DDR3 and > LPDDR3, DDR2 is not supported. > The program will automatically detect: > - channel number > - rank number > - column address number > - row address number > > The dts file do not need to describe those info after apply this patch. > > Signed-off-by: Kever Yang Tested on firefly-rk3288, 2GB and 4GB ram board variants, using u-boot 2016.11-rc1. Tested-by: Vagrant Cascadian > --- > > Changes in v2: > - update code for OF_PLATDATA enabled > - bug fix for ddrconfig > > arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 244 > ++- > 1 file changed, 202 insertions(+), 42 deletions(-) > > diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > index cf9ef2e..b3dc251 100644 > --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > @@ -57,6 +57,10 @@ struct rk3288_sdram_params { > struct regmap *map; > }; > > +#define TEST_PATTEN 0x5aa5f00f > +#define DQS_GATE_TRAINING_ERROR_RANK0(1 << 4) > +#define DQS_GATE_TRAINING_ERROR_RANK1(2 << 4) > + > #ifdef CONFIG_SPL_BUILD > static void copy_to_reg(u32 *dest, const u32 *src, u32 n) > { > @@ -214,7 +218,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, > uint channel, > } > > static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, > - const struct rk3288_sdram_params *sdram_params, > + struct rk3288_sdram_params *sdram_params, >struct rk3288_grf *grf) > { > unsigned int burstlen; > @@ -264,7 +268,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl > *pctl, > } > > static void phy_cfg(const struct chan_info *chan, u32 channel, > - const struct rk3288_sdram_params *sdram_params) > + struct rk3288_sdram_params *sdram_params) > { > struct rk3288_ddr_publ *publ = chan->publ; > struct rk3288_msch *msch = chan->msch; > @@ -446,7 +450,7 @@ static void set_bandwidth_ratio(const struct chan_info > *chan, u32 channel, > } > > static int data_training(const struct chan_info *chan, u32 channel, > - const struct rk3288_sdram_params *sdram_params) > + struct rk3288_sdram_params *sdram_params) > { > unsigned int j; > int ret = 0; > @@ -549,7 +553,7 @@ static void move_to_access_state(const struct chan_info > *chan) > } > > static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, > - const struct rk3288_sdram_params *sdram_params) > + struct rk3288_sdram_params *sdram_params) > { > struct rk3288_ddr_publ *publ = chan->publ; > > @@ -563,7 +567,7 @@ static void dram_cfg_rbc(const struct chan_info *chan, > u32 chnum, > } > > static void dram_all_config(const struct dram_info *dram, > - const struct rk3288_sdram_params *sdram_params) > + struct rk3288_sdram_params *sdram_params) > { > unsigned int chan; > u32 sys_reg = 0; > @@ -589,9 +593,173 @@ static void dram_all_config(const struct dram_info > *dram, > writel(sys_reg, &dram->pmu->sys_reg[2]); > rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); > } > +const int ddrconf_table[] = { > + /* row col,bw */ > + 0, > + ((1 << 4) | 1), > + ((2 << 4) | 1), > + ((3 << 4) | 1), > + ((4 << 4) | 1), > + ((1 << 4) | 2), > + ((2 << 4) | 2), > + ((3 << 4) | 2), > + ((1 << 4) | 0), > + ((2 << 4) | 0), > + ((3 << 4) | 0), > + 0, > + 0, > + 0, > + 0, > + ((4 << 4) | 2), > +}; > + > +static int sdram_rank_bw_detect(struct dram_info *dram, int channel, > + struct rk3288_sdram_params *sdram_params) > +{ > + int reg; > + int need_trainig = 0; > + const struct chan_info *chan = &dram->chan[channel]; > + struct rk3288_ddr_publ *publ = chan->publ; > + > + if (-1 == data_training(chan, channel, sdram_params)) { > + reg = readl(&publ->datx8[0].dxgsr[0]); > + /* Check the result for rank 0 */ > + if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { > + debug("data training fail!\n"); > + return -EIO; > + } else if ((channel == 1) && > +(reg & DQS_GATE_TRAINING_ERROR_RANK0)) { > + sdram_params->num_channels = 1; > + } > + > + /* Check the result for rank 1 */ > + if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { > + sdram_params->ch[channel].rank = 1; > + clrsetbits_le32(&publ->pgcr, 0xF << 18, > + sdram_params->ch[channel].rank << 18); > + need_trainig = 1; > + }
Re: [U-Boot] [PATCH v2 2/3] rk3288: sdram: auto-detect the capacity
Hi Kever, On 19 September 2016 at 21:28, Kever Yang wrote: > Add support for rk3288 dram capacity auto detect, support DDR3 and > LPDDR3, DDR2 is not supported. > The program will automatically detect: > - channel number > - rank number > - column address number > - row address number > > The dts file do not need to describe those info after apply this patch. > > Signed-off-by: Kever Yang > --- > > Changes in v2: > - update code for OF_PLATDATA enabled > - bug fix for ddrconfig > > arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 244 > ++- > 1 file changed, 202 insertions(+), 42 deletions(-) Tested on firefly-rk3288: Tested-by: Simon Glass > > diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > index cf9ef2e..b3dc251 100644 > --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c > @@ -57,6 +57,10 @@ struct rk3288_sdram_params { > struct regmap *map; > }; > > +#define TEST_PATTEN0x5aa5f00f > +#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4) > +#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4) > + > #ifdef CONFIG_SPL_BUILD > static void copy_to_reg(u32 *dest, const u32 *src, u32 n) > { > @@ -214,7 +218,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, > uint channel, > } > > static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, > -const struct rk3288_sdram_params *sdram_params, > +struct rk3288_sdram_params *sdram_params, > struct rk3288_grf *grf) > { > unsigned int burstlen; > @@ -264,7 +268,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl > *pctl, > } > > static void phy_cfg(const struct chan_info *chan, u32 channel, > - const struct rk3288_sdram_params *sdram_params) > + struct rk3288_sdram_params *sdram_params) > { > struct rk3288_ddr_publ *publ = chan->publ; > struct rk3288_msch *msch = chan->msch; > @@ -446,7 +450,7 @@ static void set_bandwidth_ratio(const struct chan_info > *chan, u32 channel, > } > > static int data_training(const struct chan_info *chan, u32 channel, > -const struct rk3288_sdram_params *sdram_params) > +struct rk3288_sdram_params *sdram_params) > { > unsigned int j; > int ret = 0; > @@ -549,7 +553,7 @@ static void move_to_access_state(const struct chan_info > *chan) > } > > static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, > -const struct rk3288_sdram_params *sdram_params) > +struct rk3288_sdram_params *sdram_params) > { > struct rk3288_ddr_publ *publ = chan->publ; > > @@ -563,7 +567,7 @@ static void dram_cfg_rbc(const struct chan_info *chan, > u32 chnum, > } > > static void dram_all_config(const struct dram_info *dram, > - const struct rk3288_sdram_params *sdram_params) > + struct rk3288_sdram_params *sdram_params) > { > unsigned int chan; > u32 sys_reg = 0; > @@ -589,9 +593,173 @@ static void dram_all_config(const struct dram_info > *dram, > writel(sys_reg, &dram->pmu->sys_reg[2]); > rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); > } > +const int ddrconf_table[] = { > + /* row col,bw */ > + 0, > + ((1 << 4) | 1), > + ((2 << 4) | 1), > + ((3 << 4) | 1), > + ((4 << 4) | 1), > + ((1 << 4) | 2), > + ((2 << 4) | 2), > + ((3 << 4) | 2), > + ((1 << 4) | 0), > + ((2 << 4) | 0), > + ((3 << 4) | 0), > + 0, > + 0, > + 0, > + 0, > + ((4 << 4) | 2), > +}; > + > +static int sdram_rank_bw_detect(struct dram_info *dram, int channel, > + struct rk3288_sdram_params *sdram_params) > +{ > + int reg; > + int need_trainig = 0; > + const struct chan_info *chan = &dram->chan[channel]; > + struct rk3288_ddr_publ *publ = chan->publ; > + > + if (-1 == data_training(chan, channel, sdram_params)) { > + reg = readl(&publ->datx8[0].dxgsr[0]); > + /* Check the result for rank 0 */ > + if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { > + debug("data training fail!\n"); > + return -EIO; > + } else if ((channel == 1) && > + (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { > + sdram_params->num_channels = 1; > + } > + > + /* Check the result for rank 1 */ > + if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { > + sdram_params->ch[channel].rank = 1; > + clrsetbits_le32(&publ->pgcr, 0xF << 18, > + sdram_params->ch[channel].rank << 18); > +
[U-Boot] [PATCH v2 2/3] rk3288: sdram: auto-detect the capacity
Add support for rk3288 dram capacity auto detect, support DDR3 and LPDDR3, DDR2 is not supported. The program will automatically detect: - channel number - rank number - column address number - row address number The dts file do not need to describe those info after apply this patch. Signed-off-by: Kever Yang --- Changes in v2: - update code for OF_PLATDATA enabled - bug fix for ddrconfig arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 244 ++- 1 file changed, 202 insertions(+), 42 deletions(-) diff --git a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c index cf9ef2e..b3dc251 100644 --- a/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/sdram_rk3288.c @@ -57,6 +57,10 @@ struct rk3288_sdram_params { struct regmap *map; }; +#define TEST_PATTEN0x5aa5f00f +#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4) +#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4) + #ifdef CONFIG_SPL_BUILD static void copy_to_reg(u32 *dest, const u32 *src, u32 n) { @@ -214,7 +218,7 @@ static void ddr_set_en_bst_odt(struct rk3288_grf *grf, uint channel, } static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, -const struct rk3288_sdram_params *sdram_params, +struct rk3288_sdram_params *sdram_params, struct rk3288_grf *grf) { unsigned int burstlen; @@ -264,7 +268,7 @@ static void pctl_cfg(u32 channel, struct rk3288_ddr_pctl *pctl, } static void phy_cfg(const struct chan_info *chan, u32 channel, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; struct rk3288_msch *msch = chan->msch; @@ -446,7 +450,7 @@ static void set_bandwidth_ratio(const struct chan_info *chan, u32 channel, } static int data_training(const struct chan_info *chan, u32 channel, -const struct rk3288_sdram_params *sdram_params) +struct rk3288_sdram_params *sdram_params) { unsigned int j; int ret = 0; @@ -549,7 +553,7 @@ static void move_to_access_state(const struct chan_info *chan) } static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, -const struct rk3288_sdram_params *sdram_params) +struct rk3288_sdram_params *sdram_params) { struct rk3288_ddr_publ *publ = chan->publ; @@ -563,7 +567,7 @@ static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum, } static void dram_all_config(const struct dram_info *dram, - const struct rk3288_sdram_params *sdram_params) + struct rk3288_sdram_params *sdram_params) { unsigned int chan; u32 sys_reg = 0; @@ -589,9 +593,173 @@ static void dram_all_config(const struct dram_info *dram, writel(sys_reg, &dram->pmu->sys_reg[2]); rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, sdram_params->base.stride); } +const int ddrconf_table[] = { + /* row col,bw */ + 0, + ((1 << 4) | 1), + ((2 << 4) | 1), + ((3 << 4) | 1), + ((4 << 4) | 1), + ((1 << 4) | 2), + ((2 << 4) | 2), + ((3 << 4) | 2), + ((1 << 4) | 0), + ((2 << 4) | 0), + ((3 << 4) | 0), + 0, + 0, + 0, + 0, + ((4 << 4) | 2), +}; + +static int sdram_rank_bw_detect(struct dram_info *dram, int channel, + struct rk3288_sdram_params *sdram_params) +{ + int reg; + int need_trainig = 0; + const struct chan_info *chan = &dram->chan[channel]; + struct rk3288_ddr_publ *publ = chan->publ; + + if (-1 == data_training(chan, channel, sdram_params)) { + reg = readl(&publ->datx8[0].dxgsr[0]); + /* Check the result for rank 0 */ + if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { + debug("data training fail!\n"); + return -EIO; + } else if ((channel == 1) && + (reg & DQS_GATE_TRAINING_ERROR_RANK0)) { + sdram_params->num_channels = 1; + } + + /* Check the result for rank 1 */ + if (reg & DQS_GATE_TRAINING_ERROR_RANK1) { + sdram_params->ch[channel].rank = 1; + clrsetbits_le32(&publ->pgcr, 0xF << 18, + sdram_params->ch[channel].rank << 18); + need_trainig = 1; + } + reg = readl(&publ->datx8[2].dxgsr[0]); + if (reg & (1 << 4)) { + sdram_params->ch[channel].bw = 1; + set_bandwidth_ratio(chan, channel, + sdram_params->ch[channel].bw, +