summaryrefslogtreecommitdiff
path: root/drivers/ram/rockchip
diff options
context:
space:
mode:
authorKever Yang <kever.yang@rock-chips.com>2019-08-12 15:02:29 +0300
committerKever Yang <kever.yang@rock-chips.com>2019-08-23 10:27:40 +0300
commite0f907efa529a2fe106cd585bd94730b1cf0410c (patch)
treee614c410567ae0868f0e6f24428f35c940d5488f /drivers/ram/rockchip
parentc399dca83434290ac502207f2d6db13c59d89267 (diff)
downloadu-boot-e0f907efa529a2fe106cd585bd94730b1cf0410c.tar.xz
ram: rk3399: update cap and ddrconfig for each channel after init
We need to store all the ram related cap/map info back to register for each channel after all the init has been done in case some of register was reset during the process. Signed-off-by: YouMin Chen <cym@rock-chips.com> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Diffstat (limited to 'drivers/ram/rockchip')
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c159
1 files changed, 81 insertions, 78 deletions
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 81fc71c051..ed70137ce7 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -1488,6 +1488,84 @@ static void dram_all_config(struct dram_info *dram,
clrsetbits_le32(&dram->cru->glb_rst_con, 0x3, 0x3);
}
+static void set_cap_relate_config(const struct chan_info *chan,
+ struct rk3399_sdram_params *params,
+ unsigned int channel)
+{
+ u32 *denali_ctl = chan->pctl->denali_ctl;
+ u32 tmp;
+ struct rk3399_msch_timings *noc_timing;
+
+ if (params->base.dramtype == LPDDR3) {
+ tmp = (8 << params->ch[channel].cap_info.bw) /
+ (8 << params->ch[channel].cap_info.dbw);
+
+ /**
+ * memdata_ratio
+ * 1 -> 0, 2 -> 1, 4 -> 2
+ */
+ clrsetbits_le32(&denali_ctl[197], 0x7,
+ (tmp >> 1));
+ clrsetbits_le32(&denali_ctl[198], 0x7 << 8,
+ (tmp >> 1) << 8);
+ }
+
+ noc_timing = &params->ch[channel].noc_timings;
+
+ /*
+ * noc timing bw relate timing is 32 bit, and real bw is 16bit
+ * actually noc reg is setting at function dram_all_config
+ */
+ if (params->ch[channel].cap_info.bw == 16 &&
+ noc_timing->ddrmode.b.mwrsize == 2) {
+ if (noc_timing->ddrmode.b.burstsize)
+ noc_timing->ddrmode.b.burstsize -= 1;
+ noc_timing->ddrmode.b.mwrsize -= 1;
+ noc_timing->ddrtimingc0.b.burstpenalty *= 2;
+ noc_timing->ddrtimingc0.b.wrtomwr *= 2;
+ }
+}
+
+static u32 calculate_ddrconfig(struct rk3399_sdram_params *params, u32 channel)
+{
+ unsigned int cs0_row = params->ch[channel].cap_info.cs0_row;
+ unsigned int col = params->ch[channel].cap_info.col;
+ unsigned int bw = params->ch[channel].cap_info.bw;
+ u16 ddr_cfg_2_rbc[] = {
+ /*
+ * [6] highest bit col
+ * [5:3] max row(14+n)
+ * [2] insertion row
+ * [1:0] col(9+n),col, data bus 32bit
+ *
+ * highbitcol, max_row, insertion_row, col
+ */
+ ((0 << 6) | (2 << 3) | (0 << 2) | 0), /* 0 */
+ ((0 << 6) | (2 << 3) | (0 << 2) | 1), /* 1 */
+ ((0 << 6) | (1 << 3) | (0 << 2) | 2), /* 2 */
+ ((0 << 6) | (0 << 3) | (0 << 2) | 3), /* 3 */
+ ((0 << 6) | (2 << 3) | (1 << 2) | 1), /* 4 */
+ ((0 << 6) | (1 << 3) | (1 << 2) | 2), /* 5 */
+ ((1 << 6) | (0 << 3) | (0 << 2) | 2), /* 6 */
+ ((1 << 6) | (1 << 3) | (0 << 2) | 2), /* 7 */
+ };
+ u32 i;
+
+ col -= (bw == 2) ? 0 : 1;
+ col -= 9;
+
+ for (i = 0; i < 4; i++) {
+ if ((col == (ddr_cfg_2_rbc[i] & 0x3)) &&
+ (cs0_row <= (((ddr_cfg_2_rbc[i] >> 3) & 0x7) + 14)))
+ break;
+ }
+
+ if (i >= 4)
+ i = -EINVAL;
+
+ return i;
+}
+
#if !defined(CONFIG_RAM_RK3399_LPDDR4)
static int default_data_training(struct dram_info *dram, u32 channel, u8 rank,
struct rk3399_sdram_params *params)
@@ -1588,84 +1666,6 @@ static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
}
-static void set_cap_relate_config(const struct chan_info *chan,
- struct rk3399_sdram_params *params,
- unsigned int channel)
-{
- u32 *denali_ctl = chan->pctl->denali_ctl;
- u32 tmp;
- struct rk3399_msch_timings *noc_timing;
-
- if (params->base.dramtype == LPDDR3) {
- tmp = (8 << params->ch[channel].cap_info.bw) /
- (8 << params->ch[channel].cap_info.dbw);
-
- /**
- * memdata_ratio
- * 1 -> 0, 2 -> 1, 4 -> 2
- */
- clrsetbits_le32(&denali_ctl[197], 0x7,
- (tmp >> 1));
- clrsetbits_le32(&denali_ctl[198], 0x7 << 8,
- (tmp >> 1) << 8);
- }
-
- noc_timing = &params->ch[channel].noc_timings;
-
- /*
- * noc timing bw relate timing is 32 bit, and real bw is 16bit
- * actually noc reg is setting at function dram_all_config
- */
- if (params->ch[channel].cap_info.bw == 16 &&
- noc_timing->ddrmode.b.mwrsize == 2) {
- if (noc_timing->ddrmode.b.burstsize)
- noc_timing->ddrmode.b.burstsize -= 1;
- noc_timing->ddrmode.b.mwrsize -= 1;
- noc_timing->ddrtimingc0.b.burstpenalty *= 2;
- noc_timing->ddrtimingc0.b.wrtomwr *= 2;
- }
-}
-
-static u32 calculate_ddrconfig(struct rk3399_sdram_params *params, u32 channel)
-{
- unsigned int cs0_row = params->ch[channel].cap_info.cs0_row;
- unsigned int col = params->ch[channel].cap_info.col;
- unsigned int bw = params->ch[channel].cap_info.bw;
- u16 ddr_cfg_2_rbc[] = {
- /*
- * [6] highest bit col
- * [5:3] max row(14+n)
- * [2] insertion row
- * [1:0] col(9+n),col, data bus 32bit
- *
- * highbitcol, max_row, insertion_row, col
- */
- ((0 << 6) | (2 << 3) | (0 << 2) | 0), /* 0 */
- ((0 << 6) | (2 << 3) | (0 << 2) | 1), /* 1 */
- ((0 << 6) | (1 << 3) | (0 << 2) | 2), /* 2 */
- ((0 << 6) | (0 << 3) | (0 << 2) | 3), /* 3 */
- ((0 << 6) | (2 << 3) | (1 << 2) | 1), /* 4 */
- ((0 << 6) | (1 << 3) | (1 << 2) | 2), /* 5 */
- ((1 << 6) | (0 << 3) | (0 << 2) | 2), /* 6 */
- ((1 << 6) | (1 << 3) | (0 << 2) | 2), /* 7 */
- };
- u32 i;
-
- col -= (bw == 2) ? 0 : 1;
- col -= 9;
-
- for (i = 0; i < 4; i++) {
- if ((col == (ddr_cfg_2_rbc[i] & 0x3)) &&
- (cs0_row <= (((ddr_cfg_2_rbc[i] >> 3) & 0x7) + 14)))
- break;
- }
-
- if (i >= 4)
- i = -EINVAL;
-
- return i;
-}
-
/**
* read mr_num mode register
* rank = 1: cs0
@@ -2592,8 +2592,11 @@ static int sdram_init(struct dram_info *dram,
}
sdram_print_ddr_info(cap_info, &params->base);
+ set_memory_map(chan, channel, params);
+ cap_info->ddrconfig = calculate_ddrconfig(params, channel);
set_ddrconfig(chan, params, channel, cap_info->ddrconfig);
+ set_cap_relate_config(chan, params, channel);
}
if (params->base.num_channels == 0) {