Skip to contentSkip to conversation

Add sdram capacity auto detect for rk3288

PATCH Superseded Kever Yang 4 participants 17 messages Sep 20, 2016 – Oct 7, 2016

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Kever Yang

author
#0 lore raw

v2 cover Add sdram capacity auto detect for rk3288

The rk3288 spl size is very close to 32KB while the rk3288 bootrom has the limitation of maximum size of SPL is 32KB. After apply this patch, the SPL size will exceed 32KB if we do not enable macro CONFIG_ROCKCHIP_SPL_BACK_TO_BROM.

I think this patch is usful and should be go upstream other than the size issue.

This patch has test with 2GB DDR3 and 2GB/4GB LPDDR3.

V2 add patch to clean some source code size for some rk3288 board to make the SPL size in the 32KB limitation.

Changes in v2:
- update code for OF_PLATDATA enabled
- bug fix for ddrconfig

Kever Yang (3):
rk3288: config change for enable dram capacity auto-detect.
rk3288: sdram: auto-detect the capacity
dts: rk3288: remove node in dmc which not need anymore

 arch/arm/dts/rk3288-evb.dts                  |   3 -
 arch/arm/dts/rk3288-fennec.dts               |   3 -
 arch/arm/dts/rk3288-firefly.dts              |   2 -
 arch/arm/dts/rk3288-miniarm.dts              |   3 -
 arch/arm/dts/rk3288-popmetal.dts             |   3 -
 arch/arm/dts/rk3288-rock2-square.dts         |   2 -
 arch/arm/dts/rk3288-veyron.dtsi              |   2 -
 arch/arm/mach-rockchip/rk3288/sdram_rk3288.c | 244 ++++++++++++++++++++++-----
 include/configs/evb_rk3288.h                 |   3 +-
 include/configs/fennec_rk3288.h              |   3 +-
 include/configs/miniarm_rk3288.h             |   3 +-
 include/configs/popmetal_rk3288.h            |   3 +-
 12 files changed, 206 insertions(+), 68 deletions(-)
Signature · 1 line
1.9.1
author
#1 lore raw

PATCH v2 1/3 rk3288: config change for enable dram capacity auto-detect.

Enable ROCKCHIP_SPL_BACK_TO_BROM and disable CONFIG_SPL_MMC_SUPPORT to save memory in order to enable add source code for dram capacity auto-detect.

---

Changes in v2: None

 include/configs/evb_rk3288.h      | 3 +--
 include/configs/fennec_rk3288.h   | 3 +--
 include/configs/miniarm_rk3288.h  | 3 +--
 include/configs/popmetal_rk3288.h | 3 +--
 4 files changed, 4 insertions(+), 8 deletions(-)
include/configs/evb_rk3288.h +1 -2
index 342557f..9f32184 100644
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
include/configs/fennec_rk3288.h +1 -2
index 342557f..9f32184 100644
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
include/configs/miniarm_rk3288.h +1 -2
index 342557f..9f32184 100644
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
include/configs/popmetal_rk3288.h +1 -2
index 342557f..9f32184 100644
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 1/3 rk3288: config change for enable dram capacity auto-detect.

You're probably going to need to change this around now that the Kconfig stuff has been applied to master. Suggest following patch instead:

arch/arm/mach-rockchip/Kconfig +1 -1
index 1aac3c8..dc471d6 100644
@@ -36,7 +36,7 @@ config ROCKCHIP_RK3399
 
 config ROCKCHIP_SPL_BACK_TO_BROM
        bool "SPL returns to bootrom"
-       default y if ROCKCHIP_RK3036
+       default y if ROCKCHIP_RK3036 || ROCKCHIP_RK3288
        help
          Rockchip SoCs have ability to load SPL & U-Boot binary. If

enabled,
SPL will return to the boot rom, which will then load the U-Boot

(quoted diff) +0 -0

b/arch/arm/mach-rockchip/rk3288/Kconfig
index 94863a9..1425ce1 100644

arch/arm/mach-rockchip/rk3288/Kconfig +1 -1
@@ -82,7 +82,7 @@ config SPL_LIBGENERIC_SUPPORT
        default y
 
 config SPL_MMC_SUPPORT
-       default y
+       default y if !ROCKCHIP_SPL_BACK_TO_BROM
 
 config SPL_SERIAL_SUPPORT
        default y
Quoted 90 lines · Kever Yang

Enable ROCKCHIP_SPL_BACK_TO_BROM and disable CONFIG_SPL_MMC_SUPPORT to save memory in order to enable add source code for dram capacity auto-detect.

---

Changes in v2: None

 include/configs/evb_rk3288.h      | 3 +--
 include/configs/fennec_rk3288.h   | 3 +--
 include/configs/miniarm_rk3288.h  | 3 +--
 include/configs/popmetal_rk3288.h | 3 +--
 4 files changed, 4 insertions(+), 8 deletions(-)
include/configs/evb_rk3288.h +1 -2
index 342557f..9f32184 100644
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
include/configs/fennec_ renamed from include/configs/fennec_rk3288.h +0 -0

rk3288.h
index 342557f..9f32184 100644

include/configs/fennec_rk3288.h +1 -2
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
include/configs/miniarm_ renamed from include/configs/miniarm_rk3288.h +0 -0

rk3288.h
index 342557f..9f32184 100644

include/configs/miniarm_rk3288.h +1 -2
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
include/configs/popmetal_ renamed from include/configs/popmetal_rk3288.h +0 -0

rk3288.h
index 342557f..9f32184 100644

include/configs/popmetal_rk3288.h +1 -3
@@ -7,11 +7,10 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
+#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
 #define ROCKCHIP_DEVICE_SETTINGS
 #include <configs/rk3288_common.h>
 
