From patchwork Tue Nov 22 15:31:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jit Loon Lim X-Patchwork-Id: 1707911 X-Patchwork-Delegate: marek.vasut@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=L64t03SC; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4NGpBq6vSQz23nl for ; Wed, 23 Nov 2022 02:31:31 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id D4C868522E; Tue, 22 Nov 2022 16:31:24 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=intel.com 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=intel.com header.i=@intel.com header.b="L64t03SC"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 632A985447; Tue, 22 Nov 2022 16:31:23 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=0.9 required=5.0 tests=AC_FROM_MANY_DOTS,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 59464850DE for ; Tue, 22 Nov 2022 16:31:18 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=jitloonl@ecsmtp.png.intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1669131078; x=1700667078; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=uL7br9xLXoU1MTRlZtKTycrQk1mYDWQX9V6+B1jsJtU=; b=L64t03SCR4r7yJQDu5Aa532WdXrfWVz9612QIiiJOzH7ERBHWRS64/mc asZ96cRfRUxwzrJP+hRmXI1Q1BBoVdQN145uRQWb2s7dhJiARcflgTfSK 9I5GPlMV2tJyYBy3FbXY6YTzEzc8J+Abjg0j5CSjIIYJ+wZD2zhrGOCBw cR3lMjCgYGPfD3q02rVqNSkHouq3vYKflGqAYniJD1OJ3eMu8xHCEVWTi l0ctHf1T2n2CKd2LDf3ZOtC35cfh7j/7MWerEAaWIBjfry7W/vA2pxavx jchHjXHNB14t58Kz4Vp4t70Pe6DNVCvbDvAsUBeSLVi+laV5TPJw7gxt7 A==; X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="311471130" X-IronPort-AV: E=Sophos;i="5.96,184,1665471600"; d="scan'208";a="311471130" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Nov 2022 07:31:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10539"; a="641452564" X-IronPort-AV: E=Sophos;i="5.96,184,1665471600"; d="scan'208";a="641452564" Received: from pglmail07.png.intel.com ([10.221.193.207]) by orsmga002.jf.intel.com with ESMTP; 22 Nov 2022 07:31:09 -0800 Received: from localhost (pgli0028.png.intel.com [10.221.84.177]) by pglmail07.png.intel.com (Postfix) with ESMTP id 4940A482A; Tue, 22 Nov 2022 23:31:04 +0800 (+08) Received: by localhost (Postfix, from userid 12048045) id 44A2FE00214; Tue, 22 Nov 2022 23:31:04 +0800 (+08) From: Jit Loon Lim To: u-boot@lists.denx.de Cc: Jagan Teki , Vignesh R , Marek , Simon , Tien Fong , Kok Kiang , Siew Chin , Sin Hui , Raaj , Dinesh , Boon Khai , Alif , Teik Heng , Hazim , Jit Loon Lim , Sieu Mun Tang Subject: [PATCH] ddr: altera: n5x: Add self-refresh support in DDR4 Date: Tue, 22 Nov 2022 23:31:03 +0800 Message-Id: <20221122153103.354-1-jit.loon.lim@intel.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.6 at phobos.denx.de X-Virus-Status: Clean From: Tien Fong Chee Enable self-refresh support in DDR4 for retaining DDR4 content with minimal power when reset is triggered. Signed-off-by: Tien Fong Chee Signed-off-by: Jit Loon Lim --- .../include/mach/system_manager_soc64.h | 3 +- drivers/ddr/altera/sdram_n5x.c | 751 +++++++++++++++++- 2 files changed, 730 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h index a8009664fe..c2d1f8e4b9 100644 --- a/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/system_manager_soc64.h @@ -99,8 +99,7 @@ void populate_sysmgr_pinmux(void); */ #define SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK GENMASK(27, 0) #define ALT_SYSMGR_SCRATCH_REG_0_DDR_RETENTION_MASK BIT(31) -#define ALT_SYSMGR_SCRATCH_REG_0_DDR_SHA_MASK BIT(30) -#define ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK (BIT(29) | BIT(28)) +#define ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK GENMASK(30, 28) #define ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_SHIFT 28 #define SYSMGR_SDMMC SYSMGR_SOC64_SDMMC diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c index 5a20a8d78d..135bc8fd7d 100644 --- a/drivers/ddr/altera/sdram_n5x.c +++ b/drivers/ddr/altera/sdram_n5x.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -21,11 +22,25 @@ #include #include #include +#include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; +/* PHY calibration data backup attribute */ +#define SOC64_OCRAM_PHY_BACKUP_BASE 0xFFE5E400 +/* "SKIP" */ +#define SOC64_CRAM_PHY_BACKUP_SKIP_MAGIC 0x50494B53 +#define BAC_CAL_MMC_RAW_OFFSET (CONFIG_ENV_SIZE + CONFIG_ENV_OFFSET) + +/* DDR handoff SHA384 attribute */ +#define DDR_HANDOFF_IMG_ADDR 0xFFE44000 +#define DDR_HANDOFF_IMG_LEN 0x1A000 +#define CHUNKSZ_PER_WD_RESET (256 * 1024) + /* MPFE NOC registers */ #define FPGA2SDRAM_MGR_MAIN_SIDEBANDMGR_FLAGOUTSET0 0xF8024050 @@ -379,6 +394,117 @@ enum message_mode { STREAMING_MESSAGE }; +/* Reset type */ +enum reset_type { + POR_RESET, + WARM_RESET, + COLD_RESET, + NCONFIG, + JTAG_CONFIG, + RSU_RECONFIG +}; + +enum data_type { + HEADER_ONLY, + HEADER_DATA +}; + +/* Header for backup calibration data */ +struct cal_header_t { + u32 header_magic; + u32 data_len; + u32 caldata_crc32; + u8 ddrconfig_hash[SHA384_SUM_LEN]; +} __attribute__ ((__packed__)); + +/* Header + backup calibration data */ +struct bac_cal_data_t { + struct cal_header_t header; + u16 data; +} __attribute__ ((__packed__)); + +enum data_process { + STORE, + LOADING +}; + +bool is_ddr_retention_enabled(u32 reg) +{ + if (reg & ALT_SYSMGR_SCRATCH_REG_0_DDR_RETENTION_MASK) + return true; + + return false; +} + +static enum reset_type get_reset_type(u32 reg) +{ + return (reg & ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK) >> + ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_SHIFT; +} + +void reset_type_print(enum reset_type reset_t) +{ + switch (reset_t) { + case POR_RESET: + printf("%s: POR is triggered\n", __func__); + break; + case WARM_RESET: + printf("%s: Warm reset is triggered\n", __func__); + break; + case COLD_RESET: + printf("%s: Cold reset is triggered\n", __func__); + break; + case NCONFIG: + printf("%s: NCONFIG is triggered\n", __func__); + break; + case JTAG_CONFIG: + printf("%s: JTAG_CONFIG is triggered\n", __func__); + break; + case RSU_RECONFIG: + printf("%s: RSU_RECONFIG is triggered\n", __func__); + break; + default: + printf("%s: Invalid reset type\n", __func__); + } +} + +bool is_ddr_init_skipped(u32 reg) +{ + enum reset_type reset_t = get_reset_type(reg); + + reset_type_print(reset_t); + + if (reset_t == WARM_RESET) { + debug("%s: DDR init is skipped\n", __func__); + return true; + } + + if (reset_t == COLD_RESET) { + if (is_ddr_retention_enabled(reg)) { + debug("%s: DDR retention bit is set\n", __func__); + debug("%s: DDR init is skipped\n", __func__); + return true; + } + } + + debug("%s: DDR init is required\n", __func__); + return false; +} + +bool is_ddr_calibration_skipped(u32 reg) +{ + enum reset_type reset_t = get_reset_type(reg); + + if ((reset_t == NCONFIG || reset_t == JTAG_CONFIG || + reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg)) { + debug("%s: DDR retention bit is set\n", __func__); + return true; + } + + debug("%s: DDR calibration is required\n", __func__); + return false; +} + static int clr_ca_parity_error_status(phys_addr_t umctl2_base) { int ret; @@ -711,6 +837,7 @@ static int scrubber_ddr_config(phys_addr_t umctl2_base, writel(0, umctl2_base + DDR4_SBRRANGE0_OFFSET); writel(0, umctl2_base + DDR4_SBRRANGE1_OFFSET); + printf("Enabling scrubber ...\n"); /* Enables scrubber */ setbits_le32(umctl2_base + DDR4_SBRCTL_OFFSET, DDR4_SBRCTL_SCRUB_EN); /* Polling all scrub writes commands have been sent */ @@ -924,8 +1051,513 @@ static int phy_pre_handoff_config(phys_addr_t umctl2_base, return ret; } +static void phy_ocram(phys_addr_t phy_base, phys_addr_t phy_offset, + u16 *data, enum data_process proc) +{ + u32 abs_addr; + + abs_addr = phy_base + (phy_offset << 1); + + if (proc == STORE) { + /* Storing PHY value */ + writew(readw((uintptr_t)abs_addr), data); + debug("%s: PHY offset 0x%08x, data %x\n", __func__, + (u32)phy_offset, readw((uintptr_t)data)); + } else if (proc == LOADING) { + /* Loading bak cal data to PHY */ + writew(readw(data), (uintptr_t)abs_addr); + debug("%s: PHY offset 0x%08x, data %x\n", __func__, + (u32)phy_offset, readw((uintptr_t)abs_addr)); + } +} + +static void cal_data_ocram(phys_addr_t phy_base, u32 addr, + enum data_process proc) +{ + /* + * This array variable contains a list of PHY registers required for + * backup before DDR entering self-refresh mode + */ + u32 phybak[] = {0x1005f, 0x1015f, 0x1105f, 0x1115f, 0x1205f, + 0x1215f, 0x1305f, 0x1315f, 0x1405f, 0x1415f, + 0x1505f, 0x1515f, 0x1605f, 0x1615f, 0x1705f, + 0x1715f, 0x1805f, 0x1815f, 0x00055, 0x01055, + 0x02055, 0x03055, 0x04055, 0x05055, 0x06055, + 0x07055, 0x08055, 0x09055, 0x200c5, 0x2002e, + 0x20024, 0x2003a, 0x2007d, 0x2007c, 0x20056, + 0x1004d, 0x1014d, 0x1104d, 0x1114d, 0x1204d, + 0x1214d, 0x1304d, 0x1314d, 0x1404d, 0x1414d, + 0x1504d, 0x1514d, 0x1604d, 0x1614d, 0x1704d, + 0x1714d, 0x1804d, 0x1814d, 0x10049, 0x10149, + 0x11049, 0x11149, 0x12049, 0x12149, 0x13049, + 0x13149, 0x14049, 0x14149, 0x15049, 0x15149, + 0x16049, 0x16149, 0x17049, 0x17149, 0x18049, + 0x18149, 0x00043, 0x01043, 0x02043, 0x03043, + 0x04043, 0x05043, 0x06043, 0x07043, 0x08043, + 0x09043, 0x20018, 0x20075, 0x20050, 0x2009b, + 0x20008, 0x20088, 0x200b2, 0x10043, 0x10143, + 0x11043, 0x11143, 0x12043, 0x12143, 0x13043, + 0x13143, 0x14043, 0x14143, 0x15043, 0x15143, + 0x16043, 0x16143, 0x17043, 0x17143, 0x18043, + 0x18143, 0x2005b, 0x2005c, 0x200fa, 0x20019, + 0x200f0, 0x200f1, 0x200f2, 0x200f3, 0x200f4, + 0x200f5, 0x200f6, 0x200f7, 0x1004a, 0x1104a, + 0x1204a, 0x1304a, 0x1404a, 0x1504a, 0x1604a, + 0x1704a, 0x1804a, 0x20025, 0x2002d, 0x2002c, + 0xd0000, 0x90000, 0x90001, 0x90002, 0x90003, + 0x90004, 0x90005, 0x90029, 0x9002a, 0x9002b, + 0x9002c, 0x9002d, 0x9002e, 0x9002f, 0x90030, + 0x90031, 0x90032, 0x90033, 0x90034, 0x90035, + 0x90036, 0x90037, 0x90038, 0x90039, 0x9003a, + 0x9003b, 0x9003c, 0x9003d, 0x9003e, 0x9003f, + 0x90040, 0x90041, 0x90042, 0x90043, 0x90044, + 0x90045, 0x90046, 0x90047, 0x90048, 0x90049, + 0x9004a, 0x9004b, 0x9004c, 0x9004d, 0x9004e, + 0x9004f, 0x90050, 0x90051, 0x90052, 0x90053, + 0x90054, 0x90055, 0x90056, 0x90057, 0x90058, + 0x90059, 0x9005a, 0x9005b, 0x9005c, 0x9005d, + 0x9005e, 0x9005f, 0x90060, 0x90061, 0x90062, + 0x90063, 0x90064, 0x90065, 0x90066, 0x90067, + 0x90068, 0x90069, 0x9006a, 0x9006b, 0x9006c, + 0x9006d, 0x9006e, 0x9006f, 0x90070, 0x90071, + 0x90072, 0x90073, 0x90074, 0x90075, 0x90076, + 0x90077, 0x90078, 0x90079, 0x9007a, 0x9007b, + 0x9007c, 0x9007d, 0x9007e, 0x9007f, 0x90080, + 0x90081, 0x90082, 0x90083, 0x90084, 0x90085, + 0x90086, 0x90087, 0x90088, 0x90089, 0x9008a, + 0x9008b, 0x9008c, 0x9008d, 0x9008e, 0x9008f, + 0x90090, 0x90091, 0x90092, 0x90093, 0x90094, + 0x90095, 0x90096, 0x90097, 0x90098, 0x90099, + 0x9009a, 0x9009b, 0x9009c, 0x9009d, 0x9009e, + 0x9009f, 0x900a0, 0x900a1, 0x900a2, 0x900a3, + 0x900a4, 0x900a5, 0x900a6, 0x900a7, 0x900a8, + 0x900a9, 0x900aa, 0x900ab, 0x900ac, 0x900ad, + 0x900ae, 0x900af, 0x900b0, 0x900b1, 0x900b2, + 0x900b3, 0x900b4, 0x900b5, 0x900b6, 0x900b7, + 0x900b8, 0x900b9, 0x900ba, 0x900bb, 0x900bc, + 0x900bd, 0x900be, 0x900bf, 0x900c0, 0x900c1, + 0x900c2, 0x900c3, 0x900c4, 0x900c5, 0x900c6, + 0x900c7, 0x90006, 0x90007, 0x90008, 0x90009, + 0x9000a, 0x9000b, 0xd00e7, 0x90017, 0x90026, + 0x2000b, 0x2000c, 0x2000d, 0x2000e, 0x9000c, + 0x9000d, 0x9000e, 0x9000f, 0x90010, 0x90011, + 0x90012, 0x90013, 0x20089, 0xc0080, 0x200cb, + 0x10068, 0x10069, 0x1006a, 0x1006b, 0x10168, + 0x10169, 0x1016a, 0x1016b, 0x10268, 0x10269, + 0x1026a, 0x1026b, 0x10368, 0x10369, 0x1036a, + 0x1036b, 0x10468, 0x10469, 0x1046a, 0x1046b, + 0x10568, 0x10569, 0x1056a, 0x1056b, 0x10668, + 0x10669, 0x1066a, 0x1066b, 0x10768, 0x10769, + 0x1076a, 0x1076b, 0x10868, 0x10869, 0x1086a, + 0x1086b, 0x11068, 0x11069, 0x1106a, 0x1106b, + 0x11168, 0x11169, 0x1116a, 0x1116b, 0x11268, + 0x11269, 0x1126a, 0x1126b, 0x11368, 0x11369, + 0x1136a, 0x1136b, 0x11468, 0x11469, 0x1146a, + 0x1146b, 0x11568, 0x11569, 0x1156a, 0x1156b, + 0x11668, 0x11669, 0x1166a, 0x1166b, 0x11768, + 0x11769, 0x1176a, 0x1176b, 0x11868, 0x11869, + 0x1186a, 0x1186b, 0x12068, 0x12069, 0x1206a, + 0x1206b, 0x12168, 0x12169, 0x1216a, 0x1216b, + 0x12268, 0x12269, 0x1226a, 0x1226b, 0x12368, + 0x12369, 0x1236a, 0x1236b, 0x12468, 0x12469, + 0x1246a, 0x1246b, 0x12568, 0x12569, 0x1256a, + 0x1256b, 0x12668, 0x12669, 0x1266a, 0x1266b, + 0x12768, 0x12769, 0x1276a, 0x1276b, 0x12868, + 0x12869, 0x1286a, 0x1286b, 0x13068, 0x13069, + 0x1306a, 0x1306b, 0x13168, 0x13169, 0x1316a, + 0x1316b, 0x13268, 0x13269, 0x1326a, 0x1326b, + 0x13368, 0x13369, 0x1336a, 0x1336b, 0x13468, + 0x13469, 0x1346a, 0x1346b, 0x13568, 0x13569, + 0x1356a, 0x1356b, 0x13668, 0x13669, 0x1366a, + 0x1366b, 0x13768, 0x13769, 0x1376a, 0x1376b, + 0x13868, 0x13869, 0x1386a, 0x1386b, 0x14068, + 0x14069, 0x1406a, 0x1406b, 0x14168, 0x14169, + 0x1416a, 0x1416b, 0x14268, 0x14269, 0x1426a, + 0x1426b, 0x14368, 0x14369, 0x1436a, 0x1436b, + 0x14468, 0x14469, 0x1446a, 0x1446b, 0x14568, + 0x14569, 0x1456a, 0x1456b, 0x14668, 0x14669, + 0x1466a, 0x1466b, 0x14768, 0x14769, 0x1476a, + 0x1476b, 0x14868, 0x14869, 0x1486a, 0x1486b, + 0x15068, 0x15069, 0x1506a, 0x1506b, 0x15168, + 0x15169, 0x1516a, 0x1516b, 0x15268, 0x15269, + 0x1526a, 0x1526b, 0x15368, 0x15369, 0x1536a, + 0x1536b, 0x15468, 0x15469, 0x1546a, 0x1546b, + 0x15568, 0x15569, 0x1556a, 0x1556b, 0x15668, + 0x15669, 0x1566a, 0x1566b, 0x15768, 0x15769, + 0x1576a, 0x1576b, 0x15868, 0x15869, 0x1586a, + 0x1586b, 0x16068, 0x16069, 0x1606a, 0x1606b, + 0x16168, 0x16169, 0x1616a, 0x1616b, 0x16268, + 0x16269, 0x1626a, 0x1626b, 0x16368, 0x16369, + 0x1636a, 0x1636b, 0x16468, 0x16469, 0x1646a, + 0x1646b, 0x16568, 0x16569, 0x1656a, 0x1656b, + 0x16668, 0x16669, 0x1666a, 0x1666b, 0x16768, + 0x16769, 0x1676a, 0x1676b, 0x16868, 0x16869, + 0x1686a, 0x1686b, 0x17068, 0x17069, 0x1706a, + 0x1706b, 0x17168, 0x17169, 0x1716a, 0x1716b, + 0x17268, 0x17269, 0x1726a, 0x1726b, 0x17368, + 0x17369, 0x1736a, 0x1736b, 0x17468, 0x17469, + 0x1746a, 0x1746b, 0x17568, 0x17569, 0x1756a, + 0x1756b, 0x17668, 0x17669, 0x1766a, 0x1766b, + 0x17768, 0x17769, 0x1776a, 0x1776b, 0x17868, + 0x17869, 0x1786a, 0x1786b, 0x18068, 0x18069, + 0x1806a, 0x1806b, 0x18168, 0x18169, 0x1816a, + 0x1816b, 0x18268, 0x18269, 0x1826a, 0x1826b, + 0x18368, 0x18369, 0x1836a, 0x1836b, 0x18468, + 0x18469, 0x1846a, 0x1846b, 0x18568, 0x18569, + 0x1856a, 0x1856b, 0x18668, 0x18669, 0x1866a, + 0x1866b, 0x18768, 0x18769, 0x1876a, 0x1876b, + 0x18868, 0x18869, 0x1886a, 0x1886b, 0x00080, + 0x01080, 0x02080, 0x03080, 0x04080, 0x05080, + 0x06080, 0x07080, 0x08080, 0x09080, 0x10020, + 0x10080, 0x10081, 0x10082, 0x10083, 0x100d0, + 0x100d1, 0x100d2, 0x100d3, 0x1008c, 0x1008d, + 0x1008e, 0x1008f, 0x10180, 0x10181, 0x10182, + 0x10183, 0x101d0, 0x101d1, 0x101d2, 0x101d3, + 0x1018c, 0x1018d, 0x1018e, 0x1018f, 0x100c0, + 0x100c1, 0x100c2, 0x100c3, 0x101c0, 0x101c1, + 0x101c2, 0x101c3, 0x102c0, 0x102c1, 0x102c2, + 0x102c3, 0x103c0, 0x103c1, 0x103c2, 0x103c3, + 0x104c0, 0x104c1, 0x104c2, 0x104c3, 0x105c0, + 0x105c1, 0x105c2, 0x105c3, 0x106c0, 0x106c1, + 0x106c2, 0x106c3, 0x107c0, 0x107c1, 0x107c2, + 0x107c3, 0x108c0, 0x108c1, 0x108c2, 0x108c3, + 0x11020, 0x11080, 0x11081, 0x11082, 0x11083, + 0x110d0, 0x110d1, 0x110d2, 0x110d3, 0x1108c, + 0x1108d, 0x1108e, 0x1108f, 0x11180, 0x11181, + 0x11182, 0x11183, 0x111d0, 0x111d1, 0x111d2, + 0x111d3, 0x1118c, 0x1118d, 0x1118e, 0x1118f, + 0x110c0, 0x110c1, 0x110c2, 0x110c3, 0x111c0, + 0x111c1, 0x111c2, 0x111c3, 0x112c0, 0x112c1, + 0x112c2, 0x112c3, 0x113c0, 0x113c1, 0x113c2, + 0x113c3, 0x114c0, 0x114c1, 0x114c2, 0x114c3, + 0x115c0, 0x115c1, 0x115c2, 0x115c3, 0x116c0, + 0x116c1, 0x116c2, 0x116c3, 0x117c0, 0x117c1, + 0x117c2, 0x117c3, 0x118c0, 0x118c1, 0x118c2, + 0x118c3, 0x12020, 0x12080, 0x12081, 0x12082, + 0x12083, 0x120d0, 0x120d1, 0x120d2, 0x120d3, + 0x1208c, 0x1208d, 0x1208e, 0x1208f, 0x12180, + 0x12181, 0x12182, 0x12183, 0x121d0, 0x121d1, + 0x121d2, 0x121d3, 0x1218c, 0x1218d, 0x1218e, + 0x1218f, 0x120c0, 0x120c1, 0x120c2, 0x120c3, + 0x121c0, 0x121c1, 0x121c2, 0x121c3, 0x122c0, + 0x122c1, 0x122c2, 0x122c3, 0x123c0, 0x123c1, + 0x123c2, 0x123c3, 0x124c0, 0x124c1, 0x124c2, + 0x124c3, 0x125c0, 0x125c1, 0x125c2, 0x125c3, + 0x126c0, 0x126c1, 0x126c2, 0x126c3, 0x127c0, + 0x127c1, 0x127c2, 0x127c3, 0x128c0, 0x128c1, + 0x128c2, 0x128c3, 0x13020, 0x13080, 0x13081, + 0x13082, 0x13083, 0x130d0, 0x130d1, 0x130d2, + 0x130d3, 0x1308c, 0x1308d, 0x1308e, 0x1308f, + 0x13180, 0x13181, 0x13182, 0x13183, 0x131d0, + 0x131d1, 0x131d2, 0x131d3, 0x1318c, 0x1318d, + 0x1318e, 0x1318f, 0x130c0, 0x130c1, 0x130c2, + 0x130c3, 0x131c0, 0x131c1, 0x131c2, 0x131c3, + 0x132c0, 0x132c1, 0x132c2, 0x132c3, 0x133c0, + 0x133c1, 0x133c2, 0x133c3, 0x134c0, 0x134c1, + 0x134c2, 0x134c3, 0x135c0, 0x135c1, 0x135c2, + 0x135c3, 0x136c0, 0x136c1, 0x136c2, 0x136c3, + 0x137c0, 0x137c1, 0x137c2, 0x137c3, 0x138c0, + 0x138c1, 0x138c2, 0x138c3, 0x14020, 0x14080, + 0x14081, 0x14082, 0x14083, 0x140d0, 0x140d1, + 0x140d2, 0x140d3, 0x1408c, 0x1408d, 0x1408e, + 0x1408f, 0x14180, 0x14181, 0x14182, 0x14183, + 0x141d0, 0x141d1, 0x141d2, 0x141d3, 0x1418c, + 0x1418d, 0x1418e, 0x1418f, 0x140c0, 0x140c1, + 0x140c2, 0x140c3, 0x141c0, 0x141c1, 0x141c2, + 0x141c3, 0x142c0, 0x142c1, 0x142c2, 0x142c3, + 0x143c0, 0x143c1, 0x143c2, 0x143c3, 0x144c0, + 0x144c1, 0x144c2, 0x144c3, 0x145c0, 0x145c1, + 0x145c2, 0x145c3, 0x146c0, 0x146c1, 0x146c2, + 0x146c3, 0x147c0, 0x147c1, 0x147c2, 0x147c3, + 0x148c0, 0x148c1, 0x148c2, 0x148c3, 0x15020, + 0x15080, 0x15081, 0x15082, 0x15083, 0x150d0, + 0x150d1, 0x150d2, 0x150d3, 0x1508c, 0x1508d, + 0x1508e, 0x1508f, 0x15180, 0x15181, 0x15182, + 0x15183, 0x151d0, 0x151d1, 0x151d2, 0x151d3, + 0x1518c, 0x1518d, 0x1518e, 0x1518f, 0x150c0, + 0x150c1, 0x150c2, 0x150c3, 0x151c0, 0x151c1, + 0x151c2, 0x151c3, 0x152c0, 0x152c1, 0x152c2, + 0x152c3, 0x153c0, 0x153c1, 0x153c2, 0x153c3, + 0x154c0, 0x154c1, 0x154c2, 0x154c3, 0x155c0, + 0x155c1, 0x155c2, 0x155c3, 0x156c0, 0x156c1, + 0x156c2, 0x156c3, 0x157c0, 0x157c1, 0x157c2, + 0x157c3, 0x158c0, 0x158c1, 0x158c2, 0x158c3, + 0x16020, 0x16080, 0x16081, 0x16082, 0x16083, + 0x160d0, 0x160d1, 0x160d2, 0x160d3, 0x1608c, + 0x1608d, 0x1608e, 0x1608f, 0x16180, 0x16181, + 0x16182, 0x16183, 0x161d0, 0x161d1, 0x161d2, + 0x161d3, 0x1618c, 0x1618d, 0x1618e, 0x1618f, + 0x160c0, 0x160c1, 0x160c2, 0x160c3, 0x161c0, + 0x161c1, 0x161c2, 0x161c3, 0x162c0, 0x162c1, + 0x162c2, 0x162c3, 0x163c0, 0x163c1, 0x163c2, + 0x163c3, 0x164c0, 0x164c1, 0x164c2, 0x164c3, + 0x165c0, 0x165c1, 0x165c2, 0x165c3, 0x166c0, + 0x166c1, 0x166c2, 0x166c3, 0x167c0, 0x167c1, + 0x167c2, 0x167c3, 0x168c0, 0x168c1, 0x168c2, + 0x168c3, 0x17020, 0x17080, 0x17081, 0x17082, + 0x17083, 0x170d0, 0x170d1, 0x170d2, 0x170d3, + 0x1708c, 0x1708d, 0x1708e, 0x1708f, 0x17180, + 0x17181, 0x17182, 0x17183, 0x171d0, 0x171d1, + 0x171d2, 0x171d3, 0x1718c, 0x1718d, 0x1718e, + 0x1718f, 0x170c0, 0x170c1, 0x170c2, 0x170c3, + 0x171c0, 0x171c1, 0x171c2, 0x171c3, 0x172c0, + 0x172c1, 0x172c2, 0x172c3, 0x173c0, 0x173c1, + 0x173c2, 0x173c3, 0x174c0, 0x174c1, 0x174c2, + 0x174c3, 0x175c0, 0x175c1, 0x175c2, 0x175c3, + 0x176c0, 0x176c1, 0x176c2, 0x176c3, 0x177c0, + 0x177c1, 0x177c2, 0x177c3, 0x178c0, 0x178c1, + 0x178c2, 0x178c3, 0x18020, 0x18080, 0x18081, + 0x18082, 0x18083, 0x180d0, 0x180d1, 0x180d2, + 0x180d3, 0x1808c, 0x1808d, 0x1808e, 0x1808f, + 0x18180, 0x18181, 0x18182, 0x18183, 0x181d0, + 0x181d1, 0x181d2, 0x181d3, 0x1818c, 0x1818d, + 0x1818e, 0x1818f, 0x180c0, 0x180c1, 0x180c2, + 0x180c3, 0x181c0, 0x181c1, 0x181c2, 0x181c3, + 0x182c0, 0x182c1, 0x182c2, 0x182c3, 0x183c0, + 0x183c1, 0x183c2, 0x183c3, 0x184c0, 0x184c1, + 0x184c2, 0x184c3, 0x185c0, 0x185c1, 0x185c2, + 0x185c3, 0x186c0, 0x186c1, 0x186c2, 0x186c3, + 0x187c0, 0x187c1, 0x187c2, 0x187c3, 0x188c0, + 0x188c1, 0x188c2, 0x188c3, 0x90201, 0x90202, + 0x90203, 0x90204, 0x90205, 0x90206, 0x90207, + 0x90208, 0x20077, 0x10040, 0x10030, 0x10140, + 0x10130, 0x10240, 0x10230, 0x10340, 0x10330, + 0x10440, 0x10430, 0x10540, 0x10530, 0x10640, + 0x10630, 0x10740, 0x10730, 0x10840, 0x10830, + 0x11040, 0x11030, 0x11140, 0x11130, 0x11240, + 0x11230, 0x11340, 0x11330, 0x11440, 0x11430, + 0x11540, 0x11530, 0x11640, 0x11630, 0x11740, + 0x11730, 0x11840, 0x11830, 0x12040, 0x12030, + 0x12140, 0x12130, 0x12240, 0x12230, 0x12340, + 0x12330, 0x12440, 0x12430, 0x12540, 0x12530, + 0x12640, 0x12630, 0x12740, 0x12730, 0x12840, + 0x12830, 0x13040, 0x13030, 0x13140, 0x13130, + 0x13240, 0x13230, 0x13340, 0x13330, 0x13440, + 0x13430, 0x13540, 0x13530, 0x13640, 0x13630, + 0x13740, 0x13730, 0x13840, 0x13830, 0x14040, + 0x14030, 0x14140, 0x14130, 0x14240, 0x14230, + 0x14340, 0x14330, 0x14440, 0x14430, 0x14540, + 0x14530, 0x14640, 0x14630, 0x14740, 0x14730, + 0x14840, 0x14830, 0x15040, 0x15030, 0x15140, + 0x15130, 0x15240, 0x15230, 0x15340, 0x15330, + 0x15440, 0x15430, 0x15540, 0x15530, 0x15640, + 0x15630, 0x15740, 0x15730, 0x15840, 0x15830, + 0x16040, 0x16030, 0x16140, 0x16130, 0x16240, + 0x16230, 0x16340, 0x16330, 0x16440, 0x16430, + 0x16540, 0x16530, 0x16640, 0x16630, 0x16740, + 0x16730, 0x16840, 0x16830, 0x17040, 0x17030, + 0x17140, 0x17130, 0x17240, 0x17230, 0x17340, + 0x17330, 0x17440, 0x17430, 0x17540, 0x17530, + 0x17640, 0x17630, 0x17740, 0x17730, 0x17840, + 0x17830, 0x18040, 0x18030, 0x18140, 0x18130, + 0x18240, 0x18230, 0x18340, 0x18330, 0x18440, + 0x18430, 0x18540, 0x18530, 0x18640, 0x18630, + 0x18740, 0x18730, 0x18840, 0x18830}; + size_t phybak_num; + u32 *phybak_p = phybak; + u16 *data; + struct bac_cal_data_t *cal = (struct bac_cal_data_t *) + ((uintptr_t)addr); + + /* Enable access to the PHY configuration registers */ + clrbits_le16(phy_base + DDR_PHY_APBONLY0_OFFSET, + DDR_PHY_MICROCONTMUXSEL); + + phybak_num = ARRAY_SIZE(phybak); + + debug("%s: Total PHY backup %d registers\n", __func__, + (int)phybak_num); + + if (proc == STORE) { + debug("%s: Storing PHY bak calibration to OCRAM ...\n", + __func__); + /* Creating header */ + /* Write PHY magic number */ + cal->header.header_magic = SOC64_HANDOFF_DDR_PHY_MAGIC; + cal->header.data_len = phybak_num * sizeof(*data); + } else if (proc == LOADING) { + debug("%s: Loading bak calibration to PHY from OCRAM ...\n", + __func__); + } + + data = &cal->data; + while (phybak_num) { + phy_ocram(phy_base, *phybak_p, data, proc); + phybak_p++; + phybak_num--; + data++; + WATCHDOG_RESET(); + }; + + if (proc == STORE) { + /* Creating header */ + /* Generate HASH384 from the DDR config */ + sha384_csum_wd((u8 *)DDR_HANDOFF_IMG_ADDR, + DDR_HANDOFF_IMG_LEN, + cal->header.ddrconfig_hash, + CHUNKSZ_PER_WD_RESET); + + crc32_wd_buf((u8 *)&cal->data, cal->header.data_len, + (u8 *)&cal->header.caldata_crc32, + CHUNKSZ_PER_WD_RESET); + } + + /* Isolate the APB access from internal CSRs */ + setbits_le16(phy_base + DDR_PHY_APBONLY0_OFFSET, + DDR_PHY_MICROCONTMUXSEL); +} + +static bool is_ddrconfig_hash_match(const void *buffer) +{ + int ret; + u8 hash[SHA384_SUM_LEN]; + + /* Magic symbol in first 4 bytes of header */ + struct cal_header_t *header = (struct cal_header_t *)buffer; + + /* Generate HASH384 from the image */ + sha384_csum_wd((u8 *)DDR_HANDOFF_IMG_ADDR, DDR_HANDOFF_IMG_LEN, + hash, CHUNKSZ_PER_WD_RESET); + + ret = memcmp((void *)hash, (const void *)header->ddrconfig_hash, + SHA384_SUM_LEN); + if (ret) { + debug("%s: DDR config hash mismatch\n", __func__); + return false; + } + + return true; +} + +static ofnode get_ddr_ofnode(ofnode from) +{ + return ofnode_by_compatible(from, "intel,sdr-ctl-dm"); +} + +static const char *get_ddrcal_ddr_offset(void) +{ + const char *ddr_offset = NULL; + + ofnode ddr_node = get_ddr_ofnode(ofnode_null()); + + if (ofnode_valid(ddr_node)) + ddr_offset = ofnode_read_string(ddr_node, + "intel,ddrcal-ddr-offset"); + + return ddr_offset; +} + +static const char *get_ddrcal_qspi_offset(void) +{ + const char *qspi_offset = NULL; + + ofnode ddr_node = get_ddr_ofnode(ofnode_null()); + + if (ofnode_valid(ddr_node)) + qspi_offset = ofnode_read_string(ddr_node, + "intel,ddrcal-qspi-offset"); + + return qspi_offset; +} + +static bool is_cal_bak_data_valid(void) +{ + int ret, size; + struct udevice *dev; + ofnode node; + const fdt32_t *phandle_p; + u32 phandle, crc32; + const char *qspi_offset = get_ddrcal_qspi_offset(); + struct bac_cal_data_t *cal = (struct bac_cal_data_t *)((uintptr_t) + SOC64_OCRAM_PHY_BACKUP_BASE); + + node = get_ddr_ofnode(ofnode_null()); + + if (ofnode_valid(node)) { + phandle_p = ofnode_get_property(node, "firmware-loader", + &size); + if (!phandle_p) { + node = ofnode_path("/chosen"); + if (!ofnode_valid(node)) { + debug("%s: /chosen node was not found.\n", + __func__); + return false; + } + + phandle_p = ofnode_get_property(node, + "firmware-loader", + &size); + if (!phandle_p) { + debug("%s: firmware-loader property ", + __func__); + debug("was not found.\n"); + return false; + } + } + } else { + debug("%s: DDR node was not found.\n", __func__); + return false; + } + + phandle = fdt32_to_cpu(*phandle_p); + ret = uclass_get_device_by_phandle_id(UCLASS_FS_FIRMWARE_LOADER, + phandle, &dev); + if (ret) + return false; + + /* Load DDR bak cal header into OCRAM buffer */ + ret = request_firmware_into_buf(dev, + qspi_offset, + (void *)SOC64_OCRAM_PHY_BACKUP_BASE, + sizeof(struct cal_header_t), 0); + if (ret < 0) { + debug("%s: Failed to read bak cal header from flash.\n", + __func__); + return false; + } + + if (cal->header.header_magic != SOC64_HANDOFF_DDR_PHY_MAGIC) { + debug("%s: No magic found in cal backup header\n", __func__); + return false; + } + + /* Load header + DDR bak cal into OCRAM buffer */ + ret = request_firmware_into_buf(dev, + qspi_offset, + (void *)SOC64_OCRAM_PHY_BACKUP_BASE, + cal->header.data_len + + sizeof(struct cal_header_t), + 0); + if (ret < 0) { + debug("FPGA: Failed to read DDR bak cal data from flash.\n"); + return false; + } + + crc32_wd_buf((u8 *)&cal->data, cal->header.data_len, + (u8 *)&crc32, CHUNKSZ_PER_WD_RESET); + debug("%s: crc32 %x for bak calibration data from QSPI\n", __func__, + crc32); + if (crc32 != cal->header.caldata_crc32) { + debug("%s: CRC32 mismatch for calibration backup data\n", + __func__); + return false; + } + + if (!is_ddrconfig_hash_match((const void *) + SOC64_OCRAM_PHY_BACKUP_BASE)) { + debug("%s: HASH mismatch for DDR config data\n", __func__); + return false; + } + + return true; +} + static int init_phy(struct ddr_handoff *ddr_handoff_info) { + u32 handoff_table[ddr_handoff_info->phy_handoff_length]; + u32 i, value; + u32 reg = readl(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_BOOT_SCRATCH_COLD0); int ret; printf("Initializing DDR PHY ...\n"); @@ -950,6 +1582,31 @@ static int init_phy(struct ddr_handoff *ddr_handoff_info) handoff_process(ddr_handoff_info, ddr_handoff_info->phy_handoff_base, ddr_handoff_info->phy_handoff_length, ddr_handoff_info->phy_base); + if (is_ddr_calibration_skipped(reg)) { + if (is_cal_bak_data_valid()) + *need_calibrate = false; + else + *need_calibrate = true; + } + + debug("%s: Need calibrate %d\n", __func__, *need_calibrate); + + if (*need_calibrate) { + /* Execute PHY configuration handoff */ + handoff_process(ddr_handoff_info, ddr_handoff_info->phy_handoff_base, + ddr_handoff_info->phy_handoff_length, + ddr_handoff_info->phy_base); + } else { + cal_data_ocram(ddr_handoff_info->phy_base, + SOC64_OCRAM_PHY_BACKUP_BASE, LOADING); + + /* + * Invalidate the section used for processing the PHY + * backup calibration data + */ + writel(SOC64_CRAM_PHY_BACKUP_SKIP_MAGIC, + SOC64_OCRAM_PHY_BACKUP_BASE); + } printf("DDR PHY configuration is completed\n"); @@ -1161,6 +1818,14 @@ int populate_ddr_handoff(struct ddr_handoff *handoff) debug("user setting data\n"); return -ENOEXEC; } + + /* Checking DDR handoff is overflow? */ + if (SOC64_OCRAM_PHY_BACKUP_BASE <= + (handoff->phy_engine_handoff_base + + handoff->phy_engine_total_length)) { + printf("%s: DDR handoff is overflow\n ", __func__); + return -ENOEXEC; + } } else { debug("%s: Wrong format for DDR handoff, expect PHY", __func__); @@ -1334,7 +1999,8 @@ static int ddr_trigger_sdram_init(phys_addr_t umctl2_base, } static int ddr_post_handoff_config(phys_addr_t umctl2_base, - enum ddr_type umctl2_type) + enum ddr_type umctl2_type, + bool *need_calibrate) { int ret = 0; u32 value; @@ -1364,11 +2030,13 @@ static int ddr_post_handoff_config(phys_addr_t umctl2_base, /* Checking ECC is enabled? */ value = readl(umctl2_base + DDR4_ECCCFG0_OFFSET) & DDR4_ECC_MODE; - if (value) { + if (value) printf("ECC is enabled\n"); + + if (value && *need_calibrate) { ret = scrubber_ddr_config(umctl2_base, umctl2_type); if (ret) - printf("Failed to enable ECC\n"); + printf("Failed to enable scrubber\n"); } return ret; @@ -2064,18 +2732,19 @@ static int trigger_sdram_init(struct ddr_handoff *handoff) return ret; } -static int ddr_post_config(struct ddr_handoff *handoff) +static int ddr_post_config(struct ddr_handoff *handoff, bool *need_calibrate) { int ret; - ret = ddr_post_handoff_config(handoff->cntlr_base, - handoff->cntlr_t); + ret = ddr_post_handoff_config(handoff->cntlr_base, handoff->cntlr_t, + need_calibrate); if (ret) return ret; if (handoff->cntlr2_t == DDRTYPE_LPDDR4_1) ret = ddr_post_handoff_config(handoff->cntlr2_base, - handoff->cntlr2_t); + handoff->cntlr2_t, + need_calibrate); return ret; } @@ -2149,7 +2818,13 @@ bool is_ddr_init(void) int sdram_mmr_init_full(struct udevice *dev) { u32 user_backup[2], user_backup_2nd[2]; + u32 reg = readl(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_BOOT_SCRATCH_COLD0); int ret; + bool need_calibrate = true; + ulong ddr_offset; + char *endptr; + const char *offset = get_ddrcal_ddr_offset(); struct bd_info bd; struct ddr_handoff ddr_handoff_info; struct altera_sdram_priv *priv = dev_get_priv(dev); @@ -2165,13 +2840,19 @@ int sdram_mmr_init_full(struct udevice *dev) /* Set the MPFE NoC mux to correct DDR controller type */ use_ddr4(ddr_handoff_info.cntlr_t); - if (is_ddr_init()) { + /* + * Invalidate the section used for processing the PHY backup + * calibration data + */ + writel(SOC64_CRAM_PHY_BACKUP_SKIP_MAGIC, SOC64_OCRAM_PHY_BACKUP_BASE); + + if (!is_ddr_init_skipped(reg)) { printf("SDRAM init in progress ...\n"); /* - * Polling reset complete, must be high to ensure DDR subsystem - * in complete reset state before init DDR clock and DDR - * controller + * Polling reset complete, must be high to ensure DDR + * subsystem in complete reset state before init DDR clock + * and DDR controller */ ret = wait_for_bit_le32((const void *)((uintptr_t)(readl (ddr_handoff_info.mem_reset_base) + @@ -2206,7 +2887,7 @@ int sdram_mmr_init_full(struct udevice *dev) printf("DDR controller configuration is completed\n"); /* Initialize DDR PHY */ - ret = init_phy(&ddr_handoff_info); + ret = init_phy(&ddr_handoff_info, &need_calibrate); if (ret) { debug("%s: Failed to inilialize DDR PHY\n", __func__); return ret; @@ -2214,21 +2895,43 @@ int sdram_mmr_init_full(struct udevice *dev) enable_phy_clk_for_csr_access(&ddr_handoff_info, true); - ret = start_ddr_calibration(&ddr_handoff_info); - if (ret) { - debug("%s: Failed to calibrate DDR\n", __func__); - return ret; - } + if (need_calibrate) { + ret = start_ddr_calibration(&ddr_handoff_info); + if (ret) { + debug("%s: Failed to calibrate DDR\n", + __func__); + return ret; + } - enable_phy_clk_for_csr_access(&ddr_handoff_info, false); + /* DDR freq set to support DDR4-3200 */ + phy_init_engine(&ddr_handoff_info); - /* Reset ARC processor when no using for security purpose */ + /* + * Backup calibration data to OCRAM first, these data + * might be permanant stored to flash in later + */ + if (is_ddr_retention_enabled(reg)) + cal_data_ocram(ddr_handoff_info.phy_base, + SOC64_OCRAM_PHY_BACKUP_BASE, + STORE); + + } else { + /* Updating training result to DDR controller */ + ret = update_training_result(&ddr_handoff_info); + if (ret) + return ret; + } + + /* + * Reset ARC processor when no using for security + * purpose + */ setbits_le16(ddr_handoff_info.phy_base + DDR_PHY_MICRORESET_OFFSET, DDR_PHY_MICRORESET_RESET); /* DDR freq set to support DDR4-3200 */ - phy_init_engine(&ddr_handoff_info); + enable_phy_clk_for_csr_access(&ddr_handoff_info, false); ret = dfi_init(&ddr_handoff_info); if (ret) @@ -2242,7 +2945,7 @@ int sdram_mmr_init_full(struct udevice *dev) if (ret) return ret; - ret = ddr_post_config(&ddr_handoff_info); + ret = ddr_post_config(&ddr_handoff_info, &need_calibrate); if (ret) return ret; @@ -2291,8 +2994,12 @@ int sdram_mmr_init_full(struct udevice *dev) priv->info.size = gd->ram_size; sdram_size_check(&bd); - sdram_set_firewall(&bd); + ddr_offset = simple_strtoul(offset, &endptr, 16); + if (!(offset == endptr || *endptr != '\0')) + memcpy((void *)ddr_offset, + (const void *)SOC64_OCRAM_PHY_BACKUP_BASE, SZ_4K); + return 0; }