From patchwork Fri Jul 26 06:03:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 262064 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id EF3712C00E6 for ; Fri, 26 Jul 2013 16:03:57 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C5C984A01B; Fri, 26 Jul 2013 08:03:54 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3S5vhZakNn+s; Fri, 26 Jul 2013 08:03:54 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 11EBC4A01C; Fri, 26 Jul 2013 08:03:52 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A55634A01E for ; Fri, 26 Jul 2013 08:03:45 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id c5XNzyepjI-4 for ; Fri, 26 Jul 2013 08:03:39 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 BL_NJABL=SKIP(-1.5) (only DNSBL check requested) Received: from mail-ee0-f46.google.com (mail-ee0-f46.google.com [74.125.83.46]) by theia.denx.de (Postfix) with ESMTPS id BEBEC4A018 for ; Fri, 26 Jul 2013 08:03:36 +0200 (CEST) Received: by mail-ee0-f46.google.com with SMTP id d41so1322095eek.19 for ; Thu, 25 Jul 2013 23:03:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:subject:date:message-id:x-mailer:content-type :x-gm-message-state; bh=FwKvkmKivAtxTWcfeEnR/H6/qGA+SFwZrvm/Mc86l/Q=; b=IF545KYaiZ89g7f1kxE3baIoHh5wLqpZfpQb1OwTCTJL2shmXGzE3JvsR8uRudkz+L cDZaQ2j3UQ+2o4jVQ2/beYK7v8/OyWi+Ns3VEnkEbKeDd5xVyEjBolRb38Ys5RatsxOl 5CJ6v7UmZ7ItuF/yXwKvWjJmQwKwZQw8tSf/dI3aWvujwH4Kt8OpoWMHUe3qh9lRW4YF zvNwix4CFf6lGGd8USU2aO06mFg3bWKAvz21WsOURWhFNAEBGAMDOmgIPEldbbFIw8dX 8njWGpJ4FXQuAz2OjLQPqjuMbxgiI2fxdVFQQNNUDv9iXbT631XM539sTv817uNjguV3 buNQ== X-Received: by 10.14.193.199 with SMTP id k47mr45859177een.83.1374818613426; Thu, 25 Jul 2013 23:03:33 -0700 (PDT) Received: from localhost (nat-63.starnet.cz. [178.255.168.63]) by mx.google.com with ESMTPSA id i43sm3597500eeg.10.2013.07.25.23.03.32 for (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Thu, 25 Jul 2013 23:03:32 -0700 (PDT) From: Michal Simek To: u-boot@lists.denx.de, Albert Aribaud Date: Fri, 26 Jul 2013 08:03:26 +0200 Message-Id: <2047939301432b43acea69e804a8df139d0860ec.1374818604.git.michal.simek@xilinx.com> X-Mailer: git-send-email 1.8.2.3 X-Gm-Message-State: ALoCoQlTR1lGK/TmWHdIE93oXZ076PtrZaqY7zIR+L/TL6zlAgwj5ak9rZ/HT4hSuEEIcoVNXi0t Subject: [U-Boot] [PATCH v2 1/3] zynq: Add new ddrc driver for ECC support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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 Acked-by: Jagannadha Sutradharudu Teki --- Changes in v2: - Use SPDX-License-Identifier instead of full license arch/arm/cpu/armv7/zynq/Makefile | 1 + arch/arm/cpu/armv7/zynq/ddrc.c | 50 ++++++++++++++++++++++++++++++ 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, 62 insertions(+) create mode 100644 arch/arm/cpu/armv7/zynq/ddrc.c -- 1.8.2.3 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..ba6a6ae --- /dev/null +++ b/arch/arm/cpu/armv7/zynq/ddrc.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 - 2013 Michal Simek + * Copyright (C) 2012 - 2013 Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +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; }