Patchwork [U-Boot,1/3] zynq: Add new ddrc driver for ECC support

login
register
mail settings
Submitter Michal Simek
Date July 25, 2013, 2:18 p.m.
Message ID <f22b9d17a34b5ff0dd3df107225d92b5f1606bc7.1374761918.git.michal.simek@xilinx.com>
Download mbox | patch
Permalink /patch/261706/
State Superseded
Delegated to: Albert ARIBAUD
Headers show

Comments

Michal Simek - July 25, 2013, 2:18 p.m.
The first 1MB is not initialized by first stage bootloader.
Check if memory is setup to 16bit mode and ECC is enabled.
If it is, clear the first 1MB.
Also u-boot should report only the half size of memory.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Acked-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
---
 arch/arm/cpu/armv7/zynq/Makefile           |  1 +
 arch/arm/cpu/armv7/zynq/ddrc.c             | 65 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-zynq/hardware.h  |  8 ++++
 arch/arm/include/asm/arch-zynq/sys_proto.h |  1 +
 board/xilinx/zynq/board.c                  |  2 +
 5 files changed, 77 insertions(+)
 create mode 100644 arch/arm/cpu/armv7/zynq/ddrc.c

--
1.8.2.3
Michal Simek - July 26, 2013, 5:49 a.m.
On 07/25/2013 04:18 PM, Michal Simek wrote:
> The first 1MB is not initialized by first stage bootloader.
> Check if memory is setup to 16bit mode and ECC is enabled.
> If it is, clear the first 1MB.
> Also u-boot should report only the half size of memory.
> 
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> Acked-by: Jagannadha Sutradharudu Teki <jaganna@xilinx.com>
> ---
>  arch/arm/cpu/armv7/zynq/Makefile           |  1 +
>  arch/arm/cpu/armv7/zynq/ddrc.c             | 65 ++++++++++++++++++++++++++++++
>  arch/arm/include/asm/arch-zynq/hardware.h  |  8 ++++
>  arch/arm/include/asm/arch-zynq/sys_proto.h |  1 +
>  board/xilinx/zynq/board.c                  |  2 +
>  5 files changed, 77 insertions(+)
>  create mode 100644 arch/arm/cpu/armv7/zynq/ddrc.c
> 
> diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile
> index 388085d..f38b3b7 100644
> --- a/arch/arm/cpu/armv7/zynq/Makefile
> +++ b/arch/arm/cpu/armv7/zynq/Makefile
> @@ -30,6 +30,7 @@ LIB	= $(obj)lib$(SOC).o
> 
>  COBJS-y	:= timer.o
>  COBJS-y	+= cpu.o
> +COBJS-y	+= ddrc.o
>  COBJS-y	+= slcr.o
> 
>  COBJS	:= $(COBJS-y)
> diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c
> new file mode 100644
> index 0000000..e8f8c19
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/zynq/ddrc.c
> @@ -0,0 +1,65 @@
> +/*
> + * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
> + * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */

Let me NACK this patch by myself.
I will add SPDX License identifier.

Thanks,
Michal

Patch

diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/cpu/armv7/zynq/Makefile
index 388085d..f38b3b7 100644
--- a/arch/arm/cpu/armv7/zynq/Makefile
+++ b/arch/arm/cpu/armv7/zynq/Makefile
@@ -30,6 +30,7 @@  LIB	= $(obj)lib$(SOC).o

 COBJS-y	:= timer.o
 COBJS-y	+= cpu.o
+COBJS-y	+= ddrc.o
 COBJS-y	+= slcr.o

 COBJS	:= $(COBJS-y)
diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c
new file mode 100644
index 0000000..e8f8c19
--- /dev/null
+++ b/arch/arm/cpu/armv7/zynq/ddrc.c
@@ -0,0 +1,65 @@ 
+/*
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 Xilinx, Inc. All rights reserved.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Control regsiter bitfield definitions */
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK		0xC
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT	2
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT	1
+
+/* ECC scrub regsiter definitions */
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK	0x7
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED	0x4
+
+void zynq_ddrc_init(void)
+{
+	u32 width, ecctype;
+
+	width = readl(&ddrc_base->ddrc_ctrl);
+	width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >>
+					ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT;
+	ecctype = (readl(&ddrc_base->ecc_scrub) &
+		ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK);
+
+	/* ECC is enabled when memory is in 16bit mode and it is enabled */
+	if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED) &&
+	    (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)) {
+		puts("Memory: ECC enabled\n");
+		/*
+		 * Clear the first 1MB because it is not initialized from
+		 * first stage bootloader. To get ECC to work all memory has
+		 * been initialized by writing any value.
+		 */
+		memset(0, 0, 1 * 1024 * 1024);
+	} else {
+		puts("Memory: ECC disabled\n");
+	}
+
+	if (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)
+		gd->ram_size /= 2;
+}
diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h
index 8b8a91a..b0e713d 100644
--- a/arch/arm/include/asm/arch-zynq/hardware.h
+++ b/arch/arm/include/asm/arch-zynq/hardware.h
@@ -33,6 +33,7 @@ 
 #define ZYNQ_SDHCI_BASEADDR1		0xE0101000
 #define ZYNQ_I2C_BASEADDR0		0xE0004000
 #define ZYNQ_I2C_BASEADDR1		0xE0005000
+#define ZYNQ_DDRC_BASEADDR		0xF8006000

 /* Reflect slcr offsets */
 struct slcr_regs {
@@ -100,4 +101,11 @@  struct scu_regs {

 #define scu_base ((struct scu_regs *)ZYNQ_SCU_BASEADDR)

+struct ddrc_regs {
+	u32 ddrc_ctrl; /* 0x0 */
+	u32 reserved[60];
+	u32 ecc_scrub; /* 0xF4 */
+};
+#define ddrc_base ((struct ddrc_regs *)ZYNQ_DDRC_BASEADDR)
+
 #endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h
index 2317121..2698846 100644
--- a/arch/arm/include/asm/arch-zynq/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynq/sys_proto.h
@@ -30,6 +30,7 @@  extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);
 extern void zynq_slcr_devcfg_disable(void);
 extern void zynq_slcr_devcfg_enable(void);
 extern u32 zynq_slcr_get_idcode(void);
+extern void zynq_ddrc_init(void);

 /* Driver extern functions */
 extern int zynq_sdhci_init(u32 regbase);
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index b02c364..61a96b8 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -112,5 +112,7 @@  int dram_init(void)
 {
 	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;

+	zynq_ddrc_init();
+
 	return 0;
 }