All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] ram: stm32mp1: fixes
@ 2020-03-06 10:14 Patrick Delaunay
  2020-03-06 10:14 ` [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR Patrick Delaunay
                   ` (8 more replies)
  0 siblings, 9 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot


This serie fixes the stm32mp1 ram driver:
- adapt voltage for the LPDDR2 and LPDDR3
- solve tuning and BIST issues
- allow to skip built-in calibration

Most of these patch are available on the latest STM32MP downstrean
U-Boot: https://github.com/STMicroelectronics/u-boot



Patrick Delaunay (9):
  ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR
  ram: stm32mp1: display result for software read DQS gating
  ram: stm32mp1: don't display the prompt two times
  ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE
  ram: stm32mp1: tuning: deactivate derating during BIST test
  ram: stm32mp1: update BIST config for tuning
  ram: stm32mp1_ddr: fix self refresh disable during DQS training
  ram: stm32mp1: reduce delay after BIST reset for tuning
  ram: stm32mp1: the property st,phy-cal becomes optional

 arch/arm/dts/stm32mp15-ddr.dtsi               |   3 +
 arch/arm/mach-stm32mp/include/mach/ddr.h      |   6 +-
 board/st/stm32mp1/board.c                     |  23 +-
 .../memory-controllers/st,stm32mp1-ddr.txt    |   2 +
 drivers/ram/stm32mp1/stm32mp1_ddr.c           |  54 ++++-
 drivers/ram/stm32mp1/stm32mp1_ddr.h           |   1 +
 drivers/ram/stm32mp1/stm32mp1_ddr_regs.h      |   1 +
 drivers/ram/stm32mp1/stm32mp1_interactive.c   |  17 +-
 drivers/ram/stm32mp1/stm32mp1_ram.c           |  34 ++-
 drivers/ram/stm32mp1/stm32mp1_tuning.c        | 223 +++++++++++++++---
 include/power/stpmic1.h                       |   1 +
 11 files changed, 300 insertions(+), 65 deletions(-)

-- 
2.17.1

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:39   ` Patrice CHOTARD
  2020-03-24  8:48   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating Patrick Delaunay
                   ` (7 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

Need to increase the LPDDR2/LPDDR3 the voltage vdd2_ddr: buck2
form 1.2V to 1.25V for 32bits configuration.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 arch/arm/mach-stm32mp/include/mach/ddr.h |  6 +++--
 board/st/stm32mp1/board.c                | 23 ++++++++++++++----
 drivers/ram/stm32mp1/stm32mp1_ddr.c      | 30 ++++++++++++++++++++----
 include/power/stpmic1.h                  |  1 +
 4 files changed, 49 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h
index b8a17cfbdd..bfc42a7c48 100644
--- a/arch/arm/mach-stm32mp/include/mach/ddr.h
+++ b/arch/arm/mach-stm32mp/include/mach/ddr.h
@@ -9,8 +9,10 @@
 /* DDR power initializations */
 enum ddr_type {
 	STM32MP_DDR3,
-	STM32MP_LPDDR2,
-	STM32MP_LPDDR3,
+	STM32MP_LPDDR2_16,
+	STM32MP_LPDDR2_32,
+	STM32MP_LPDDR3_16,
+	STM32MP_LPDDR3_32,
 };
 
 int board_ddr_power_init(enum ddr_type ddr_type);
diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
index c3d832f584..4e35d36c76 100644
--- a/board/st/stm32mp1/board.c
+++ b/board/st/stm32mp1/board.c
@@ -43,6 +43,7 @@ int board_ddr_power_init(enum ddr_type ddr_type)
 	struct udevice *dev;
 	bool buck3_at_1800000v = false;
 	int ret;
+	u32 buck2;
 
 	ret = uclass_get_device_by_driver(UCLASS_PMIC,
 					  DM_GET_DRIVER(pmic_stpmic1), &dev);
@@ -102,8 +103,10 @@ int board_ddr_power_init(enum ddr_type ddr_type)
 
 		break;
 
-	case STM32MP_LPDDR2:
-	case STM32MP_LPDDR3:
+	case STM32MP_LPDDR2_16:
+	case STM32MP_LPDDR2_32:
+	case STM32MP_LPDDR3_16:
+	case STM32MP_LPDDR3_32:
 		/*
 		 * configure VDD_DDR1 = LDO3
 		 * Set LDO3 to 1.8V
@@ -133,11 +136,23 @@ int board_ddr_power_init(enum ddr_type ddr_type)
 		if (ret < 0)
 			return ret;
 
-		/* VDD_DDR2 : Set BUCK2 to 1.2V */
+		/* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
+		switch (ddr_type) {
+		case STM32MP_LPDDR2_32:
+		case STM32MP_LPDDR3_32:
+			buck2 = STPMIC1_BUCK2_1250000V;
+			break;
+		default:
+		case STM32MP_LPDDR2_16:
+		case STM32MP_LPDDR3_16:
+			buck2 = STPMIC1_BUCK2_1200000V;
+			break;
+		}
+
 		ret = pmic_clrsetbits(dev,
 				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
 				      STPMIC1_BUCK_VOUT_MASK,
-				      STPMIC1_BUCK2_1200000V);
+				      buck2);
 		if (ret < 0)
 			return ret;
 
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index d765a46f7c..a87914f2d5 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -668,14 +668,34 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
 {
 	u32 pir;
 	int ret = -EINVAL;
+	char bus_width;
+
+	switch (config->c_reg.mstr & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
+	case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
+		bus_width = 8;
+		break;
+	case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
+		bus_width = 16;
+		break;
+	default:
+		bus_width = 32;
+		break;
+	}
+
 
 	if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
 		ret = board_ddr_power_init(STM32MP_DDR3);
-	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2)
-		ret = board_ddr_power_init(STM32MP_LPDDR2);
-	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3)
-		ret = board_ddr_power_init(STM32MP_LPDDR3);
-
+	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) {
+		if (bus_width == 32)
+			ret = board_ddr_power_init(STM32MP_LPDDR2_32);
+		else
+			ret = board_ddr_power_init(STM32MP_LPDDR2_16);
+	} else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) {
+		if (bus_width == 32)
+			ret = board_ddr_power_init(STM32MP_LPDDR3_32);
+		else
+			ret = board_ddr_power_init(STM32MP_LPDDR3_16);
+	}
 	if (ret)
 		panic("ddr power init failed\n");
 
diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h
index dc8b5a7459..1493a677f0 100644
--- a/include/power/stpmic1.h
+++ b/include/power/stpmic1.h
@@ -37,6 +37,7 @@
 #define STPMIC1_BUCK_VOUT(sel)		(sel << STPMIC1_BUCK_VOUT_SHIFT)
 
 #define STPMIC1_BUCK2_1200000V		STPMIC1_BUCK_VOUT(24)
+#define STPMIC1_BUCK2_1250000V		STPMIC1_BUCK_VOUT(26)
 #define STPMIC1_BUCK2_1350000V		STPMIC1_BUCK_VOUT(30)
 
 #define STPMIC1_BUCK3_1800000V		STPMIC1_BUCK_VOUT(39)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
  2020-03-06 10:14 ` [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:39   ` Patrice CHOTARD
  2020-03-24  8:48   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 3/9] ram: stm32mp1: don't display the prompt two times Patrick Delaunay
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

Display result information for software read DQS gating, the tuning 0
which be used by CubeMX DDR tuning tools.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_tuning.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
index 4e1c1fab54..e3e6f0f79c 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -1182,15 +1182,17 @@ static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte,
 				 dqs_gate_values[byte][0],
 				 dqs_gate_values[byte][1]);
 			pr_debug("*******the nominal values were system latency: 0  phase: 2*******\n");
-			set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
-			set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
 		}
 	} else {
 		/* if intermitant, restore defaut values */
 		pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n");
-		set_r0dgsl_delay(phy, byte, 0);
-		set_r0dgps_delay(phy, byte, 2);
+		dqs_gate_values[byte][0] = 0;
+		dqs_gate_values[byte][1] = 2;
 	}
+	set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
+	set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
+	printf("Byte %d, R0DGSL = %d, R0DGPS = %d\n",
+	       byte, dqs_gate_values[byte][0], dqs_gate_values[byte][1]);
 
 	/* return 0 if intermittent or if both left_bound
 	 * and right_bound are not found
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 3/9] ram: stm32mp1: don't display the prompt two times
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
  2020-03-06 10:14 ` [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR Patrick Delaunay
  2020-03-06 10:14 ` [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:39   ` Patrice CHOTARD
  2020-03-24  8:49   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE Patrick Delaunay
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

Remove one "DDR>" display on command
- next
- step
- go

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_interactive.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c
index cc9b2e7c96..cedf92cb5f 100644
--- a/drivers/ram/stm32mp1/stm32mp1_interactive.c
+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c
@@ -367,7 +367,6 @@ bool stm32mp1_ddr_interactive(void *priv,
 			      enum stm32mp1_ddr_interact_step step,
 			      const struct stm32mp1_ddr_config *config)
 {
-	const char *prompt = "DDR>";
 	char buffer[CONFIG_SYS_CBSIZE];
 	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated */
 	int argc;
@@ -403,13 +402,12 @@ bool stm32mp1_ddr_interactive(void *priv,
 	}
 
 	printf("%d:%s\n", step, step_str[step]);
