From patchwork Wed Aug 5 11:23:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 1341200 X-Patchwork-Delegate: trini@ti.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=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=rG12rP94; 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 RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BM8R93Jbcz9sR4 for ; Wed, 5 Aug 2020 21:24:37 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4ADF8820EE; Wed, 5 Aug 2020 13:24:13 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="rG12rP94"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id A4AFB82130; Wed, 5 Aug 2020 13:24:10 +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,DKIM_SIGNED, DKIM_VALID,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-ej1-x641.google.com (mail-ej1-x641.google.com [IPv6:2a00:1450:4864:20::641]) (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 20BA481BB4 for ; Wed, 5 Aug 2020 13:24:04 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: phobos.denx.de; spf=none smtp.mailfrom=monstr@monstr.eu Received: by mail-ej1-x641.google.com with SMTP id g19so32169004ejc.9 for ; Wed, 05 Aug 2020 04:24:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monstr-eu.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=E9recC5mVArdPAvSLuuYxzBPnWw5m9zWOW4wS+UtgV4=; b=rG12rP948JSeDhIFvroFZMQQ6ihORCrAiFvpIGGqJrVjqHNz14Qd1u0KWt3RD5rDHk bxhKkihruCL9zk5nEKZPE3mPPBeUBXbOTZqJ5CZEhnNyWFquYIU0k34giUi3W/GjaM2H 47BsfJ16HPFaejzeKmhy737qQoEB1GP2Bj/bK6PfvjoMn9wlpbX22hsTyjR13tRLdtVF xmOOP0Mm09d0trZMOfd3vq+0ty9MEj+avXOIv+LvUYGgzKHpXw3h1xQKC8VArK91Y179 7KkewfTRYe+Gh+yjZsDPmQ3dpPVNug5F3SCQ3qOak3vvuu6eHV5DqbGGjOeGS9GTldIS sUMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=E9recC5mVArdPAvSLuuYxzBPnWw5m9zWOW4wS+UtgV4=; b=YnVIINcMXakOtaRa+6E75QOV/hJZrkIMW0aIbmQFGr6H4er+IV5azaVSu34uHfGoP2 HKJ2t9JeR5+Etbmd3226gg/JFgEZQmj9JNs6G5wOWzwk5vQS2Y5oeoqciv2lmhH+xRGb opP+ufDlMADjIba0iwbiNZrplL3nFoF5KgrM/1/0IyYpvUwVz1hAa2qEU/3zTeIDl06D OXl0VlK37YyvttmKI2xsXiWGmw7mdTBicfT3+5P2yaKamnIFEod4qacqPwHIPSmdKjah gMwjagL3XhqwgTD/qpp0meFLFp17bDQo3D2DSrLpLRMPmcKGZVrVkmCHy4hKB7mGtwHG Z3AQ== X-Gm-Message-State: AOAM531pwTqK47eCzc+cSIbimIrK/iL/5Qe9ij/WrCiM0Q2uFQKxJQlF EQYD3V9N5D8BCT1gXXkDX67PN71PdK91HA== X-Google-Smtp-Source: ABdhPJy/NokeHjJrsYdYEe/D54QL+m/LeNJ2m4AYhikB0mtdamHoJq/KuCY6+FxXFKQSK7gSy8fSrQ== X-Received: by 2002:a17:906:fb07:: with SMTP id lz7mr2646904ejb.49.1596626643530; Wed, 05 Aug 2020 04:24:03 -0700 (PDT) Received: from localhost (nat-35.starnet.cz. [178.255.168.35]) by smtp.gmail.com with ESMTPSA id t3sm997717eje.82.2020.08.05.04.24.02 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 05 Aug 2020 04:24:03 -0700 (PDT) From: Michal Simek To: u-boot@lists.denx.de, git@xilinx.com Cc: Ibai Erkiaga , Luca Ceresoli , Michal Simek , Rajan Vaja , Simon Glass , Siva Durga Prasad Paladugu Subject: [PATCH 2/8] xilinx: zynqmp: merge firmware calls for EL2 and EL3 Date: Wed, 5 Aug 2020 13:23:49 +0200 Message-Id: X-Mailer: git-send-email 2.27.0 In-Reply-To: References: 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.102.3 at phobos.denx.de X-Virus-Status: Clean From: Ibai Erkiaga This patch merges ZynqMP firmware calls under xilinx_pm_request in order to make trainsparent the EL. Calls at EL3 are send through IPI messages and EL2 through SMC calls. The EL2 call uses fixed payload and arg size as the EL3 call. The firmware is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the firmware API is limited by the SMC call size. Signed-off-by: Ibai Erkiaga Signed-off-by: Michal Simek --- drivers/firmware/firmware-zynqmp.c | 84 +++++++++++++++--------------- 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 66edc1693016..41394d487ad5 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -37,6 +37,7 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen) if (!(zynqmp_power.tx_chan.dev) || !(&zynqmp_power.rx_chan.dev)) return -EINVAL; + debug("%s, Sending IPI message with ID: 0x%0x\n", __func__, req[0]); msg.buf = (u32 *)req; msg.len = req_len; ret = mbox_send(&zynqmp_power.tx_chan, &msg); @@ -54,14 +55,6 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen) return ret; } -static int send_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen) -{ - if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) - return ipi_req(req, req_len, res, res_maxlen); - - return xilinx_pm_request(req[0], 0, 0, 0, 0, res); -} - unsigned int zynqmp_firmware_version(void) { int ret; @@ -74,9 +67,9 @@ unsigned int zynqmp_firmware_version(void) * asking PMUFW again. **/ if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) { - const u32 request[] = { PM_GET_API_VERSION }; - ret = send_req(request, ARRAY_SIZE(request), ret_payload, 2); + ret = xilinx_pm_request(PM_GET_API_VERSION, 0, 0, 0, 0, + ret_payload); if (ret) panic("PMUFW is not found - Please load it!\n"); @@ -97,16 +90,13 @@ unsigned int zynqmp_firmware_version(void) */ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) { - const u32 request[] = { - PM_SET_CONFIGURATION, - (u32)((u64)cfg_obj) - }; - u32 response = 0; int err; + u32 ret_payload[PAYLOAD_ARG_CNT]; printf("Loading new PMUFW cfg obj (%ld bytes)\n", size); - err = send_req(request, ARRAY_SIZE(request), &response, 1); + err = xilinx_pm_request(PM_SET_CONFIGURATION, (u32)(u64)cfg_obj, 0, 0, + 0, ret_payload); if (err == XST_PM_NO_ACCESS) { printf("PMUFW no permission to change config object\n"); return; @@ -115,10 +105,10 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) if (err) printf("Cannot load PMUFW configuration object (%d)\n", err); - if (response) - printf("PMUFW returned 0x%08x status!\n", response); + if (ret_payload[0]) + printf("PMUFW returned 0x%08x status!\n", ret_payload[0]); - if ((err || response) && IS_ENABLED(CONFIG_SPL_BUILD)) + if ((err || ret_payload[0]) && IS_ENABLED(CONFIG_SPL_BUILD)) panic("PMUFW config object loading failed in EL3\n"); } @@ -164,32 +154,40 @@ U_BOOT_DRIVER(zynqmp_power) = { int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 *ret_payload) { - /* - * Added SIP service call Function Identifier - * Make sure to stay in x0 register - */ - struct pt_regs regs; - - if (current_el() == 3) { - printf("%s: Can't call SMC from EL3 context\n", __func__); - return -EPERM; - } - - regs.regs[0] = PM_SIP_SVC | api_id; - regs.regs[1] = ((u64)arg1 << 32) | arg0; - regs.regs[2] = ((u64)arg3 << 32) | arg2; + debug("%s at EL%d, API ID: 0x%0x\n", __func__, current_el(), api_id); + + if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) { + /* + * Use fixed payload and arg size as the EL2 call. The firmware + * is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the + * firmware API is limited by the SMC call size + */ + u32 regs[] = {api_id, arg0, arg1, arg2, arg3}; + + ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT); + } else { + /* + * Added SIP service call Function Identifier + * Make sure to stay in x0 register + */ + struct pt_regs regs; + + regs.regs[0] = PM_SIP_SVC | api_id; + regs.regs[1] = ((u64)arg1 << 32) | arg0; + regs.regs[2] = ((u64)arg3 << 32) | arg2; + + smc_call(®s); + + if (ret_payload) { + ret_payload[0] = (u32)regs.regs[0]; + ret_payload[1] = upper_32_bits(regs.regs[0]); + ret_payload[2] = (u32)regs.regs[1]; + ret_payload[3] = upper_32_bits(regs.regs[1]); + ret_payload[4] = (u32)regs.regs[2]; + } - smc_call(®s); - - if (ret_payload) { - ret_payload[0] = (u32)regs.regs[0]; - ret_payload[1] = upper_32_bits(regs.regs[0]); - ret_payload[2] = (u32)regs.regs[1]; - ret_payload[3] = upper_32_bits(regs.regs[1]); - ret_payload[4] = (u32)regs.regs[2]; } - - return regs.regs[0]; + return (ret_payload) ? ret_payload[0] : 0; } static const struct udevice_id zynqmp_firmware_ids[] = {