From patchwork Thu Mar 21 15:48:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Ceresoli X-Patchwork-Id: 1060254 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=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=lucaceresoli.net Authentication-Results: ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=lucaceresoli.net header.i=@lucaceresoli.net header.b="aP6pdKt4"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44QB816GlZz9sRG for ; Fri, 22 Mar 2019 02:50:25 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 7B35EC2209B; Thu, 21 Mar 2019 15:49:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=T_DKIM_INVALID, UPPERCASE_50_75 autolearn=no autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 3F660C22094; Thu, 21 Mar 2019 15:49:17 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 38DE6C2203D; Thu, 21 Mar 2019 15:49:14 +0000 (UTC) Received: from hostingweb31-40.netsons.net (hostingweb31-40.netsons.net [89.40.174.40]) by lists.denx.de (Postfix) with ESMTPS id D18D4C22036 for ; Thu, 21 Mar 2019 15:49:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lucaceresoli.net; s=default; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=lFmkXJM6lOQzslzTBppld+nAoc1l520gQDfYJiL1GtQ=; b=aP6pdKt43PJxcdVQ3NY9lygtZ G0D2WFO15/+4ZwxmJ3J/1sK72ELOwp1jxWlFcpLxaliga69pFJxE5v3sNW00cMiuJqjoVuWraRV9Q Vyr8JAJGcocejNrYOfAjUVMRzYCKoe3BqzxfGv1PqQ/7RaYkxegcKFmTvYL0BglL052sk=; Received: from [109.168.11.45] (port=40018 helo=pc-ceresoli.dev.aim) by hostingweb31.netsons.net with esmtpa (Exim 4.91) (envelope-from ) id 1h6zwO-00EWCd-HZ; Thu, 21 Mar 2019 16:49:12 +0100 From: Luca Ceresoli To: u-boot@lists.denx.de Date: Thu, 21 Mar 2019 16:48:56 +0100 Message-Id: <20190321154857.29892-2-luca@lucaceresoli.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190321154857.29892-1-luca@lucaceresoli.net> References: <20190321154857.29892-1-luca@lucaceresoli.net> X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - hostingweb31.netsons.net X-AntiAbuse: Original Domain - lists.denx.de X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - lucaceresoli.net X-Get-Message-Sender-Via: hostingweb31.netsons.net: authenticated_id: luca+lucaceresoli.net/only user confirmed/virtual account not confirmed X-Authenticated-Sender: hostingweb31.netsons.net: luca@lucaceresoli.net X-Source: X-Source-Args: X-Source-Dir: Cc: Luca Ceresoli , Michal Simek Subject: [U-Boot] [RFC v2 1/2] zynqmp: add minimal include files to build a pm_cfg_obj.c X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" A following commit will allow U-Boot to pass a configuration object to the ZynqMP PMU firmware. This configuration object is generated by Xilinx tools in the form of a C file (pm_cfg_obj.c), which #includes a few headers with constants definitions. In order to allow pm_cfg_obj.c to build, include in U-Boot a minimal version of those headers files: - pm_defs: a copy of [0], reduced to remove unneeded values - pmu_global.h: empty file, it is included but not really needed - xil_types.h: just includes common.h which has all the needed types [0] https://github.com/Xilinx/embeddedsw/blob/xilinx-v2018.3/lib/sw_services/xilpm/src/common/pm_defs.h Signed-off-by: Luca Ceresoli --- board/xilinx/zynqmp/pm_defs.h | 254 +++++++++++++++++++++++++++++++ board/xilinx/zynqmp/pmu_global.h | 0 board/xilinx/zynqmp/xil_types.h | 1 + 3 files changed, 255 insertions(+) create mode 100644 board/xilinx/zynqmp/pm_defs.h create mode 100644 board/xilinx/zynqmp/pmu_global.h create mode 100644 board/xilinx/zynqmp/xil_types.h diff --git a/board/xilinx/zynqmp/pm_defs.h b/board/xilinx/zynqmp/pm_defs.h new file mode 100644 index 000000000000..a339d5ef4fd1 --- /dev/null +++ b/board/xilinx/zynqmp/pm_defs.h @@ -0,0 +1,254 @@ +/****************************************************************************** +* +* Copyright (C) 2015-2018 Xilinx, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +* SOFTWARE. +* +* Except as contained in this notice, the name of the Xilinx shall not be used +* in advertising or otherwise to promote the sale, use or other dealings in +* this Software without prior written authorization from Xilinx. +* +******************************************************************************/ + +/*****************************************************************************/ +/** + * @file pm_defs.h + * + * PM Definitions implementation + * @addtogroup xpm_apis XilPM APIs + * @{ + *****************************************************************************/ + +#ifndef PM_DEFS_H_ +#define PM_DEFS_H_ + +/** @name Capabilities for RAM + * + * @{ + */ +#define PM_CAP_ACCESS 0x1U +#define PM_CAP_CONTEXT 0x2U +#define PM_CAP_WAKEUP 0x4U +/**@}*/ + +/** + * PM Node ID Enum + */ +enum XPmNodeId { + NODE_UNKNOWN, + NODE_APU, + NODE_APU_0, + NODE_APU_1, + NODE_APU_2, + NODE_APU_3, + NODE_RPU, + NODE_RPU_0, + NODE_RPU_1, + NODE_PLD, + NODE_FPD, + NODE_OCM_BANK_0, + NODE_OCM_BANK_1, + NODE_OCM_BANK_2, + NODE_OCM_BANK_3, + NODE_TCM_0_A, + NODE_TCM_0_B, + NODE_TCM_1_A, + NODE_TCM_1_B, + NODE_L2, + NODE_GPU_PP_0, + NODE_GPU_PP_1, + NODE_USB_0, + NODE_USB_1, + NODE_TTC_0, + NODE_TTC_1, + NODE_TTC_2, + NODE_TTC_3, + NODE_SATA, + NODE_ETH_0, + NODE_ETH_1, + NODE_ETH_2, + NODE_ETH_3, + NODE_UART_0, + NODE_UART_1, + NODE_SPI_0, + NODE_SPI_1, + NODE_I2C_0, + NODE_I2C_1, + NODE_SD_0, + NODE_SD_1, + NODE_DP, + NODE_GDMA, + NODE_ADMA, + NODE_NAND, + NODE_QSPI, + NODE_GPIO, + NODE_CAN_0, + NODE_CAN_1, + NODE_EXTERN, + NODE_APLL, + NODE_VPLL, + NODE_DPLL, + NODE_RPLL, + NODE_IOPLL, + NODE_DDR, + NODE_IPI_APU, + NODE_IPI_RPU_0, + NODE_GPU, + NODE_PCIE, + NODE_PCAP, + NODE_RTC, + NODE_LPD, + NODE_VCU, + NODE_IPI_RPU_1, + NODE_IPI_PL_0, + NODE_IPI_PL_1, + NODE_IPI_PL_2, + NODE_IPI_PL_3, + NODE_PL, + NODE_ID_MAX +}; + +/** + * PM Reset Line IDs + */ +enum XPmReset { + XILPM_RESET_PCIE_CFG = 1000, + XILPM_RESET_PCIE_BRIDGE, + XILPM_RESET_PCIE_CTRL, + XILPM_RESET_DP, + XILPM_RESET_SWDT_CRF, + XILPM_RESET_AFI_FM5, + XILPM_RESET_AFI_FM4, + XILPM_RESET_AFI_FM3, + XILPM_RESET_AFI_FM2, + XILPM_RESET_AFI_FM1, + XILPM_RESET_AFI_FM0, + XILPM_RESET_GDMA, + XILPM_RESET_GPU_PP1, + XILPM_RESET_GPU_PP0, + XILPM_RESET_GPU, + XILPM_RESET_GT, + XILPM_RESET_SATA, + XILPM_RESET_ACPU3_PWRON, + XILPM_RESET_ACPU2_PWRON, + XILPM_RESET_ACPU1_PWRON, + XILPM_RESET_ACPU0_PWRON, + XILPM_RESET_APU_L2, + XILPM_RESET_ACPU3, + XILPM_RESET_ACPU2, + XILPM_RESET_ACPU1, + XILPM_RESET_ACPU0, + XILPM_RESET_DDR, + XILPM_RESET_APM_FPD, + XILPM_RESET_SOFT, + XILPM_RESET_GEM0, + XILPM_RESET_GEM1, + XILPM_RESET_GEM2, + XILPM_RESET_GEM3, + XILPM_RESET_QSPI, + XILPM_RESET_UART0, + XILPM_RESET_UART1, + XILPM_RESET_SPI0, + XILPM_RESET_SPI1, + XILPM_RESET_SDIO0, + XILPM_RESET_SDIO1, + XILPM_RESET_CAN0, + XILPM_RESET_CAN1, + XILPM_RESET_I2C0, + XILPM_RESET_I2C1, + XILPM_RESET_TTC0, + XILPM_RESET_TTC1, + XILPM_RESET_TTC2, + XILPM_RESET_TTC3, + XILPM_RESET_SWDT_CRL, + XILPM_RESET_NAND, + XILPM_RESET_ADMA, + XILPM_RESET_GPIO, + XILPM_RESET_IOU_CC, + XILPM_RESET_TIMESTAMP, + XILPM_RESET_RPU_R50, + XILPM_RESET_RPU_R51, + XILPM_RESET_RPU_AMBA, + XILPM_RESET_OCM, + XILPM_RESET_RPU_PGE, + XILPM_RESET_USB0_CORERESET, + XILPM_RESET_USB1_CORERESET, + XILPM_RESET_USB0_HIBERRESET, + XILPM_RESET_USB1_HIBERRESET, + XILPM_RESET_USB0_APB, + XILPM_RESET_USB1_APB, + XILPM_RESET_IPI, + XILPM_RESET_APM_LPD, + XILPM_RESET_RTC, + XILPM_RESET_SYSMON, + XILPM_RESET_AFI_FM6, + XILPM_RESET_LPD_SWDT, + XILPM_RESET_FPD, + XILPM_RESET_RPU_DBG1, + XILPM_RESET_RPU_DBG0, + XILPM_RESET_DBG_LPD, + XILPM_RESET_DBG_FPD, + XILPM_RESET_APLL, + XILPM_RESET_DPLL, + XILPM_RESET_VPLL, + XILPM_RESET_IOPLL, + XILPM_RESET_RPLL, + XILPM_RESET_GPO3_PL_0, + XILPM_RESET_GPO3_PL_1, + XILPM_RESET_GPO3_PL_2, + XILPM_RESET_GPO3_PL_3, + XILPM_RESET_GPO3_PL_4, + XILPM_RESET_GPO3_PL_5, + XILPM_RESET_GPO3_PL_6, + XILPM_RESET_GPO3_PL_7, + XILPM_RESET_GPO3_PL_8, + XILPM_RESET_GPO3_PL_9, + XILPM_RESET_GPO3_PL_10, + XILPM_RESET_GPO3_PL_11, + XILPM_RESET_GPO3_PL_12, + XILPM_RESET_GPO3_PL_13, + XILPM_RESET_GPO3_PL_14, + XILPM_RESET_GPO3_PL_15, + XILPM_RESET_GPO3_PL_16, + XILPM_RESET_GPO3_PL_17, + XILPM_RESET_GPO3_PL_18, + XILPM_RESET_GPO3_PL_19, + XILPM_RESET_GPO3_PL_20, + XILPM_RESET_GPO3_PL_21, + XILPM_RESET_GPO3_PL_22, + XILPM_RESET_GPO3_PL_23, + XILPM_RESET_GPO3_PL_24, + XILPM_RESET_GPO3_PL_25, + XILPM_RESET_GPO3_PL_26, + XILPM_RESET_GPO3_PL_27, + XILPM_RESET_GPO3_PL_28, + XILPM_RESET_GPO3_PL_29, + XILPM_RESET_GPO3_PL_30, + XILPM_RESET_GPO3_PL_31, + XILPM_RESET_RPU_LS, + XILPM_RESET_PS_ONLY, + XILPM_RESET_PL, + XILPM_RESET_GPIO5_EMIO_92, + XILPM_RESET_GPIO5_EMIO_93, + XILPM_RESET_GPIO5_EMIO_94, + XILPM_RESET_GPIO5_EMIO_95, +}; + + /** @} */ +#endif /* PM_DEFS_H_ */ diff --git a/board/xilinx/zynqmp/pmu_global.h b/board/xilinx/zynqmp/pmu_global.h new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/board/xilinx/zynqmp/xil_types.h b/board/xilinx/zynqmp/xil_types.h new file mode 100644 index 000000000000..65e11030d85e --- /dev/null +++ b/board/xilinx/zynqmp/xil_types.h @@ -0,0 +1 @@ +#include From patchwork Thu Mar 21 15:48:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Ceresoli X-Patchwork-Id: 1060252 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=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=lucaceresoli.net Authentication-Results: ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=lucaceresoli.net header.i=@lucaceresoli.net header.b="MBRJr379"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44QB6q0Bzrz9sRG for ; Fri, 22 Mar 2019 02:49:22 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id AE4C2C2208E; Thu, 21 Mar 2019 15:49:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 362ADC22036; Thu, 21 Mar 2019 15:49:16 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 20182C22049; Thu, 21 Mar 2019 15:49:14 +0000 (UTC) Received: from hostingweb31-40.netsons.net (hostingweb31-40.netsons.net [89.40.174.40]) by lists.denx.de (Postfix) with ESMTPS id D6FDFC2203D for ; Thu, 21 Mar 2019 15:49:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lucaceresoli.net; s=default; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=tMw1Sm0ZIPpfoQuiZbqCOvWwsW0WLBlwlJnU3G56Wtk=; b=MBRJr379uFnQfdG/FWgyfgHRQ Df1UA1/UumbWHdYMZV8ZDAZO+9jLjNqrvRZ2Gleop/dhG3bUteJVMvSFZ/zQHKWcp8b1y8yvAyIDh PnTF1RbH7+FKUQBIqXHK07wl2IDVSMWznFY7JCKv1j84FtB4/EGV5tusMd6CGc2Ik2Lu8=; Received: from [109.168.11.45] (port=40018 helo=pc-ceresoli.dev.aim) by hostingweb31.netsons.net with esmtpa (Exim 4.91) (envelope-from ) id 1h6zwO-00EWCd-SB; Thu, 21 Mar 2019 16:49:13 +0100 From: Luca Ceresoli To: u-boot@lists.denx.de Date: Thu, 21 Mar 2019 16:48:57 +0100 Message-Id: <20190321154857.29892-3-luca@lucaceresoli.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190321154857.29892-1-luca@lucaceresoli.net> References: <20190321154857.29892-1-luca@lucaceresoli.net> X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - hostingweb31.netsons.net X-AntiAbuse: Original Domain - lists.denx.de X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - lucaceresoli.net X-Get-Message-Sender-Via: hostingweb31.netsons.net: authenticated_id: luca+lucaceresoli.net/only user confirmed/virtual account not confirmed X-Authenticated-Sender: hostingweb31.netsons.net: luca@lucaceresoli.net X-Source: X-Source-Args: X-Source-Dir: Cc: Luca Ceresoli , Michal Simek Subject: [U-Boot] [RFC v2 2/2] arm64: zynqmp: spl: install a PMU firmware config object at runtime X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Optionally allow U-Boot to load at the PMU firmware configuration object into the Power Management Unit (PMU) on Xilinx ZynqMP. The configuration object is required by the PMU FW to enable most SoC peripherals. So far the only way to boot using U-Boot SPL was to hard-code the configuration object in the PMU firmware. Allow a different boot process, where the PMU FW is equal for any ZynqMP chip and its configuration is passed at runtime by U-Boot SPL. All the code for Inter-processor communication with the PMU is isolated in a new file (pmu_ipc.c). The code is inspired by the same feature as implemented in the Xilinx First Stage Bootloader (FSBL) and Arm Trusted Firmware: * https://github.com/Xilinx/embeddedsw/blob/fb647e6b4c00f5154eba52a88b948195b6f1dc2b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c#L295 * https://github.com/ARM-software/arm-trusted-firmware/blob/c48d02bade88b07fa7f43aa44e5217f68e5d047f/plat/xilinx/zynqmp/pm_service/pm_api_sys.c#L357 The load is logged on the console during boot: U-Boot SPL 2018.01 (Mar 20 2019 - 08:12:21) Loading PMUFW cfg obj (2008 bytes) EL Level: EL3 ... Signed-off-by: Luca Ceresoli --- Changes RFC v1 -> RFC v2: - Load the cfg_obj in SPL, not U-Boot proper: this required a complete reimplementation since we cannot rely on ATF now - Update and refine the Kconfig option help Todo: - don't compile pm_cfg_obj.c from source, load it from a binary file --- board/xilinx/zynqmp/Kconfig | 26 ++++++++ board/xilinx/zynqmp/Makefile | 5 ++ board/xilinx/zynqmp/pmu_ipc.c | 116 ++++++++++++++++++++++++++++++++++ board/xilinx/zynqmp/pmu_ipc.h | 14 ++++ board/xilinx/zynqmp/zynqmp.c | 11 ++++ 5 files changed, 172 insertions(+) create mode 100644 board/xilinx/zynqmp/pmu_ipc.c create mode 100644 board/xilinx/zynqmp/pmu_ipc.h diff --git a/board/xilinx/zynqmp/Kconfig b/board/xilinx/zynqmp/Kconfig index 7d1f7398c3e9..4201e38571e7 100644 --- a/board/xilinx/zynqmp/Kconfig +++ b/board/xilinx/zynqmp/Kconfig @@ -15,4 +15,30 @@ config CMD_ZYNQMP and authentication feature enabled while generating BOOT.BIN using Xilinx bootgen tool. +config ZYNQMP_LOAD_PM_CFG_OBJ_FILE + string "PMU firmware configuration object to load at runtime" + help + Path to a PMU firmware configuration object to be built into + U-Boot and loaded at runtime by SPL into the PMU firmware. + + The ZynqMP Power Management Unit (PMU) needs a configuration + object for most SoC peripherals to work. It can be either + hard-coded in the PMUFW or passed at runtime. + + If the configuration object is not hard-coded in the PMU + firmware, U-Boot SPL can load it at runtime. To enable this + feature set here the file name (absolute path or relative to + board/xilinx/zynqmp/). It will be loaded into the PMU firmware by + U-Boot SPL during board initialization. + + Note: if your pm_cfg_obj.c is generated by the Xilinx tools, + you must remove any linking directives from the + XPm_ConfigObject declaration! E.g.: + + -const u32 XPm_ConfigObject[] __attribute__((used, section(".sys_cfg_data"))) = { + +const u32 XPm_ConfigObject[] = { + + Leave this option empty if your PMU firmware has a hard-coded + configuration object or you are loading it by any other means. + endif diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 80f8ca7e1e4b..0d8f52ecd631 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -33,6 +33,11 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif +ifneq ($(CONFIG_ZYNQMP_LOAD_PM_CFG_OBJ_FILE),"") +CFLAGS_zynqmp.o += -DZYNQMP_LOAD_PM_CFG_OBJ -I$(srctree)/$(src) +obj-$(CONFIG_SPL_BUILD) += pmu_ipc.o +endif + obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o ifndef CONFIG_SPL_BUILD diff --git a/board/xilinx/zynqmp/pmu_ipc.c b/board/xilinx/zynqmp/pmu_ipc.c new file mode 100644 index 000000000000..6306d33d6f17 --- /dev/null +++ b/board/xilinx/zynqmp/pmu_ipc.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Inter-Processor Communication with the Platform Management Unit (PMU) + * firmware. + * + * (C) Copyright 2019 Luca Ceresoli + * Luca Ceresoli + */ + +#include "pmu_ipc.h" +#include +#include + +/* IPI bitmasks, register base and register offsets */ +#define IPI_BIT_MASK_APU 0x00001 +#define IPI_BIT_MASK_PMU0 0x10000 +#define IPI_REG_BASE_APU 0xFF300000 +#define IPI_REG_BASE_PMU0 0xFF330000 +#define IPI_REG_OFFSET_TRIG 0x00 +#define IPI_REG_OFFSET_OBR 0x04 + +/* IPI mailbox buffer offsets */ +#define IPI_BUF_BASE_APU 0xFF990400 +#define IPI_BUF_OFFSET_TARGET_PMU 0x1C0 +#define IPI_BUF_OFFSET_REQ 0x00 +#define IPI_BUF_OFFSET_RESP 0x20 + +/* Xilinx FSBL sets 8, ATF sets 6. Which one is correct? */ +#define PMUFW_PAYLOAD_ARG_CNT 6 + +/* PMUFW commands */ +#define PMUFW_CMD_SET_CONFIGURATION 2 + +static void pmu_ipc_send_request(const u32 *req, size_t req_len) +{ + u32 *mbx = IPI_BUF_BASE_APU + + IPI_BUF_OFFSET_TARGET_PMU + + IPI_BUF_OFFSET_REQ; + size_t i; + + for (i = 0; i < req_len; i++) + writel(req[i], &mbx[i]); +} + +static void pmu_ipc_read_response(unsigned int *value, size_t count) +{ + u32 *mbx = IPI_BUF_BASE_APU + + IPI_BUF_OFFSET_TARGET_PMU + + IPI_BUF_OFFSET_RESP; + size_t i; + + for (i = 0; i < count; i++) + value[i] = readl(&mbx[i]); +} + +/** + * Send request to PMU and get the response. + * + * @req Request buffer. Byte 0 is the API ID, other bytes are optional + * parameters. + * @req_len Request length in number of 32-bit words. + * @res Response buffer. Byte 0 is the error code, other bytes are + * optional parameters. Optional, if @res_maxlen==0 the parameters + * will not be read. + * @res_maxlen Space allocated for the response in number of 32-bit words. + * + * @return Error code returned by the PMU (i.e. the first word of the response) + */ +static int pmu_ipc_request(const u32 *req, size_t req_len, + u32 *res, size_t res_maxlen) +{ + u32 status; + + if (req_len > PMUFW_PAYLOAD_ARG_CNT || + res_maxlen > PMUFW_PAYLOAD_ARG_CNT) + return -EINVAL; + + pmu_ipc_send_request(req, req_len); + + /* Raise Inter-Processor Interrupt to PMU and wait for response */ + writel(IPI_BIT_MASK_PMU0, IPI_REG_BASE_APU + IPI_REG_OFFSET_TRIG); + do { + status = readl(IPI_REG_BASE_APU + IPI_REG_OFFSET_OBR); + } while (status & IPI_BIT_MASK_PMU0); + + pmu_ipc_read_response(res, res_maxlen); + + return 0; +} + +/** + * Send a configuration object to the PMU firmware. + * + * @cfg_obj Pointer to the configuration object + * @size Size of @cfg_obj in bytes + */ +void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) +{ + const u32 *ocm = (u32 *)CONFIG_SPL_TEXT_BASE; + const u32 request[] = { + PMUFW_CMD_SET_CONFIGURATION, + CONFIG_SPL_TEXT_BASE + }; + u32 response; + int err; + + printf("Loading PMUFW cfg obj (%ld bytes)\n", size); + + memcpy(ocm, cfg_obj, size); + + err = pmu_ipc_request(request, ARRAY_SIZE(request), &response, 1); + if (err) + panic("Cannot load PMUFW configuration object (%d)\n", err); + if (response != 0) + panic("PMUFW returned 0x%08x status!\n", response); +} diff --git a/board/xilinx/zynqmp/pmu_ipc.h b/board/xilinx/zynqmp/pmu_ipc.h new file mode 100644 index 000000000000..37bb72c1b20a --- /dev/null +++ b/board/xilinx/zynqmp/pmu_ipc.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Luca Ceresoli + * Luca Ceresoli + */ + +#ifndef __ZYNQMP_PMU_IPC_H__ +#define __ZYNQMP_PMU_IPC_H__ + +#include + +void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size); + +#endif /* __ZYNQMP_PMU_IPC_H__ */ diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 5e1d2116bc32..1d5e25961863 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -4,6 +4,8 @@ * Michal Simek */ +#include "pmu_ipc.h" + #include #include #include @@ -302,6 +304,10 @@ static char *zynqmp_get_silicon_idcode_name(void) } #endif +#ifdef ZYNQMP_LOAD_PM_CFG_OBJ +#include CONFIG_ZYNQMP_LOAD_PM_CFG_OBJ_FILE +#endif + int board_early_init_f(void) { int ret = 0; @@ -332,6 +338,11 @@ int board_early_init_f(void) int board_init(void) { +#if defined(CONFIG_SPL_BUILD) && defined(ZYNQMP_LOAD_PM_CFG_OBJ) + zynqmp_pmufw_load_config_object(XPm_ConfigObject, + sizeof(XPm_ConfigObject)); +#endif + printf("EL Level:\tEL%d\n", current_el()); #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \