diff mbox

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

Message ID f22b9d17a34b5ff0dd3df107225d92b5f1606bc7.1374761918.git.michal.simek@xilinx.com
State Superseded
Delegated to: Albert ARIBAUD
Headers show

Commit Message

Michal Simek July 25, 2013, 2:18 p.m. UTC
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

Comments

Michal Simek July 26, 2013, 5:49 a.m. UTC | #1
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
diff mbox

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;
 }