From patchwork Fri Jun 11 10:09:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jorge Ramirez-Ortiz, Foundries" X-Patchwork-Id: 1490882 X-Patchwork-Delegate: monstr@monstr.eu Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=foundries.io header.i=@foundries.io header.a=rsa-sha256 header.s=google header.b=RI1rKLsp; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G1c5v3nrwz9sRf for ; Fri, 11 Jun 2021 20:09:55 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 70828801DE; Fri, 11 Jun 2021 12:09:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=foundries.io Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=foundries.io header.i=@foundries.io header.b="RI1rKLsp"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E1E4E801E8; Fri, 11 Jun 2021 12:09:43 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id C2DD1801D7 for ; Fri, 11 Jun 2021 12:09:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=foundries.io Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=jorge@foundries.io Received: by mail-wm1-x331.google.com with SMTP id v206-20020a1cded70000b02901a586d3fa23so8153741wmg.4 for ; Fri, 11 Jun 2021 03:09:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foundries.io; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=x3zBrLG8gd9uKG3LCUpPTH0zlzYXNPgQym/yILxUJ2Y=; b=RI1rKLspnNQuOv5tizeAJw31nKnrBNHL5PyDnSbLaIfcr6DC0UR1tdQRKKx1sjeWqB +r8fm4wv9BU0csqpR8TaWFdlg+3SGrUHCAxxwYEmYeOsLWlCy7l68vT2VUT6e002IvCe Y21eokdleN44s5lDjt5Kpsrzfa5xyhotsNDjS3WxkH3uWF6DFwmeKZqD+DUNXak7Gh5C RsUjtpKhlDWDmS4e3VCTcvIWvpxCGmu2GrY05ufja9wJZgvlqxyXfl/L8bnmWrP9GgCi UvIAZL2DNOqywcfA/bNRDsIM7FIii7TxJP8lWCybUN5Lz1CeNfn74Cqt3tAJzBNf8Q+y G0WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=x3zBrLG8gd9uKG3LCUpPTH0zlzYXNPgQym/yILxUJ2Y=; b=caqETjD9HX/zHvjLm0a60Cvu0UpUmi/1ZOfaNMq/Q+iwrrEWcpczcp8RVmixQjwikc k+SreTky8CIqW6MzU9K8Dvp2ZupAAldsKiAIenusYC+NDRP8tA/mrXBZK2rLURQimwVE nFoZ/rvIIbQ2kB1NckUFHhEXga6q/c8d8QgMxK/Cq89UyDLxyyg+ZdATGuJZkBklPMmk wt3nfHNy4L5uzYjBikELiBWHlw8rYZ+HOzWAgN+y3+/Vc4pI3CdM6IO+Br08HzdZ/jAL SLhkzwn8vv4rgZvva11EyuqkDnoKCxX9hLdhO9B8H9mr2LuavIBDT4xl3+tYO5WwIRBl gTvw== X-Gm-Message-State: AOAM530RuZiMmzxLOzyY7ATo7JxJSZzc839wEuWOrBBiEUx6G+dKjA9n olcZOGNW+s4wOCt1hHhesgL7ZA== X-Google-Smtp-Source: ABdhPJw5DmoBDh4h8/KBVKiVL1Am7MPohxDdPmSD5nX+Vg0mLELAl/zJmXuRQYxsUs+L/1YUzHq4hQ== X-Received: by 2002:a05:600c:4106:: with SMTP id j6mr3185476wmi.76.1623406180373; Fri, 11 Jun 2021 03:09:40 -0700 (PDT) Received: from localhost.localdomain (138.red-79-146-80.dynamicip.rima-tde.net. [79.146.80.138]) by smtp.gmail.com with ESMTPSA id e27sm7068136wra.50.2021.06.11.03.09.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jun 2021 03:09:39 -0700 (PDT) From: Jorge Ramirez-Ortiz To: jorge@foundries.io, monstr@monstr.eu Cc: ricardo@foundries.io, mike@foundries.io, u-boot@lists.denx.de Subject: [PATCH] zynqmp: spl: support DRAM ECC initialization Date: Fri, 11 Jun 2021 12:09:36 +0200 Message-Id: <20210611100936.12474-1-jorge@foundries.io> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Use the ZDMA channel 0 to initialize the DRAM banks. Signed-off-by: Jorge Ramirez-Ortiz --- arch/arm/mach-zynqmp/Kconfig | 35 +++++++ arch/arm/mach-zynqmp/Makefile | 1 + arch/arm/mach-zynqmp/ecc_spl_init.c | 139 ++++++++++++++++++++++++++++ arch/arm/mach-zynqmp/spl.c | 8 ++ 4 files changed, 183 insertions(+) create mode 100644 arch/arm/mach-zynqmp/ecc_spl_init.c diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig index f1301f6661..79197a351f 100644 --- a/arch/arm/mach-zynqmp/Kconfig +++ b/arch/arm/mach-zynqmp/Kconfig @@ -92,6 +92,41 @@ config ZYNQMP_NO_DDR This option configures MMU with no DDR to avoid speculative access to DDR memory where DDR is not present. +config SPL_ZYNQMP_DRAM_ECC_INIT + bool "Initialize DRAM ECC" + depends on SPL + help + This option initializes all memory to 0xdeadbeef. Must be set if your + memory is of ECC type. + +config SPL_ZYNQMP_DRAM_BANK1 + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank1 address" + default 0x00000000 + help + Start address of DRAM ECC bank1 + +config SPL_ZYNQMP_DRAM_BANK1_LEN + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank1 size" + default 0x80000000 + help + Size in bytes of the DRAM ECC bank1 + +config SPL_ZYNQMP_DRAM_BANK2 + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank2 address" + default 0x0 + help + Start address of DRAM ECC bank2 + +config SPL_ZYNQMP_DRAM_BANK2_LEN + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank2 size" + default 0x0 + help + Size in bytes of the DRAM ECC bank2. A null size takes no action. + config SYS_MALLOC_F_LEN default 0x600 diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index 8a3b074724..eb6c5112b3 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -7,4 +7,5 @@ obj-y += clk.o obj-y += cpu.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o +obj-$(CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT) += ecc_spl_init.o obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o diff --git a/arch/arm/mach-zynqmp/ecc_spl_init.c b/arch/arm/mach-zynqmp/ecc_spl_init.c new file mode 100644 index 0000000000..d8d93883c2 --- /dev/null +++ b/arch/arm/mach-zynqmp/ecc_spl_init.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright(c) 2015 - 2020 Xilinx, Inc. + * + * Jorge Ramirez-Ortiz + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ADMA_CH0_BASEADDR 0xFFA80000U +#define ZDMA_TRANSFER_MAX_LEN (0x3FFFFFFFU - 7U) +#define ZDMA_CH_STATUS ((ADMA_CH0_BASEADDR) + 0x0000011CU) +#define ZDMA_CH_STATUS_STATE_MASK 0x00000003U +#define ZDMA_CH_STATUS_STATE_DONE 0x00000000U +#define ZDMA_CH_STATUS_STATE_ERR 0x00000003U +#define ZDMA_CH_CTRL0 ((ADMA_CH0_BASEADDR) + 0x00000110U) +#define ZDMA_CH_CTRL0_POINT_TYPE_MASK (u32)0x00000040U +#define ZDMA_CH_CTRL0_POINT_TYPE_NORMAL (u32)0x00000000U +#define ZDMA_CH_CTRL0_MODE_MASK (u32)0x00000030U +#define ZDMA_CH_CTRL0_MODE_WR_ONLY (u32)0x00000010U +#define ZDMA_CH_CTRL0_TOTAL_BYTE_COUNT ((ADMA_CH0_BASEADDR) + 0x00000188U) +#define ZDMA_CH_WR_ONLY_WORD0 ((ADMA_CH0_BASEADDR) + 0x00000148U) +#define ZDMA_CH_WR_ONLY_WORD1 ((ADMA_CH0_BASEADDR) + 0x0000014CU) +#define ZDMA_CH_WR_ONLY_WORD2 ((ADMA_CH0_BASEADDR) + 0x00000150U) +#define ZDMA_CH_WR_ONLY_WORD3 ((ADMA_CH0_BASEADDR) + 0x00000154U) +#define ZDMA_CH_DST_DSCR_WORD0 ((ADMA_CH0_BASEADDR) + 0x00000138U) +#define ZDMA_CH_DST_DSCR_WORD0_LSB_MASK 0xFFFFFFFFU +#define ZDMA_CH_DST_DSCR_WORD1 ((ADMA_CH0_BASEADDR) + 0x0000013CU) +#define ZDMA_CH_DST_DSCR_WORD1_MSB_MASK 0x0001FFFFU +#define ZDMA_CH_SRC_DSCR_WORD2 ((ADMA_CH0_BASEADDR) + 0x00000130U) +#define ZDMA_CH_DST_DSCR_WORD2 ((ADMA_CH0_BASEADDR) + 0x00000140U) +#define ZDMA_CH_CTRL2 ((ADMA_CH0_BASEADDR) + 0x00000200U) +#define ZDMA_CH_CTRL2_EN_MASK 0x00000001U +#define ZDMA_CH_ISR ((ADMA_CH0_BASEADDR) + 0x00000100U) +#define ZDMA_CH_ISR_DMA_DONE_MASK 0x00000400U +#define ECC_INIT_VAL_WORD 0xDEADBEEFU + +static void ecc_dram_bank_init(u64 addr, u64 len) +{ + u64 bytes = len; + u64 src = addr; + u32 size; + u32 reg; + + flush_dcache_all(); + dcache_disable(); + + while (bytes > 0) { + size = bytes > ZDMA_TRANSFER_MAX_LEN ? + ZDMA_TRANSFER_MAX_LEN : (u32)bytes; + + /* Wait until the DMA is in idle state */ + do { + reg = readl(ZDMA_CH_STATUS); + reg &= ZDMA_CH_STATUS_STATE_MASK; + } while ((reg != ZDMA_CH_STATUS_STATE_DONE) && + (reg != ZDMA_CH_STATUS_STATE_ERR)); + + /* Enable Simple (Write Only) Mode */ + reg = readl(ZDMA_CH_CTRL0); + reg &= (ZDMA_CH_CTRL0_POINT_TYPE_MASK | + ZDMA_CH_CTRL0_MODE_MASK); + reg |= (ZDMA_CH_CTRL0_POINT_TYPE_NORMAL | + ZDMA_CH_CTRL0_MODE_WR_ONLY); + writel(reg, ZDMA_CH_CTRL0); + + /* Fill in the data to be written */ + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD0); + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD1); + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD2); + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD3); + + /* Write Destination Address */ + writel((u32)(src & ZDMA_CH_DST_DSCR_WORD0_LSB_MASK), + ZDMA_CH_DST_DSCR_WORD0); + writel((u32)((src >> 32) & ZDMA_CH_DST_DSCR_WORD1_MSB_MASK), + ZDMA_CH_DST_DSCR_WORD1); + + /* Size to be Transferred. Recommended to set both src and dest sizes */ + writel(size, ZDMA_CH_SRC_DSCR_WORD2); + writel(size, ZDMA_CH_DST_DSCR_WORD2); + + /* DMA Enable */ + reg = readl(ZDMA_CH_CTRL2); + reg |= ZDMA_CH_CTRL2_EN_MASK; + writel(reg, ZDMA_CH_CTRL2); + + /* Check the status of the transfer by polling on DMA Done */ + do { + reg = readl(ZDMA_CH_ISR); + reg &= ZDMA_CH_ISR_DMA_DONE_MASK; + } while (reg != ZDMA_CH_ISR_DMA_DONE_MASK); + + /* Clear DMA status */ + reg = readl(ZDMA_CH_ISR); + reg |= ZDMA_CH_ISR_DMA_DONE_MASK; + writel(ZDMA_CH_ISR_DMA_DONE_MASK, ZDMA_CH_ISR); + + /* Read the channel status for errors */ + reg = readl(ZDMA_CH_STATUS); + if (reg == ZDMA_CH_STATUS_STATE_ERR) + break; + + bytes -= size; + src += size; + } + + dcache_enable(); + + /* Restore reset values for the DMA registers used */ + writel(ZDMA_CH_CTRL0, 0x00000080U); + writel(ZDMA_CH_WR_ONLY_WORD0, 0x00000000U); + writel(ZDMA_CH_WR_ONLY_WORD1, 0x00000000U); + writel(ZDMA_CH_WR_ONLY_WORD2, 0x00000000U); + writel(ZDMA_CH_WR_ONLY_WORD3, 0x00000000U); + writel(ZDMA_CH_DST_DSCR_WORD0, 0x00000000U); + writel(ZDMA_CH_DST_DSCR_WORD1, 0x00000000U); + writel(ZDMA_CH_SRC_DSCR_WORD2, 0x00000000U); + writel(ZDMA_CH_DST_DSCR_WORD2, 0x00000000U); + writel(ZDMA_CH_CTRL0_TOTAL_BYTE_COUNT, 0x00000000U); +} + +void zynqmp_ecc_init(void) +{ + ecc_dram_bank_init(CONFIG_SPL_ZYNQMP_DRAM_BANK1, + CONFIG_SPL_ZYNQMP_DRAM_BANK1_LEN); + + ecc_dram_bank_init(CONFIG_SPL_ZYNQMP_DRAM_BANK2, + CONFIG_SPL_ZYNQMP_DRAM_BANK2_LEN); +} diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c index 88386b23e5..f85e68b9c2 100644 --- a/arch/arm/mach-zynqmp/spl.c +++ b/arch/arm/mach-zynqmp/spl.c @@ -18,10 +18,18 @@ #include #include +#ifdef CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT +extern void zynqmp_ecc_init(void); +#endif + void board_init_f(ulong dummy) { board_early_init_f(); board_early_init_r(); + board_early_init_r(); +#ifdef CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT + zynqmp_ecc_init(); +#endif } static void ps_mode_reset(ulong mode)