From patchwork Sun Jun 13 08:48:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siew Chin Lim X-Patchwork-Id: 1491372 X-Patchwork-Delegate: simon.k.r.goldschmidt@gmail.com 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=) 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)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G2pFT3lw2z9sWk for ; Sun, 13 Jun 2021 18:50:37 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EC05681D1F; Sun, 13 Jun 2021 10:49:47 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 8EEC080C9A; Sun, 13 Jun 2021 10:49:25 +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=-1.9 required=5.0 tests=BAYES_00,SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) (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 0B72080C67 for ; Sun, 13 Jun 2021 10:49:08 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=elly.siew.chin.lim@intel.com IronPort-SDR: ER/ozPysD3wZlVJ9MjUdy3WJ+JoSdMCOPic7bNmYWyB6xDwZFL3ijMCsppapN9yi7sy/epFBud +gNpA0+B+OdA== X-IronPort-AV: E=McAfee;i="6200,9189,10013"; a="185398428" X-IronPort-AV: E=Sophos;i="5.83,270,1616482800"; d="scan'208";a="185398428" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Jun 2021 01:49:08 -0700 IronPort-SDR: DxX3Lr+V1imU5x8z0fYjWeuvYgp9vJptkJQCB5+/27p1GQbuzXgAQP2XpkbJDOcgmhzPzuIyk2 f6pKQIa9lDTg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.83,270,1616482800"; d="scan'208";a="441941627" Received: from pg-iccf0307.altera.com ([10.104.1.103]) by orsmga007.jf.intel.com with ESMTP; 13 Jun 2021 01:49:05 -0700 From: Siew Chin Lim To: u-boot@lists.denx.de Cc: Marek Vasut , Ley Foon Tan , Simon Goldschmidt , Tien Fong Chee , Dalon Westergreen , Simon Glass , Yau Wai Gan , Siew Chin Lim Subject: [v3 04/17] arm: socfpga: Add handoff data support for Intel N5X device Date: Sun, 13 Jun 2021 16:48:39 +0800 Message-Id: <20210613084852.30868-5-elly.siew.chin.lim@intel.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20210613084852.30868-1-elly.siew.chin.lim@intel.com> References: <20210613084852.30868-1-elly.siew.chin.lim@intel.com> 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 From: Tien Fong Chee N5X support both HPS handoff data and DDR handoff data. Existing HPS handoff functions are restructured to support both existing devices and N5X device. Signed-off-by: Siew Chin Lim Signed-off-by: Tien Fong Chee Reviewed-by: Ley Foon Tan --- v3 - Adding helper function for getting endianness type. v2: - Enabled auto detect the endianness from the magic word - Merged and simplifying the big and little endian flow --- .../mach-socfpga/include/mach/handoff_soc64.h | 38 ++++- arch/arm/mach-socfpga/system_manager_soc64.c | 18 +-- arch/arm/mach-socfpga/wrap_handoff_soc64.c | 132 +++++++++++++----- 3 files changed, 140 insertions(+), 48 deletions(-) diff --git a/arch/arm/mach-socfpga/include/mach/handoff_soc64.h b/arch/arm/mach-socfpga/include/mach/handoff_soc64.h index 3750216a9a..902fc6bfb5 100644 --- a/arch/arm/mach-socfpga/include/mach/handoff_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/handoff_soc64.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 * - * Copyright (C) 2016-2020 Intel Corporation + * Copyright (C) 2016-2021 Intel Corporation * */ @@ -23,8 +23,36 @@ #define SOC64_HANDOFF_OFFSET_DATA 0x10 #define SOC64_HANDOFF_SIZE 4096 +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_STRATIX10) || \ + IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) #define SOC64_HANDOFF_BASE 0xFFE3F000 #define SOC64_HANDOFF_MISC (SOC64_HANDOFF_BASE + 0x610) +#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) +#define SOC64_HANDOFF_BASE 0xFFE5F000 +#define SOC64_HANDOFF_MISC (SOC64_HANDOFF_BASE + 0x630) + +/* DDR handoff */ +#define SOC64_HANDOFF_DDR_BASE 0xFFE5C000 +#define SOC64_HANDOFF_DDR_MAGIC 0x48524444 +#define SOC64_HANDOFF_DDR_UMCTL2_MAGIC 0x4C54434D +#define SOC64_HANDOFF_DDR_UMCTL2_DDR4_TYPE 0x34524444 +#define SOC64_HANDOFF_DDR_UMCTL2_LPDDR4_0_TYPE 0x3044504C +#define SOC64_HANDOFF_DDR_UMCTL2_LPDDR4_1_TYPE 0x3144504C +#define SOC64_HANDOFF_DDR_MEMRESET_BASE (SOC64_HANDOFF_DDR_BASE + 0xC) +#define SOC64_HANDOFF_DDR_UMCTL2_SECTION (SOC64_HANDOFF_DDR_BASE + 0x10) +#define SOC64_HANDOFF_DDR_PHY_MAGIC 0x43594850 +#define SOC64_HANDOFF_DDR_PHY_INIT_ENGINE_MAGIC 0x45594850 +#define SOC64_HANDOFF_DDR_PHY_BASE_OFFSET 0x8 +#define SOC64_HANDOFF_DDR_UMCTL2_TYPE_OFFSET 0x8 +#define SOC64_HANDOFF_DDR_UMCTL2_BASE_ADDR_OFFSET 0xC +#define SOC64_HANDOFF_DDR_TRAIN_IMEM_1D_SECTION 0xFFE50000 +#define SOC64_HANDOFF_DDR_TRAIN_DMEM_1D_SECTION 0xFFE58000 +#define SOC64_HANDOFF_DDR_TRAIN_IMEM_2D_SECTION 0xFFE44000 +#define SOC64_HANDOFF_DDR_TRAIN_DMEM_2D_SECTION 0xFFE4C000 +#define SOC64_HANDOFF_DDR_TRAIN_IMEM_LENGTH SZ_32K +#define SOC64_HANDOFF_DDR_TRAIN_DMEM_LENGTH SZ_16K +#endif + #define SOC64_HANDOFF_MUX (SOC64_HANDOFF_BASE + 0x10) #define SOC64_HANDOFF_IOCTL (SOC64_HANDOFF_BASE + 0x1A0) #define SOC64_HANDOFF_FPGA (SOC64_HANDOFF_BASE + 0x330) @@ -52,11 +80,11 @@ #include enum endianness { LITTLE_ENDIAN = 0, - BIG_ENDIAN + BIG_ENDIAN, + UNKNOWN_ENDIANNESS }; -int socfpga_get_handoff_size(void *handoff_address, enum endianness endian); -int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len, - enum endianness big_endian); +int socfpga_get_handoff_size(void *handoff_address); +int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len); #endif #endif /* _HANDOFF_SOC64_H_ */ diff --git a/arch/arm/mach-socfpga/system_manager_soc64.c b/arch/arm/mach-socfpga/system_manager_soc64.c index 3b5e774e2d..958bb5107b 100644 --- a/arch/arm/mach-socfpga/system_manager_soc64.c +++ b/arch/arm/mach-socfpga/system_manager_soc64.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2016-2018 Intel Corporation + * Copyright (C) 2016-2021 Intel Corporation * */ @@ -66,10 +66,10 @@ void populate_sysmgr_fpgaintf_module(void) void populate_sysmgr_pinmux(void) { u32 len, i; - u32 len_mux = socfpga_get_handoff_size((void *)SOC64_HANDOFF_MUX, BIG_ENDIAN); - u32 len_ioctl = socfpga_get_handoff_size((void *)SOC64_HANDOFF_IOCTL, BIG_ENDIAN); - u32 len_fpga = socfpga_get_handoff_size((void *)SOC64_HANDOFF_FPGA, BIG_ENDIAN); - u32 len_delay = socfpga_get_handoff_size((void *)SOC64_HANDOFF_DELAY, BIG_ENDIAN); + u32 len_mux = socfpga_get_handoff_size((void *)SOC64_HANDOFF_MUX); + u32 len_ioctl = socfpga_get_handoff_size((void *)SOC64_HANDOFF_IOCTL); + u32 len_fpga = socfpga_get_handoff_size((void *)SOC64_HANDOFF_FPGA); + u32 len_delay = socfpga_get_handoff_size((void *)SOC64_HANDOFF_DELAY); len = (len_mux > len_ioctl) ? len_mux : len_ioctl; len = (len > len_fpga) ? len : len_fpga; @@ -79,7 +79,7 @@ void populate_sysmgr_pinmux(void) /* setup the pin sel */ len = (len_mux < SOC64_HANDOFF_MUX_LEN) ? len_mux : SOC64_HANDOFF_MUX_LEN; - socfpga_handoff_read((void *)SOC64_HANDOFF_MUX, handoff_table, len, BIG_ENDIAN); + socfpga_handoff_read((void *)SOC64_HANDOFF_MUX, handoff_table, len); for (i = 0; i < len; i = i + 2) { writel(handoff_table[i + 1], handoff_table[i] + @@ -89,7 +89,7 @@ void populate_sysmgr_pinmux(void) /* setup the pin ctrl */ len = (len_ioctl < SOC64_HANDOFF_IOCTL_LEN) ? len_ioctl : SOC64_HANDOFF_IOCTL_LEN; - socfpga_handoff_read((void *)SOC64_HANDOFF_IOCTL, handoff_table, len, BIG_ENDIAN); + socfpga_handoff_read((void *)SOC64_HANDOFF_IOCTL, handoff_table, len); for (i = 0; i < len; i = i + 2) { writel(handoff_table[i + 1], handoff_table[i] + @@ -99,7 +99,7 @@ void populate_sysmgr_pinmux(void) /* setup the fpga use */ len = (len_fpga < SOC64_HANDOFF_FPGA_LEN) ? len_fpga : SOC64_HANDOFF_FPGA_LEN; - socfpga_handoff_read((void *)SOC64_HANDOFF_FPGA, handoff_table, len, BIG_ENDIAN); + socfpga_handoff_read((void *)SOC64_HANDOFF_FPGA, handoff_table, len); for (i = 0; i < len; i = i + 2) { writel(handoff_table[i + 1], handoff_table[i] + @@ -109,7 +109,7 @@ void populate_sysmgr_pinmux(void) /* setup the IO delay */ len = (len_delay < SOC64_HANDOFF_DELAY_LEN) ? len_delay : SOC64_HANDOFF_DELAY_LEN; - socfpga_handoff_read((void *)SOC64_HANDOFF_DELAY, handoff_table, len, BIG_ENDIAN); + socfpga_handoff_read((void *)SOC64_HANDOFF_DELAY, handoff_table, len); for (i = 0; i < len; i = i + 2) { writel(handoff_table[i + 1], handoff_table[i] + diff --git a/arch/arm/mach-socfpga/wrap_handoff_soc64.c b/arch/arm/mach-socfpga/wrap_handoff_soc64.c index a7ad7a18ed..e7cb5ea89c 100644 --- a/arch/arm/mach-socfpga/wrap_handoff_soc64.c +++ b/arch/arm/mach-socfpga/wrap_handoff_soc64.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2021 Intel Corporation * */ @@ -10,12 +10,64 @@ #include #include "log.h" -int socfpga_get_handoff_size(void *handoff_address, enum endianness endian) +static enum endianness check_endianness(u32 handoff) +{ + switch (handoff) { + case SOC64_HANDOFF_MAGIC_BOOT: + case SOC64_HANDOFF_MAGIC_MUX: + case SOC64_HANDOFF_MAGIC_IOCTL: + case SOC64_HANDOFF_MAGIC_FPGA: + case SOC64_HANDOFF_MAGIC_DELAY: + case SOC64_HANDOFF_MAGIC_CLOCK: + case SOC64_HANDOFF_MAGIC_MISC: + return BIG_ENDIAN; +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) + case SOC64_HANDOFF_DDR_UMCTL2_MAGIC: + debug("%s: umctl2 handoff data\n", __func__); + return LITTLE_ENDIAN; + case SOC64_HANDOFF_DDR_PHY_MAGIC: + debug("%s: PHY handoff data\n", __func__); + return LITTLE_ENDIAN; + case SOC64_HANDOFF_DDR_PHY_INIT_ENGINE_MAGIC: + debug("%s: PHY engine handoff data\n", __func__); + return LITTLE_ENDIAN; +#endif + default: + debug("%s: Unknown endianness!!\n", __func__); + return UNKNOWN_ENDIANNESS; + } +} + +static int getting_endianness(void *handoff_address, enum endianness *endian_t) +{ + /* Checking handoff data is little endian ? */ + *endian_t = check_endianness(readl(handoff_address)); + + if (*endian_t == UNKNOWN_ENDIANNESS) { + /* Trying to check handoff data is big endian? */ + *endian_t = check_endianness(swab32(readl(handoff_address))); + if (*endian_t == UNKNOWN_ENDIANNESS) { + debug("%s: Cannot find HANDOFF MAGIC ", __func__); + debug("at addr 0x%p\n", (u32 *)handoff_address); + return -EPERM; + } + } + + return 0; +} + +int socfpga_get_handoff_size(void *handoff_address) { u32 size; + int ret; + enum endianness endian_t; + + ret = getting_endianness(handoff_address, &endian_t); + if (ret) + return ret; size = readl(handoff_address + SOC64_HANDOFF_OFFSET_LENGTH); - if (endian == BIG_ENDIAN) + if (endian_t == BIG_ENDIAN) size = swab32(size); size = (size - SOC64_HANDOFF_OFFSET_DATA) / sizeof(u32); @@ -26,41 +78,53 @@ int socfpga_get_handoff_size(void *handoff_address, enum endianness endian) return size; } -int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len, - enum endianness big_endian) +int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len) { - u32 temp, i; + u32 temp; u32 *table_x32 = table; + u32 i = 0; + int ret; + enum endianness endian_t; - debug("%s: handoff addr = 0x%p ", __func__, (u32 *)handoff_address); - - if (big_endian) { - if (swab32(readl(SOC64_HANDOFF_BASE)) == SOC64_HANDOFF_MAGIC_BOOT) { - debug("Handoff table address = 0x%p ", table_x32); - debug("table length = 0x%x\n", table_len); - debug("%s: handoff data =\n{\n", __func__); - - for (i = 0; i < table_len; i++) { - temp = readl(handoff_address + - SOC64_HANDOFF_OFFSET_DATA + - (i * sizeof(u32))); - *table_x32 = swab32(temp); - - if (!(i % 2)) - debug(" No.%d Addr 0x%08x: ", i, - *table_x32); - else - debug(" 0x%08x\n", *table_x32); - - table_x32++; - } - debug("\n}\n"); - } else { - debug("%s: Cannot find SOC64_HANDOFF_MAGIC_BOOT ", __func__); - debug("at addr 0x%p\n", (u32 *)handoff_address); - return -EPERM; - } + ret = getting_endianness(handoff_address, &endian_t); + if (ret) + return ret; + + temp = readl(handoff_address + SOC64_HANDOFF_OFFSET_DATA + + (i * sizeof(u32))); + + if (endian_t == BIG_ENDIAN) { + debug("%s: Handoff addr = 0x%p ", __func__, (u32 *)handoff_address); + debug("Handoff table address = 0x%p ", table_x32); + debug("table length = 0x%x\n", table_len); + debug("%s: handoff data =\n{\n", __func__); + *table_x32 = swab32(temp); + } else if (endian_t == LITTLE_ENDIAN) { + debug(" {\n"); + *table_x32 = temp; + } + + debug(" No.%d Addr 0x%08x: ", i, *table_x32); + + for (i = 1; i < table_len; i++) { + table_x32++; + + temp = readl(handoff_address + + SOC64_HANDOFF_OFFSET_DATA + + (i * sizeof(u32))); + + if (endian_t == BIG_ENDIAN) + *table_x32 = swab32(temp); + else if (endian_t == LITTLE_ENDIAN) + *table_x32 = temp; + + if (!(i % 2)) + debug(" No.%d Addr 0x%08x: ", i, + *table_x32); + else + debug(" 0x%08x\n", *table_x32); } + debug("\n}\n"); return 0; }