-	printf("%s\n", prompt);
 
 	if (next_step > step)
 		return false;
 
 	while (next_step == step) {
-		cli_readline_into_buffer(prompt, buffer, 0);
+		cli_readline_into_buffer("DDR>", buffer, 0);
 		argc = cli_simple_parse_line(buffer, argv);
 		if (!argc)
 			continue;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
                   ` (2 preceding siblings ...)
  2020-03-06 10:14 ` [PATCH 3/9] ram: stm32mp1: don't display the prompt two times Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:40   ` Patrice CHOTARD
  2020-03-24  8:49   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test Patrick Delaunay
                   ` (4 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

Avoid to block the tuning procedure on BIST error (not finished
BIST procedure) by adding a 1000us timeout on the polling of
BISTGSR.BDDONE executed to detect the end of BIST.

The normal duration of the BIST test is around 5us.

This patch also cleanup comments.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_tuning.c | 45 ++++++++++++++------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
index e3e6f0f79c..cab6cf087a 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -8,6 +8,7 @@
 #include <ram.h>
 #include <reset.h>
 #include <asm/io.h>
+#include <linux/iopoll.h>
 
 #include "stm32mp1_ddr_regs.h"
 #include "stm32mp1_ddr.h"
@@ -246,6 +247,8 @@ static void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte,
 	bool result = true; /* BIST_SUCCESS */
 	u32 cnt = 0;
 	u32 error = 0;
+	u32 val;
+	int ret;
 
 	bist->test_result = true;
 
@@ -274,27 +277,29 @@ run:
 			0x00000001);
 	/* Write BISTRR.BINST = 3?b001; */
 
-	/* Wait for a number of CTL clocks before reading BIST register*/
-	/* Wait 300 ctl_clk cycles;  ... IS it really needed?? */
-	/* Perform BIST Instruction Stop*/
-	/* Write BISTRR.BINST = 3?b010;*/
-
-	/* poll on BISTGSR.BDONE. If 0, wait.  ++TODO Add timeout */
-	while (!(readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDDONE))
-		;
-
-	/*Check if received correct number of words*/
-	/* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
-	if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT) ==
-	    readl(&phy->bistwcr)) {
-		/*Determine if there is a data comparison error*/
-		/* if (Read BISTGSR.BDXERR = 1?b0) */
-		if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
-			result = false; /* BIST_FAIL; */
-		else
-			result = true; /* BIST_SUCCESS; */
-	} else {
+	/* poll on BISTGSR.BDONE and wait max 1000 us */
+	ret = readl_poll_timeout(&phy->bistgsr, val,
+				 val & DDRPHYC_BISTGSR_BDDONE, 1000);
+
+	if (ret < 0) {
+		printf("warning: BIST timeout\n");
 		result = false; /* BIST_FAIL; */
+		/*Perform BIST Stop */
+		clrsetbits_le32(&phy->bistrr, 0x00000007, 0x00000002);
+	} else {
+		/*Check if received correct number of words*/
+		/* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
+		if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT)
+		    == readl(&phy->bistwcr)) {
+			/*Determine if there is a data comparison error*/
+			/* if (Read BISTGSR.BDXERR = 1?b0) */
+			if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
+				result = false; /* BIST_FAIL; */
+			else
+				result = true; /* BIST_SUCCESS; */
+		} else {
+			result = false; /* BIST_FAIL; */
+		}
 	}
 
 	/* loop while success */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
                   ` (3 preceding siblings ...)
  2020-03-06 10:14 ` [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:43   ` Patrice CHOTARD
  2020-03-24  8:50   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 6/9] ram: stm32mp1: update BIST config for tuning Patrick Delaunay
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

The derating (timing parameter derating using MR4 read value)
can't be activated during BIST test, as the MR4 read answer will
be not understood by BIST (BISTGSR.BDONE bit stay at 0,
BISTWCSR.DXWCNT = 0x206 instead of BISTWCR.BWCNT = 0x200).

This patch only impacts the tuning on LPDDR2/LPDDR3,
if derateen.derate_enable = 1.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_tuning.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
index cab6cf087a..37d3ec8fef 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -1288,11 +1288,16 @@ static enum test_result do_read_dqs_gating(struct stm32mp1_ddrctl *ctl,
 {
 	u32 rfshctl3 = readl(&ctl->rfshctl3);
 	u32 pwrctl = readl(&ctl->pwrctl);
+	u32 derateen = readl(&ctl->derateen);
 	enum test_result res;
 
+	writel(0x0, &ctl->derateen);
 	stm32mp1_refresh_disable(ctl);
+
 	res = read_dqs_gating(ctl, phy, string);
+
 	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+	writel(derateen, &ctl->derateen);
 
 	return res;
 }
@@ -1303,11 +1308,16 @@ static enum test_result do_bit_deskew(struct stm32mp1_ddrctl *ctl,
 {
 	u32 rfshctl3 = readl(&ctl->rfshctl3);
 	u32 pwrctl = readl(&ctl->pwrctl);
+	u32 derateen = readl(&ctl->derateen);
 	enum test_result res;
 
+	writel(0x0, &ctl->derateen);
 	stm32mp1_refresh_disable(ctl);
+
 	res = bit_deskew(ctl, phy, string);
+
 	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+	writel(derateen, &ctl->derateen);
 
 	return res;
 }
@@ -1318,11 +1328,16 @@ static enum test_result do_eye_training(struct stm32mp1_ddrctl *ctl,
 {
 	u32 rfshctl3 = readl(&ctl->rfshctl3);
 	u32 pwrctl = readl(&ctl->pwrctl);
+	u32 derateen = readl(&ctl->derateen);
 	enum test_result res;
 
+	writel(0x0, &ctl->derateen);
 	stm32mp1_refresh_disable(ctl);
+
 	res = eye_training(ctl, phy, string);
+
 	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
+	writel(derateen, &ctl->derateen);
 
 	return res;
 }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 6/9] ram: stm32mp1: update BIST config for tuning
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
                   ` (4 preceding siblings ...)
  2020-03-06 10:14 ` [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:45   ` Patrice CHOTARD
  2020-03-24  8:50   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training Patrick Delaunay
                   ` (2 subsequent siblings)
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

Update the BIST config to compute the real use mask for the real
bank, row and col of the used DDR. The values are get from addrmap
register value.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_tuning.c | 151 +++++++++++++++++++++++--
 1 file changed, 142 insertions(+), 9 deletions(-)

diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
index 37d3ec8fef..07d57d496c 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -8,6 +8,7 @@
 #include <ram.h>
 #include <reset.h>
 #include <asm/io.h>
+#include <linux/bitops.h>
 #include <linux/iopoll.h>
 
 #include "stm32mp1_ddr_regs.h"
@@ -76,6 +77,133 @@ static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl)
 	return nb_bytes;
 }
 
+static u8 get_nb_bank(struct stm32mp1_ddrctl *ctl)
+{
+	/* Count bank address bits */
+	u8 bits = 0;
+	u32 reg, val;
+
+	reg = readl(&ctl->addrmap1);
+	/* addrmap1.addrmap_bank_b1 */
+	val = (reg & GENMASK(5, 0)) >> 0;
+	if (val <= 31)
+		bits++;
+	/* addrmap1.addrmap_bank_b2 */
+	val = (reg & GENMASK(13, 8)) >> 8;
+	if (val <= 31)
+		bits++;
+	/* addrmap1.addrmap_bank_b3 */
+	val = (reg & GENMASK(21, 16)) >> 16;
+	if (val <= 31)
+		bits++;
+
+	return bits;
+}
+
+static u8 get_nb_col(struct stm32mp1_ddrctl *ctl)
+{
+	u8 bits;
+	u32 reg, val;
+
+	/* Count column address bits, start@2 for b0 and b1 (fixed) */
+	bits = 2;
+
+	reg = readl(&ctl->addrmap2);
+	/* addrmap2.addrmap_col_b2 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap2.addrmap_col_b3 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+	/* addrmap2.addrmap_col_b4 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 7)
+		bits++;
+	/* addrmap2.addrmap_col_b5 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 7)
+		bits++;
+
+	reg = readl(&ctl->addrmap3);
+	/* addrmap3.addrmap_col_b6 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap3.addrmap_col_b7 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+	/* addrmap3.addrmap_col_b8 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 7)
+		bits++;
+	/* addrmap3.addrmap_col_b9 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 7)
+		bits++;
+
+	reg = readl(&ctl->addrmap4);
+	/* addrmap4.addrmap_col_b10 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap4.addrmap_col_b11 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+
+	return bits;
+}
+
+static u8 get_nb_row(struct stm32mp1_ddrctl *ctl)
+{
+	/* Count row address bits */
+	u8 bits = 0;
+	u32 reg, val;
+
+	reg = readl(&ctl->addrmap5);
+	/* addrmap5.addrmap_row_b0 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 11)
+		bits++;
+	/* addrmap5.addrmap_row_b1 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 11)
+		bits++;
+	/* addrmap5.addrmap_row_b2_10 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 11)
+		bits += 9;
+	else
+		printf("warning: addrmap5.addrmap_row_b2_10 not supported\n");
+	/* addrmap5.addrmap_row_b11 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 11)
+		bits++;
+
+	reg = readl(&ctl->addrmap6);
+	/* addrmap6.addrmap_row_b12 */
+	val = (reg & GENMASK(3, 0)) >> 0;
+	if (val <= 7)
+		bits++;
+	/* addrmap6.addrmap_row_b13 */
+	val = (reg & GENMASK(11, 8)) >> 8;
+	if (val <= 7)
+		bits++;
+	/* addrmap6.addrmap_row_b14 */
+	val = (reg & GENMASK(19, 16)) >> 16;
+	if (val <= 7)
+		bits++;
+	/* addrmap6.addrmap_row_b15 */
+	val = (reg & GENMASK(27, 24)) >> 24;
+	if (val <= 7)
+		bits++;
+
+	return bits;
+}
+
 static void itm_soft_reset(struct stm32mp1_ddrphy *phy)
 {
 	stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST);
@@ -170,8 +298,13 @@ static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy,
 }
 
 /* Basic BIST configuration for data lane tests. */
