ram: rk3399: update cap and ddrconfig for each channel after init
authorKever Yang <kever.yang@rock-chips.com>
Mon, 12 Aug 2019 12:02:29 +0000 (20:02 +0800)
committerKever Yang <kever.yang@rock-chips.com>
Fri, 23 Aug 2019 07:27:40 +0000 (15:27 +0800)
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>
drivers/ram/rockchip/sdram_rk3399.c

index 81fc71c051d461f558e1a701782a3229d73d4819..ed70137ce7a461e5798e8d43d0de5e7f4ea6b87c 100644 (file)
@@ -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) {