Re: [U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines

2016-10-30 Thread Marek Vasut
On 10/30/2016 06:19 PM, Eric Nelson wrote:
> The DDR calibration routines have scattered support for bus
> widths other than 64-bits:
> 
> -- The mmdc_do_write_level_calibration() routine assumes the
> presence of PHY1, and
> -- The mmdc_do_dqs_calibration() routine tries to determine
> whether one or two DDR PHYs are active by reading MDCTL.
> 
> Since a caller of these routines must have a valid struct mx6_ddr_sysinfo
> for use in calling mx6_dram_cfg(), and the bus width is available in the
> "dsize" field, use this structure to inform the calibration routines which
> PHYs are active.
> 
> This allows the use of the DDR calibration routines on CPU variants
> like i.MX6SL that only have a single MMDC port.
> 
> Signed-off-by: Eric Nelson 

Reviewed-by: Marek Vasut 

-- 
Best regards,
Marek Vasut
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


[U-Boot] [PATCH 2/3] mx6: ddr: pass mx6_ddr_sysinfo to calibration routines

2016-10-30 Thread Eric Nelson
The DDR calibration routines have scattered support for bus
widths other than 64-bits:

-- The mmdc_do_write_level_calibration() routine assumes the
presence of PHY1, and
-- The mmdc_do_dqs_calibration() routine tries to determine
whether one or two DDR PHYs are active by reading MDCTL.

Since a caller of these routines must have a valid struct mx6_ddr_sysinfo
for use in calling mx6_dram_cfg(), and the bus width is available in the
"dsize" field, use this structure to inform the calibration routines which
PHYs are active.

This allows the use of the DDR calibration routines on CPU variants
like i.MX6SL that only have a single MMDC port.

Signed-off-by: Eric Nelson 
---
 arch/arm/cpu/armv7/mx6/ddr.c| 98 +++--
 arch/arm/include/asm/arch-mx6/mx6-ddr.h |  4 +-
 board/kosagi/novena/novena_spl.c|  4 +-
 3 files changed, 60 insertions(+), 46 deletions(-)

diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c
index b15f376..274a0ba 100644
--- a/arch/arm/cpu/armv7/mx6/ddr.c
+++ b/arch/arm/cpu/armv7/mx6/ddr.c
@@ -86,14 +86,15 @@ static void modify_dg_result(u32 *reg_st0, u32 *reg_st1, 
u32 *reg_ctrl)
writel(val_ctrl, reg_ctrl);
 }
 
-int mmdc_do_write_level_calibration(void)
+int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo)
 {
struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
u32 esdmisc_val, zq_val;
u32 errors = 0;
-   u32 ldectrl[4];
+   u32 ldectrl[4] = {0};
u32 ddr_mr1 = 0x4;
+   u32 rwalat_max;
 
/*
 * Stash old values in case calibration fails,
@@ -101,8 +102,10 @@ int mmdc_do_write_level_calibration(void)
 */
ldectrl[0] = readl(>mpwldectrl0);
ldectrl[1] = readl(>mpwldectrl1);
-   ldectrl[2] = readl(>mpwldectrl0);
-   ldectrl[3] = readl(>mpwldectrl1);
+   if (sysinfo->dsize == 2) {
+   ldectrl[2] = readl(>mpwldectrl0);
+   ldectrl[3] = readl(>mpwldectrl1);
+   }
 
/* disable DDR logic power down timer */
clrbits_le32(>mdpdc, 0xff00);
@@ -122,10 +125,10 @@ int mmdc_do_write_level_calibration(void)
writel(zq_val & ~0x3, >mpzqhwctrl);
 
/* 3. increase walat and ralat to maximum */
-   setbits_le32(>mdmisc,
-(1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17));
-   setbits_le32(>mdmisc,
-(1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17));
+   rwalat_max = (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17);
+   setbits_le32(>mdmisc, rwalat_max);
+   if (sysinfo->dsize == 2)
+   setbits_le32(>mdmisc, rwalat_max);
/*
 * 4 & 5. Configure the external DDR device to enter write-leveling
 * mode through Load Mode Register command.
@@ -152,21 +155,25 @@ int mmdc_do_write_level_calibration(void)
 */
if (readl(>mpwlgcr) & 0x0F00)
errors |= 1;
-   if (readl(>mpwlgcr) & 0x0F00)
-   errors |= 2;
+   if (sysinfo->dsize == 2)
+   if (readl(>mpwlgcr) & 0x0F00)
+   errors |= 2;
 
debug("Ending write leveling calibration. Error mask: 0x%x\n", errors);
 
/* check to see if cal failed */
if ((readl(>mpwldectrl0) == 0x001F001F) &&
(readl(>mpwldectrl1) == 0x001F001F) &&
-   (readl(>mpwldectrl0) == 0x001F001F) &&
-   (readl(>mpwldectrl1) == 0x001F001F)) {
+   ((sysinfo->dsize < 2) ||
+((readl(>mpwldectrl0) == 0x001F001F) &&
+ (readl(>mpwldectrl1) == 0x001F001F {
debug("Cal seems to have soft-failed due to memory not 
supporting write leveling on all channels. Restoring original write leveling 
values.\n");
writel(ldectrl[0], >mpwldectrl0);
writel(ldectrl[1], >mpwldectrl1);
-   writel(ldectrl[2], >mpwldectrl0);
-   writel(ldectrl[3], >mpwldectrl1);
+   if (sysinfo->dsize == 2) {
+   writel(ldectrl[2], >mpwldectrl0);
+   writel(ldectrl[3], >mpwldectrl1);
+   }
errors |= 4;
}
 
@@ -189,16 +196,20 @@ int mmdc_do_write_level_calibration(void)
  readl(>mpwldectrl0));
debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
  readl(>mpwldectrl1));
-   debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n",
- readl(>mpwldectrl0));
-   debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
- readl(>mpwldectrl1));
+   if (sysinfo->dsize == 2) {
+   debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n",
+ readl(>mpwldectrl0));
+   debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n",
+