-static void config_BIST(struct stm32mp1_ddrphy *phy)
+static void config_BIST(struct stm32mp1_ddrctl *ctl,
+			struct stm32mp1_ddrphy *phy)
 {
+	u8 nb_bank = get_nb_bank(ctl);
+	u8 nb_row = get_nb_row(ctl);
+	u8 nb_col = get_nb_col(ctl);
+
 	/* Selects the SDRAM bank address to be used during BIST. */
 	u32 bbank = 0;
 	/* Selects the SDRAM row address to be used during BIST. */
@@ -191,18 +324,20 @@ static void config_BIST(struct stm32mp1_ddrphy *phy)
 	 * must be 0 with single rank
 	 */
 	u32 brank = 0;
+
 	/* Specifies the maximum SDRAM bank address to be used during
 	 * BIST before the address & increments to the next rank.
 	 */
-	u32 bmbank = 1;
+	u32 bmbank = (1 << nb_bank) - 1;
 	/* Specifies the maximum SDRAM row address to be used during
 	 * BIST before the address & increments to the next bank.
 	 */
-	u32 bmrow = 0x7FFF; /* To check */
+	u32 bmrow = (1 << nb_row) - 1;
 	/* Specifies the maximum SDRAM column address to be used during
 	 * BIST before the address & increments to the next row.
 	 */
-	u32 bmcol = 0x3FF;  /* To check */
+	u32 bmcol = (1 << nb_col) - 1;
+
 	u32 bmode_conf = 0x00000001;  /* DRam mode */
 	u32 bdxen_conf = 0x00000001;  /* BIST on Data byte */
 	u32 bdpat_conf = 0x00000002;  /* Select LFSR pattern */
@@ -224,8 +359,6 @@ static void config_BIST(struct stm32mp1_ddrphy *phy)
 
 	writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0);
 	writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1);
-
-	/* To check this line : */
 	writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2);
 }
 
@@ -399,7 +532,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl,
 	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
 
 	/* Config the BIST block */
-	config_BIST(phy);
+	config_BIST(ctl, phy);
 	pr_debug("BIST Config done.\n");
 
 	/* Train each byte */
@@ -812,7 +945,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl,
 	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
 
 	/* Config the BIST block */
-	config_BIST(phy);
+	config_BIST(ctl, phy);
 
 	for (byte = 0; byte < nb_bytes; byte++) {
 		if (ctrlc()) {
@@ -1234,7 +1367,7 @@ static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl,
 	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
 
 	/* config the bist block */
-	config_BIST(phy);
+	config_BIST(ctl, phy);
 
 	for (byte = 0; byte < nb_bytes; byte++) {
 		if (ctrlc()) {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
                   ` (5 preceding siblings ...)
  2020-03-06 10:14 ` [PATCH 6/9] ram: stm32mp1: update BIST config for tuning Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:46   ` Patrice CHOTARD
  2020-03-24  8:51   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning Patrick Delaunay
  2020-03-06 10:14 ` [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional Patrick Delaunay
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

DDRCTRL_PWRCTL.SELFREF_EN needs to be reset before DQS training step, not
to enter in self refresh mode during the execution of this phase.
Depending on settings, it can be set after the DQS training.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_ddr.c      | 5 ++++-
 drivers/ram/stm32mp1/stm32mp1_ddr_regs.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index a87914f2d5..b9300dd6d1 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -639,7 +639,8 @@ void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
 	start_sw_done(ctl);
 	/* quasi-dynamic register update*/
 	setbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
-	clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+	clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN |
+				   DDRCTRL_PWRCTL_SELFREF_EN);
 	clrbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
 	wait_sw_done_ack(ctl);
 }
@@ -652,6 +653,8 @@ void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
 		clrbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
 	if (pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN)
 		setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_EN))
+		setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
 	setbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
 	wait_sw_done_ack(ctl);
 }
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
index 9d33186b3a..afd93c518e 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
@@ -260,6 +260,7 @@ struct stm32mp1_ddrphy {
 
 #define DDRCTRL_MRSTAT_MR_WR_BUSY		BIT(0)
 
+#define DDRCTRL_PWRCTL_SELFREF_EN		BIT(0)
 #define DDRCTRL_PWRCTL_POWERDOWN_EN		BIT(1)
 #define DDRCTRL_PWRCTL_SELFREF_SW		BIT(5)
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
                   ` (6 preceding siblings ...)
  2020-03-06 10:14 ` [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:46   ` Patrice CHOTARD
  2020-03-24  8:51   ` Patrick DELAUNAY
  2020-03-06 10:14 ` [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional Patrick Delaunay
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

Reduce the delay after BIST delay, from 1ms to 10us
which is enough accoriding datasheet.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 drivers/ram/stm32mp1/stm32mp1_tuning.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
index 07d57d496c..3013b7b667 100644
--- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
+++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
@@ -402,7 +402,7 @@ run:
 		writel(rand(), &phy->bistlsr);
 
 	/* some delay to reset BIST */
-	mdelay(1);
+	udelay(10);
 
 	/*Perform BIST Run*/
 	clrsetbits_le32(&phy->bistrr,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional
  2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
                   ` (7 preceding siblings ...)
  2020-03-06 10:14 ` [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning Patrick Delaunay
@ 2020-03-06 10:14 ` Patrick Delaunay
  2020-03-18  9:52   ` Patrice CHOTARD
  2020-03-24  8:51   ` Patrick DELAUNAY
  8 siblings, 2 replies; 28+ messages in thread
From: Patrick Delaunay @ 2020-03-06 10:14 UTC (permalink / raw)
  To: u-boot

This parameter "st,phy-cal" becomes optional and when it is
absent the built-in PHY calibration is done.

It is the case in the helper dtsi file "stm32mp15-ddr.dtsi"
except if DDR_PHY_CAL_SKIP is defined.

This patch also impact the ddr interactive mode
- the registers of the param 'phy.cal' are initialized to 0 when
  "st,phy-cal" is not present in device tree (default behavior when
  DDR_PHY_CAL_SKIP is not activated)
- the info 'cal' field can be use to change the calibration behavior
  - cal=1 => use param phy.cal to initialize the PHY, built-in training
             is skipped
  - cal=0 => param phy.cal is absent, built-in training is used (default)

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
---

 arch/arm/dts/stm32mp15-ddr.dtsi               |  3 ++
 .../memory-controllers/st,stm32mp1-ddr.txt    |  2 ++
 drivers/ram/stm32mp1/stm32mp1_ddr.c           | 19 +++++++----
 drivers/ram/stm32mp1/stm32mp1_ddr.h           |  1 +
 drivers/ram/stm32mp1/stm32mp1_interactive.c   | 13 ++++++-
 drivers/ram/stm32mp1/stm32mp1_ram.c           | 34 ++++++++++++++-----
 6 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi
index 38f29bb789..8b20b5e173 100644
--- a/arch/arm/dts/stm32mp15-ddr.dtsi
+++ b/arch/arm/dts/stm32mp15-ddr.dtsi
@@ -133,6 +133,7 @@
 				DDR_MR3
 			>;
 
+#ifdef DDR_PHY_CAL_SKIP
 			st,phy-cal = <
 				DDR_DX0DLLCR
 				DDR_DX0DQTR
@@ -148,6 +149,8 @@
 				DDR_DX3DQSTR
 			>;
 
+#endif
+
 			status = "okay";
 		};
 	};
diff --git a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
index ee708ce92c..ac6a7df432 100644
--- a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
+++ b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
@@ -129,6 +129,8 @@ phyc attributes:
 		MR3
 
 - st,phy-cal	: phy cal depending of calibration or tuning of DDR
+	This parameter is optional; when it is absent the built-in PHY
+	calibration is done.
 	for STM32MP15x: 12 values are requested in this order
 		DX0DLLCR
 		DX0DQTR
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
index b9300dd6d1..11b14ae652 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
@@ -769,7 +769,8 @@ start:
  */
 	set_reg(priv, REGPHY_REG, &config->p_reg);
 	set_reg(priv, REGPHY_TIMING, &config->p_timing);
-	set_reg(priv, REGPHY_CAL, &config->p_cal);
+	if (config->p_cal_present)
+		set_reg(priv, REGPHY_CAL, &config->p_cal);
 
 	if (INTERACTIVE(STEP_PHY_INIT))
 		goto start;
@@ -804,13 +805,16 @@ start:
 
 	wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
 
-	debug("DDR DQS training : ");
+	if (config->p_cal_present) {
+		debug("DDR DQS training skipped.\n");
+	} else {
+		debug("DDR DQS training : ");
 /*  8. Disable Auto refresh and power down by setting
  *    - RFSHCTL3.dis_au_refresh = 1
  *    - PWRCTL.powerdown_en = 0
  *    - DFIMISC.dfiinit_complete_en = 0
  */
-	stm32mp1_refresh_disable(priv->ctl);
+		stm32mp1_refresh_disable(priv->ctl);
 
 /*  9. Program PUBL PGCR to enable refresh during training and rank to train
  *     not done => keep the programed value in PGCR
@@ -818,14 +822,15 @@ start:
 
 /* 10. configure PUBL PIR register to specify which training step to run */
 	/* warning : RVTRN  is not supported by this PUBL */
-	stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
+		stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
 
 /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
-	ddrphy_idone_wait(priv->phy);
+		ddrphy_idone_wait(priv->phy);
 
 /* 12. set back registers in step 8 to the orginal values if desidered */
-	stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
-				 config->c_reg.pwrctl);
+		stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
+					 config->c_reg.pwrctl);
+	} /* if (config->p_cal_present) */
 
 	/* enable uMCTL2 AXI port 0 and 1 */
 	setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h
index 52b748f3ca..4998f04439 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ddr.h
+++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h
@@ -170,6 +170,7 @@ struct stm32mp1_ddr_config {
 	struct stm32mp1_ddrphy_reg p_reg;
 	struct stm32mp1_ddrphy_timing p_timing;
 	struct stm32mp1_ddrphy_cal p_cal;
+	bool p_cal_present;
 };
 
 int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed);
diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c
index cedf92cb5f..805c9ddaad 100644
--- a/drivers/ram/stm32mp1/stm32mp1_interactive.c
+++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c
@@ -106,7 +106,7 @@ static void stm32mp1_do_usage(void)
 		"help                       displays help\n"
 		"info                       displays DDR information\n"
 		"info  <param> <val>        changes DDR information\n"
-		"      with <param> = step, name, size or speed\n"
+		"      with <param> = step, name, size, speed or cal\n"
 		"freq                       displays the DDR PHY frequency in kHz\n"
 		"freq  <freq>               changes the DDR PHY frequency\n"
 		"param [type|reg]           prints input parameters\n"
@@ -160,6 +160,7 @@ static void stm32mp1_do_info(struct ddr_info *priv,
 		printf("name = %s\n", config->info.name);
 		printf("size = 0x%x\n", config->info.size);
 		printf("speed = %d kHz\n", config->info.speed);
+		printf("cal = %d\n", config->p_cal_present);
 		return;
 	}
 
@@ -208,6 +209,16 @@ static void stm32mp1_do_info(struct ddr_info *priv,
 		}
 		return;
 	}
+	if (!strcmp(argv[1], "cal")) {
+		if (strict_strtoul(argv[2], 10, &value) < 0 ||
+		    (value != 0 && value != 1)) {
+			printf("invalid value %s\n", argv[2]);
+		} else {
+			config->p_cal_present = value;
+			printf("cal = %d\n", config->p_cal_present);
+		}
+		return;
+	}
 	printf("argument %s invalid\n", argv[1]);
 }
 
diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c
index eb78f1198d..b1e593f86b 100644
--- a/drivers/ram/stm32mp1/stm32mp1_ram.c
+++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
@@ -65,18 +65,22 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
 	struct clk axidcg;
 	struct stm32mp1_ddr_config config;
 
-#define PARAM(x, y) \
-	{ x,\
-	  offsetof(struct stm32mp1_ddr_config, y),\
-	  sizeof(config.y) / sizeof(u32)}
+#define PARAM(x, y, z)							\
+	{	.name = x,						\
+		.offset = offsetof(struct stm32mp1_ddr_config, y),	\
+		.size = sizeof(config.y) / sizeof(u32),			\
+		.present = z,						\
+	}
 
-#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
-#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
+#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x, NULL)
+#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x, NULL)
+#define PHY_PARAM_OPT(x) PARAM("st,phy-"#x, p_##x, &config.p_##x##_present)
 
 	const struct {
 		const char *name; /* name in DT */
 		const u32 offset; /* offset in config struct */
 		const u32 size;   /* size of parameters */
+		bool * const present;  /* presence indication for opt */
 	} param[] = {
 		CTL_PARAM(reg),
 		CTL_PARAM(timing),
@@ -84,7 +88,7 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
 		CTL_PARAM(perf),
 		PHY_PARAM(reg),
 		PHY_PARAM(timing),
-		PHY_PARAM(cal)
+		PHY_PARAM_OPT(cal)
 	};
 
 	config.info.speed = dev_read_u32_default(dev, "st,mem-speed", 0);
@@ -103,11 +107,25 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
 					 param[idx].size);
 		debug("%s: %s[0x%x] = %d\n", __func__,
 		      param[idx].name, param[idx].size, ret);
-		if (ret) {
+		if (ret &&
+		    (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) {
 			pr_err("%s: Cannot read %s, error=%d\n",
 			       __func__, param[idx].name, ret);
 			return -EINVAL;
 		}
+		if (param[idx].present) {
+			/* save presence of optional parameters */
+			*param[idx].present = true;
+			if (ret == -FDT_ERR_NOTFOUND) {
+				*param[idx].present = false;
+#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
+				/* reset values if used later */
+				memset((void *)((u32)&config +
+						param[idx].offset),
+					0, param[idx].size * sizeof(u32));
+#endif
+			}
+		}
 	}
 
 	ret = clk_get_by_name(dev, "axidcg", &axidcg);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR
  2020-03-06 10:14 ` [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR Patrick Delaunay
@ 2020-03-18  9:39   ` Patrice CHOTARD
  2020-03-24  8:48   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:39 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Need to increase the LPDDR2/LPDDR3 the voltage vdd2_ddr: buck2
> form 1.2V to 1.25V for 32bits configuration.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  arch/arm/mach-stm32mp/include/mach/ddr.h |  6 +++--
>  board/st/stm32mp1/board.c                | 23 ++++++++++++++----
>  drivers/ram/stm32mp1/stm32mp1_ddr.c      | 30 ++++++++++++++++++++----
>  include/power/stpmic1.h                  |  1 +
>  4 files changed, 49 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-stm32mp/include/mach/ddr.h b/arch/arm/mach-stm32mp/include/mach/ddr.h
> index b8a17cfbdd..bfc42a7c48 100644
> --- a/arch/arm/mach-stm32mp/include/mach/ddr.h
> +++ b/arch/arm/mach-stm32mp/include/mach/ddr.h
> @@ -9,8 +9,10 @@
>  /* DDR power initializations */
>  enum ddr_type {
>  	STM32MP_DDR3,
> -	STM32MP_LPDDR2,
> -	STM32MP_LPDDR3,
> +	STM32MP_LPDDR2_16,
> +	STM32MP_LPDDR2_32,
> +	STM32MP_LPDDR3_16,
> +	STM32MP_LPDDR3_32,
>  };
>  
>  int board_ddr_power_init(enum ddr_type ddr_type);
> diff --git a/board/st/stm32mp1/board.c b/board/st/stm32mp1/board.c
> index c3d832f584..4e35d36c76 100644
> --- a/board/st/stm32mp1/board.c
> +++ b/board/st/stm32mp1/board.c
> @@ -43,6 +43,7 @@ int board_ddr_power_init(enum ddr_type ddr_type)
>  	struct udevice *dev;
>  	bool buck3_at_1800000v = false;
>  	int ret;
> +	u32 buck2;
>  
>  	ret = uclass_get_device_by_driver(UCLASS_PMIC,
>  					  DM_GET_DRIVER(pmic_stpmic1), &dev);
> @@ -102,8 +103,10 @@ int board_ddr_power_init(enum ddr_type ddr_type)
>  
>  		break;
>  
> -	case STM32MP_LPDDR2:
> -	case STM32MP_LPDDR3:
> +	case STM32MP_LPDDR2_16:
> +	case STM32MP_LPDDR2_32:
> +	case STM32MP_LPDDR3_16:
> +	case STM32MP_LPDDR3_32:
>  		/*
>  		 * configure VDD_DDR1 = LDO3
>  		 * Set LDO3 to 1.8V
> @@ -133,11 +136,23 @@ int board_ddr_power_init(enum ddr_type ddr_type)
>  		if (ret < 0)
>  			return ret;
>  
> -		/* VDD_DDR2 : Set BUCK2 to 1.2V */
> +		/* VDD_DDR2 : Set BUCK2 to 1.2V (16bits) or 1.25V (32 bits)*/
> +		switch (ddr_type) {
> +		case STM32MP_LPDDR2_32:
> +		case STM32MP_LPDDR3_32:
> +			buck2 = STPMIC1_BUCK2_1250000V;
> +			break;
> +		default:
> +		case STM32MP_LPDDR2_16:
> +		case STM32MP_LPDDR3_16:
> +			buck2 = STPMIC1_BUCK2_1200000V;
> +			break;
> +		}
> +
>  		ret = pmic_clrsetbits(dev,
>  				      STPMIC1_BUCKX_MAIN_CR(STPMIC1_BUCK2),
>  				      STPMIC1_BUCK_VOUT_MASK,
> -				      STPMIC1_BUCK2_1200000V);
> +				      buck2);
>  		if (ret < 0)
>  			return ret;
>  
> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
> index d765a46f7c..a87914f2d5 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
> @@ -668,14 +668,34 @@ void stm32mp1_ddr_init(struct ddr_info *priv,
>  {
>  	u32 pir;
>  	int ret = -EINVAL;
> +	char bus_width;
> +
> +	switch (config->c_reg.mstr & DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK) {
> +	case DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER:
> +		bus_width = 8;
> +		break;
> +	case DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF:
> +		bus_width = 16;
> +		break;
> +	default:
> +		bus_width = 32;
> +		break;
> +	}
> +
>  
>  	if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
>  		ret = board_ddr_power_init(STM32MP_DDR3);
> -	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2)
> -		ret = board_ddr_power_init(STM32MP_LPDDR2);
> -	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3)
> -		ret = board_ddr_power_init(STM32MP_LPDDR3);
> -
> +	else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2) {
> +		if (bus_width == 32)
> +			ret = board_ddr_power_init(STM32MP_LPDDR2_32);
> +		else
> +			ret = board_ddr_power_init(STM32MP_LPDDR2_16);
> +	} else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3) {
> +		if (bus_width == 32)
> +			ret = board_ddr_power_init(STM32MP_LPDDR3_32);
> +		else
> +			ret = board_ddr_power_init(STM32MP_LPDDR3_16);
> +	}
>  	if (ret)
>  		panic("ddr power init failed\n");
>  
> diff --git a/include/power/stpmic1.h b/include/power/stpmic1.h
> index dc8b5a7459..1493a677f0 100644
> --- a/include/power/stpmic1.h
> +++ b/include/power/stpmic1.h
> @@ -37,6 +37,7 @@
>  #define STPMIC1_BUCK_VOUT(sel)		(sel << STPMIC1_BUCK_VOUT_SHIFT)
>  
>  #define STPMIC1_BUCK2_1200000V		STPMIC1_BUCK_VOUT(24)
> +#define STPMIC1_BUCK2_1250000V		STPMIC1_BUCK_VOUT(26)
>  #define STPMIC1_BUCK2_1350000V		STPMIC1_BUCK_VOUT(30)
>  
>  #define STPMIC1_BUCK3_1800000V		STPMIC1_BUCK_VOUT(39)

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating
  2020-03-06 10:14 ` [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating Patrick Delaunay
@ 2020-03-18  9:39   ` Patrice CHOTARD
  2020-03-24  8:48   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:39 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Display result information for software read DQS gating, the tuning 0