-#define CONFIG_SPL_MMC_SUPPORT
-
 #define CONFIG_ENV_IS_IN_MMC
 #define CONFIG_SYS_MMC_ENV_DEV 1
 /* SPL @ 32k for ~36k
--

1.9.1

author
#3 lore raw

PATCH v2 1/3 rk3288: config change for enable dram capacity auto-detect.

Hi Sandy,

Quoted 2 lines · Sandy Patterson

You're probably going to need to change this around now that the Kconfig stuff has been applied to master. Suggest following patch instead:

I didn't enable the BACK_TO_BROM for all of rk3288 board, because boards like firefly and chromebook-jerry have enough space without this macro, and I'm not able to test them, so I only change for those boards which must enable this macro.

What's you opinion for firefly-rk3288 and chrome-jerry?

Thanks,
- Kever

Quoted 125 lines
arch/arm/mach-rockchip/Kconfig +1 -1
index 1aac3c8..dc471d6 100644
@@ -36,7 +36,7 @@ config ROCKCHIP_RK3399
 config ROCKCHIP_SPL_BACK_TO_BROM
        bool "SPL returns to bootrom"
-       default y if ROCKCHIP_RK3036
+       default y if ROCKCHIP_RK3036 || ROCKCHIP_RK3288
        help
          Rockchip SoCs have ability to load SPL & U-Boot binary. If 
 enabled,
           SPL will return to the boot rom, which will then load the 

U-Boot

arch/arm/mach-rockchip/rk3288/Kconfig +1 -1
index 94863a9..1425ce1 100644
@@ -82,7 +82,7 @@ config SPL_LIBGENERIC_SUPPORT
        default y
 config SPL_MMC_SUPPORT
-       default y
+       default y if !ROCKCHIP_SPL_BACK_TO_BROM
 config SPL_SERIAL_SUPPORT
        default y
 
 

On Mon, Sep 19, 2016 at 11:28 PM, Kever Yang
<kever.yang at rock-chips.com <mailto:[email protected]>> wrote:

    Enable ROCKCHIP_SPL_BACK_TO_BROM and disable CONFIG_SPL_MMC_SUPPORT
    to save memory in order to enable add source code for dram capacity
    auto-detect.

    Signed-off-by: Kever Yang <[email protected]
    <mailto:[email protected]>>
    ---

    Changes in v2: None

     include/configs/evb_rk3288.h      | 3 +--
     include/configs/fennec_rk3288.h   | 3 +--
     include/configs/miniarm_rk3288.h  | 3 +--
     include/configs/popmetal_rk3288.h | 3 +--
     4 files changed, 4 insertions(+), 8 deletions(-)

    diff --git a/include/configs/evb_rk3288.h
    b/include/configs/evb_rk3288.h
    index 342557f..9f32184 100644
    --- a/include/configs/evb_rk3288.h
    +++ b/include/configs/evb_rk3288.h
    @@ -7,11 +7,10 @@
     #ifndef __CONFIG_H
     #define __CONFIG_H

    +#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
     #define ROCKCHIP_DEVICE_SETTINGS
     #include <configs/rk3288_common.h>

    -#define CONFIG_SPL_MMC_SUPPORT
    -
     #define CONFIG_ENV_IS_IN_MMC
     #define CONFIG_SYS_MMC_ENV_DEV 1
     /* SPL @ 32k for ~36k
    diff --git a/include/configs/fennec_rk3288.h
    b/include/configs/fennec_rk3288.h
    index 342557f..9f32184 100644
    --- a/include/configs/fennec_rk3288.h
    +++ b/include/configs/fennec_rk3288.h
    @@ -7,11 +7,10 @@
     #ifndef __CONFIG_H
     #define __CONFIG_H

    +#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
     #define ROCKCHIP_DEVICE_SETTINGS
     #include <configs/rk3288_common.h>

    -#define CONFIG_SPL_MMC_SUPPORT
    -
     #define CONFIG_ENV_IS_IN_MMC
     #define CONFIG_SYS_MMC_ENV_DEV 1
     /* SPL @ 32k for ~36k
    diff --git a/include/configs/miniarm_rk3288.h
    b/include/configs/miniarm_rk3288.h
    index 342557f..9f32184 100644
    --- a/include/configs/miniarm_rk3288.h
    +++ b/include/configs/miniarm_rk3288.h
    @@ -7,11 +7,10 @@
     #ifndef __CONFIG_H
     #define __CONFIG_H

    +#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
     #define ROCKCHIP_DEVICE_SETTINGS
     #include <configs/rk3288_common.h>

    -#define CONFIG_SPL_MMC_SUPPORT
    -
     #define CONFIG_ENV_IS_IN_MMC
     #define CONFIG_SYS_MMC_ENV_DEV 1
     /* SPL @ 32k for ~36k
    diff --git a/include/configs/popmetal_rk3288.h
    b/include/configs/popmetal_rk3288.h
    index 342557f..9f32184 100644
    --- a/include/configs/popmetal_rk3288.h
    +++ b/include/configs/popmetal_rk3288.h
    @@ -7,11 +7,10 @@
     #ifndef __CONFIG_H
     #define __CONFIG_H

    +#define CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
     #define ROCKCHIP_DEVICE_SETTINGS
     #include <configs/rk3288_common.h>

    -#define CONFIG_SPL_MMC_SUPPORT
    -
     #define CONFIG_ENV_IS_IN_MMC
     #define CONFIG_SYS_MMC_ENV_DEV 1
     /* SPL @ 32k for ~36k
    --
    1.9.1
#4 lore raw

PATCH v2 1/3 rk3288: config change for enable dram capacity auto-detect.

Quoted 4 lines · Kever Yang

Hi Sandy,

On 09/20/2016 09:21 PM, Sandy Patterson wrote:

Quoted 9 lines

You're probably going to need to change this around now that the Kconfig stuff has been applied to master. Suggest following patch instead:

I didn't enable the BACK_TO_BROM for all of rk3288 board, because boards like firefly and chromebook-jerry have enough space without this macro, and I'm not able to test them, so I only change for those boards which must enable this macro.

That's fine, I only meant to suggest you use Kconfig instead. If you want to only change a few boards you can do this with *_defconfig file now. This way those options are controllable from "make menuconfig" after make *_defconfig.

Quoted 3 lines

What's you opinion for firefly-rk3288 and chrome-jerry?

I had a firefly, I expect this should work fine with BACK_TO_BROM option, but I have broken it, so I can't test. Vagrant probably can though. I don't know anything about chrome-jerry, but it has a lot of different storage settings.

author
#5 lore raw

PATCH v2 1/3 rk3288: config change for enable dram capacity auto-detect.

Hi Sandy,

Quoted 17 lines · Sandy Patterson

On Tue, Sep 20, 2016 at 11:00 PM, Kever Yang
<kever.yang at rock-chips.com <mailto:[email protected]>> wrote:

    Hi Sandy,

    On 09/20/2016 09:21 PM, Sandy Patterson wrote:
Quoted 3 lines

You're probably going to need to change this around now that the Kconfig stuff has been applied to master. Suggest following patch instead:

I didn't enable the BACK_TO_BROM for all of rk3288 board, because boards like firefly and chromebook-jerry have enough space without this macro,
and I'm not able to test them, so I only change for those boards which must enable this macro.

Quoted 4 lines

That's fine, I only meant to suggest you use Kconfig instead. If you want to only change a few boards you can do this with *_defconfig file now. This way those options are controllable from "make menuconfig" after make *_defconfig.

OK, I will move the definition to Kconfig.

Thanks,
- Kever

Quoted 8 lines

What's you opinion for firefly-rk3288 and chrome-jerry?

I had a firefly, I expect this should work fine with BACK_TO_BROM option, but I have broken it, so I can't test. Vagrant probably can though. I don't know anything about chrome-jerry, but it has a lot of different storage settings.

author
#6 lore raw

PATCH v2 2/3 rk3288: sdram: auto-detect the capacity

In reply to Kever Yang

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.

---

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(-)
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +202 -42
index cf9ef2e..b3dc251 100644
@@ -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;
+		}
+		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,
+					    dram->grf);
+			need_trainig = 1;
+		}
+	}
+	/* Assume the Die bit width are the same with the chip bit width*/
+	sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+	if (need_trainig &&
+	    (-1 == data_training(chan, channel, sdram_params))) {
+		if (sdram_params->base.dramtype == LPDDR3) {
+			ddr_phy_ctl_reset(dram->cru, channel, 1);
+			udelay(10);
+			ddr_phy_ctl_reset(dram->cru, channel, 0);
+			udelay(10);
+		}
+		debug("2nd data training failed!");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void sdram_col_row_detect(struct dram_info *dram, int channel,
+		struct rk3288_sdram_params *sdram_params)
+{
+	int row, col;
+	unsigned int addr;
+	const struct chan_info *chan = &dram->chan[channel];
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	struct rk3288_ddr_publ *publ = chan->publ;
+	/* Detect col */
+	for (col = 11; col >= 9; col--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE +
+			(1 << (col + sdram_params->ch[channel].bw - 1));
+		writel(TEST_PATTEN, addr);
+		if ((readl(addr) == TEST_PATTEN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (col == 8)
+		debug("Col detect error\n");
+	else
+		sdram_params->ch[channel].col = col;
+
+	move_to_config_state(publ, pctl);
+	writel(4, &chan->msch->ddrconf);
+	move_to_access_state(chan);
+	/* Detect row*/
+	for (row = 16; row >= 12; row--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+		writel(TEST_PATTEN, addr);
+		if ((readl(addr) == TEST_PATTEN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (row == 11)
+		debug("Row detect error\n");
+	else
+		sdram_params->ch[channel].cs0_row = row;
+	sdram_params->ch[channel].cs1_row = row;
+	sdram_params->ch[channel].row_3_4 = 0;
+	debug("chn %d col %d, row %d\n", channel, col, row);
+}
+
+static void sdram_get_niu_config(struct rk3288_sdram_params *sdram_params)
+{
+	int i, tmp, size;
+
+	tmp = sdram_params->ch[0].col - 9;
+	tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+	tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4);
+	size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
+	for (i = 0; i < size; i++)
+		if (tmp == ddrconf_table[i])
+			break;
+	if (i >= size)
+		debug("niu config not found\n");
+	else
+		sdram_params->base.ddrconfig = i;
+}
+
+static void sdram_get_stride(struct rk3288_sdram_params *sdram_params)
+{
+	int stride = -1;
+	long cap = sdram_params->num_channels * (1u <<
+			(sdram_params->ch[0].cs0_row +
+			 sdram_params->ch[0].col +
+			 (sdram_params->ch[0].rank - 1) +
+			 sdram_params->ch[0].bw +
+			 3 - 20));
+
+	switch (cap) {
+	case 512:
+		stride = 0;
+		break;
+	case 1024:
+		stride = 5;
+		break;
+	case 2048:
+		stride = 9;
+		break;
+	case 4096:
+		stride = 0xd;
+		break;
+	default:
+		stride = -1;
+		debug("could not find correct stride, cap error!\n");
+		break;
+	}
+	sdram_params->base.stride = stride;
+}
 
 static int sdram_init(struct dram_info *dram,
-		      const struct rk3288_sdram_params *sdram_params)
+		      struct rk3288_sdram_params *sdram_params)
 {
 	int channel;
 	int zqcr;
@@ -619,12 +787,13 @@ static int sdram_init(struct dram_info *dram,
 		struct rk3288_ddr_pctl *pctl = chan->pctl;
 		struct rk3288_ddr_publ *publ = chan->publ;
 
+		if (channel)
+			rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17);
+		else
+			rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a);
 		phy_pctrl_reset(dram->cru, publ, channel);
 		phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
 
-		if (channel >= sdram_params->num_channels)
-			continue;
-
 		dfi_cfg(pctl, sdram_params->base.dramtype);
 
 		pctl_cfg(channel, pctl, sdram_params, dram->grf);
@@ -658,16 +827,20 @@ static int sdram_init(struct dram_info *dram,
 			udelay(1);
 		}
 
+		/* Using 32bit bus width for detect */
+		sdram_params->ch[channel].bw = 2;
 		set_bandwidth_ratio(chan, channel,
 				    sdram_params->ch[channel].bw, dram->grf);
 		/*
-		 * set cs
+		 * set cs, using n=3 for detect
 		 * CS0, n=1
 		 * CS1, n=2
 		 * CS0 & CS1, n = 3
 		 */
+		sdram_params->ch[channel].rank = 2,
 		clrsetbits_le32(&publ->pgcr, 0xF << 18,
 				(sdram_params->ch[channel].rank | 1) << 18);
+
 		/* DS=40ohm,ODT=155ohm */
 		zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
 			2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
@@ -693,16 +866,8 @@ static int sdram_init(struct dram_info *dram,
 			}
 		}
 
-		if (-1 == data_training(chan, channel, sdram_params)) {
-			if (sdram_params->base.dramtype == LPDDR3) {
-				ddr_phy_ctl_reset(dram->cru, channel, 1);
-				udelay(10);
-				ddr_phy_ctl_reset(dram->cru, channel, 0);
-				udelay(10);
-			}
-			debug("failed!");
-			return -EIO;
-		}
+		/* Detect the rank and bit-width with data-training */
+		sdram_rank_bw_detect(dram, channel, sdram_params);
 
 		if (sdram_params->base.dramtype == LPDDR3) {
 			u32 i;
@@ -710,8 +875,18 @@ static int sdram_init(struct dram_info *dram,
 			for (i = 0; i < 17; i++)
 				send_command_op(pctl, 1, MRR_CMD, i, 0);
 		}
+		writel(15, &chan->msch->ddrconf);
 		move_to_access_state(chan);
+		/* DDR3 and LPDDR3 are always 8 bank, no need detect */
+		sdram_params->ch[channel].bk = 3;
+		/* Detect Col and Row number*/
+		sdram_col_row_detect(dram, channel, sdram_params);
 	}
+	/* Find NIU DDR configuration */
+	sdram_get_niu_config(sdram_params);
+	/* Find stride setting */
+	sdram_get_stride(sdram_params);
+
 	dram_all_config(dram, sdram_params);
 	debug("%s done\n", __func__);
 
@@ -743,7 +918,6 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
 			SYS_REG_BW_MASK));
 		row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
 			SYS_REG_ROW_3_4_MASK;
-
 		chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
 
 		if (rank > 1)
@@ -814,21 +988,10 @@ static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
 	struct rk3288_sdram_params *params = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
 	int node = dev->of_offset;
-	int i, ret;
-
-	params->num_channels = fdtdec_get_int(blob, node,
-					      "rockchip,num-channels", 1);
-	for (i = 0; i < params->num_channels; i++) {
-		ret = fdtdec_get_byte_array(blob, node,
-					    "rockchip,sdram-channel",
-					    (u8 *)&params->ch[i],
-					    sizeof(params->ch[i]));
-		if (ret) {
-			debug("%s: Cannot read rockchip,sdram-channel\n",
-			      __func__);
-			return -EINVAL;
-		}
-	}
+	int ret;
+
+	/* Rk3288 supports dual-channel, set default channel num to 2 */
+	params->num_channels = 2;
 	ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
 				   (u32 *)&params->pctl_timing,
 				   sizeof(params->pctl_timing) / sizeof(u32));
@@ -869,18 +1032,15 @@ static int conv_of_platdata(struct udevice *dev)
 {
 	struct rk3288_sdram_params *plat = dev_get_platdata(dev);
 	struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
-	int i, ret;
+	int ret;
 
-	for (i = 0; i < 2; i++) {
-		memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
-		       sizeof(plat->ch[i]));
-	}
 	memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
 	       sizeof(plat->pctl_timing));
 	memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
 	       sizeof(plat->phy_timing));
 	memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
-	plat->num_channels = of_plat->rockchip_num_channels;
+	/* Rk3288 supports dual-channel, set default channel num to 2 */
+	plat->num_channels = 2;
 	ret = regmap_init_mem_platdata(dev, of_plat->reg,
 				       ARRAY_SIZE(of_plat->reg) / 2,
 				       &plat->map);
Signature · 1 line
1.9.1
#7 lore raw

PATCH v2 2/3 rk3288: sdram: auto-detect the capacity

Hi Kever,

Quoted 11 lines · Kever Yang

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.

Quoted 8 lines

---

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:

Quoted 148 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +92 -5
index cf9ef2e..b3dc251 100644
@@ -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;
+               }
+               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,
+                                           dram->grf);
+                       need_trainig = 1;
+               }
+       }
+       /* Assume the Die bit width are the same with the chip bit width*/
+       sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+       if (need_trainig &&
+           (-1 == data_training(chan, channel, sdram_params))) {
+               if (sdram_params->base.dramtype == LPDDR3) {
+                       ddr_phy_ctl_reset(dram->cru, channel, 1);
+                       udelay(10);
+                       ddr_phy_ctl_reset(dram->cru, channel, 0);
+                       udelay(10);
+               }
+               debug("2nd data training failed!");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void sdram_col_row_detect(struct dram_info *dram, int channel,
+               struct rk3288_sdram_params *sdram_params)
+{
+       int row, col;
+       unsigned int addr;
+       const struct chan_info *chan = &dram->chan[channel];
+       struct rk3288_ddr_pctl *pctl = chan->pctl;
+       struct rk3288_ddr_publ *publ = chan->publ;
+       /* Detect col */
+       for (col = 11; col >= 9; col--) {

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 688

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+               writel(0, CONFIG_SYS_SDRAM_BASE);
+               addr = CONFIG_SYS_SDRAM_BASE +
+                       (1 << (col + sdram_params->ch[channel].bw - 1));
+               writel(TEST_PATTEN, addr);
+               if ((readl(addr) == TEST_PATTEN) &&
+                   (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+                       break;
+       }
+       if (col == 8)
+               debug("Col detect error\n");

Tis is an error, so please return an error code and halt the board.

Quoted 7 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -0
+       else
+               sdram_params->ch[channel].col = col;
+
+       move_to_config_state(publ, pctl);
+       writel(4, &chan->msch->ddrconf);
+       move_to_access_state(chan);
+       /* Detect row*/

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 705

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+       for (row = 16; row >= 12; row--) {
+               writel(0, CONFIG_SYS_SDRAM_BASE);
+               addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+               writel(TEST_PATTEN, addr);
+               if ((readl(addr) == TEST_PATTEN) &&
+                   (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+                       break;
+       }
+       if (row == 11)
+               debug("Row detect error\n");

Here also.

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+       else
+               sdram_params->ch[channel].cs0_row = row;
+       sdram_params->ch[channel].cs1_row = row;
+       sdram_params->ch[channel].row_3_4 = 0;
+       debug("chn %d col %d, row %d\n", channel, col, row);
+}
+
+static void sdram_get_niu_config(struct rk3288_sdram_params *sdram_params)
+{
+       int i, tmp, size;

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 725

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+
+       tmp = sdram_params->ch[0].col - 9;
+       tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+       tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4);
+       size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
+       for (i = 0; i < size; i++)
+               if (tmp == ddrconf_table[i])
+                       break;
+       if (i >= size)
+               debug("niu config not found\n");

And here

Quoted 20 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +20 -0
+       else
+               sdram_params->base.ddrconfig = i;
+}
+
+static void sdram_get_stride(struct rk3288_sdram_params *sdram_params)
+{
+       int stride = -1;
+       long cap = sdram_params->num_channels * (1u <<
+                       (sdram_params->ch[0].cs0_row +
+                        sdram_params->ch[0].col +
+                        (sdram_params->ch[0].rank - 1) +
+                        sdram_params->ch[0].bw +
+                        3 - 20));
+
+       switch (cap) {
+       case 512:
+               stride = 0;
+               break;
+       case 1024:
+               stride = 5;

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 755

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+               break;
+       case 2048:
+               stride = 9;
+               break;
+       case 4096:
+               stride = 0xd;
+               break;
+       default:
+               stride = -1;
+               debug("could not find correct stride, cap error!\n");

And here

Quoted 12 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +5 -1
+               break;
+       }
+       sdram_params->base.stride = stride;
+}
 
 static int sdram_init(struct dram_info *dram,
-                     const struct rk3288_sdram_params *sdram_params)
+                     struct rk3288_sdram_params *sdram_params)
 {
        int channel;
        int zqcr;

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static int sdram_init(struct dram_info *dram, · line 793

Quoted 7 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +4 -0
@@ -619,12 +787,13 @@ static int sdram_init(struct dram_info *dram,
                struct rk3288_ddr_pctl *pctl = chan->pctl;
                struct rk3288_ddr_publ *publ = chan->publ;
 
+               if (channel)
+                       rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17);
+               else
+                       rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a);

What are these magic numbers? Please can you add defines?

Quoted 51 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -14
                phy_pctrl_reset(dram->cru, publ, channel);
                phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
 
-               if (channel >= sdram_params->num_channels)
-                       continue;
-
                dfi_cfg(pctl, sdram_params->base.dramtype);
 
                pctl_cfg(channel, pctl, sdram_params, dram->grf);
@@ -658,16 +827,20 @@ static int sdram_init(struct dram_info *dram,
                        udelay(1);
                }
 
+               /* Using 32bit bus width for detect */
+               sdram_params->ch[channel].bw = 2;
                set_bandwidth_ratio(chan, channel,
                                    sdram_params->ch[channel].bw, dram->grf);
                /*
-                * set cs
+                * set cs, using n=3 for detect
                 * CS0, n=1
                 * CS1, n=2
                 * CS0 & CS1, n = 3
                 */
+               sdram_params->ch[channel].rank = 2,
                clrsetbits_le32(&publ->pgcr, 0xF << 18,
                                (sdram_params->ch[channel].rank | 1) << 18);
+
                /* DS=40ohm,ODT=155ohm */
                zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
                        2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
@@ -693,16 +866,8 @@ static int sdram_init(struct dram_info *dram,
                        }
                }
 
-               if (-1 == data_training(chan, channel, sdram_params)) {
-                       if (sdram_params->base.dramtype == LPDDR3) {
-                               ddr_phy_ctl_reset(dram->cru, channel, 1);
-                               udelay(10);
-                               ddr_phy_ctl_reset(dram->cru, channel, 0);
-                               udelay(10);
-                       }
-                       debug("failed!");
-                       return -EIO;
-               }
+               /* Detect the rank and bit-width with data-training */
+               sdram_rank_bw_detect(dram, channel, sdram_params);
 
                if (sdram_params->base.dramtype == LPDDR3) {
                        u32 i;

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static int sdram_init(struct dram_info *dram, · line 881

Quoted 7 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +3 -0
@@ -710,8 +875,18 @@ static int sdram_init(struct dram_info *dram,
                        for (i = 0; i < 17; i++)
                                send_command_op(pctl, 1, MRR_CMD, i, 0);
                }
+               writel(15, &chan->msch->ddrconf);
                move_to_access_state(chan);
+               /* DDR3 and LPDDR3 are always 8 bank, no need detect */
+               sdram_params->ch[channel].bk = 3;

Do you have a define for 3?

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static int sdram_init(struct dram_info *dram, · line 889

Quoted 8 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -0
+               /* Detect Col and Row number*/
+               sdram_col_row_detect(dram, channel, sdram_params);
        }
+       /* Find NIU DDR configuration */
+       sdram_get_niu_config(sdram_params);
+       /* Find stride setting */
+       sdram_get_stride(sdram_params);
+

Check errors here. At the very top level, printf a short error.

Quoted 60 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -23
        dram_all_config(dram, sdram_params);
        debug("%s done\n", __func__);
 
@@ -743,7 +918,6 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
                        SYS_REG_BW_MASK));
                row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
                        SYS_REG_ROW_3_4_MASK;
-
                chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
 
                if (rank > 1)
@@ -814,21 +988,10 @@ static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
        struct rk3288_sdram_params *params = dev_get_platdata(dev);
        const void *blob = gd->fdt_blob;
        int node = dev->of_offset;
-       int i, ret;
-
-       params->num_channels = fdtdec_get_int(blob, node,
-                                             "rockchip,num-channels", 1);
-       for (i = 0; i < params->num_channels; i++) {
-               ret = fdtdec_get_byte_array(blob, node,
-                                           "rockchip,sdram-channel",
-                                           (u8 *)&params->ch[i],
-                                           sizeof(params->ch[i]));
-               if (ret) {
-                       debug("%s: Cannot read rockchip,sdram-channel\n",
-                             __func__);
-                       return -EINVAL;
-               }
-       }
+       int ret;
+
+       /* Rk3288 supports dual-channel, set default channel num to 2 */
+       params->num_channels = 2;
        ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
                                   (u32 *)&params->pctl_timing,
                                   sizeof(params->pctl_timing) / sizeof(u32));
@@ -869,18 +1032,15 @@ static int conv_of_platdata(struct udevice *dev)
 {
        struct rk3288_sdram_params *plat = dev_get_platdata(dev);
        struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
-       int i, ret;
+       int ret;
 
-       for (i = 0; i < 2; i++) {
-               memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
-                      sizeof(plat->ch[i]));
-       }
        memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
               sizeof(plat->pctl_timing));
        memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
               sizeof(plat->phy_timing));
        memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
-       plat->num_channels = of_plat->rockchip_num_channels;
+       /* Rk3288 supports dual-channel, set default channel num to 2 */
+       plat->num_channels = 2;
        ret = regmap_init_mem_platdata(dev, of_plat->reg,
                                       ARRAY_SIZE(of_plat->reg) / 2,
                                       &plat->map);
--
Quoted 2 lines

1.9.1

Regards,
Simon

author
#8 lore raw

PATCH v2 2/3 rk3288: sdram: auto-detect the capacity

Hi Simon,

Quoted 16 lines · Simon Glass

Hi Kever,

Quoted 13 lines · Kever Yang

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.

---

Quoted 8 lines
Quoted 6 lines

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:

Thanks for your test.

Quoted 150 lines
Quoted 150 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +95 -5
index cf9ef2e..b3dc251 100644
@@ -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;
+               }
+               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,
+                                           dram->grf);
+                       need_trainig = 1;
+               }
+       }
+       /* Assume the Die bit width are the same with the chip bit width*/
+       sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+       if (need_trainig &&
+           (-1 == data_training(chan, channel, sdram_params))) {
+               if (sdram_params->base.dramtype == LPDDR3) {
+                       ddr_phy_ctl_reset(dram->cru, channel, 1);
+                       udelay(10);
+                       ddr_phy_ctl_reset(dram->cru, channel, 0);
+                       udelay(10);
+               }
+               debug("2nd data training failed!");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void sdram_col_row_detect(struct dram_info *dram, int channel,
+               struct rk3288_sdram_params *sdram_params)
+{
+       int row, col;
+       unsigned int addr;
+       const struct chan_info *chan = &dram->chan[channel];
+       struct rk3288_ddr_pctl *pctl = chan->pctl;
+       struct rk3288_ddr_publ *publ = chan->publ;
+       /* Detect col */
+       for (col = 11; col >= 9; col--) {
+               writel(0, CONFIG_SYS_SDRAM_BASE);
+               addr = CONFIG_SYS_SDRAM_BASE +
+                       (1 << (col + sdram_params->ch[channel].bw - 1));
Quoted 8 lines

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 688

Quoted 7 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -0
+               writel(TEST_PATTEN, addr);
+               if ((readl(addr) == TEST_PATTEN) &&
+                   (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+                       break;
+       }
+       if (col == 8)
+               debug("Col detect error\n");

Tis is an error, so please return an error code and halt the board.

Will add return value and hang() if error happen.

Quoted 89 lines
Quoted 8 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -0
+       else
+               sdram_params->ch[channel].col = col;
+
+       move_to_config_state(publ, pctl);
+       writel(4, &chan->msch->ddrconf);
+       move_to_access_state(chan);
+       /* Detect row*/

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 705

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+       for (row = 16; row >= 12; row--) {
+               writel(0, CONFIG_SYS_SDRAM_BASE);
+               addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+               writel(TEST_PATTEN, addr);
+               if ((readl(addr) == TEST_PATTEN) &&
+                   (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+                       break;
+       }
+       if (row == 11)
+               debug("Row detect error\n");

Here also.

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+       else
+               sdram_params->ch[channel].cs0_row = row;
+       sdram_params->ch[channel].cs1_row = row;
+       sdram_params->ch[channel].row_3_4 = 0;
+       debug("chn %d col %d, row %d\n", channel, col, row);
+}
+
+static void sdram_get_niu_config(struct rk3288_sdram_params *sdram_params)
+{
+       int i, tmp, size;

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 725

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+
+       tmp = sdram_params->ch[0].col - 9;
+       tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+       tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4);
+       size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
+       for (i = 0; i < size; i++)
+               if (tmp == ddrconf_table[i])
+                       break;
+       if (i >= size)
+               debug("niu config not found\n");

And here

Quoted 20 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +20 -0
+       else
+               sdram_params->base.ddrconfig = i;
+}
+
+static void sdram_get_stride(struct rk3288_sdram_params *sdram_params)
+{
+       int stride = -1;
+       long cap = sdram_params->num_channels * (1u <<
+                       (sdram_params->ch[0].cs0_row +
+                        sdram_params->ch[0].col +
+                        (sdram_params->ch[0].rank - 1) +
+                        sdram_params->ch[0].bw +
+                        3 - 20));
+
+       switch (cap) {
+       case 512:
+               stride = 0;
+               break;
+       case 1024:
+               stride = 5;

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static void dram_all_config(const struct dram_info *dram, · line 755

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +10 -0
+               break;
+       case 2048:
+               stride = 9;
+               break;
+       case 4096:
+               stride = 0xd;
+               break;
+       default:
+               stride = -1;
+               debug("could not find correct stride, cap error!\n");

And here

Quoted 15 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +5 -1
+               break;
+       }
+       sdram_params->base.stride = stride;
+}
 
  static int sdram_init(struct dram_info *dram,
-                     const struct rk3288_sdram_params *sdram_params)
+                     struct rk3288_sdram_params *sdram_params)
  {
         int channel;
         int zqcr;
@@ -619,12 +787,13 @@ static int sdram_init(struct dram_info *dram,
                 struct rk3288_ddr_pctl *pctl = chan->pctl;
                 struct rk3288_ddr_publ *publ = chan->publ;
 
Quoted 5 lines

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static int sdram_init(struct dram_info *dram, · line 793

Quoted 4 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +4 -0
+               if (channel)
+                       rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17);
+               else
+                       rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a);

What are these magic numbers? Please can you add defines?

This is DDR stride setting, I will add comments in stride structure.

Quoted 49 lines
Quoted 49 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -14
                 phy_pctrl_reset(dram->cru, publ, channel);
                 phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
 
-               if (channel >= sdram_params->num_channels)
-                       continue;
-
                 dfi_cfg(pctl, sdram_params->base.dramtype);
 
                 pctl_cfg(channel, pctl, sdram_params, dram->grf);
@@ -658,16 +827,20 @@ static int sdram_init(struct dram_info *dram,
                         udelay(1);
                 }
 
+               /* Using 32bit bus width for detect */
+               sdram_params->ch[channel].bw = 2;
                 set_bandwidth_ratio(chan, channel,
                                     sdram_params->ch[channel].bw, dram->grf);
                 /*
-                * set cs
+                * set cs, using n=3 for detect
                  * CS0, n=1
                  * CS1, n=2
                  * CS0 & CS1, n = 3
                  */
+               sdram_params->ch[channel].rank = 2,
                 clrsetbits_le32(&publ->pgcr, 0xF << 18,
                                 (sdram_params->ch[channel].rank | 1) << 18);
+
                 /* DS=40ohm,ODT=155ohm */
                 zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
                         2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
@@ -693,16 +866,8 @@ static int sdram_init(struct dram_info *dram,
                         }
                 }
 
-               if (-1 == data_training(chan, channel, sdram_params)) {
-                       if (sdram_params->base.dramtype == LPDDR3) {
-                               ddr_phy_ctl_reset(dram->cru, channel, 1);
-                               udelay(10);
-                               ddr_phy_ctl_reset(dram->cru, channel, 0);
-                               udelay(10);
-                       }
-                       debug("failed!");
-                       return -EIO;
-               }
+               /* Detect the rank and bit-width with data-training */
+               sdram_rank_bw_detect(dram, channel, sdram_params);
 
Quoted 11 lines

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static int sdram_init(struct dram_info *dram, · line 881

Quoted 10 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +3 -0
                 if (sdram_params->base.dramtype == LPDDR3) {
                         u32 i;
@@ -710,8 +875,18 @@ static int sdram_init(struct dram_info *dram,
                         for (i = 0; i < 17; i++)
                                 send_command_op(pctl, 1, MRR_CMD, i, 0);
                 }
+               writel(15, &chan->msch->ddrconf);
                 move_to_access_state(chan);
+               /* DDR3 and LPDDR3 are always 8 bank, no need detect */
+               sdram_params->ch[channel].bk = 3;

Do you have a define for 3?

This is address bits need to use, eg. 3 bits for 8 bank here. will add comments in structure.

Thanks,
- Kever

Quoted 78 lines

arch/arm/mach-rockchip/rk3288/sdram_rk3288.c static int sdram_init(struct dram_info *dram, · line 889

Quoted 9 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -0
+               /* Detect Col and Row number*/
+               sdram_col_row_detect(dram, channel, sdram_params);
         }
+       /* Find NIU DDR configuration */
+       sdram_get_niu_config(sdram_params);
+       /* Find stride setting */
+       sdram_get_stride(sdram_params);
+

Check errors here. At the very top level, printf a short error.

Quoted 60 lines
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +7 -23
         dram_all_config(dram, sdram_params);
         debug("%s done\n", __func__);
 
@@ -743,7 +918,6 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
                         SYS_REG_BW_MASK));
                 row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
                         SYS_REG_ROW_3_4_MASK;
-
                 chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
 
                 if (rank > 1)
@@ -814,21 +988,10 @@ static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
         struct rk3288_sdram_params *params = dev_get_platdata(dev);
         const void *blob = gd->fdt_blob;
         int node = dev->of_offset;
-       int i, ret;
-
-       params->num_channels = fdtdec_get_int(blob, node,
-                                             "rockchip,num-channels", 1);
-       for (i = 0; i < params->num_channels; i++) {
-               ret = fdtdec_get_byte_array(blob, node,
-                                           "rockchip,sdram-channel",
-                                           (u8 *)&params->ch[i],
-                                           sizeof(params->ch[i]));
-               if (ret) {
-                       debug("%s: Cannot read rockchip,sdram-channel\n",
-                             __func__);
-                       return -EINVAL;
-               }
-       }
+       int ret;
+
+       /* Rk3288 supports dual-channel, set default channel num to 2 */
+       params->num_channels = 2;
         ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
                                    (u32 *)&params->pctl_timing,
                                    sizeof(params->pctl_timing) / sizeof(u32));
@@ -869,18 +1032,15 @@ static int conv_of_platdata(struct udevice *dev)
  {
         struct rk3288_sdram_params *plat = dev_get_platdata(dev);
         struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
-       int i, ret;
+       int ret;
 
-       for (i = 0; i < 2; i++) {
-               memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
-                      sizeof(plat->ch[i]));
-       }
         memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
                sizeof(plat->pctl_timing));
         memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
                sizeof(plat->phy_timing));
         memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
-       plat->num_channels = of_plat->rockchip_num_channels;
+       /* Rk3288 supports dual-channel, set default channel num to 2 */
+       plat->num_channels = 2;
         ret = regmap_init_mem_platdata(dev, of_plat->reg,
                                        ARRAY_SIZE(of_plat->reg) / 2,
                                        &plat->map);
--
Quoted 2 lines

1.9.1

Regards,
Simon

#9 lore raw

PATCH v2 2/3 rk3288: sdram: auto-detect the capacity

In reply to Kever Yang
Quoted 11 lines · Kever Yang

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.

Tested on firefly-rk3288, 2GB and 4GB ram board variants, using u-boot 2016.11-rc1.

Quoted 379 lines

---

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(-)
arch/arm/mach-rockchip/rk3288/sdram_rk3288.c +202 -42
index cf9ef2e..b3dc251 100644
@@ -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;
+		}
+		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,
+					    dram->grf);
+			need_trainig = 1;
+		}
+	}
+	/* Assume the Die bit width are the same with the chip bit width*/
+	sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+	if (need_trainig &&
+	    (-1 == data_training(chan, channel, sdram_params))) {
+		if (sdram_params->base.dramtype == LPDDR3) {
+			ddr_phy_ctl_reset(dram->cru, channel, 1);
+			udelay(10);
+			ddr_phy_ctl_reset(dram->cru, channel, 0);
+			udelay(10);
+		}
+		debug("2nd data training failed!");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void sdram_col_row_detect(struct dram_info *dram, int channel,
+		struct rk3288_sdram_params *sdram_params)
+{
+	int row, col;
+	unsigned int addr;
+	const struct chan_info *chan = &dram->chan[channel];
+	struct rk3288_ddr_pctl *pctl = chan->pctl;
+	struct rk3288_ddr_publ *publ = chan->publ;
+	/* Detect col */
+	for (col = 11; col >= 9; col--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE +
+			(1 << (col + sdram_params->ch[channel].bw - 1));
+		writel(TEST_PATTEN, addr);
+		if ((readl(addr) == TEST_PATTEN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (col == 8)
+		debug("Col detect error\n");
+	else
+		sdram_params->ch[channel].col = col;
+
+	move_to_config_state(publ, pctl);
+	writel(4, &chan->msch->ddrconf);
+	move_to_access_state(chan);
+	/* Detect row*/
+	for (row = 16; row >= 12; row--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+		writel(TEST_PATTEN, addr);
+		if ((readl(addr) == TEST_PATTEN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (row == 11)
+		debug("Row detect error\n");
+	else
+		sdram_params->ch[channel].cs0_row = row;
+	sdram_params->ch[channel].cs1_row = row;
+	sdram_params->ch[channel].row_3_4 = 0;
+	debug("chn %d col %d, row %d\n", channel, col, row);
+}
+
+static void sdram_get_niu_config(struct rk3288_sdram_params *sdram_params)
+{
+	int i, tmp, size;
+
+	tmp = sdram_params->ch[0].col - 9;
+	tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+	tmp |= ((sdram_params->ch[0].cs0_row - 12) << 4);
+	size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
+	for (i = 0; i < size; i++)
+		if (tmp == ddrconf_table[i])
+			break;
+	if (i >= size)
+		debug("niu config not found\n");
+	else
+		sdram_params->base.ddrconfig = i;
+}
+
+static void sdram_get_stride(struct rk3288_sdram_params *sdram_params)
+{
+	int stride = -1;
+	long cap = sdram_params->num_channels * (1u <<
+			(sdram_params->ch[0].cs0_row +
+			 sdram_params->ch[0].col +
+			 (sdram_params->ch[0].rank - 1) +
+			 sdram_params->ch[0].bw +
+			 3 - 20));
+
+	switch (cap) {
+	case 512:
+		stride = 0;
+		break;
+	case 1024:
+		stride = 5;
+		break;
+	case 2048:
+		stride = 9;
+		break;
+	case 4096:
+		stride = 0xd;
+		break;
+	default:
+		stride = -1;
+		debug("could not find correct stride, cap error!\n");
+		break;
+	}
+	sdram_params->base.stride = stride;
+}
 
 static int sdram_init(struct dram_info *dram,
-		      const struct rk3288_sdram_params *sdram_params)
+		      struct rk3288_sdram_params *sdram_params)
 {
 	int channel;
 	int zqcr;
@@ -619,12 +787,13 @@ static int sdram_init(struct dram_info *dram,
 		struct rk3288_ddr_pctl *pctl = chan->pctl;
 		struct rk3288_ddr_publ *publ = chan->publ;
 
+		if (channel)
+			rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x17);
+		else
+			rk_clrsetreg(&dram->sgrf->soc_con2, 0x1f, 0x1a);
 		phy_pctrl_reset(dram->cru, publ, channel);
 		phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
 
-		if (channel >= sdram_params->num_channels)
-			continue;
-
 		dfi_cfg(pctl, sdram_params->base.dramtype);
 
 		pctl_cfg(channel, pctl, sdram_params, dram->grf);
@@ -658,16 +827,20 @@ static int sdram_init(struct dram_info *dram,
 			udelay(1);
 		}
 
+		/* Using 32bit bus width for detect */
+		sdram_params->ch[channel].bw = 2;
 		set_bandwidth_ratio(chan, channel,
 				    sdram_params->ch[channel].bw, dram->grf);
 		/*
-		 * set cs
+		 * set cs, using n=3 for detect
 		 * CS0, n=1
 		 * CS1, n=2
 		 * CS0 & CS1, n = 3
 		 */
+		sdram_params->ch[channel].rank = 2,
 		clrsetbits_le32(&publ->pgcr, 0xF << 18,
 				(sdram_params->ch[channel].rank | 1) << 18);
+
 		/* DS=40ohm,ODT=155ohm */
 		zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
 			2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
@@ -693,16 +866,8 @@ static int sdram_init(struct dram_info *dram,
 			}
 		}
 
-		if (-1 == data_training(chan, channel, sdram_params)) {
-			if (sdram_params->base.dramtype == LPDDR3) {
-				ddr_phy_ctl_reset(dram->cru, channel, 1);
-				udelay(10);
-				ddr_phy_ctl_reset(dram->cru, channel, 0);
-				udelay(10);
-			}
-			debug("failed!");
-			return -EIO;
-		}
+		/* Detect the rank and bit-width with data-training */
+		sdram_rank_bw_detect(dram, channel, sdram_params);
 
 		if (sdram_params->base.dramtype == LPDDR3) {
 			u32 i;
@@ -710,8 +875,18 @@ static int sdram_init(struct dram_info *dram,
 			for (i = 0; i < 17; i++)
 				send_command_op(pctl, 1, MRR_CMD, i, 0);
 		}
+		writel(15, &chan->msch->ddrconf);
 		move_to_access_state(chan);
+		/* DDR3 and LPDDR3 are always 8 bank, no need detect */
+		sdram_params->ch[channel].bk = 3;
+		/* Detect Col and Row number*/
+		sdram_col_row_detect(dram, channel, sdram_params);
 	}
+	/* Find NIU DDR configuration */
+	sdram_get_niu_config(sdram_params);
+	/* Find stride setting */
+	sdram_get_stride(sdram_params);
+
 	dram_all_config(dram, sdram_params);
 	debug("%s done\n", __func__);
 
@@ -743,7 +918,6 @@ size_t sdram_size_mb(struct rk3288_pmu *pmu)
 			SYS_REG_BW_MASK));
 		row_3_4 = sys_reg >> SYS_REG_ROW_3_4_SHIFT(ch) &
 			SYS_REG_ROW_3_4_MASK;
-
 		chipsize_mb = (1 << (cs0_row + col + bk + bw - 20));
 
 		if (rank > 1)
@@ -814,21 +988,10 @@ static int rk3288_dmc_ofdata_to_platdata(struct udevice *dev)
 	struct rk3288_sdram_params *params = dev_get_platdata(dev);
 	const void *blob = gd->fdt_blob;
 	int node = dev->of_offset;
-	int i, ret;
-
-	params->num_channels = fdtdec_get_int(blob, node,
-					      "rockchip,num-channels", 1);
-	for (i = 0; i < params->num_channels; i++) {
-		ret = fdtdec_get_byte_array(blob, node,
-					    "rockchip,sdram-channel",
-					    (u8 *)&params->ch[i],
-					    sizeof(params->ch[i]));
-		if (ret) {
-			debug("%s: Cannot read rockchip,sdram-channel\n",
-			      __func__);
-			return -EINVAL;
-		}
-	}
+	int ret;
+
+	/* Rk3288 supports dual-channel, set default channel num to 2 */
+	params->num_channels = 2;
 	ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
 				   (u32 *)&params->pctl_timing,
 				   sizeof(params->pctl_timing) / sizeof(u32));
@@ -869,18 +1032,15 @@ static int conv_of_platdata(struct udevice *dev)
 {
 	struct rk3288_sdram_params *plat = dev_get_platdata(dev);
 	struct dtd_rockchip_rk3288_dmc *of_plat = &plat->of_plat;
-	int i, ret;
+	int ret;
 
-	for (i = 0; i < 2; i++) {
-		memcpy(&plat->ch[i], of_plat->rockchip_sdram_channel,
-		       sizeof(plat->ch[i]));
-	}
 	memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
 	       sizeof(plat->pctl_timing));
 	memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
 	       sizeof(plat->phy_timing));
 	memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
-	plat->num_channels = of_plat->rockchip_num_channels;
+	/* Rk3288 supports dual-channel, set default channel num to 2 */
+	plat->num_channels = 2;
 	ret = regmap_init_mem_platdata(dev, of_plat->reg,
 				       ARRAY_SIZE(of_plat->reg) / 2,
 				       &plat->map);
Signature · 1 line
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161005/b68187c8/attachment.sig>

author
#10 lore raw

PATCH v2 3/3 dts: rk3288: remove node in dmc which not need anymore

In reply to Kever Yang

Since we implement the dram capacity auto detect, we don't need to set the channel number and sdram-channel in dts.

---

Changes in v2: None

 arch/arm/dts/rk3288-evb.dts          | 3 ---
 arch/arm/dts/rk3288-fennec.dts       | 3 ---
 arch/arm/dts/rk3288-firefly.dts      | 2 --
 arch/arm/dts/rk3288-miniarm.dts      | 3 ---
 arch/arm/dts/rk3288-popmetal.dts     | 3 ---
 arch/arm/dts/rk3288-rock2-square.dts | 2 --
 arch/arm/dts/rk3288-veyron.dtsi      | 2 --
 7 files changed, 18 deletions(-)
arch/arm/dts/rk3288-evb.dts +0 -3
index 3e1ee58..3f03e13 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
 		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
 		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
@@ -25,8 +24,6 @@
 		0x8 0x1f4>;
 	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
 		0x0 0xc3 0x6 0x2>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>;
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
arch/arm/dts/rk3288-fennec.dts +0 -3
index 36e9f3d..66ddf8d 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
 		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
 		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
@@ -25,8 +24,6 @@
 		0x8 0x1f4>;
 	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
 		0x0 0xc3 0x6 0x2>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>;
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
arch/arm/dts/rk3288-firefly.dts +0 -2
index 3176d50..97568a3 100644
@@ -22,7 +22,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -31,7 +30,6 @@
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
 	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-miniarm.dts +0 -3
index c741082..9083028 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -25,8 +24,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-popmetal.dts +0 -3
index 3f61a61..284d5ed 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -25,8 +24,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-rock2-square.dts +0 -2
index 2c30355..11c580a 100644
@@ -184,7 +184,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -192,7 +191,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-veyron.dtsi +0 -2
index d9d5187..2ffe39c 100644
@@ -245,7 +245,6 @@
 		533000 1150000
 		666000 1200000
 	>;
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f4 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -253,7 +252,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
Signature · 1 line
1.9.1
#11 lore raw

PATCH v2 3/3 dts: rk3288: remove node in dmc which not need anymore

Quoted 8 lines · Kever Yang

Since we implement the dram capacity auto detect, we don't need to set the channel number and sdram-channel in dts.

---

Changes in v2: None

Quoted 8 lines
 arch/arm/dts/rk3288-evb.dts          | 3 ---
 arch/arm/dts/rk3288-fennec.dts       | 3 ---
 arch/arm/dts/rk3288-firefly.dts      | 2 --
 arch/arm/dts/rk3288-miniarm.dts      | 3 ---
 arch/arm/dts/rk3288-popmetal.dts     | 3 ---
 arch/arm/dts/rk3288-rock2-square.dts | 2 --
 arch/arm/dts/rk3288-veyron.dtsi      | 2 --
 7 files changed, 18 deletions(-)

Tested on firefly-rk3288:

#12 lore raw

PATCH v2 3/3 dts: rk3288: remove node in dmc which not need anymore

In reply to Kever Yang
Quoted 4 lines · Kever Yang

Since we implement the dram capacity auto detect, we don't need to set the channel number and sdram-channel in dts.

Tested on firefly-rk3288, 2GB and 4GB ram board variants, using u-boot 2016.11-rc1.

Quoted 159 lines

---

Changes in v2: None

 arch/arm/dts/rk3288-evb.dts          | 3 ---
 arch/arm/dts/rk3288-fennec.dts       | 3 ---
 arch/arm/dts/rk3288-firefly.dts      | 2 --
 arch/arm/dts/rk3288-miniarm.dts      | 3 ---
 arch/arm/dts/rk3288-popmetal.dts     | 3 ---
 arch/arm/dts/rk3288-rock2-square.dts | 2 --
 arch/arm/dts/rk3288-veyron.dtsi      | 2 --
 7 files changed, 18 deletions(-)
arch/arm/dts/rk3288-evb.dts +0 -3
index 3e1ee58..3f03e13 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
 		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
 		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
@@ -25,8 +24,6 @@
 		0x8 0x1f4>;
 	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
 		0x0 0xc3 0x6 0x2>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>;
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
arch/arm/dts/rk3288-fennec.dts +0 -3
index 36e9f3d..66ddf8d 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
 		0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
 		0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
@@ -25,8 +24,6 @@
 		0x8 0x1f4>;
 	rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
 		0x0 0xc3 0x6 0x2>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x2 0xa 0x3 0x2 0x2 0x0 0xe 0xe 0xff>;
 	rockchip,sdram-params = <0x20d266a4 0x5b6 2 533000000 6 9 0>;
 };
 
arch/arm/dts/rk3288-firefly.dts +0 -2
index 3176d50..97568a3 100644
@@ -22,7 +22,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -31,7 +30,6 @@
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
 	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-miniarm.dts +0 -3
index c741082..9083028 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -25,8 +24,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-popmetal.dts +0 -3
index 3f61a61..284d5ed 100644
@@ -17,7 +17,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -25,8 +24,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	/* Add a dummy value to cause of-platdata think this is bytes */
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-rock2-square.dts +0 -2
index 2c30355..11c580a 100644
@@ -184,7 +184,6 @@
 };
 
 &dmc {
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f8 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -192,7 +191,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
arch/arm/dts/rk3288-veyron.dtsi +0 -2
index d9d5187..2ffe39c 100644
@@ -245,7 +245,6 @@
 		533000 1150000
 		666000 1200000
 	>;
-	rockchip,num-channels = <2>;
 	rockchip,pctl-timing = <0x29a 0xc8 0x1f4 0x42 0x4e 0x4 0xea 0xa
 		0x5 0x0 0xa 0x7 0x19 0x24 0xa 0x7
 		0x5 0xa 0x5 0x200 0x5 0x10 0x40 0x0
@@ -253,7 +252,6 @@
 		0x5 0x0>;
 	rockchip,phy-timing = <0x48f9aab4 0xea0910 0x1002c200
 		0xa60 0x40 0x10 0x0>;
-	rockchip,sdram-channel = /bits/ 8 <0x1 0xa 0x3 0x2 0x1 0x0 0xf 0xf 0xff>;
 	rockchip,sdram-params = <0x30B25564 0x627 3 666000000 3 9 1>;
 };
 
Signature · 1 line
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 800 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20161005/39510e94/attachment.sig>

#13 lore raw

v2 cover Add sdram capacity auto detect for rk3288

In reply to Kever Yang

I can confirm that this boots on rock2 with current master branch. 9b1b6d42256a4c2e59c803afdbf90d39371e61ba

It doesn't boot for me using rock2 on v2016.09 tag. I get:
U-Boot SPL 2016.09-00002-g690a8a3 (Sep 20 2016 - 10:47:44) Trying to boot from MMC1

It continues to detect 2GB of ram. on master.

I get nervous with these memory changes. We found that some memory parameters persisted through to linux and had the ability to cause instability. I don't run have linux setup right now on my rock2, so I can't test that.

I also wanted to test that the parameters detected via the new routine matched those removed from the dts file. I tried enabling DEBUG but that somehow caused no console output anymore (on master). I'm not sure what's going on. I also tried doing some printfs but they had the same effect. It looks like somehow the console init has moved and maybe isn't setup yet.

Sandy

author
#14 lore raw

v2 cover Add sdram capacity auto detect for rk3288

Hi Sandy,

Quoted 3 lines · Sandy Patterson

I can confirm that this boots on rock2 with current master branch. 9b1b6d42256a4c2e59c803afdbf90d39371e61ba

Thanks for your test.

Quoted 11 lines

It doesn't boot for me using rock2 on v2016.09 tag. I get:
U-Boot SPL 2016.09-00002-g690a8a3 (Sep 20 2016 - 10:47:44) Trying to boot from MMC1

It continues to detect 2GB of ram. on master.

I get nervous with these memory changes. We found that some memory parameters persisted through to linux and had the ability to cause instability. I don't run have linux setup right now on my rock2, so I can't test that.

parameters changes from dts to auto-detect including those I removed from dts and ddrconfig, stride, they should be the same as without my patch, which means my patch suppose to not change any parameter for DDR other than how we get those parameters.

Quoted 6 lines

I also wanted to test that the parameters detected via the new routine matched those removed from the dts file. I tried enabling DEBUG but that somehow caused no console output anymore (on master). I'm not sure what's going on. I also tried doing some printfs but they had the same effect. It looks like somehow the console init has moved and maybe isn't setup yet.

I think you need to define EARLY_DEBUG in arch/arm/mach-rockchip/rk3288-board-spl.c and then using printf or debug with DEBUG macro enable.

Thanks,
- Kever

Quoted 6 lines

Sandy

#15 lore raw

v2 cover Add sdram capacity auto detect for rk3288

Quoted 6 lines · Kever Yang

