Message ID | 20190715182856.21688-8-jagan@amarulasolutions.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
On 2019/7/16 上午2:28, Jagan Teki wrote: > Add support for pctl start for both channel 0, 1 control > and phy registers. > > This would also handle pwrup_srefresh_exit init based > on the channel number. > > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com> > Signed-off-by: YouMin Chen <cym@rock-chips.com> Reviewed-by: Kever Yang <Kever.yang@rock-chips.com> Thanks, - Kever > --- > drivers/ram/rockchip/sdram_rk3399.c | 75 +++++++++++++++++++++-------- > 1 file changed, 55 insertions(+), 20 deletions(-) > > diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c > index 6e944cafd9..084c949728 100644 > --- a/drivers/ram/rockchip/sdram_rk3399.c > +++ b/drivers/ram/rockchip/sdram_rk3399.c > @@ -49,10 +49,11 @@ struct chan_info { > struct dram_info { > #if defined(CONFIG_TPL_BUILD) || \ > (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD)) > - u32 pwrup_srefresh_exit; > + u32 pwrup_srefresh_exit[2]; > struct chan_info chan[2]; > struct clk ddr_clk; > struct rk3399_cru *cru; > + struct rk3399_grf_regs *grf; > struct rk3399_pmucru *pmucru; > struct rk3399_pmusgrf_regs *pmusgrf; > struct rk3399_ddr_cic_regs *cic; > @@ -73,6 +74,11 @@ struct rockchip_dmc_plat { > struct regmap *map; > }; > > +static void *get_ddrc0_con(struct dram_info *dram, u8 channel) > +{ > + return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc0_con1; > +} > + > static void copy_to_reg(u32 *dest, const u32 *src, u32 n) > { > int i; > @@ -328,6 +334,48 @@ static void set_ds_odt(const struct chan_info *chan, > clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value); > } > > +static void pctl_start(struct dram_info *dram, u8 channel) > +{ > + const struct chan_info *chan = &dram->chan[channel]; > + u32 *denali_ctl = chan->pctl->denali_ctl; > + u32 *denali_phy = chan->publ->denali_phy; > + u32 *ddrc0_con = get_ddrc0_con(dram, channel); > + u32 count = 0; > + u32 byte, tmp; > + > + writel(0x01000000, &ddrc0_con); > + > + clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24); > + > + while (!(readl(&denali_ctl[203]) & (1 << 3))) { > + if (count > 1000) { > + printf("%s: Failed to init pctl for channel %d\n", > + __func__, channel); > + while (1) > + ; > + } > + > + udelay(1); > + count++; > + } > + > + writel(0x01000100, &ddrc0_con); > + > + for (byte = 0; byte < 4; byte++) { > + tmp = 0x820; > + writel((tmp << 16) | tmp, &denali_phy[53 + (128 * byte)]); > + writel((tmp << 16) | tmp, &denali_phy[54 + (128 * byte)]); > + writel((tmp << 16) | tmp, &denali_phy[55 + (128 * byte)]); > + writel((tmp << 16) | tmp, &denali_phy[56 + (128 * byte)]); > + writel((tmp << 16) | tmp, &denali_phy[57 + (128 * byte)]); > + > + clrsetbits_le32(&denali_phy[58 + (128 * byte)], 0xffff, tmp); > + } > + > + clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT, > + dram->pwrup_srefresh_exit[channel]); > +} > + > static int phy_io_config(const struct chan_info *chan, > const struct rk3399_sdram_params *params) > { > @@ -498,7 +546,6 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan, > const u32 *params_phy = params->phy_regs.denali_phy; > u32 tmp, tmp1, tmp2; > int ret; > - const ulong timeout_ms = 200; > > /* > * work around controller bug: > @@ -518,8 +565,8 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan, > writel(params->phy_regs.denali_phy[911], &denali_phy[911]); > writel(params->phy_regs.denali_phy[912], &denali_phy[912]); > > - dram->pwrup_srefresh_exit = readl(&denali_ctl[68]) & > - PWRUP_SREFRESH_EXIT; > + dram->pwrup_srefresh_exit[channel] = readl(&denali_ctl[68]) & > + PWRUP_SREFRESH_EXIT; > clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT); > > /* PHY_DLL_RST_EN */ > @@ -580,22 +627,6 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan, > if (ret) > return ret; > > - /* PHY_DLL_RST_EN */ > - clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24); > - > - /* Waiting for PHY and DRAM init complete */ > - tmp = get_timer(0); > - do { > - if (get_timer(tmp) > timeout_ms) { > - pr_err("DRAM (%s): phy failed to lock within %ld ms\n", > - __func__, timeout_ms); > - return -ETIME; > - } > - } while (!(readl(&denali_ctl[203]) & (1 << 3))); > - debug("DRAM (%s): phy locked after %ld ms\n", __func__, get_timer(tmp)); > - > - clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT, > - dram->pwrup_srefresh_exit); > return 0; > } > > @@ -1186,6 +1217,9 @@ static int sdram_init(struct dram_info *dram, > return ret; > } > > + /* start to trigger initialization */ > + pctl_start(dram, channel); > + > /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ > if (dramtype == LPDDR3) > udelay(10); > @@ -1262,6 +1296,7 @@ static int rk3399_dmc_init(struct udevice *dev) > #endif > > priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC); > + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); > priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); > priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF); > priv->pmucru = rockchip_get_pmucru();
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index 6e944cafd9..084c949728 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -49,10 +49,11 @@ struct chan_info { struct dram_info { #if defined(CONFIG_TPL_BUILD) || \ (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD)) - u32 pwrup_srefresh_exit; + u32 pwrup_srefresh_exit[2]; struct chan_info chan[2]; struct clk ddr_clk; struct rk3399_cru *cru; + struct rk3399_grf_regs *grf; struct rk3399_pmucru *pmucru; struct rk3399_pmusgrf_regs *pmusgrf; struct rk3399_ddr_cic_regs *cic; @@ -73,6 +74,11 @@ struct rockchip_dmc_plat { struct regmap *map; }; +static void *get_ddrc0_con(struct dram_info *dram, u8 channel) +{ + return (channel == 0) ? &dram->grf->ddrc0_con0 : &dram->grf->ddrc0_con1; +} + static void copy_to_reg(u32 *dest, const u32 *src, u32 n) { int i; @@ -328,6 +334,48 @@ static void set_ds_odt(const struct chan_info *chan, clrsetbits_le32(&denali_phy[930], 0x1 << 17, reg_value); } +static void pctl_start(struct dram_info *dram, u8 channel) +{ + const struct chan_info *chan = &dram->chan[channel]; + u32 *denali_ctl = chan->pctl->denali_ctl; + u32 *denali_phy = chan->publ->denali_phy; + u32 *ddrc0_con = get_ddrc0_con(dram, channel); + u32 count = 0; + u32 byte, tmp; + + writel(0x01000000, &ddrc0_con); + + clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24); + + while (!(readl(&denali_ctl[203]) & (1 << 3))) { + if (count > 1000) { + printf("%s: Failed to init pctl for channel %d\n", + __func__, channel); + while (1) + ; + } + + udelay(1); + count++; + } + + writel(0x01000100, &ddrc0_con); + + for (byte = 0; byte < 4; byte++) { + tmp = 0x820; + writel((tmp << 16) | tmp, &denali_phy[53 + (128 * byte)]); + writel((tmp << 16) | tmp, &denali_phy[54 + (128 * byte)]); + writel((tmp << 16) | tmp, &denali_phy[55 + (128 * byte)]); + writel((tmp << 16) | tmp, &denali_phy[56 + (128 * byte)]); + writel((tmp << 16) | tmp, &denali_phy[57 + (128 * byte)]); + + clrsetbits_le32(&denali_phy[58 + (128 * byte)], 0xffff, tmp); + } + + clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT, + dram->pwrup_srefresh_exit[channel]); +} + static int phy_io_config(const struct chan_info *chan, const struct rk3399_sdram_params *params) { @@ -498,7 +546,6 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan, const u32 *params_phy = params->phy_regs.denali_phy; u32 tmp, tmp1, tmp2; int ret; - const ulong timeout_ms = 200; /* * work around controller bug: @@ -518,8 +565,8 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan, writel(params->phy_regs.denali_phy[911], &denali_phy[911]); writel(params->phy_regs.denali_phy[912], &denali_phy[912]); - dram->pwrup_srefresh_exit = readl(&denali_ctl[68]) & - PWRUP_SREFRESH_EXIT; + dram->pwrup_srefresh_exit[channel] = readl(&denali_ctl[68]) & + PWRUP_SREFRESH_EXIT; clrbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT); /* PHY_DLL_RST_EN */ @@ -580,22 +627,6 @@ static int pctl_cfg(struct dram_info *dram, const struct chan_info *chan, if (ret) return ret; - /* PHY_DLL_RST_EN */ - clrsetbits_le32(&denali_phy[957], 0x3 << 24, 0x2 << 24); - - /* Waiting for PHY and DRAM init complete */ - tmp = get_timer(0); - do { - if (get_timer(tmp) > timeout_ms) { - pr_err("DRAM (%s): phy failed to lock within %ld ms\n", - __func__, timeout_ms); - return -ETIME; - } - } while (!(readl(&denali_ctl[203]) & (1 << 3))); - debug("DRAM (%s): phy locked after %ld ms\n", __func__, get_timer(tmp)); - - clrsetbits_le32(&denali_ctl[68], PWRUP_SREFRESH_EXIT, - dram->pwrup_srefresh_exit); return 0; } @@ -1186,6 +1217,9 @@ static int sdram_init(struct dram_info *dram, return ret; } + /* start to trigger initialization */ + pctl_start(dram, channel); + /* LPDDR2/LPDDR3 need to wait DAI complete, max 10us */ if (dramtype == LPDDR3) udelay(10); @@ -1262,6 +1296,7 @@ static int rk3399_dmc_init(struct udevice *dev) #endif priv->cic = syscon_get_first_range(ROCKCHIP_SYSCON_CIC); + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF); priv->pmusgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF); priv->pmucru = rockchip_get_pmucru();