> which be used by CubeMX DDR tuning tools.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_tuning.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> index 4e1c1fab54..e3e6f0f79c 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> @@ -1182,15 +1182,17 @@ static u8 set_midpoint_read_dqs_gating(struct stm32mp1_ddrphy *phy, u8 byte,
>  				 dqs_gate_values[byte][0],
>  				 dqs_gate_values[byte][1]);
>  			pr_debug("*******the nominal values were system latency: 0  phase: 2*******\n");
> -			set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
> -			set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
>  		}
>  	} else {
>  		/* if intermitant, restore defaut values */
>  		pr_debug("dqs gating:no regular fail/pass/fail found. defaults values restored.\n");
> -		set_r0dgsl_delay(phy, byte, 0);
> -		set_r0dgps_delay(phy, byte, 2);
> +		dqs_gate_values[byte][0] = 0;
> +		dqs_gate_values[byte][1] = 2;
>  	}
> +	set_r0dgsl_delay(phy, byte, dqs_gate_values[byte][0]);
> +	set_r0dgps_delay(phy, byte, dqs_gate_values[byte][1]);
> +	printf("Byte %d, R0DGSL = %d, R0DGPS = %d\n",
> +	       byte, dqs_gate_values[byte][0], dqs_gate_values[byte][1]);
>  
>  	/* return 0 if intermittent or if both left_bound
>  	 * and right_bound are not found

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 3/9] ram: stm32mp1: don't display the prompt two times
  2020-03-06 10:14 ` [PATCH 3/9] ram: stm32mp1: don't display the prompt two times Patrick Delaunay
@ 2020-03-18  9:39   ` Patrice CHOTARD
  2020-03-24  8:49   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:39 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Remove one "DDR>" display on command
> - next
> - step
> - go
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_interactive.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c
> index cc9b2e7c96..cedf92cb5f 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_interactive.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c
> @@ -367,7 +367,6 @@ bool stm32mp1_ddr_interactive(void *priv,
>  			      enum stm32mp1_ddr_interact_step step,
>  			      const struct stm32mp1_ddr_config *config)
>  {
> -	const char *prompt = "DDR>";
>  	char buffer[CONFIG_SYS_CBSIZE];
>  	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated */
>  	int argc;
> @@ -403,13 +402,12 @@ bool stm32mp1_ddr_interactive(void *priv,
>  	}
>  
>  	printf("%d:%s\n", step, step_str[step]);
> -	printf("%s\n", prompt);
>  
>  	if (next_step > step)
>  		return false;
>  
>  	while (next_step == step) {
> -		cli_readline_into_buffer(prompt, buffer, 0);
> +		cli_readline_into_buffer("DDR>", buffer, 0);
>  		argc = cli_simple_parse_line(buffer, argv);
>  		if (!argc)
>  			continue;

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE
  2020-03-06 10:14 ` [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE Patrick Delaunay
@ 2020-03-18  9:40   ` Patrice CHOTARD
  2020-03-24  8:49   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:40 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Avoid to block the tuning procedure on BIST error (not finished
> BIST procedure) by adding a 1000us timeout on the polling of
> BISTGSR.BDDONE executed to detect the end of BIST.
>
> The normal duration of the BIST test is around 5us.
>
> This patch also cleanup comments.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_tuning.c | 45 ++++++++++++++------------
>  1 file changed, 25 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> index e3e6f0f79c..cab6cf087a 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> @@ -8,6 +8,7 @@
>  #include <ram.h>
>  #include <reset.h>
>  #include <asm/io.h>
> +#include <linux/iopoll.h>
>  
>  #include "stm32mp1_ddr_regs.h"
>  #include "stm32mp1_ddr.h"
> @@ -246,6 +247,8 @@ static void BIST_test(struct stm32mp1_ddrphy *phy, u8 byte,
>  	bool result = true; /* BIST_SUCCESS */
>  	u32 cnt = 0;
>  	u32 error = 0;
> +	u32 val;
> +	int ret;
>  
>  	bist->test_result = true;
>  
> @@ -274,27 +277,29 @@ run:
>  			0x00000001);
>  	/* Write BISTRR.BINST = 3?b001; */
>  
> -	/* Wait for a number of CTL clocks before reading BIST register*/
> -	/* Wait 300 ctl_clk cycles;  ... IS it really needed?? */
> -	/* Perform BIST Instruction Stop*/
> -	/* Write BISTRR.BINST = 3?b010;*/
> -
> -	/* poll on BISTGSR.BDONE. If 0, wait.  ++TODO Add timeout */
> -	while (!(readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDDONE))
> -		;
> -
> -	/*Check if received correct number of words*/
> -	/* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
> -	if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT) ==
> -	    readl(&phy->bistwcr)) {
> -		/*Determine if there is a data comparison error*/
> -		/* if (Read BISTGSR.BDXERR = 1?b0) */
> -		if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
> -			result = false; /* BIST_FAIL; */
> -		else
> -			result = true; /* BIST_SUCCESS; */
> -	} else {
> +	/* poll on BISTGSR.BDONE and wait max 1000 us */
> +	ret = readl_poll_timeout(&phy->bistgsr, val,
> +				 val & DDRPHYC_BISTGSR_BDDONE, 1000);
> +
> +	if (ret < 0) {
> +		printf("warning: BIST timeout\n");
>  		result = false; /* BIST_FAIL; */
> +		/*Perform BIST Stop */
> +		clrsetbits_le32(&phy->bistrr, 0x00000007, 0x00000002);
> +	} else {
> +		/*Check if received correct number of words*/
> +		/* if (Read BISTWCSR.DXWCNT = Read BISTWCR.BWCNT) */
> +		if (((readl(&phy->bistwcsr)) >> DDRPHYC_BISTWCSR_DXWCNT_SHIFT)
> +		    == readl(&phy->bistwcr)) {
> +			/*Determine if there is a data comparison error*/
> +			/* if (Read BISTGSR.BDXERR = 1?b0) */
> +			if (readl(&phy->bistgsr) & DDRPHYC_BISTGSR_BDXERR)
> +				result = false; /* BIST_FAIL; */
> +			else
> +				result = true; /* BIST_SUCCESS; */
> +		} else {
> +			result = false; /* BIST_FAIL; */
> +		}
>  	}
>  
>  	/* loop while success */

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test
  2020-03-06 10:14 ` [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test Patrick Delaunay
@ 2020-03-18  9:43   ` Patrice CHOTARD
  2020-03-24  8:50   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:43 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> The derating (timing parameter derating using MR4 read value)
> can't be activated during BIST test, as the MR4 read answer will
> be not understood by BIST (BISTGSR.BDONE bit stay at 0,
> BISTWCSR.DXWCNT = 0x206 instead of BISTWCR.BWCNT = 0x200).
>
> This patch only impacts the tuning on LPDDR2/LPDDR3,
> if derateen.derate_enable = 1.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_tuning.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> index cab6cf087a..37d3ec8fef 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> @@ -1288,11 +1288,16 @@ static enum test_result do_read_dqs_gating(struct stm32mp1_ddrctl *ctl,
>  {
>  	u32 rfshctl3 = readl(&ctl->rfshctl3);
>  	u32 pwrctl = readl(&ctl->pwrctl);
> +	u32 derateen = readl(&ctl->derateen);
>  	enum test_result res;
>  
> +	writel(0x0, &ctl->derateen);
>  	stm32mp1_refresh_disable(ctl);
> +
>  	res = read_dqs_gating(ctl, phy, string);
> +
>  	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
> +	writel(derateen, &ctl->derateen);
>  
>  	return res;
>  }
> @@ -1303,11 +1308,16 @@ static enum test_result do_bit_deskew(struct stm32mp1_ddrctl *ctl,
>  {
>  	u32 rfshctl3 = readl(&ctl->rfshctl3);
>  	u32 pwrctl = readl(&ctl->pwrctl);
> +	u32 derateen = readl(&ctl->derateen);
>  	enum test_result res;
>  
> +	writel(0x0, &ctl->derateen);
>  	stm32mp1_refresh_disable(ctl);
> +
>  	res = bit_deskew(ctl, phy, string);
> +
>  	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
> +	writel(derateen, &ctl->derateen);
>  
>  	return res;
>  }
> @@ -1318,11 +1328,16 @@ static enum test_result do_eye_training(struct stm32mp1_ddrctl *ctl,
>  {
>  	u32 rfshctl3 = readl(&ctl->rfshctl3);
>  	u32 pwrctl = readl(&ctl->pwrctl);
> +	u32 derateen = readl(&ctl->derateen);
>  	enum test_result res;
>  
> +	writel(0x0, &ctl->derateen);
>  	stm32mp1_refresh_disable(ctl);
> +
>  	res = eye_training(ctl, phy, string);
> +
>  	stm32mp1_refresh_restore(ctl, rfshctl3, pwrctl);
> +	writel(derateen, &ctl->derateen);
>  
>  	return res;
>  }

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 6/9] ram: stm32mp1: update BIST config for tuning
  2020-03-06 10:14 ` [PATCH 6/9] ram: stm32mp1: update BIST config for tuning Patrick Delaunay
@ 2020-03-18  9:45   ` Patrice CHOTARD
  2020-03-24  8:50   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:45 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Update the BIST config to compute the real use mask for the real
> bank, row and col of the used DDR. The values are get from addrmap
> register value.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_tuning.c | 151 +++++++++++++++++++++++--
>  1 file changed, 142 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> index 37d3ec8fef..07d57d496c 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> @@ -8,6 +8,7 @@
>  #include <ram.h>
>  #include <reset.h>
>  #include <asm/io.h>
> +#include <linux/bitops.h>
>  #include <linux/iopoll.h>
>  
>  #include "stm32mp1_ddr_regs.h"
> @@ -76,6 +77,133 @@ static u8 get_nb_bytes(struct stm32mp1_ddrctl *ctl)
>  	return nb_bytes;
>  }
>  
> +static u8 get_nb_bank(struct stm32mp1_ddrctl *ctl)
> +{
> +	/* Count bank address bits */
> +	u8 bits = 0;
> +	u32 reg, val;
> +
> +	reg = readl(&ctl->addrmap1);
> +	/* addrmap1.addrmap_bank_b1 */
> +	val = (reg & GENMASK(5, 0)) >> 0;
> +	if (val <= 31)
> +		bits++;
> +	/* addrmap1.addrmap_bank_b2 */
> +	val = (reg & GENMASK(13, 8)) >> 8;
> +	if (val <= 31)
> +		bits++;
> +	/* addrmap1.addrmap_bank_b3 */
> +	val = (reg & GENMASK(21, 16)) >> 16;
> +	if (val <= 31)
> +		bits++;
> +
> +	return bits;
> +}
> +
> +static u8 get_nb_col(struct stm32mp1_ddrctl *ctl)
> +{
> +	u8 bits;
> +	u32 reg, val;
> +
> +	/* Count column address bits, start at 2 for b0 and b1 (fixed) */
> +	bits = 2;
> +
> +	reg = readl(&ctl->addrmap2);
> +	/* addrmap2.addrmap_col_b2 */
> +	val = (reg & GENMASK(3, 0)) >> 0;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap2.addrmap_col_b3 */
> +	val = (reg & GENMASK(11, 8)) >> 8;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap2.addrmap_col_b4 */
> +	val = (reg & GENMASK(19, 16)) >> 16;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap2.addrmap_col_b5 */
> +	val = (reg & GENMASK(27, 24)) >> 24;
> +	if (val <= 7)
> +		bits++;
> +
> +	reg = readl(&ctl->addrmap3);
> +	/* addrmap3.addrmap_col_b6 */
> +	val = (reg & GENMASK(3, 0)) >> 0;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap3.addrmap_col_b7 */
> +	val = (reg & GENMASK(11, 8)) >> 8;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap3.addrmap_col_b8 */
> +	val = (reg & GENMASK(19, 16)) >> 16;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap3.addrmap_col_b9 */
> +	val = (reg & GENMASK(27, 24)) >> 24;
> +	if (val <= 7)
> +		bits++;
> +
> +	reg = readl(&ctl->addrmap4);
> +	/* addrmap4.addrmap_col_b10 */
> +	val = (reg & GENMASK(3, 0)) >> 0;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap4.addrmap_col_b11 */
> +	val = (reg & GENMASK(11, 8)) >> 8;
> +	if (val <= 7)
> +		bits++;
> +
> +	return bits;
> +}
> +
> +static u8 get_nb_row(struct stm32mp1_ddrctl *ctl)
> +{
> +	/* Count row address bits */
> +	u8 bits = 0;
> +	u32 reg, val;
> +
> +	reg = readl(&ctl->addrmap5);
> +	/* addrmap5.addrmap_row_b0 */
> +	val = (reg & GENMASK(3, 0)) >> 0;
> +	if (val <= 11)
> +		bits++;
> +	/* addrmap5.addrmap_row_b1 */
> +	val = (reg & GENMASK(11, 8)) >> 8;
> +	if (val <= 11)
> +		bits++;
> +	/* addrmap5.addrmap_row_b2_10 */
> +	val = (reg & GENMASK(19, 16)) >> 16;
> +	if (val <= 11)
> +		bits += 9;
> +	else
> +		printf("warning: addrmap5.addrmap_row_b2_10 not supported\n");
> +	/* addrmap5.addrmap_row_b11 */
> +	val = (reg & GENMASK(27, 24)) >> 24;
> +	if (val <= 11)
> +		bits++;
> +
> +	reg = readl(&ctl->addrmap6);
> +	/* addrmap6.addrmap_row_b12 */
> +	val = (reg & GENMASK(3, 0)) >> 0;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap6.addrmap_row_b13 */
> +	val = (reg & GENMASK(11, 8)) >> 8;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap6.addrmap_row_b14 */
> +	val = (reg & GENMASK(19, 16)) >> 16;
> +	if (val <= 7)
> +		bits++;
> +	/* addrmap6.addrmap_row_b15 */
> +	val = (reg & GENMASK(27, 24)) >> 24;
> +	if (val <= 7)
> +		bits++;
> +
> +	return bits;
> +}
> +
>  static void itm_soft_reset(struct stm32mp1_ddrphy *phy)
>  {
>  	stm32mp1_ddrphy_init(phy, DDRPHYC_PIR_ITMSRST);
> @@ -170,8 +298,13 @@ static void set_r0dgps_delay(struct stm32mp1_ddrphy *phy,
>  }
>  
>  /* Basic BIST configuration for data lane tests. */
> -static void config_BIST(struct stm32mp1_ddrphy *phy)
> +static void config_BIST(struct stm32mp1_ddrctl *ctl,
> +			struct stm32mp1_ddrphy *phy)
>  {
> +	u8 nb_bank = get_nb_bank(ctl);
> +	u8 nb_row = get_nb_row(ctl);
> +	u8 nb_col = get_nb_col(ctl);
> +
>  	/* Selects the SDRAM bank address to be used during BIST. */
>  	u32 bbank = 0;
>  	/* Selects the SDRAM row address to be used during BIST. */
> @@ -191,18 +324,20 @@ static void config_BIST(struct stm32mp1_ddrphy *phy)
>  	 * must be 0 with single rank
>  	 */
>  	u32 brank = 0;
> +
>  	/* Specifies the maximum SDRAM bank address to be used during
>  	 * BIST before the address & increments to the next rank.
>  	 */
> -	u32 bmbank = 1;
> +	u32 bmbank = (1 << nb_bank) - 1;
>  	/* Specifies the maximum SDRAM row address to be used during
>  	 * BIST before the address & increments to the next bank.
>  	 */
> -	u32 bmrow = 0x7FFF; /* To check */
> +	u32 bmrow = (1 << nb_row) - 1;
>  	/* Specifies the maximum SDRAM column address to be used during
>  	 * BIST before the address & increments to the next row.
>  	 */
> -	u32 bmcol = 0x3FF;  /* To check */
> +	u32 bmcol = (1 << nb_col) - 1;
> +
>  	u32 bmode_conf = 0x00000001;  /* DRam mode */
>  	u32 bdxen_conf = 0x00000001;  /* BIST on Data byte */
>  	u32 bdpat_conf = 0x00000002;  /* Select LFSR pattern */
> @@ -224,8 +359,6 @@ static void config_BIST(struct stm32mp1_ddrphy *phy)
>  
>  	writel(bcol | (brow << 12) | (bbank << 28), &phy->bistar0);
>  	writel(brank | (bmrank << 2) | (bainc << 4), &phy->bistar1);
> -
> -	/* To check this line : */
>  	writel(bmcol | (bmrow << 12) | (bmbank << 28), &phy->bistar2);
>  }
>  
> @@ -399,7 +532,7 @@ static enum test_result bit_deskew(struct stm32mp1_ddrctl *ctl,
>  	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
>  
>  	/* Config the BIST block */
> -	config_BIST(phy);
> +	config_BIST(ctl, phy);
>  	pr_debug("BIST Config done.\n");
>  
>  	/* Train each byte */
> @@ -812,7 +945,7 @@ static enum test_result eye_training(struct stm32mp1_ddrctl *ctl,
>  	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
>  
>  	/* Config the BIST block */
> -	config_BIST(phy);
> +	config_BIST(ctl, phy);
>  
>  	for (byte = 0; byte < nb_bytes; byte++) {
>  		if (ctrlc()) {
> @@ -1234,7 +1367,7 @@ static enum test_result read_dqs_gating(struct stm32mp1_ddrctl *ctl,
>  	clrbits_le32(&phy->dx3gcr, DDRPHYC_DXNGCR_DXEN);
>  
>  	/* config the bist block */
> -	config_BIST(phy);
> +	config_BIST(ctl, phy);
>  
>  	for (byte = 0; byte < nb_bytes; byte++) {
>  		if (ctrlc()) {


Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training
  2020-03-06 10:14 ` [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training Patrick Delaunay
@ 2020-03-18  9:46   ` Patrice CHOTARD
  2020-03-24  8:51   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:46 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> DDRCTRL_PWRCTL.SELFREF_EN needs to be reset before DQS training step, not
> to enter in self refresh mode during the execution of this phase.
> Depending on settings, it can be set after the DQS training.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_ddr.c      | 5 ++++-
>  drivers/ram/stm32mp1/stm32mp1_ddr_regs.h | 1 +
>  2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
> index a87914f2d5..b9300dd6d1 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
> @@ -639,7 +639,8 @@ void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
>  	start_sw_done(ctl);
>  	/* quasi-dynamic register update*/
>  	setbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
> -	clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
> +	clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN |
> +				   DDRCTRL_PWRCTL_SELFREF_EN);
>  	clrbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
>  	wait_sw_done_ack(ctl);
>  }
> @@ -652,6 +653,8 @@ void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
>  		clrbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
>  	if (pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN)
>  		setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
> +	if ((pwrctl & DDRCTRL_PWRCTL_SELFREF_EN))
> +		setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_SELFREF_EN);
>  	setbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
>  	wait_sw_done_ack(ctl);
>  }
> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
> index 9d33186b3a..afd93c518e 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr_regs.h
> @@ -260,6 +260,7 @@ struct stm32mp1_ddrphy {
>  
>  #define DDRCTRL_MRSTAT_MR_WR_BUSY		BIT(0)
>  
> +#define DDRCTRL_PWRCTL_SELFREF_EN		BIT(0)
>  #define DDRCTRL_PWRCTL_POWERDOWN_EN		BIT(1)
>  #define DDRCTRL_PWRCTL_SELFREF_SW		BIT(5)
>  

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning
  2020-03-06 10:14 ` [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning Patrick Delaunay
@ 2020-03-18  9:46   ` Patrice CHOTARD
  2020-03-24  8:51   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:46 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> Reduce the delay after BIST delay, from 1ms to 10us
> which is enough accoriding datasheet.
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  drivers/ram/stm32mp1/stm32mp1_tuning.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/ram/stm32mp1/stm32mp1_tuning.c b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> index 07d57d496c..3013b7b667 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_tuning.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_tuning.c
> @@ -402,7 +402,7 @@ run:
>  		writel(rand(), &phy->bistlsr);
>  
>  	/* some delay to reset BIST */
> -	mdelay(1);
> +	udelay(10);
>  
>  	/*Perform BIST Run*/
>  	clrsetbits_le32(&phy->bistrr,

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional
  2020-03-06 10:14 ` [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional Patrick Delaunay
@ 2020-03-18  9:52   ` Patrice CHOTARD
  2020-03-24  8:51   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrice CHOTARD @ 2020-03-18  9:52 UTC (permalink / raw)
  To: u-boot


On 3/6/20 11:14 AM, Patrick Delaunay wrote:
> This parameter "st,phy-cal" becomes optional and when it is
> absent the built-in PHY calibration is done.
>
> It is the case in the helper dtsi file "stm32mp15-ddr.dtsi"
> except if DDR_PHY_CAL_SKIP is defined.
>
> This patch also impact the ddr interactive mode
> - the registers of the param 'phy.cal' are initialized to 0 when
>   "st,phy-cal" is not present in device tree (default behavior when
>   DDR_PHY_CAL_SKIP is not activated)
> - the info 'cal' field can be use to change the calibration behavior
>   - cal=1 => use param phy.cal to initialize the PHY, built-in training
>              is skipped
>   - cal=0 => param phy.cal is absent, built-in training is used (default)
>
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---
>
>  arch/arm/dts/stm32mp15-ddr.dtsi               |  3 ++
>  .../memory-controllers/st,stm32mp1-ddr.txt    |  2 ++
>  drivers/ram/stm32mp1/stm32mp1_ddr.c           | 19 +++++++----
>  drivers/ram/stm32mp1/stm32mp1_ddr.h           |  1 +
>  drivers/ram/stm32mp1/stm32mp1_interactive.c   | 13 ++++++-
>  drivers/ram/stm32mp1/stm32mp1_ram.c           | 34 ++++++++++++++-----
>  6 files changed, 56 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi
> index 38f29bb789..8b20b5e173 100644
> --- a/arch/arm/dts/stm32mp15-ddr.dtsi
> +++ b/arch/arm/dts/stm32mp15-ddr.dtsi
> @@ -133,6 +133,7 @@
>  				DDR_MR3
>  			>;
>  
> +#ifdef DDR_PHY_CAL_SKIP
>  			st,phy-cal = <
>  				DDR_DX0DLLCR
>  				DDR_DX0DQTR
> @@ -148,6 +149,8 @@
>  				DDR_DX3DQSTR
>  			>;
>  
> +#endif
> +
>  			status = "okay";
>  		};
>  	};
> diff --git a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
> index ee708ce92c..ac6a7df432 100644
> --- a/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
> +++ b/doc/device-tree-bindings/memory-controllers/st,stm32mp1-ddr.txt
> @@ -129,6 +129,8 @@ phyc attributes:
>  		MR3
>  
>  - st,phy-cal	: phy cal depending of calibration or tuning of DDR
> +	This parameter is optional; when it is absent the built-in PHY
> +	calibration is done.
>  	for STM32MP15x: 12 values are requested in this order
>  		DX0DLLCR
>  		DX0DQTR
> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.c b/drivers/ram/stm32mp1/stm32mp1_ddr.c
> index b9300dd6d1..11b14ae652 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_ddr.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.c
> @@ -769,7 +769,8 @@ start:
>   */
>  	set_reg(priv, REGPHY_REG, &config->p_reg);
>  	set_reg(priv, REGPHY_TIMING, &config->p_timing);
> -	set_reg(priv, REGPHY_CAL, &config->p_cal);
> +	if (config->p_cal_present)
> +		set_reg(priv, REGPHY_CAL, &config->p_cal);
>  
>  	if (INTERACTIVE(STEP_PHY_INIT))
>  		goto start;
> @@ -804,13 +805,16 @@ start:
>  
>  	wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
>  
> -	debug("DDR DQS training : ");
> +	if (config->p_cal_present) {
> +		debug("DDR DQS training skipped.\n");
> +	} else {
> +		debug("DDR DQS training : ");
>  /*  8. Disable Auto refresh and power down by setting
>   *    - RFSHCTL3.dis_au_refresh = 1
>   *    - PWRCTL.powerdown_en = 0
>   *    - DFIMISC.dfiinit_complete_en = 0
>   */
> -	stm32mp1_refresh_disable(priv->ctl);
> +		stm32mp1_refresh_disable(priv->ctl);
>  
>  /*  9. Program PUBL PGCR to enable refresh during training and rank to train
>   *     not done => keep the programed value in PGCR
> @@ -818,14 +822,15 @@ start:
>  
>  /* 10. configure PUBL PIR register to specify which training step to run */
>  	/* warning : RVTRN  is not supported by this PUBL */
> -	stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
> +		stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
>  
>  /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
> -	ddrphy_idone_wait(priv->phy);
> +		ddrphy_idone_wait(priv->phy);
>  
>  /* 12. set back registers in step 8 to the orginal values if desidered */
> -	stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
> -				 config->c_reg.pwrctl);
> +		stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
> +					 config->c_reg.pwrctl);
> +	} /* if (config->p_cal_present) */
>  
>  	/* enable uMCTL2 AXI port 0 and 1 */
>  	setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
> diff --git a/drivers/ram/stm32mp1/stm32mp1_ddr.h b/drivers/ram/stm32mp1/stm32mp1_ddr.h
> index 52b748f3ca..4998f04439 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_ddr.h
> +++ b/drivers/ram/stm32mp1/stm32mp1_ddr.h
> @@ -170,6 +170,7 @@ struct stm32mp1_ddr_config {
>  	struct stm32mp1_ddrphy_reg p_reg;
>  	struct stm32mp1_ddrphy_timing p_timing;
>  	struct stm32mp1_ddrphy_cal p_cal;
> +	bool p_cal_present;
>  };
>  
>  int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed);
> diff --git a/drivers/ram/stm32mp1/stm32mp1_interactive.c b/drivers/ram/stm32mp1/stm32mp1_interactive.c
> index cedf92cb5f..805c9ddaad 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_interactive.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_interactive.c
> @@ -106,7 +106,7 @@ static void stm32mp1_do_usage(void)
>  		"help                       displays help\n"
>  		"info                       displays DDR information\n"
>  		"info  <param> <val>        changes DDR information\n"
> -		"      with <param> = step, name, size or speed\n"
> +		"      with <param> = step, name, size, speed or cal\n"
>  		"freq                       displays the DDR PHY frequency in kHz\n"
>  		"freq  <freq>               changes the DDR PHY frequency\n"
>  		"param [type|reg]           prints input parameters\n"
> @@ -160,6 +160,7 @@ static void stm32mp1_do_info(struct ddr_info *priv,
>  		printf("name = %s\n", config->info.name);
>  		printf("size = 0x%x\n", config->info.size);
>  		printf("speed = %d kHz\n", config->info.speed);
> +		printf("cal = %d\n", config->p_cal_present);
>  		return;
>  	}
>  
> @@ -208,6 +209,16 @@ static void stm32mp1_do_info(struct ddr_info *priv,
>  		}
>  		return;
>  	}
> +	if (!strcmp(argv[1], "cal")) {
> +		if (strict_strtoul(argv[2], 10, &value) < 0 ||
> +		    (value != 0 && value != 1)) {
> +			printf("invalid value %s\n", argv[2]);
> +		} else {
> +			config->p_cal_present = value;
> +			printf("cal = %d\n", config->p_cal_present);
> +		}
> +		return;
> +	}
>  	printf("argument %s invalid\n", argv[1]);
>  }
>  
> diff --git a/drivers/ram/stm32mp1/stm32mp1_ram.c b/drivers/ram/stm32mp1/stm32mp1_ram.c
> index eb78f1198d..b1e593f86b 100644
> --- a/drivers/ram/stm32mp1/stm32mp1_ram.c
> +++ b/drivers/ram/stm32mp1/stm32mp1_ram.c
> @@ -65,18 +65,22 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
>  	struct clk axidcg;
>  	struct stm32mp1_ddr_config config;
>  
> -#define PARAM(x, y) \
> -	{ x,\
> -	  offsetof(struct stm32mp1_ddr_config, y),\
> -	  sizeof(config.y) / sizeof(u32)}
> +#define PARAM(x, y, z)							\
> +	{	.name = x,						\
> +		.offset = offsetof(struct stm32mp1_ddr_config, y),	\
> +		.size = sizeof(config.y) / sizeof(u32),			\
> +		.present = z,						\
> +	}
>  
> -#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
> -#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
> +#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x, NULL)
> +#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x, NULL)
> +#define PHY_PARAM_OPT(x) PARAM("st,phy-"#x, p_##x, &config.p_##x##_present)
>  
>  	const struct {
>  		const char *name; /* name in DT */
>  		const u32 offset; /* offset in config struct */
>  		const u32 size;   /* size of parameters */
> +		bool * const present;  /* presence indication for opt */
>  	} param[] = {
>  		CTL_PARAM(reg),
>  		CTL_PARAM(timing),
> @@ -84,7 +88,7 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
>  		CTL_PARAM(perf),
>  		PHY_PARAM(reg),
>  		PHY_PARAM(timing),
> -		PHY_PARAM(cal)
> +		PHY_PARAM_OPT(cal)
>  	};
>  
>  	config.info.speed = dev_read_u32_default(dev, "st,mem-speed", 0);
> @@ -103,11 +107,25 @@ static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
>  					 param[idx].size);
>  		debug("%s: %s[0x%x] = %d\n", __func__,
>  		      param[idx].name, param[idx].size, ret);
> -		if (ret) {
> +		if (ret &&
> +		    (ret != -FDT_ERR_NOTFOUND || !param[idx].present)) {
>  			pr_err("%s: Cannot read %s, error=%d\n",
>  			       __func__, param[idx].name, ret);
>  			return -EINVAL;
>  		}
> +		if (param[idx].present) {
> +			/* save presence of optional parameters */
> +			*param[idx].present = true;
> +			if (ret == -FDT_ERR_NOTFOUND) {
> +				*param[idx].present = false;
> +#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
> +				/* reset values if used later */
> +				memset((void *)((u32)&config +
> +						param[idx].offset),
> +					0, param[idx].size * sizeof(u32));
> +#endif
> +			}
> +		}
>  	}
>  
>  	ret = clk_get_by_name(dev, "axidcg", &axidcg);

Acked-by: Patrice Chotard <patrice.chotard@st.com>

Thanks

Patrice

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR
  2020-03-06 10:14 ` [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR Patrick Delaunay
  2020-03-18  9:39   ` Patrice CHOTARD
@ 2020-03-24  8:48   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:48 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> Need to increase the LPDDR2/LPDDR3 the voltage vdd2_ddr: buck2 form 1.2V to
> 1.25V for 32bits configuration.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating
  2020-03-06 10:14 ` [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating Patrick Delaunay
  2020-03-18  9:39   ` Patrice CHOTARD
@ 2020-03-24  8:48   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:48 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> Display result information for software read DQS gating, the tuning 0 which be
> used by CubeMX DDR tuning tools.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---


Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 3/9] ram: stm32mp1: don't display the prompt two times
  2020-03-06 10:14 ` [PATCH 3/9] ram: stm32mp1: don't display the prompt two times Patrick Delaunay
  2020-03-18  9:39   ` Patrice CHOTARD
@ 2020-03-24  8:49   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:49 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> Remove one "DDR>" display on command
> - next
> - step
> - go
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---


Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE
  2020-03-06 10:14 ` [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE Patrick Delaunay
  2020-03-18  9:40   ` Patrice CHOTARD
@ 2020-03-24  8:49   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:49 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> Avoid to block the tuning procedure on BIST error (not finished BIST procedure)
> by adding a 1000us timeout on the polling of BISTGSR.BDDONE executed to
> detect the end of BIST.
> 
> The normal duration of the BIST test is around 5us.
> 
> This patch also cleanup comments.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test
  2020-03-06 10:14 ` [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test Patrick Delaunay
  2020-03-18  9:43   ` Patrice CHOTARD
@ 2020-03-24  8:50   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:50 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> The derating (timing parameter derating using MR4 read value) can't be activated
> during BIST test, as the MR4 read answer will be not understood by BIST
> (BISTGSR.BDONE bit stay at 0, BISTWCSR.DXWCNT = 0x206 instead of
> BISTWCR.BWCNT = 0x200).
> 
> This patch only impacts the tuning on LPDDR2/LPDDR3, if
> derateen.derate_enable = 1.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 6/9] ram: stm32mp1: update BIST config for tuning
  2020-03-06 10:14 ` [PATCH 6/9] ram: stm32mp1: update BIST config for tuning Patrick Delaunay
  2020-03-18  9:45   ` Patrice CHOTARD
@ 2020-03-24  8:50   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:50 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> Update the BIST config to compute the real use mask for the real bank, row and
> col of the used DDR. The values are get from addrmap register value.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training
  2020-03-06 10:14 ` [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training Patrick Delaunay
  2020-03-18  9:46   ` Patrice CHOTARD
@ 2020-03-24  8:51   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:51 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> DDRCTRL_PWRCTL.SELFREF_EN needs to be reset before DQS training step,
> not to enter in self refresh mode during the execution of this phase.
> Depending on settings, it can be set after the DQS training.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning
  2020-03-06 10:14 ` [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning Patrick Delaunay
  2020-03-18  9:46   ` Patrice CHOTARD