parameters changes from dts to auto-detect including those I removed from dts and ddrconfig, stride, they should be the same as without my patch, which means my patch suppose to not change any parameter for DDR other than how we get those parameters.

EARLY_DEBUG was the right idea. Only for some reason it's called EARLY_UART on rk3288.

I tested rock2 and it is getting dbw parameter of 2 instead of 1 for with the unmodified code for both channels. I'm afraid I do not know the significance of this and don't have a good way to test for stability. I am using rock2 square model a with 2gb ram.

Sandy

author
#16 lore raw

v2 cover Add sdram capacity auto detect for rk3288

Hi Sandy,

Quoted 9 lines · Sandy Patterson

On Tue, Sep 20, 2016 at 10:56 PM, Kever Yang
<kever.yang at rock-chips.com <mailto:[email protected]>> wrote:

parameters changes from dts to auto-detect including those I removed from dts and ddrconfig, stride, they should be the same as without my patch, which means my patch suppose to not change any parameter for DDR other than how we get those parameters.

Quoted 8 lines

EARLY_DEBUG was the right idea. Only for some reason it's called EARLY_UART on rk3288.

I tested rock2 and it is getting dbw parameter of 2 instead of 1 for with the unmodified code for both channels. I'm afraid I do not know the significance of this and don't have a good way to test for stability. I am using rock2 square model a with 2gb ram.

For LPDDR3, the die bit width(dbw) is fix 2(32bits); and for DDR3 it might be dbw=1(16bit, more likely) or dbw=0(8bit), this parameter only affect the DRAM tRFC, won't affect the stability but maybe very little performance difference if we use smaller die bitwidth.

Thanks,
- Kever

Quoted 1 line

Sandy