@ 2020-03-24  8:51   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:51 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> Reduce the delay after BIST delay, from 1ms to 10us which is enough accoriding
> datasheet.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional
  2020-03-06 10:14 ` [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional Patrick Delaunay
  2020-03-18  9:52   ` Patrice CHOTARD
@ 2020-03-24  8:51   ` Patrick DELAUNAY
  1 sibling, 0 replies; 28+ messages in thread
From: Patrick DELAUNAY @ 2020-03-24  8:51 UTC (permalink / raw)
  To: u-boot

Hi,

> From: Patrick DELAUNAY <patrick.delaunay@st.com>
> Sent: vendredi 6 mars 2020 11:14
> 
> This parameter "st,phy-cal" becomes optional and when it is absent the built-in
> PHY calibration is done.
> 
> It is the case in the helper dtsi file "stm32mp15-ddr.dtsi"
> except if DDR_PHY_CAL_SKIP is defined.
> 
> This patch also impact the ddr interactive mode
> - the registers of the param 'phy.cal' are initialized to 0 when
>   "st,phy-cal" is not present in device tree (default behavior when
>   DDR_PHY_CAL_SKIP is not activated)
> - the info 'cal' field can be use to change the calibration behavior
>   - cal=1 => use param phy.cal to initialize the PHY, built-in training
>              is skipped
>   - cal=0 => param phy.cal is absent, built-in training is used (default)
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> ---

Applied to u-boot-stm/next, thanks!

Regards

Patrick

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2020-03-24  8:51 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-06 10:14 [PATCH 0/9] ram: stm32mp1: fixes Patrick Delaunay
2020-03-06 10:14 ` [PATCH 1/9] ram: stm32mp1: increase vdd2_ddr: buck2 for 32bits LPDDR Patrick Delaunay
2020-03-18  9:39   ` Patrice CHOTARD
2020-03-24  8:48   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 2/9] ram: stm32mp1: display result for software read DQS gating Patrick Delaunay
2020-03-18  9:39   ` Patrice CHOTARD
2020-03-24  8:48   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 3/9] ram: stm32mp1: don't display the prompt two times Patrick Delaunay
2020-03-18  9:39   ` Patrice CHOTARD
2020-03-24  8:49   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 4/9] ram: stm32mp1: tuning: add timeout for polling BISTGSR.BDDONE Patrick Delaunay
2020-03-18  9:40   ` Patrice CHOTARD
2020-03-24  8:49   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 5/9] ram: stm32mp1: tuning: deactivate derating during BIST test Patrick Delaunay
2020-03-18  9:43   ` Patrice CHOTARD
2020-03-24  8:50   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 6/9] ram: stm32mp1: update BIST config for tuning Patrick Delaunay
2020-03-18  9:45   ` Patrice CHOTARD
2020-03-24  8:50   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 7/9] ram: stm32mp1_ddr: fix self refresh disable during DQS training Patrick Delaunay
2020-03-18  9:46   ` Patrice CHOTARD
2020-03-24  8:51   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 8/9] ram: stm32mp1: reduce delay after BIST reset for tuning Patrick Delaunay
2020-03-18  9:46   ` Patrice CHOTARD
2020-03-24  8:51   ` Patrick DELAUNAY
2020-03-06 10:14 ` [PATCH 9/9] ram: stm32mp1: the property st,phy-cal becomes optional Patrick Delaunay
2020-03-18  9:52   ` Patrice CHOTARD
2020-03-24  8:51   ` Patrick DELAUNAY

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.