From patchwork Thu Dec 12 18:51:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289195 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F40941593 for ; Thu, 12 Dec 2019 18:52:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C08152253D for ; Thu, 12 Dec 2019 18:52:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="B4vgbGvZ"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="NcEFEIZj" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730591AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 Received: from a27-56.smtp-out.us-west-2.amazonses.com ([54.240.27.56]:37124 "EHLO a27-56.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730485AbfLLSvJ (ORCPT ); Thu, 12 Dec 2019 13:51:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176668; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=3O+wXC7g249LCZBdLWpVNcA7JpQ8PQ2bILr41dWjDV4=; b=B4vgbGvZkQoFFoQeUWSQXnEL6Ir/eKvtVqUgpmlV25FS13vEtre+vqaEIvXivPfD h6SvKkAIOhwPJXfopWE+Qr41zdbFKcMVawGP9PR5TvCRSh5RaGjsEW2/NdZvh/fMdRQ RiTGym7cSYox2910P7/Im3a1wAH+d2tEvzWB9YOk= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176668; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=3O+wXC7g249LCZBdLWpVNcA7JpQ8PQ2bILr41dWjDV4=; b=NcEFEIZjhVkhZ3bGuS5T8KwXeouvpmWTGg0fhPGZePT6UWxGbrM4hAu7M3zkW2PK zLyFIVFpOPh2OIZwZqyFZ8uQgdWaEuHvqtMfqCGEmZ2TNnLfHxk5C6wEvkI4Sl48JCQ dZ9IKA+aMTkVcpHO4n/mwncAaWWJmpCY4/MZn1z8= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 27D98C4479C Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 01/17] firmware: qcom_scm: Rename macros and structures Date: Thu, 12 Dec 2019 18:51:08 +0000 Message-ID: <0101016efb734d53-a54ea4d2-b680-4248-a0f7-d85c22bcd49e-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.56 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Rename legacy-specific structures and macros with legacy prefix; rename smc-specific structures and macros with smc prefix. This should make it clearer which structures are generic to "SCM" and which are specfically for implementing the convention. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 71 ++++++++++++++++++++++-------------------- drivers/firmware/qcom_scm-64.c | 53 +++++++++++++++---------------- 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 48e2ef7..2542c42 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2010,2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. */ @@ -39,30 +39,30 @@ static struct qcom_scm_entry qcom_scm_wb[] = { static DEFINE_MUTEX(qcom_scm_lock); /** - * struct qcom_scm_command - one SCM command buffer + * struct scm_legacy_command - one SCM command buffer * @len: total available memory for command and response * @buf_offset: start of command buffer * @resp_hdr_offset: start of response buffer * @id: command to be executed - * @buf: buffer returned from qcom_scm_get_command_buffer() + * @buf: buffer returned from scm_legacy_get_command_buffer() * * An SCM command is laid out in memory as follows: * - * ------------------- <--- struct qcom_scm_command + * ------------------- <--- struct scm_legacy_command * | command header | - * ------------------- <--- qcom_scm_get_command_buffer() + * ------------------- <--- scm_legacy_get_command_buffer() * | command buffer | - * ------------------- <--- struct qcom_scm_response and - * | response header | qcom_scm_command_to_response() - * ------------------- <--- qcom_scm_get_response_buffer() + * ------------------- <--- struct scm_legacy_response and + * | response header | scm_legacy_command_to_response() + * ------------------- <--- scm_legacy_get_response_buffer() * | response buffer | * ------------------- * * There can be arbitrary padding between the headers and buffers so - * you should always use the appropriate qcom_scm_get_*_buffer() routines + * you should always use the appropriate scm_legacy_get_*_buffer() routines * to access the buffers in a safe manner. */ -struct qcom_scm_command { +struct scm_legacy_command { __le32 len; __le32 buf_offset; __le32 resp_hdr_offset; @@ -71,52 +71,54 @@ struct qcom_scm_command { }; /** - * struct qcom_scm_response - one SCM response buffer + * struct scm_legacy_response - one SCM response buffer * @len: total available memory for response - * @buf_offset: start of response data relative to start of qcom_scm_response + * @buf_offset: start of response data relative to start of scm_legacy_response * @is_complete: indicates if the command has finished processing */ -struct qcom_scm_response { +struct scm_legacy_response { __le32 len; __le32 buf_offset; __le32 is_complete; }; /** - * qcom_scm_command_to_response() - Get a pointer to a qcom_scm_response + * scm_legacy_command_to_response() - Get a pointer to a scm_legacy_response * @cmd: command * * Returns a pointer to a response for a command. */ -static inline struct qcom_scm_response *qcom_scm_command_to_response( - const struct qcom_scm_command *cmd) +static inline struct scm_legacy_response *scm_legacy_command_to_response( + const struct scm_legacy_command *cmd) { return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset); } /** - * qcom_scm_get_command_buffer() - Get a pointer to a command buffer + * scm_legacy_get_command_buffer() - Get a pointer to a command buffer * @cmd: command * * Returns a pointer to the command buffer of a command. */ -static inline void *qcom_scm_get_command_buffer(const struct qcom_scm_command *cmd) +static inline void *scm_legacy_get_command_buffer( + const struct scm_legacy_command *cmd) { return (void *)cmd->buf; } /** - * qcom_scm_get_response_buffer() - Get a pointer to a response buffer + * scm_legacy_get_response_buffer() - Get a pointer to a response buffer * @rsp: response * * Returns a pointer to a response buffer of a response. */ -static inline void *qcom_scm_get_response_buffer(const struct qcom_scm_response *rsp) +static inline void *scm_legacy_get_response_buffer( + const struct scm_legacy_response *rsp) { return (void *)rsp + le32_to_cpu(rsp->buf_offset); } -static u32 smc(u32 cmd_addr) +static u32 __scm_legacy_do(u32 cmd_addr) { int context_id; register u32 r0 asm("r0") = 1; @@ -164,8 +166,8 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, size_t resp_len) { int ret; - struct qcom_scm_command *cmd; - struct qcom_scm_response *rsp; + struct scm_legacy_command *cmd; + struct scm_legacy_response *rsp; size_t alloc_len = sizeof(*cmd) + cmd_len + sizeof(*rsp) + resp_len; dma_addr_t cmd_phys; @@ -179,9 +181,9 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, cmd->id = cpu_to_le32((svc_id << 10) | cmd_id); if (cmd_buf) - memcpy(qcom_scm_get_command_buffer(cmd), cmd_buf, cmd_len); + memcpy(scm_legacy_get_command_buffer(cmd), cmd_buf, cmd_len); - rsp = qcom_scm_command_to_response(cmd); + rsp = scm_legacy_command_to_response(cmd); cmd_phys = dma_map_single(dev, cmd, alloc_len, DMA_TO_DEVICE); if (dma_mapping_error(dev, cmd_phys)) { @@ -190,7 +192,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, } mutex_lock(&qcom_scm_lock); - ret = smc(cmd_phys); + ret = __scm_legacy_do(cmd_phys); if (ret < 0) ret = qcom_scm_remap_error(ret); mutex_unlock(&qcom_scm_lock); @@ -206,7 +208,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len + le32_to_cpu(rsp->buf_offset), resp_len, DMA_FROM_DEVICE); - memcpy(resp_buf, qcom_scm_get_response_buffer(rsp), + memcpy(resp_buf, scm_legacy_get_response_buffer(rsp), resp_len); } out: @@ -215,11 +217,12 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, return ret; } -#define SCM_CLASS_REGISTER (0x2 << 8) -#define SCM_MASK_IRQS BIT(5) -#define SCM_ATOMIC(svc, cmd, n) (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \ - SCM_CLASS_REGISTER | \ - SCM_MASK_IRQS | \ +#define SCM_LEGACY_CLASS_REGISTER (0x2 << 8) +#define SCM_LEGACY_MASK_IRQS BIT(5) +#define SCM_LEGACY_ATOMIC_ID(svc, cmd, n) \ + (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \ + SCM_LEGACY_CLASS_REGISTER | \ + SCM_LEGACY_MASK_IRQS | \ (n & 0xf)) /** @@ -235,7 +238,7 @@ static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1) { int context_id; - register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1); + register u32 r0 asm("r0") = SCM_LEGACY_ATOMIC_ID(svc, cmd, 1); register u32 r1 asm("r1") = (u32)&context_id; register u32 r2 asm("r2") = arg1; @@ -268,7 +271,7 @@ static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2) { int context_id; - register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 2); + register u32 r0 asm("r0") = SCM_LEGACY_ATOMIC_ID(svc, cmd, 2); register u32 r1 asm("r1") = (u32)&context_id; register u32 r2 asm("r2") = arg1; register u32 r3 asm("r3") = arg2; diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 3c58503..9c7ea74 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved. */ #include @@ -14,7 +14,7 @@ #include "qcom_scm.h" -#define QCOM_SCM_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) +#define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) #define MAX_QCOM_SCM_ARGS 10 #define MAX_QCOM_SCM_RETS 3 @@ -58,11 +58,11 @@ static DEFINE_MUTEX(qcom_scm_lock); #define QCOM_SCM_EBUSY_WAIT_MS 30 #define QCOM_SCM_EBUSY_MAX_RETRY 20 -#define N_EXT_QCOM_SCM_ARGS 7 -#define FIRST_EXT_ARG_IDX 3 -#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1) +#define SCM_SMC_N_EXT_ARGS 7 +#define SCM_SMC_FIRST_EXT_IDX 3 +#define SCM_SMC_N_REG_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_EXT_ARGS + 1) -static void __qcom_scm_call_do(const struct qcom_scm_desc *desc, +static void __scm_smc_do_quirk(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, u64 x5, u32 type) { @@ -85,22 +85,23 @@ static void __qcom_scm_call_do(const struct qcom_scm_desc *desc, } while (res->a0 == QCOM_SCM_INTERRUPTED); } -static void qcom_scm_call_do(const struct qcom_scm_desc *desc, +static void __scm_smc_do(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, u64 x5, bool atomic) { int retry_count = 0; if (atomic) { - __qcom_scm_call_do(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL); + __scm_smc_do_quirk(desc, res, fn_id, x5, + ARM_SMCCC_FAST_CALL); return; } do { mutex_lock(&qcom_scm_lock); - __qcom_scm_call_do(desc, res, fn_id, x5, - ARM_SMCCC_STD_CALL); + __scm_smc_do_quirk(desc, res, fn_id, x5, + ARM_SMCCC_STD_CALL); mutex_unlock(&qcom_scm_lock); @@ -112,21 +113,21 @@ static void qcom_scm_call_do(const struct qcom_scm_desc *desc, } while (res->a0 == QCOM_SCM_V2_EBUSY); } -static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, - const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, bool atomic) +static int __scm_smc_call(struct device *dev, u32 svc_id, u32 cmd_id, + const struct qcom_scm_desc *desc, + struct arm_smccc_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; int i; - u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id); - u64 x5 = desc->args[FIRST_EXT_ARG_IDX]; + u32 fn_id = SCM_SMC_FNID(svc_id, cmd_id); + u64 x5 = desc->args[SCM_SMC_FIRST_EXT_IDX]; dma_addr_t args_phys = 0; void *args_virt = NULL; size_t alloc_len; gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL; - if (unlikely(arglen > N_REGISTER_ARGS)) { - alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64); + if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) { + alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64); args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag); if (!args_virt) @@ -135,15 +136,15 @@ static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, if (qcom_smccc_convention == ARM_SMCCC_SMC_32) { __le32 *args = args_virt; - for (i = 0; i < N_EXT_QCOM_SCM_ARGS; i++) + for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++) args[i] = cpu_to_le32(desc->args[i + - FIRST_EXT_ARG_IDX]); + SCM_SMC_FIRST_EXT_IDX]); } else { __le64 *args = args_virt; - for (i = 0; i < N_EXT_QCOM_SCM_ARGS; i++) + for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++) args[i] = cpu_to_le64(desc->args[i + - FIRST_EXT_ARG_IDX]); + SCM_SMC_FIRST_EXT_IDX]); } args_phys = dma_map_single(dev, args_virt, alloc_len, @@ -157,7 +158,7 @@ static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, x5 = args_phys; } - qcom_scm_call_do(desc, res, fn_id, x5, atomic); + __scm_smc_do(desc, res, fn_id, x5, atomic); if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); @@ -185,7 +186,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, struct arm_smccc_res *res) { might_sleep(); - return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, false); + return __scm_smc_call(dev, svc_id, cmd_id, desc, res, false); } /** @@ -203,7 +204,7 @@ static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { - return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, true); + return __scm_smc_call(dev, svc_id, cmd_id, desc, res, true); } /** @@ -253,7 +254,7 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) struct arm_smccc_res res; desc.arginfo = QCOM_SCM_ARGS(1); - desc.args[0] = QCOM_SCM_FNID(svc_id, cmd_id) | + desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) | (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, @@ -307,7 +308,7 @@ void __qcom_scm_init(void) { u64 cmd; struct arm_smccc_res res; - u32 function = QCOM_SCM_FNID(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD); + u32 function = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD); /* First try a SMC64 call */ cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, From patchwork Thu Dec 12 18:51:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289187 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9A53C14DB for ; Thu, 12 Dec 2019 18:52:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5B9AD24654 for ; Thu, 12 Dec 2019 18:52:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="K6/GlVOZ"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="BS1CzeTZ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730600AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 Received: from a27-186.smtp-out.us-west-2.amazonses.com ([54.240.27.186]:35740 "EHLO a27-186.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730516AbfLLSvK (ORCPT ); Thu, 12 Dec 2019 13:51:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176669; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=dJVSwMz2Vy2i2F+MMDTEB/Ea61CQO1altGX/sXH9PaU=; b=K6/GlVOZ4cTosL9Hepisjghj5nlnvbBCeA3F3Tp73EUCteMLC0DGQ3mv30hK1Xsa 5lFXp5UghCih3gfPiUbzBY5C7tFCmezU9OUHMHOS9bAkVr4ych/rXzI+4jdOTX1et+Y vkROFFLJMuDFbRkEpk8uWYMJyn95YMvyx4geNxog= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176669; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=dJVSwMz2Vy2i2F+MMDTEB/Ea61CQO1altGX/sXH9PaU=; b=BS1CzeTZvk/Hlt9ewf531uiZutwyCPKfOI805BtJgkFXxcRAB1lrStnAv97Qq+xe fDkR+v0cxgOOMg4r63iriDFJSjyp6CGrIQD16Tg4i0fHiRmalHZwwtpSrFfxyIrBZqw ow+UUqjEr3KIuVYALPwqvgnVdNzbilEumINu9c0k= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org B50CDC447A0 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 02/17] firmware: qcom_scm: Apply consistent naming scheme to command IDs Date: Thu, 12 Dec 2019 18:51:09 +0000 Message-ID: <0101016efb735383-0a633dce-99e6-41e9-a7f0-548d2f20d985-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.186 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Create a consistent naming scheme for command IDs. The scheme is QCOM_SCM_##svc_##cmd. Remove unused macros QCOM_SCM_FLAG_HLOS, QCOM_SCM_FLAG_COLDBOOT_MC, QCOM_SCM_FLAG_WARMBOOT_MC, QCOM_SCM_CMD_CORE_HOTPLUGGED, and QCOM_SCM_BOOT_ADDR_MC. Reviewed-by: Bjorn Andersson Reviewed-by: Vinod Koul Reviewed-by: Stephen Boyd Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 34 +++++++++++++++---------------- drivers/firmware/qcom_scm-64.c | 40 ++++++++++++++++++------------------- drivers/firmware/qcom_scm.c | 17 +++++++--------- drivers/firmware/qcom_scm.h | 45 +++++++++++++++++++----------------------- 4 files changed, 64 insertions(+), 72 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 2542c42..6e62f73 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -357,7 +357,7 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) set_cpu_present(cpu, false); } - return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR, + return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_ADDR, flags, virt_to_phys(entry)); } @@ -396,7 +396,7 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, cmd.addr = cpu_to_le32(virt_to_phys(entry)); cmd.flags = cpu_to_le32(flags); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_ADDR, &cmd, sizeof(cmd), NULL, 0); if (!ret) { for_each_cpu(cpu, cpus) @@ -416,7 +416,7 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, */ void __qcom_scm_cpu_power_down(u32 flags) { - qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC, + qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_TERMINATE_PC, flags & QCOM_SCM_FLUSH_FLAG_MASK); } @@ -426,7 +426,7 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id); __le32 ret_val = 0; - ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, &svc_cmd, sizeof(svc_cmd), &ret_val, sizeof(ret_val)); if (ret) @@ -441,7 +441,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) return -ERANGE; - return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP, + return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_HDCP_INVOKE, req, req_cnt * sizeof(*req), resp, sizeof(*resp)); } @@ -460,7 +460,7 @@ int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, request.size = cpu_to_le32(size); request.mode = cpu_to_le32(mode); - return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, + return qcom_scm_call(dev, QCOM_SCM_SVC_OCMEM, QCOM_SCM_OCMEM_LOCK_CMD, &request, sizeof(request), NULL, 0); } @@ -476,7 +476,7 @@ int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) request.offset = cpu_to_le32(offset); request.size = cpu_to_le32(size); - return qcom_scm_call(dev, QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, + return qcom_scm_call(dev, QCOM_SCM_SVC_OCMEM, QCOM_SCM_OCMEM_UNLOCK_CMD, &request, sizeof(request), NULL, 0); } @@ -492,7 +492,7 @@ bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) in = cpu_to_le32(peripheral); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_IS_SUPPORTED_CMD, + QCOM_SCM_PIL_PAS_IS_SUPPORTED, &in, sizeof(in), &out, sizeof(out)); @@ -513,7 +513,7 @@ int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, request.image_addr = cpu_to_le32(metadata_phys); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_INIT_IMAGE_CMD, + QCOM_SCM_PIL_PAS_INIT_IMAGE, &request, sizeof(request), &scm_ret, sizeof(scm_ret)); @@ -536,7 +536,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, request.len = cpu_to_le32(size); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_MEM_SETUP_CMD, + QCOM_SCM_PIL_PAS_MEM_SETUP, &request, sizeof(request), &scm_ret, sizeof(scm_ret)); @@ -551,7 +551,7 @@ int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) in = cpu_to_le32(peripheral); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_AUTH_AND_RESET_CMD, + QCOM_SCM_PIL_PAS_AUTH_AND_RESET, &in, sizeof(in), &out, sizeof(out)); @@ -566,7 +566,7 @@ int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) in = cpu_to_le32(peripheral); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_SHUTDOWN_CMD, + QCOM_SCM_PIL_PAS_SHUTDOWN, &in, sizeof(in), &out, sizeof(out)); @@ -579,7 +579,7 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) __le32 in = cpu_to_le32(reset); int ret; - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MSS_RESET, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MSS_RESET, &in, sizeof(in), &out, sizeof(out)); @@ -588,8 +588,8 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { - return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_DLOAD_MODE, - enable ? QCOM_SCM_SET_DLOAD_MODE : 0, 0); + return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, + enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0, 0); } int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) @@ -604,7 +604,7 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) req.state = cpu_to_le32(state); req.id = cpu_to_le32(id); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_REMOTE_STATE, &req, sizeof(req), &scm_ret, sizeof(scm_ret)); return ret ? : le32_to_cpu(scm_ret); @@ -629,7 +629,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, cfg.id = cpu_to_le32(device_id); cfg.ctx_bank_num = cpu_to_le32(spare); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_RESTORE_SEC_CFG, &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); if (ret || scm_ret) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 9c7ea74..976c2b9 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -257,7 +257,7 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) | (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, &desc, &res); return ret ? : res.a1; @@ -285,7 +285,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, desc.args[9] = req[4].val; desc.arginfo = QCOM_SCM_ARGS(10); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP, &desc, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_HDCP_INVOKE, &desc, &res); *resp = res.a1; @@ -308,11 +308,11 @@ void __qcom_scm_init(void) { u64 cmd; struct arm_smccc_res res; - u32 function = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD); + u32 fnid = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL); /* First try a SMC64 call */ cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, - ARM_SMCCC_OWNER_SIP, function); + ARM_SMCCC_OWNER_SIP, fnid); arm_smccc_smc(cmd, QCOM_SCM_ARGS(1), cmd & (~BIT(ARM_SMCCC_TYPE_SHIFT)), 0, 0, 0, 0, 0, &res); @@ -333,7 +333,7 @@ bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_IS_SUPPORTED_CMD, + QCOM_SCM_PIL_PAS_IS_SUPPORTED, &desc, &res); return ret ? false : !!res.a1; @@ -350,7 +350,7 @@ int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, desc.args[1] = metadata_phys; desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_INIT_IMAGE, &desc, &res); return ret ? : res.a1; @@ -368,7 +368,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, desc.args[2] = size; desc.arginfo = QCOM_SCM_ARGS(3); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MEM_SETUP, &desc, &res); return ret ? : res.a1; @@ -384,7 +384,7 @@ int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_AUTH_AND_RESET_CMD, + QCOM_SCM_PIL_PAS_AUTH_AND_RESET, &desc, &res); return ret ? : res.a1; @@ -399,7 +399,7 @@ int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_SHUTDOWN, &desc, &res); return ret ? : res.a1; @@ -415,7 +415,7 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) desc.args[1] = 0; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MSS_RESET, &desc, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MSS_RESET, &desc, &res); return ret ? : res.a1; @@ -431,7 +431,7 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) desc.args[1] = id; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_REMOTE_STATE, &desc, &res); return ret ? : res.a1; @@ -458,7 +458,7 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, QCOM_SCM_VAL, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, - QCOM_MEM_PROT_ASSIGN_ID, + QCOM_SCM_MP_ASSIGN, &desc, &res); return ret ? : res.a1; @@ -474,7 +474,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) desc.args[1] = spare; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_RESTORE_SEC_CFG, &desc, &res); return ret ? : res.a1; @@ -491,7 +491,7 @@ int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, - QCOM_SCM_IOMMU_SECURE_PTBL_SIZE, &desc, &res); + QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, &desc, &res); if (size) *size = res.a1; @@ -513,7 +513,7 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, QCOM_SCM_VAL); ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, - QCOM_SCM_IOMMU_SECURE_PTBL_INIT, &desc, &res); + QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, &desc, &res); /* the pg table has been initialized already, ignore the error */ if (ret == -EPERM) @@ -527,11 +527,11 @@ int __qcom_scm_set_dload_mode(struct device *dev, bool enable) struct qcom_scm_desc desc = {0}; struct arm_smccc_res res; - desc.args[0] = QCOM_SCM_SET_DLOAD_MODE; - desc.args[1] = enable ? QCOM_SCM_SET_DLOAD_MODE : 0; + desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; + desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_DLOAD_MODE, + return qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, &desc, &res); } @@ -571,10 +571,10 @@ int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) struct qcom_scm_desc desc = {0}; struct arm_smccc_res res; - desc.args[0] = QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL; + desc.args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL; desc.args[1] = en; desc.arginfo = QCOM_SCM_ARGS(2); return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM, - QCOM_SCM_CONFIG_ERRATA1, &desc, &res); + QCOM_SCM_SMMU_CONFIG_ERRATA1, &desc, &res); } diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 1ba0df4..097f8b3 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -1,8 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* - * Qualcomm SCM driver - * - * Copyright (c) 2010,2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. */ #include @@ -142,7 +139,7 @@ bool qcom_scm_hdcp_available(void) return ret; ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP, - QCOM_SCM_CMD_HDCP); + QCOM_SCM_HDCP_INVOKE); qcom_scm_clk_disable(); @@ -183,7 +180,7 @@ bool qcom_scm_pas_supported(u32 peripheral) int ret; ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PAS_IS_SUPPORTED_CMD); + QCOM_SCM_PIL_PAS_IS_SUPPORTED); if (ret <= 0) return false; @@ -196,7 +193,7 @@ EXPORT_SYMBOL(qcom_scm_pas_supported); */ bool qcom_scm_ocmem_lock_available(void) { - return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC, + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_OCMEM, QCOM_SCM_OCMEM_LOCK_CMD); } EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); @@ -376,7 +373,7 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { bool qcom_scm_restore_sec_cfg_available(void) { return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, - QCOM_SCM_RESTORE_SEC_CFG); + QCOM_SCM_MP_RESTORE_SEC_CFG); } EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); @@ -423,12 +420,12 @@ static void qcom_scm_set_download_mode(bool enable) avail = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, - QCOM_SCM_SET_DLOAD_MODE); + QCOM_SCM_BOOT_SET_DLOAD_MODE); if (avail) { ret = __qcom_scm_set_dload_mode(__scm->dev, enable); } else if (__scm->dload_mode_addr) { ret = __qcom_scm_io_writel(__scm->dev, __scm->dload_mode_addr, - enable ? QCOM_SCM_SET_DLOAD_MODE : 0); + enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); } else { dev_err(__scm->dev, "No available mechanism for setting download mode\n"); diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 81dcf5f..afcca16 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -1,27 +1,22 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2015,2019 The Linux Foundation. All rights reserved. */ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H #define QCOM_SCM_SVC_BOOT 0x1 -#define QCOM_SCM_BOOT_ADDR 0x1 -#define QCOM_SCM_SET_DLOAD_MODE 0x10 -#define QCOM_SCM_BOOT_ADDR_MC 0x11 -#define QCOM_SCM_SET_REMOTE_STATE 0xa +#define QCOM_SCM_BOOT_SET_ADDR 0x1 +#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 +#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0xa extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); -#define QCOM_SCM_FLAG_HLOS 0x01 -#define QCOM_SCM_FLAG_COLDBOOT_MC 0x02 -#define QCOM_SCM_FLAG_WARMBOOT_MC 0x04 extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); -#define QCOM_SCM_CMD_TERMINATE_PC 0x2 +#define QCOM_SCM_BOOT_TERMINATE_PC 0x2 #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 -#define QCOM_SCM_CMD_CORE_HOTPLUGGED 0x10 extern void __qcom_scm_cpu_power_down(u32 flags); #define QCOM_SCM_SVC_IO 0x5 @@ -31,18 +26,18 @@ extern int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned in extern int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val); #define QCOM_SCM_SVC_INFO 0x6 -#define QCOM_IS_CALL_AVAIL_CMD 0x1 +#define QCOM_SCM_INFO_IS_CALL_AVAIL 0x1 extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id); #define QCOM_SCM_SVC_HDCP 0x11 -#define QCOM_SCM_CMD_HDCP 0x01 +#define QCOM_SCM_HDCP_INVOKE 0x01 extern int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); extern void __qcom_scm_init(void); -#define QCOM_SCM_OCMEM_SVC 0xf +#define QCOM_SCM_SVC_OCMEM 0xf #define QCOM_SCM_OCMEM_LOCK_CMD 0x1 #define QCOM_SCM_OCMEM_UNLOCK_CMD 0x2 @@ -52,12 +47,12 @@ extern int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size); #define QCOM_SCM_SVC_PIL 0x2 -#define QCOM_SCM_PAS_INIT_IMAGE_CMD 0x1 -#define QCOM_SCM_PAS_MEM_SETUP_CMD 0x2 -#define QCOM_SCM_PAS_AUTH_AND_RESET_CMD 0x5 -#define QCOM_SCM_PAS_SHUTDOWN_CMD 0x6 -#define QCOM_SCM_PAS_IS_SUPPORTED_CMD 0x7 -#define QCOM_SCM_PAS_MSS_RESET 0xa +#define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x1 +#define QCOM_SCM_PIL_PAS_MEM_SETUP 0x2 +#define QCOM_SCM_PIL_PAS_AUTH_AND_RESET 0x5 +#define QCOM_SCM_PIL_PAS_SHUTDOWN 0x6 +#define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x7 +#define QCOM_SCM_PIL_PAS_MSS_RESET 0xa extern bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral); extern int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, dma_addr_t metadata_phys); @@ -95,21 +90,21 @@ static inline int qcom_scm_remap_error(int err) } #define QCOM_SCM_SVC_MP 0xc -#define QCOM_SCM_RESTORE_SEC_CFG 2 +#define QCOM_SCM_MP_RESTORE_SEC_CFG 2 extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare); -#define QCOM_SCM_IOMMU_SECURE_PTBL_SIZE 3 -#define QCOM_SCM_IOMMU_SECURE_PTBL_INIT 4 +#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 3 +#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 4 #define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 -#define QCOM_SCM_CONFIG_ERRATA1 0x3 -#define QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL 0x2 +#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x3 +#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x2 extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, size_t *size); extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare); extern int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable); -#define QCOM_MEM_PROT_ASSIGN_ID 0x16 +#define QCOM_SCM_MP_ASSIGN 0x16 extern int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, From patchwork Thu Dec 12 18:51:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289165 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BB57C109A for ; Thu, 12 Dec 2019 18:51:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 970A0206C3 for ; Thu, 12 Dec 2019 18:51:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="bi61r69f"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="B2aOfVNy" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730556AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 Received: from a27-186.smtp-out.us-west-2.amazonses.com ([54.240.27.186]:35742 "EHLO a27-186.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730532AbfLLSvK (ORCPT ); Thu, 12 Dec 2019 13:51:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176670; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=AXrIkffOoSweX+hzBomhDUPMjvV7peO7xejAL21ZX+I=; b=bi61r69fLs8QHs3K++GP0HGU2/YjBpQi9URyAZMwaYY9ZZClT6m2kRniIynwdXhS K6fXuf9nIBruDAe8fFxNJCofLK3+raHexGZd+mnBBSLvIBavQcu0YhhUoxLPVZk4HdI iHkaedAyIedVfHlcv/P3I+Oxg9NozfVapY7nmEqo= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176670; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=AXrIkffOoSweX+hzBomhDUPMjvV7peO7xejAL21ZX+I=; b=B2aOfVNyA9X8IbACcyccSdW3FEgklx/6XQJ5GPJPaKItAyAZ6ciOUxavJW0hpFy2 AO23H7P7tTJwXx7TrkJUMNVmx5VY/jOkRVAn8SGEeNdkVAMKpQvesI/Bs7YZPJ7Y9pi Rr42rUlh9cvMSDksE0girOTDuv+Bw+2eZE0Grjz0= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 6639FC447A1 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 03/17] firmware: qcom_scm: Remove unused qcom_scm_get_version Date: Thu, 12 Dec 2019 18:51:10 +0000 Message-ID: <0101016efb73556c-e2c248e5-7d93-4eb8-8f44-f8cad10af521-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.186 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Remove unused qcom_scm_get_version. Reviewed-by: Bjorn Andersson Reviewed-by: Vinod Koul Reviewed-by: Stephen Boyd Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 36 ------------------------------------ include/linux/qcom_scm.h | 2 -- 2 files changed, 38 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 6e62f73..8b57240 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -292,42 +292,6 @@ static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2) return r0; } -u32 qcom_scm_get_version(void) -{ - int context_id; - static u32 version = -1; - register u32 r0 asm("r0"); - register u32 r1 asm("r1"); - - if (version != -1) - return version; - - mutex_lock(&qcom_scm_lock); - - r0 = 0x1 << 8; - r1 = (u32)&context_id; - do { - asm volatile( - __asmeq("%0", "r0") - __asmeq("%1", "r1") - __asmeq("%2", "r0") - __asmeq("%3", "r1") -#ifdef REQUIRES_SEC - ".arch_extension sec\n" -#endif - "smc #0 @ switch to secure world\n" - : "=r" (r0), "=r" (r1) - : "r" (r0), "r" (r1) - : "r2", "r3", "r12"); - } while (r0 == QCOM_SCM_INTERRUPTED); - - version = r1; - mutex_unlock(&qcom_scm_lock); - - return version; -} -EXPORT_SYMBOL(qcom_scm_get_version); - /** * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus * @entry: Entry point function for the cpus diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index d05ddac..6fb23c5 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -78,7 +78,6 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, const struct qcom_scm_vmperm *newvm, unsigned int dest_cnt); extern void qcom_scm_cpu_power_down(u32 flags); -extern u32 qcom_scm_get_version(void); extern int qcom_scm_set_remote_state(u32 state, u32 id); extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); @@ -118,7 +117,6 @@ static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, const struct qcom_scm_vmperm *newvm, unsigned int dest_cnt) { return -ENODEV; } static inline void qcom_scm_cpu_power_down(u32 flags) {} -static inline u32 qcom_scm_get_version(void) { return 0; } static inline u32 qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; } static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; } From patchwork Thu Dec 12 18:51:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289193 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B1F01109A for ; Thu, 12 Dec 2019 18:52:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 910592253D for ; Thu, 12 Dec 2019 18:52:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="hY/5JiSz"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="SV4WXI+0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730595AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 Received: from a27-188.smtp-out.us-west-2.amazonses.com ([54.240.27.188]:60194 "EHLO a27-188.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730528AbfLLSvK (ORCPT ); Thu, 12 Dec 2019 13:51:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176669; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=/f/uwcycvkqHfz6rQ6bCQ07NgIkbE8y3JfXx2nqrEJw=; b=hY/5JiSz9C49d3MyANFZXKWw1R7TEKXr4XQea/8sP410LFo46qmTMyt5btL3uwp/ RbIsh18Tjrop9qefgr/UFLsvUPf3yvuZOLHTr+S+gK6/tnsc0IKXQnjj4eJKw6e0PGV dKKBbU9Za4oi3IWWCPYqjEIu/qXEhn+kjQFkDtPU= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176669; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=/f/uwcycvkqHfz6rQ6bCQ07NgIkbE8y3JfXx2nqrEJw=; b=SV4WXI+0If9zlz0QEF9uskHUpBenPhDTJQbC1lqntPL87d9uV4dBxs8M5CKXCr6b zWMvn7RBLZcCm8GVvxODG1VaIEORrYb4utIjQZq2w8meRzk2EFZwForzMZ/SMZ/NTM2 lzAbP8guRqrNTMaBhhGZOUQd3HLXYJZ73+b9XHNc= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 22662C4479F Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 04/17] firmware: qcom_scm-64: Make SMC macros less magical Date: Thu, 12 Dec 2019 18:51:09 +0000 Message-ID: <0101016efb7353b8-d392d835-835b-4851-a560-4d6a11e7d46a-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.188 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Improve understandability of SMC macros by reversing the logic as they are all functions of how many arguments can be shoved in registers and how many SCM arguments are supported. There aren't 4 register arguments because are 7 arguments that go into a buffer - there are up to 7 arguments that are overflowed into a buffer because only 4 registers are allocated for arguments. Reviewed-by: Stephen Boyd Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 976c2b9..3101f36 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -58,9 +58,9 @@ static DEFINE_MUTEX(qcom_scm_lock); #define QCOM_SCM_EBUSY_WAIT_MS 30 #define QCOM_SCM_EBUSY_MAX_RETRY 20 -#define SCM_SMC_N_EXT_ARGS 7 -#define SCM_SMC_FIRST_EXT_IDX 3 -#define SCM_SMC_N_REG_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_EXT_ARGS + 1) +#define SCM_SMC_N_REG_ARGS 4 +#define SCM_SMC_FIRST_EXT_IDX (SCM_SMC_N_REG_ARGS - 1) +#define SCM_SMC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1) static void __scm_smc_do_quirk(const struct qcom_scm_desc *desc, struct arm_smccc_res *res, u32 fn_id, From patchwork Thu Dec 12 18:51:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289191 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 58C5D109A for ; Thu, 12 Dec 2019 18:52:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1AD7824654 for ; Thu, 12 Dec 2019 18:52:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="P8BvRnZe"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="EP6RA1tl" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730629AbfLLSwN (ORCPT ); Thu, 12 Dec 2019 13:52:13 -0500 Received: from a27-185.smtp-out.us-west-2.amazonses.com ([54.240.27.185]:42822 "EHLO a27-185.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730541AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176672; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=D3EWoUInC6Ldbtvyvb++Uc5zZ2L6faGZ0pvn0ELdH6M=; b=P8BvRnZecrEejcznC8wjsiOdqdmwHDF41wrYCJGop18nhqJDxuLqhpVnEEyPhxjP J4BazAOHIk9hSbYF23mBQLNQ1mlEkH4Adh0XBTVSKL5mug2EcSh+vdKBeVghkwNDDK0 vT5vBiUdNcMVZy2+AbzYiu6lXQPrEX9FvSi8EH9g= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176672; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=D3EWoUInC6Ldbtvyvb++Uc5zZ2L6faGZ0pvn0ELdH6M=; b=EP6RA1tlJm3sm/Mkaa6E2MREvKRn/BwiqbMfxS4vH815z5cDIUeIuBviW8ANaweU nyFJxl7ysfNFB8Nzn7ZTpGL7x0CAsxWCsXihTX/3jlbpdgeNSxBOSE7v+nUtQpQ0bDt MdMOLVWlwReOZW6m0O+eEriCI2bJ1RCGdoN1YsAk= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 0669FC447A5 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 05/17] firmware: qcom_scm-64: Move svc/cmd/owner into qcom_scm_desc Date: Thu, 12 Dec 2019 18:51:11 +0000 Message-ID: <0101016efb735ca9-2c5838f8-4796-4916-957d-e492bda3441f-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.185 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Service, command, and owner IDs are all part of qcom_scm_desc struct and have no special reason to be a function argument (or hard-coded in the case of owner [1]). Moving them to be part of qcom_scm_desc struct improves readability. [1]: Example of SCM function using owner vale other than hard-coded SIP value: https://source.codeaurora.org/quic/la/kernel/msm-4.9/tree/drivers/soc/qcom/smcinvoke.c?h=kernel.lnx.4.9.r28-rel#n35 Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-64.c | 195 +++++++++++++++++++++++++---------------- 1 file changed, 121 insertions(+), 74 deletions(-) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 3101f36..7b7aa88 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -48,8 +48,11 @@ enum qcom_scm_arg_types { * @res: The values returned by the secure syscall */ struct qcom_scm_desc { + u32 svc; + u32 cmd; u32 arginfo; u64 args[MAX_QCOM_SCM_ARGS]; + u32 owner; }; static u64 qcom_smccc_convention = -1; @@ -63,14 +66,16 @@ static DEFINE_MUTEX(qcom_scm_lock); #define SCM_SMC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1) static void __scm_smc_do_quirk(const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, u32 fn_id, - u64 x5, u32 type) + struct arm_smccc_res *res, u64 x5, u32 type) { u64 cmd; struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 }; - cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention, - ARM_SMCCC_OWNER_SIP, fn_id); + cmd = ARM_SMCCC_CALL_VAL( + type, + qcom_smccc_convention, + desc->owner, + SCM_SMC_FNID(desc->svc, desc->cmd)); quirk.state.a6 = 0; @@ -86,22 +91,19 @@ static void __scm_smc_do_quirk(const struct qcom_scm_desc *desc, } static void __scm_smc_do(const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, u32 fn_id, - u64 x5, bool atomic) + struct arm_smccc_res *res, u64 x5, bool atomic) { int retry_count = 0; if (atomic) { - __scm_smc_do_quirk(desc, res, fn_id, x5, - ARM_SMCCC_FAST_CALL); + __scm_smc_do_quirk(desc, res, x5, ARM_SMCCC_FAST_CALL); return; } do { mutex_lock(&qcom_scm_lock); - __scm_smc_do_quirk(desc, res, fn_id, x5, - ARM_SMCCC_STD_CALL); + __scm_smc_do_quirk(desc, res, x5, ARM_SMCCC_STD_CALL); mutex_unlock(&qcom_scm_lock); @@ -113,13 +115,11 @@ static void __scm_smc_do(const struct qcom_scm_desc *desc, } while (res->a0 == QCOM_SCM_V2_EBUSY); } -static int __scm_smc_call(struct device *dev, u32 svc_id, u32 cmd_id, - const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, bool atomic) +static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, + struct arm_smccc_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; int i; - u32 fn_id = SCM_SMC_FNID(svc_id, cmd_id); u64 x5 = desc->args[SCM_SMC_FIRST_EXT_IDX]; dma_addr_t args_phys = 0; void *args_virt = NULL; @@ -158,7 +158,7 @@ static int __scm_smc_call(struct device *dev, u32 svc_id, u32 cmd_id, x5 = args_phys; } - __scm_smc_do(desc, res, fn_id, x5, atomic); + __scm_smc_do(desc, res, x5, atomic); if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); @@ -181,12 +181,11 @@ static int __scm_smc_call(struct device *dev, u32 svc_id, u32 cmd_id, * Sends a command to the SCM and waits for the command to finish processing. * This should *only* be called in pre-emptible context. */ -static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, - const struct qcom_scm_desc *desc, +static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { might_sleep(); - return __scm_smc_call(dev, svc_id, cmd_id, desc, res, false); + return __scm_smc_call(dev, desc, res, false); } /** @@ -200,11 +199,11 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, * Sends a command to the SCM and waits for the command to finish processing. * This can be called in atomic context. */ -static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id, +static int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, struct arm_smccc_res *res) { - return __scm_smc_call(dev, svc_id, cmd_id, desc, res, true); + return __scm_smc_call(dev, desc, res, true); } /** @@ -250,15 +249,18 @@ void __qcom_scm_cpu_power_down(u32 flags) int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_INFO, + .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.arginfo = QCOM_SCM_ARGS(1); desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) | (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } @@ -267,7 +269,11 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_HDCP, + .cmd = QCOM_SCM_HDCP_INVOKE, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) @@ -285,8 +291,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, desc.args[9] = req[4].val; desc.arginfo = QCOM_SCM_ARGS(10); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_HDCP_INVOKE, &desc, - &res); + ret = qcom_scm_call(dev, &desc, &res); *resp = res.a1; return ret; @@ -326,15 +331,17 @@ void __qcom_scm_init(void) bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_IS_SUPPORTED, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? false : !!res.a1; } @@ -343,15 +350,18 @@ int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, dma_addr_t metadata_phys) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = peripheral; desc.args[1] = metadata_phys; desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_INIT_IMAGE, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } @@ -360,7 +370,11 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, phys_addr_t addr, phys_addr_t size) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = peripheral; @@ -368,8 +382,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, desc.args[2] = size; desc.arginfo = QCOM_SCM_ARGS(3); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MEM_SETUP, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } @@ -377,15 +390,17 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_AUTH_AND_RESET, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } @@ -393,21 +408,28 @@ int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_SHUTDOWN, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; int ret; @@ -415,15 +437,18 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) desc.args[1] = 0; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MSS_RESET, &desc, - &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; int ret; @@ -431,8 +456,7 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) desc.args[1] = id; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_REMOTE_STATE, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } @@ -442,7 +466,11 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, phys_addr_t dest, size_t dest_sz) { int ret; - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_ASSIGN, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = mem_region; @@ -457,16 +485,18 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_VAL); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, - QCOM_SCM_MP_ASSIGN, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; int ret; @@ -474,8 +504,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) desc.args[1] = spare; desc.arginfo = QCOM_SCM_ARGS(2); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_RESTORE_SEC_CFG, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); return ret ? : res.a1; } @@ -483,15 +512,18 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, size_t *size) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; int ret; desc.args[0] = spare; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, - QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); if (size) *size = res.a1; @@ -502,7 +534,11 @@ int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; int ret; @@ -512,8 +548,7 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, - QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); /* the pg table has been initialized already, ignore the error */ if (ret == -EPERM) @@ -524,29 +559,35 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, - &desc, &res); + return qcom_scm_call(dev, &desc, &res); } int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_READ, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; int ret; desc.args[0] = addr; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, - &desc, &res); + ret = qcom_scm_call(dev, &desc, &res); if (ret >= 0) *val = res.a1; @@ -555,26 +596,32 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_WRITE, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = addr; desc.args[1] = val; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, - &desc, &res); + return qcom_scm_call(dev, &desc, &res); } int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) { - struct qcom_scm_desc desc = {0}; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_SMMU_PROGRAM, + .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1, + .owner = ARM_SMCCC_OWNER_SIP, + }; struct arm_smccc_res res; desc.args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL; desc.args[1] = en; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM, - QCOM_SCM_SMMU_CONFIG_ERRATA1, &desc, &res); + return qcom_scm_call_atomic(dev, &desc, &res); } From patchwork Thu Dec 12 18:51:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289185 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5796E1593 for ; Thu, 12 Dec 2019 18:52:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 22EC224654 for ; Thu, 12 Dec 2019 18:52:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="E7s9qhaS"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="U0/voD7S" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730532AbfLLSvO (ORCPT ); Thu, 12 Dec 2019 13:51:14 -0500 Received: from a27-186.smtp-out.us-west-2.amazonses.com ([54.240.27.186]:35770 "EHLO a27-186.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730553AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176672; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=jwLhQQGuqNJyzWEnxy/X3p8MfPER2Mhyd1Yc/MeMZC4=; b=E7s9qhaSg4jCUPxGkt/oq744zMPzkGnTdD7xxAJBVe7hUlHflYja0fQCdnUM475b I6cNzMwP9yW5IW+XD9hsyiw5qYK/P1HULklLnwvBy7ae9EKxt8u2q2vo0A3XjDq0o7d GoWmen5KIZM2OxLkSMk3SaOloouA6pKFWikxWr20= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176672; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=jwLhQQGuqNJyzWEnxy/X3p8MfPER2Mhyd1Yc/MeMZC4=; b=U0/voD7SomVcCoGvlTVWVlLRLGy9vUPM6zsKojDddhgex3vji6TDpMLk6097lopS ChkWW0O5Ej/c5Cw+6eQ6x3h3yhaMChJywTYlk//9jf9+V2z7fWHAgTZGSnmqiTVw9+E 6PMdJfCz88SLO2AhNjos2Qo+BubnVwI//GvUH/dI= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org AAE47C4479C Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 06/17] firmware: qcom_scm-64: Add SCM results struct Date: Thu, 12 Dec 2019 18:51:12 +0000 Message-ID: <0101016efb735f0f-b0a97ff5-d4fa-42eb-bc3f-edf02edad436-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.186 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Remove knowledge of arm_smccc_res struct from client wrappers so that client wrappers only work QCOM SCM data structures. SCM calls may have up to 3 arguments, so qcom_scm_call_smccc is responsible now for filling those 3 arguments accordingly. This is necessary to support merging legacy and SMC conventions in an upcoming patch. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-64.c | 93 +++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 7b7aa88..e0e6530 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -45,7 +45,6 @@ enum qcom_scm_arg_types { * struct qcom_scm_desc * @arginfo: Metadata describing the arguments in args[] * @args: The array of arguments for the secure syscall - * @res: The values returned by the secure syscall */ struct qcom_scm_desc { u32 svc; @@ -55,6 +54,14 @@ struct qcom_scm_desc { u32 owner; }; +/** + * struct qcom_scm_res + * @result: The values returned by the secure syscall + */ +struct qcom_scm_res { + u64 result[MAX_QCOM_SCM_RETS]; +}; + static u64 qcom_smccc_convention = -1; static DEFINE_MUTEX(qcom_scm_lock); @@ -116,7 +123,7 @@ static void __scm_smc_do(const struct qcom_scm_desc *desc, } static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, bool atomic) + struct qcom_scm_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; int i; @@ -125,6 +132,7 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, void *args_virt = NULL; size_t alloc_len; gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL; + struct arm_smccc_res smc_res; if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) { alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64); @@ -158,17 +166,20 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, x5 = args_phys; } - __scm_smc_do(desc, res, x5, atomic); + __scm_smc_do(desc, &smc_res, x5, atomic); if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); kfree(args_virt); } - if ((long)res->a0 < 0) - return qcom_scm_remap_error(res->a0); + if (res) { + res->result[0] = smc_res.a1; + res->result[1] = smc_res.a2; + res->result[2] = smc_res.a3; + } - return 0; + return (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0; } /** @@ -182,7 +193,7 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, * This should *only* be called in pre-emptible context. */ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, - struct arm_smccc_res *res) + struct qcom_scm_res *res) { might_sleep(); return __scm_smc_call(dev, desc, res, false); @@ -201,7 +212,7 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, */ static int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, - struct arm_smccc_res *res) + struct qcom_scm_res *res) { return __scm_smc_call(dev, desc, res, true); } @@ -254,7 +265,7 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.arginfo = QCOM_SCM_ARGS(1); desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) | @@ -262,7 +273,7 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, @@ -274,7 +285,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, .cmd = QCOM_SCM_HDCP_INVOKE, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) return -ERANGE; @@ -292,7 +303,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, desc.arginfo = QCOM_SCM_ARGS(10); ret = qcom_scm_call(dev, &desc, &res); - *resp = res.a1; + *resp = res.result[0]; return ret; } @@ -336,14 +347,14 @@ bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, &desc, &res); - return ret ? false : !!res.a1; + return ret ? false : !!res.result[0]; } int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, @@ -355,7 +366,7 @@ int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.args[0] = peripheral; desc.args[1] = metadata_phys; @@ -363,7 +374,7 @@ int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, @@ -375,7 +386,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.args[0] = peripheral; desc.args[1] = addr; @@ -384,7 +395,7 @@ int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) @@ -395,14 +406,14 @@ int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) @@ -413,14 +424,14 @@ int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.args[0] = peripheral; desc.arginfo = QCOM_SCM_ARGS(1); ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) @@ -430,7 +441,7 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; int ret; desc.args[0] = reset; @@ -439,7 +450,7 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) @@ -449,7 +460,7 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; int ret; desc.args[0] = state; @@ -458,7 +469,7 @@ int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, @@ -471,7 +482,7 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, .cmd = QCOM_SCM_MP_ASSIGN, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; desc.args[0] = mem_region; desc.args[1] = mem_sz; @@ -487,7 +498,7 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) @@ -497,7 +508,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; int ret; desc.args[0] = device_id; @@ -506,7 +517,7 @@ int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) ret = qcom_scm_call(dev, &desc, &res); - return ret ? : res.a1; + return ret ? : res.result[0]; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, @@ -517,7 +528,7 @@ int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; int ret; desc.args[0] = spare; @@ -526,9 +537,9 @@ int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, ret = qcom_scm_call(dev, &desc, &res); if (size) - *size = res.a1; + *size = res.result[0]; - return ret ? : res.a2; + return ret ? : res.result[1]; } int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, @@ -539,7 +550,6 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; int ret; desc.args[0] = addr; @@ -548,7 +558,7 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL); - ret = qcom_scm_call(dev, &desc, &res); + ret = qcom_scm_call(dev, &desc, NULL); /* the pg table has been initialized already, ignore the error */ if (ret == -EPERM) @@ -564,13 +574,12 @@ int __qcom_scm_set_dload_mode(struct device *dev, bool enable) .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call(dev, &desc, &res); + return qcom_scm_call(dev, &desc, NULL); } int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, @@ -581,7 +590,7 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, .cmd = QCOM_SCM_IO_READ, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; + struct qcom_scm_res res; int ret; desc.args[0] = addr; @@ -589,7 +598,7 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, ret = qcom_scm_call(dev, &desc, &res); if (ret >= 0) - *val = res.a1; + *val = res.result[0]; return ret < 0 ? ret : 0; } @@ -601,13 +610,12 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) .cmd = QCOM_SCM_IO_WRITE, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; desc.args[0] = addr; desc.args[1] = val; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call(dev, &desc, &res); + return qcom_scm_call(dev, &desc, NULL); } int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) @@ -617,11 +625,10 @@ int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1, .owner = ARM_SMCCC_OWNER_SIP, }; - struct arm_smccc_res res; desc.args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL; desc.args[1] = en; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call_atomic(dev, &desc, &res); + return qcom_scm_call_atomic(dev, &desc, NULL); } From patchwork Thu Dec 12 18:51:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289189 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D16461593 for ; Thu, 12 Dec 2019 18:52:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id AFCEE24654 for ; Thu, 12 Dec 2019 18:52:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="iQIx2Eml"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="g60m9oBY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730471AbfLLSwM (ORCPT ); Thu, 12 Dec 2019 13:52:12 -0500 Received: from a27-186.smtp-out.us-west-2.amazonses.com ([54.240.27.186]:35742 "EHLO a27-186.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730594AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176673; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=RsBjYxf6e/v2D1W9VWnbIzneWQAHd8KCVqyRvE/8IT8=; b=iQIx2EmlThxQ0u6BxXA+VbmYcoOQ4mK64YAdyJKZxm0ULjOHkABumWQgTyiQmN4Y xeNzPoMPUbPBY7oQvJ2hktjPmNHMbpSN3tqL56CrSBN1qRKlOsbKWmwQN9j9UqG7tLW k78lLJq8N110FOKQvDECtP6o/wPwkgPAR7Cdg51A= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176673; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=RsBjYxf6e/v2D1W9VWnbIzneWQAHd8KCVqyRvE/8IT8=; b=g60m9oBY69U0l/CsZIEmwKbRzm2Sis2AUhUHDn9axs7WFlvqsiVH1J6EzfHVJ4uR /q7+kRgedRYYtqqpx51/X106JH1AZrWetmwjjKHo43O1HTbfZg+AmrtxwQQkpqO6Syu aAh/WMPsp2ocf0lk2Fr+tSeJcSWI7Jp8ygehM4GA= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4D73FC4479F Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 07/17] firmware: qcom_scm-64: Move SMC register filling to qcom_scm_call_smccc Date: Thu, 12 Dec 2019 18:51:13 +0000 Message-ID: <0101016efb7360ec-bd705208-1fd6-43f5-b088-b8bcd3031793-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.186 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org qcom_scm_call_smccc should be responsible for converting qcom_scm_desc into arguments for smc call. Consolidate the dispersed logic to convert qcom_scm_desc into smc arguments inside qcom_scm_call_smccc. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-64.c | 54 ++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index e0e6530..3ae171a 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -62,6 +62,14 @@ struct qcom_scm_res { u64 result[MAX_QCOM_SCM_RETS]; }; +/** + * struct arm_smccc_args + * @args: The array of values used in registers in smc instruction + */ +struct arm_smccc_args { + unsigned long args[8]; +}; + static u64 qcom_smccc_convention = -1; static DEFINE_MUTEX(qcom_scm_lock); @@ -71,46 +79,42 @@ static DEFINE_MUTEX(qcom_scm_lock); #define SCM_SMC_N_REG_ARGS 4 #define SCM_SMC_FIRST_EXT_IDX (SCM_SMC_N_REG_ARGS - 1) #define SCM_SMC_N_EXT_ARGS (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1) +#define SCM_SMC_FIRST_REG_IDX 2 +#define SCM_SMC_LAST_REG_IDX (SCM_SMC_FIRST_REG_IDX + SCM_SMC_N_REG_ARGS - 1) -static void __scm_smc_do_quirk(const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, u64 x5, u32 type) +static void __scm_smc_do_quirk(const struct arm_smccc_args *smc, + struct arm_smccc_res *res) { - u64 cmd; + unsigned long a0 = smc->args[0]; struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 }; - cmd = ARM_SMCCC_CALL_VAL( - type, - qcom_smccc_convention, - desc->owner, - SCM_SMC_FNID(desc->svc, desc->cmd)); - quirk.state.a6 = 0; do { - arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0], - desc->args[1], desc->args[2], x5, - quirk.state.a6, 0, res, &quirk); + arm_smccc_smc_quirk(a0, smc->args[1], smc->args[2], + smc->args[3], smc->args[4], smc->args[5], + quirk.state.a6, smc->args[7], res, &quirk); if (res->a0 == QCOM_SCM_INTERRUPTED) - cmd = res->a0; + a0 = res->a0; } while (res->a0 == QCOM_SCM_INTERRUPTED); } -static void __scm_smc_do(const struct qcom_scm_desc *desc, - struct arm_smccc_res *res, u64 x5, bool atomic) +static void __scm_smc_do(const struct arm_smccc_args *smc, + struct arm_smccc_res *res, bool atomic) { int retry_count = 0; if (atomic) { - __scm_smc_do_quirk(desc, res, x5, ARM_SMCCC_FAST_CALL); + __scm_smc_do_quirk(smc, res); return; } do { mutex_lock(&qcom_scm_lock); - __scm_smc_do_quirk(desc, res, x5, ARM_SMCCC_STD_CALL); + __scm_smc_do_quirk(smc, res); mutex_unlock(&qcom_scm_lock); @@ -127,12 +131,22 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, { int arglen = desc->arginfo & 0xf; int i; - u64 x5 = desc->args[SCM_SMC_FIRST_EXT_IDX]; dma_addr_t args_phys = 0; void *args_virt = NULL; size_t alloc_len; gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL; + u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL; struct arm_smccc_res smc_res; + struct arm_smccc_args smc = {0}; + + smc.args[0] = ARM_SMCCC_CALL_VAL( + smccc_call_type, + qcom_smccc_convention, + desc->owner, + SCM_SMC_FNID(desc->svc, desc->cmd)); + smc.args[1] = desc->arginfo; + for (i = 0; i < SCM_SMC_N_REG_ARGS; i++) + smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i]; if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) { alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64); @@ -163,10 +177,10 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, return -ENOMEM; } - x5 = args_phys; + smc.args[SCM_SMC_LAST_REG_IDX] = args_phys; } - __scm_smc_do(desc, &smc_res, x5, atomic); + __scm_smc_do(&smc, &smc_res, atomic); if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); From patchwork Thu Dec 12 18:51:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289197 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B1D1F109A for ; Thu, 12 Dec 2019 18:52:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 90E6A2253D for ; Thu, 12 Dec 2019 18:52:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="KDxeMpNv"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="V50vGQlF" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730449AbfLLSwX (ORCPT ); Thu, 12 Dec 2019 13:52:23 -0500 Received: from a27-11.smtp-out.us-west-2.amazonses.com ([54.240.27.11]:51078 "EHLO a27-11.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730552AbfLLSvN (ORCPT ); Thu, 12 Dec 2019 13:51:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176672; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=w1SrKHHyeBDteMNP8O/IVD/2wQ7Wzg3QyRcWSjuUtGs=; b=KDxeMpNvKcAxS7hpxyrqFnqTmpbhNvIjSZV8yNz0PrGYfC4iCWxm1SxrxaDgiXL5 yZzp7sbLa0sXp2MxzNFFhanKaLk1mcH+DsvhcAzzVfi+ANNzsGd2cjBt6lqMOa+ybq0 zE6O+Q/2nWW1CljwChS5jLiM4DZLP1uptXGOkm3U= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176672; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=w1SrKHHyeBDteMNP8O/IVD/2wQ7Wzg3QyRcWSjuUtGs=; b=V50vGQlFmtu7aY7Pm9CVUDFGfqdIIPIKUPO7wWImQXhGrIva9Kg8p8iJPofcMDzM K818HB16/c+va+tEDIKjWUNhDuzG4fDI5BdNNsLg8qnULg+XLOkVF5D8oAi1NSTN5qD gPJboxS1Wp/BzcYB+AlJlvxHJ10m3JlPMBj+svUI= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=ham autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 1BA2AC447A1 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 08/17] firmware: qcom_scm-64: Improve SMC convention detection Date: Thu, 12 Dec 2019 18:51:12 +0000 Message-ID: <0101016efb735e6d-94821623-6253-48d9-992c-d268d6961791-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.11 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Improve the calling convention detection to use __qcom_scm_is_call_available() and not blindly assume 32-bit mode if the checks fails. BUG() if neither 32-bit or 64-bit mode works. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-64.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 3ae171a..6bc7f69 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -336,21 +336,34 @@ int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, void __qcom_scm_init(void) { - u64 cmd; - struct arm_smccc_res res; - u32 fnid = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL); - - /* First try a SMC64 call */ - cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, - ARM_SMCCC_OWNER_SIP, fnid); - - arm_smccc_smc(cmd, QCOM_SCM_ARGS(1), cmd & (~BIT(ARM_SMCCC_TYPE_SHIFT)), - 0, 0, 0, 0, 0, &res); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_INFO, + .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, + .args[0] = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, + QCOM_SCM_INFO_IS_CALL_AVAIL) | + (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT), + .arginfo = QCOM_SCM_ARGS(1), + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; - if (!res.a0 && res.a1) - qcom_smccc_convention = ARM_SMCCC_SMC_64; - else - qcom_smccc_convention = ARM_SMCCC_SMC_32; + qcom_smccc_convention = ARM_SMCCC_SMC_64; + // Device isn't required as there is only one argument - no device + // needed to dma_map_single to secure world + ret = qcom_scm_call_atomic(NULL, &desc, &res); + if (!ret && res.result[0] == 1) + goto out; + + qcom_smccc_convention = ARM_SMCCC_SMC_32; + ret = qcom_scm_call_atomic(NULL, &desc, &res); + if (!ret && res.result[0] == 1) + goto out; + + qcom_smccc_convention = -1; + BUG(); +out: + pr_info("QCOM SCM SMC Convention: %lld\n", qcom_smccc_convention); } bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) From patchwork Thu Dec 12 18:51:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289183 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E6D74109A for ; Thu, 12 Dec 2019 18:52:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C596224654 for ; Thu, 12 Dec 2019 18:52:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="PUXVGmcy"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="P2TJf/fQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730610AbfLLSvO (ORCPT ); Thu, 12 Dec 2019 13:51:14 -0500 Received: from a27-21.smtp-out.us-west-2.amazonses.com ([54.240.27.21]:39998 "EHLO a27-21.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730601AbfLLSvO (ORCPT ); Thu, 12 Dec 2019 13:51:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176673; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=nS5dpPxwP7JE8bX7G/pF3Js40aKiOtZzLGDlluiHQHc=; b=PUXVGmcyYwoKEE0joP8hhmxsSFjfHUx0eYaDmlitfLTu/1VYI++qhsq9M1tvZCVY oNuBR7GDZAamtTphtoMeg3JiyP1xU7ky3X/+/ErsWAfjH4e1ZwgWdcQdlZvtnHA7BmS +zvHgoTOnXVyuaMQCq3XWeFV/7nFQhpx7l1QHy4c= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176673; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=nS5dpPxwP7JE8bX7G/pF3Js40aKiOtZzLGDlluiHQHc=; b=P2TJf/fQKhOvS8t2/shHpntoLTfKDnMpQbN8usGqh6nGxgXBoVKPEgXYu+b92ebS gGGjo8vLXELOiAQSgA0ThjZR6Z5xx6D+z67ISmMPIL0BgfIEe3Tzlkuff1eURb0ra2u 8tIN4CQQWzwz7m4mGwt9SyFSCZhnZSF5fBmFsdww= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org D5545C447B1 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 09/17] firmware: qcom_scm-32: Use SMC arch wrappers Date: Thu, 12 Dec 2019 18:51:13 +0000 Message-ID: <0101016efb736222-1f17d78f-df52-44e0-bb93-caca35d12d7f-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.21 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Use SMC arch wrappers instead of inline assembly. Signed-off-by: Elliot Berman --- drivers/firmware/Makefile | 1 - drivers/firmware/qcom_scm-32.c | 71 ++++++++++-------------------------------- 2 files changed, 17 insertions(+), 55 deletions(-) diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 3fcb919..747fb73 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o obj-$(CONFIG_QCOM_SCM) += qcom_scm.o obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o -CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 8b57240..362d042 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "qcom_scm.h" @@ -121,25 +122,13 @@ static inline void *scm_legacy_get_response_buffer( static u32 __scm_legacy_do(u32 cmd_addr) { int context_id; - register u32 r0 asm("r0") = 1; - register u32 r1 asm("r1") = (u32)&context_id; - register u32 r2 asm("r2") = cmd_addr; + struct arm_smccc_res res; do { - asm volatile( - __asmeq("%0", "r0") - __asmeq("%1", "r0") - __asmeq("%2", "r1") - __asmeq("%3", "r2") -#ifdef REQUIRES_SEC - ".arch_extension sec\n" -#endif - "smc #0 @ switch to secure world\n" - : "=r" (r0) - : "r" (r0), "r" (r1), "r" (r2) - : "r3", "r12"); - } while (r0 == QCOM_SCM_INTERRUPTED); - - return r0; + arm_smccc_smc(1, (unsigned long)&context_id, cmd_addr, + 0, 0, 0, 0, 0, &res); + } while (res.a0 == QCOM_SCM_INTERRUPTED); + + return res.a0; } /** @@ -237,24 +226,12 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1) { int context_id; + struct arm_smccc_res res; + + arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(svc, cmd, 1), + (unsigned long)&context_id, arg1, 0, 0, 0, 0, 0, &res); - register u32 r0 asm("r0") = SCM_LEGACY_ATOMIC_ID(svc, cmd, 1); - register u32 r1 asm("r1") = (u32)&context_id; - register u32 r2 asm("r2") = arg1; - - asm volatile( - __asmeq("%0", "r0") - __asmeq("%1", "r0") - __asmeq("%2", "r1") - __asmeq("%3", "r2") -#ifdef REQUIRES_SEC - ".arch_extension sec\n" -#endif - "smc #0 @ switch to secure world\n" - : "=r" (r0) - : "r" (r0), "r" (r1), "r" (r2) - : "r3", "r12"); - return r0; + return res.a0; } /** @@ -270,26 +247,12 @@ static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1) static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2) { int context_id; + struct arm_smccc_res res; + + arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(svc, cmd, 2), + (unsigned long)&context_id, arg1, 0, 0, 0, 0, 0, &res); - register u32 r0 asm("r0") = SCM_LEGACY_ATOMIC_ID(svc, cmd, 2); - register u32 r1 asm("r1") = (u32)&context_id; - register u32 r2 asm("r2") = arg1; - register u32 r3 asm("r3") = arg2; - - asm volatile( - __asmeq("%0", "r0") - __asmeq("%1", "r0") - __asmeq("%2", "r1") - __asmeq("%3", "r2") - __asmeq("%4", "r3") -#ifdef REQUIRES_SEC - ".arch_extension sec\n" -#endif - "smc #0 @ switch to secure world\n" - : "=r" (r0) - : "r" (r0), "r" (r1), "r" (r2), "r" (r3) - : "r12"); - return r0; + return res.a0; } /** From patchwork Thu Dec 12 18:51:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289181 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2924214DB for ; Thu, 12 Dec 2019 18:52:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0731C24654 for ; Thu, 12 Dec 2019 18:52:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="M/pK/kGC"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="Kk7SUA5n" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730566AbfLLSvO (ORCPT ); Thu, 12 Dec 2019 13:51:14 -0500 Received: from a27-186.smtp-out.us-west-2.amazonses.com ([54.240.27.186]:35740 "EHLO a27-186.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730604AbfLLSvO (ORCPT ); Thu, 12 Dec 2019 13:51:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176673; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=Rn03FluCaDQLghrbQl4vahU7+G26SUGCOzkKXznyMik=; b=M/pK/kGCcjaTqixWdNXoYORCn92xThqw0cAGZsz7NneTCpYvppGXezYpSv+xrRZ7 G46RNdyUROhoHxDllsw6uCBU/0yCBka0TTy8aCKGwiXpWu3YpyLuT5nIlL0L8MJCtV9 Er1MeutFHUhxsqL5PDZGeMIvQUR9QtxSYov/OVXw= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176673; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=Rn03FluCaDQLghrbQl4vahU7+G26SUGCOzkKXznyMik=; b=Kk7SUA5nRa3hsTGMmwWENG5HSUCmK02IaLDGneY3UhWzxsKgsKojhyOV0KH48xec k2bSuVlfHpankA03Eph2PhpEKRcO/Ou54zDMZQdsZHQYJ88GHZUaSsAKfH9HEoOQYAs lKaG6/OOkUMN2/bfNeASzzv2VqTQhQnJvD1eUW50= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=ham autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 81D03C447A6 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 10/17] firmware: qcom_scm-32: Add funcnum IDs Date: Thu, 12 Dec 2019 18:51:13 +0000 Message-ID: <0101016efb7363da-a7c086c4-3107-4443-b223-1b8e84f41736-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.186 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add SCM_LEGACY_FNID macro to qcom_scm-32. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 362d042..fcbe9e0 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -39,6 +39,8 @@ static struct qcom_scm_entry qcom_scm_wb[] = { static DEFINE_MUTEX(qcom_scm_lock); +#define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff)) + /** * struct scm_legacy_command - one SCM command buffer * @len: total available memory for command and response @@ -168,7 +170,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, cmd->buf_offset = cpu_to_le32(sizeof(*cmd)); cmd->resp_hdr_offset = cpu_to_le32(sizeof(*cmd) + cmd_len); - cmd->id = cpu_to_le32((svc_id << 10) | cmd_id); + cmd->id = cpu_to_le32(SCM_LEGACY_FNID(svc_id, cmd_id)); if (cmd_buf) memcpy(scm_legacy_get_command_buffer(cmd), cmd_buf, cmd_len); @@ -209,7 +211,7 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, #define SCM_LEGACY_CLASS_REGISTER (0x2 << 8) #define SCM_LEGACY_MASK_IRQS BIT(5) #define SCM_LEGACY_ATOMIC_ID(svc, cmd, n) \ - (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \ + ((SCM_LEGACY_FNID(svc, cmd) << 12) | \ SCM_LEGACY_CLASS_REGISTER | \ SCM_LEGACY_MASK_IRQS | \ (n & 0xf)) @@ -350,7 +352,7 @@ void __qcom_scm_cpu_power_down(u32 flags) int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; - __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id); + __le32 svc_cmd = cpu_to_le32(SCM_LEGACY_FNID(svc_id, cmd_id)); __le32 ret_val = 0; ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, From patchwork Thu Dec 12 18:51:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289167 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F7B9109A for ; Thu, 12 Dec 2019 18:51:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 01FD424656 for ; Thu, 12 Dec 2019 18:51:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="dUcazDUD"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="cXqGkwbf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730667AbfLLSvV (ORCPT ); Thu, 12 Dec 2019 13:51:21 -0500 Received: from a27-18.smtp-out.us-west-2.amazonses.com ([54.240.27.18]:39284 "EHLO a27-18.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730651AbfLLSvU (ORCPT ); Thu, 12 Dec 2019 13:51:20 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176679; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=uq9M1dVWf+QqJzV6adGNLbbVNXhGOgFpQQ3FWV0kh5k=; b=dUcazDUDIYt2HgL0Rpv4RmK/VOzKh8Kqs6wnSdipOke76yHBlM0rtK1PbK2fJeBr RQGgGkNA31U00xhs1DltiAxJ3pSKCIxTZUXqHLOzUe9Wpc/r2YvE0YdhLSbir6bdpck 7FOk+wImrAyGxBy0fVq5EUFrEmv1eTwGzZkFCyM4= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176679; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=uq9M1dVWf+QqJzV6adGNLbbVNXhGOgFpQQ3FWV0kh5k=; b=cXqGkwbfSCs5EuaBlZHN/CdRw/6T5jZotkp9s94UD8PErrTboUuCgkpFqdn/fmN7 1dd2qJ4xeJ/V8i/uyMIi3+YKVOlCEyDzjG/EdbZQAPWnZ145OpF6ZpCRpnUdMPdcPGf 6gG/Qc/uIg1forU870QeoD5XHZJqFpdo1H0NkJME= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 4718FC4479F Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 11/17] firmware: qcom_scm-32: Use qcom_scm_desc in non-atomic calls Date: Thu, 12 Dec 2019 18:51:19 +0000 Message-ID: <0101016efb737a9f-c9f68d45-f966-409d-8f8f-a808ffc84e91-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.18 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Use qcom_scm_desc in non-atomic calls to remove legacy convention details from every SCM wrapper function. Implementations were copied from qcom_scm-64 and are functionally equivalent when using the qcom_scm_desc and qcom_scm_res structs. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 367 ++++++++++++++++++++++++----------------- 1 file changed, 218 insertions(+), 149 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index fcbe9e0..ce3a61b 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -39,6 +39,52 @@ static struct qcom_scm_entry qcom_scm_wb[] = { static DEFINE_MUTEX(qcom_scm_lock); +#define MAX_QCOM_SCM_ARGS 10 +#define MAX_QCOM_SCM_RETS 3 + +enum qcom_scm_arg_types { + QCOM_SCM_VAL, + QCOM_SCM_RO, + QCOM_SCM_RW, + QCOM_SCM_BUFVAL, +}; + +#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\ + (((a) & 0x3) << 4) | \ + (((b) & 0x3) << 6) | \ + (((c) & 0x3) << 8) | \ + (((d) & 0x3) << 10) | \ + (((e) & 0x3) << 12) | \ + (((f) & 0x3) << 14) | \ + (((g) & 0x3) << 16) | \ + (((h) & 0x3) << 18) | \ + (((i) & 0x3) << 20) | \ + (((j) & 0x3) << 22) | \ + ((num) & 0xf)) + +#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +/** + * struct qcom_scm_desc + * @arginfo: Metadata describing the arguments in args[] + * @args: The array of arguments for the secure syscall + */ +struct qcom_scm_desc { + u32 svc; + u32 cmd; + u32 arginfo; + u64 args[MAX_QCOM_SCM_ARGS]; + u32 owner; +}; + +/** + * struct qcom_scm_res + * @result: The values returned by the secure syscall + */ +struct qcom_scm_res { + u64 result[MAX_QCOM_SCM_RETS]; +}; + #define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff)) /** @@ -134,16 +180,8 @@ static u32 __scm_legacy_do(u32 cmd_addr) } /** - * qcom_scm_call() - Send an SCM command - * @dev: struct device - * @svc_id: service identifier - * @cmd_id: command identifier - * @cmd_buf: command buffer - * @cmd_len: length of the command buffer - * @resp_buf: response buffer - * @resp_len: length of the response buffer - * - * Sends a command to the SCM and waits for the command to finish processing. + * qcom_scm_call() - Sends a command to the SCM and waits for the command to + * finish processing. * * A note on cache maintenance: * Note that any buffers that are expected to be accessed by the secure world @@ -152,15 +190,20 @@ static u32 __scm_legacy_do(u32 cmd_addr) * and response buffers is taken care of by qcom_scm_call; however, callers are * responsible for any other cached buffers passed over to the secure world. */ -static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, - const void *cmd_buf, size_t cmd_len, void *resp_buf, - size_t resp_len) +static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { + u8 arglen = desc->arginfo & 0xf; int ret; + unsigned int i; struct scm_legacy_command *cmd; struct scm_legacy_response *rsp; + const size_t cmd_len = arglen * sizeof(__le32); + const size_t resp_len = MAX_QCOM_SCM_RETS * sizeof(__le32); size_t alloc_len = sizeof(*cmd) + cmd_len + sizeof(*rsp) + resp_len; dma_addr_t cmd_phys; + __le32 *arg_buf; + const __le32 *res_buf; cmd = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL); if (!cmd) @@ -169,10 +212,11 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, cmd->len = cpu_to_le32(alloc_len); cmd->buf_offset = cpu_to_le32(sizeof(*cmd)); cmd->resp_hdr_offset = cpu_to_le32(sizeof(*cmd) + cmd_len); + cmd->id = cpu_to_le32(SCM_LEGACY_FNID(desc->svc, desc->cmd)); - cmd->id = cpu_to_le32(SCM_LEGACY_FNID(svc_id, cmd_id)); - if (cmd_buf) - memcpy(scm_legacy_get_command_buffer(cmd), cmd_buf, cmd_len); + arg_buf = scm_legacy_get_command_buffer(cmd); + for (i = 0; i < arglen; i++) + arg_buf[i] = cpu_to_le32(desc->args[i]); rsp = scm_legacy_command_to_response(cmd); @@ -195,12 +239,14 @@ static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id, sizeof(*rsp), DMA_FROM_DEVICE); } while (!rsp->is_complete); - if (resp_buf) { - dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len + - le32_to_cpu(rsp->buf_offset), - resp_len, DMA_FROM_DEVICE); - memcpy(resp_buf, scm_legacy_get_response_buffer(rsp), - resp_len); + dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len + + le32_to_cpu(rsp->buf_offset), + resp_len, DMA_FROM_DEVICE); + + if (res) { + res_buf = scm_legacy_get_response_buffer(rsp); + for (i = 0; i < MAX_QCOM_SCM_RETS; i++) + res->result[i] = le32_to_cpu(res_buf[i]); } out: dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE); @@ -304,10 +350,10 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, int ret; int flags = 0; int cpu; - struct { - __le32 flags; - __le32 addr; - } cmd; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_ADDR, + }; /* * Reassign only if we are switching from hotplug entry point @@ -323,10 +369,11 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, if (!flags) return 0; - cmd.addr = cpu_to_le32(virt_to_phys(entry)); - cmd.flags = cpu_to_le32(flags); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_ADDR, - &cmd, sizeof(cmd), NULL, 0); + desc.args[0] = flags; + desc.args[1] = virt_to_phys(entry); + desc.arginfo = QCOM_SCM_ARGS(2); + + ret = qcom_scm_call(dev, &desc, NULL); if (!ret) { for_each_cpu(cpu, cpus) qcom_scm_wb[cpu].entry = entry; @@ -352,61 +399,80 @@ void __qcom_scm_cpu_power_down(u32 flags) int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; - __le32 svc_cmd = cpu_to_le32(SCM_LEGACY_FNID(svc_id, cmd_id)); - __le32 ret_val = 0; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_INFO, + .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, + .args[0] = SCM_LEGACY_FNID(svc_id, cmd_id), + .arginfo = QCOM_SCM_ARGS(1), + }; + struct qcom_scm_res res; - ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_SCM_INFO_IS_CALL_AVAIL, - &svc_cmd, sizeof(svc_cmd), &ret_val, - sizeof(ret_val)); - if (ret) - return ret; + ret = qcom_scm_call(dev, &desc, &res); - return le32_to_cpu(ret_val); + return ret ? : res.result[0]; } int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_HDCP, + .cmd = QCOM_SCM_HDCP_INVOKE, + }; + struct qcom_scm_res res; + if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) return -ERANGE; - return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_HDCP_INVOKE, - req, req_cnt * sizeof(*req), resp, sizeof(*resp)); + desc.args[0] = req[0].addr; + desc.args[1] = req[0].val; + desc.args[2] = req[1].addr; + desc.args[3] = req[1].val; + desc.args[4] = req[2].addr; + desc.args[5] = req[2].val; + desc.args[6] = req[3].addr; + desc.args[7] = req[3].val; + desc.args[8] = req[4].addr; + desc.args[9] = req[4].val; + desc.arginfo = QCOM_SCM_ARGS(10); + + ret = qcom_scm_call(dev, &desc, &res); + *resp = res.result[0]; + + return ret; } int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, u32 mode) { - struct ocmem_tz_lock { - __le32 id; - __le32 offset; - __le32 size; - __le32 mode; - } request; - - request.id = cpu_to_le32(id); - request.offset = cpu_to_le32(offset); - request.size = cpu_to_le32(size); - request.mode = cpu_to_le32(mode); - - return qcom_scm_call(dev, QCOM_SCM_SVC_OCMEM, QCOM_SCM_OCMEM_LOCK_CMD, - &request, sizeof(request), NULL, 0); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_OCMEM, + .cmd = QCOM_SCM_OCMEM_LOCK_CMD, + }; + + desc.args[0] = id; + desc.args[1] = offset; + desc.args[2] = size; + desc.args[3] = mode; + desc.arginfo = QCOM_SCM_ARGS(4); + + return qcom_scm_call(dev, &desc, NULL); } int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) { - struct ocmem_tz_unlock { - __le32 id; - __le32 offset; - __le32 size; - } request; - - request.id = cpu_to_le32(id); - request.offset = cpu_to_le32(offset); - request.size = cpu_to_le32(size); - - return qcom_scm_call(dev, QCOM_SCM_SVC_OCMEM, QCOM_SCM_OCMEM_UNLOCK_CMD, - &request, sizeof(request), NULL, 0); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_OCMEM, + .cmd = QCOM_SCM_OCMEM_UNLOCK_CMD, + }; + + desc.args[0] = id; + desc.args[1] = offset; + desc.args[2] = size; + desc.arginfo = QCOM_SCM_ARGS(3); + + return qcom_scm_call(dev, &desc, NULL); } void __qcom_scm_init(void) @@ -415,104 +481,110 @@ void __qcom_scm_init(void) bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) { - __le32 out; - __le32 in; int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, + }; + struct qcom_scm_res res; + + desc.args[0] = peripheral; + desc.arginfo = QCOM_SCM_ARGS(1); - in = cpu_to_le32(peripheral); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_IS_SUPPORTED, - &in, sizeof(in), - &out, sizeof(out)); + ret = qcom_scm_call(dev, &desc, &res); - return ret ? false : !!out; + return ret ? false : !!res.result[0]; } int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, dma_addr_t metadata_phys) { - __le32 scm_ret; int ret; - struct { - __le32 proc; - __le32 image_addr; - } request; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, + }; + struct qcom_scm_res res; - request.proc = cpu_to_le32(peripheral); - request.image_addr = cpu_to_le32(metadata_phys); + desc.args[0] = peripheral; + desc.args[1] = metadata_phys; + desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_INIT_IMAGE, - &request, sizeof(request), - &scm_ret, sizeof(scm_ret)); + ret = qcom_scm_call(dev, &desc, &res); - return ret ? : le32_to_cpu(scm_ret); + return ret ? : res.result[0]; } int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, - phys_addr_t addr, phys_addr_t size) + phys_addr_t addr, phys_addr_t size) { - __le32 scm_ret; int ret; - struct { - __le32 proc; - __le32 addr; - __le32 len; - } request; - - request.proc = cpu_to_le32(peripheral); - request.addr = cpu_to_le32(addr); - request.len = cpu_to_le32(size); - - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_MEM_SETUP, - &request, sizeof(request), - &scm_ret, sizeof(scm_ret)); - - return ret ? : le32_to_cpu(scm_ret); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, + }; + struct qcom_scm_res res; + + desc.args[0] = peripheral; + desc.args[1] = addr; + desc.args[2] = size; + desc.arginfo = QCOM_SCM_ARGS(3); + + ret = qcom_scm_call(dev, &desc, &res); + + return ret ? : res.result[0]; } int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) { - __le32 out; - __le32 in; int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, + }; + struct qcom_scm_res res; + + desc.args[0] = peripheral; + desc.arginfo = QCOM_SCM_ARGS(1); - in = cpu_to_le32(peripheral); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_AUTH_AND_RESET, - &in, sizeof(in), - &out, sizeof(out)); + ret = qcom_scm_call(dev, &desc, &res); - return ret ? : le32_to_cpu(out); + return ret ? : res.result[0]; } int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) { - __le32 out; - __le32 in; int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, + }; + struct qcom_scm_res res; + + desc.args[0] = peripheral; + desc.arginfo = QCOM_SCM_ARGS(1); - in = cpu_to_le32(peripheral); - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_SHUTDOWN, - &in, sizeof(in), - &out, sizeof(out)); + ret = qcom_scm_call(dev, &desc, &res); - return ret ? : le32_to_cpu(out); + return ret ? : res.result[0]; } int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) { - __le32 out; - __le32 in = cpu_to_le32(reset); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, + }; + struct qcom_scm_res res; int ret; - ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_MSS_RESET, - &in, sizeof(in), - &out, sizeof(out)); + desc.args[0] = reset; + desc.args[1] = 0; + desc.arginfo = QCOM_SCM_ARGS(2); - return ret ? : le32_to_cpu(out); + ret = qcom_scm_call(dev, &desc, &res); + + return ret ? : res.result[0]; } int __qcom_scm_set_dload_mode(struct device *dev, bool enable) @@ -523,20 +595,19 @@ int __qcom_scm_set_dload_mode(struct device *dev, bool enable) int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) { - struct { - __le32 state; - __le32 id; - } req; - __le32 scm_ret = 0; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, + }; + struct qcom_scm_res res; int ret; - req.state = cpu_to_le32(state); - req.id = cpu_to_le32(id); + desc.args[0] = state; + desc.args[1] = id; - ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_REMOTE_STATE, - &req, sizeof(req), &scm_ret, sizeof(scm_ret)); + ret = qcom_scm_call(dev, &desc, &res); - return ret ? : le32_to_cpu(scm_ret); + return ret ? : res.result[0]; } int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, @@ -549,22 +620,20 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) { - struct msm_scm_sec_cfg { - __le32 id; - __le32 ctx_bank_num; - } cfg; - int ret, scm_ret = 0; - - cfg.id = cpu_to_le32(device_id); - cfg.ctx_bank_num = cpu_to_le32(spare); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, + }; + struct qcom_scm_res res; + int ret; - ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_MP_RESTORE_SEC_CFG, - &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + desc.args[0] = device_id; + desc.args[1] = spare; + desc.arginfo = QCOM_SCM_ARGS(2); - if (ret || scm_ret) - return ret ? ret : -EINVAL; + ret = qcom_scm_call(dev, &desc, &res); - return 0; + return ret ? : res.result[0]; } int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, From patchwork Thu Dec 12 18:51:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289179 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EDF2014DB for ; Thu, 12 Dec 2019 18:52:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CCB1E2073D for ; Thu, 12 Dec 2019 18:52:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="GpmnajeG"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="VVMmiNZ3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730756AbfLLSwB (ORCPT ); Thu, 12 Dec 2019 13:52:01 -0500 Received: from a27-56.smtp-out.us-west-2.amazonses.com ([54.240.27.56]:37124 "EHLO a27-56.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730629AbfLLSvR (ORCPT ); Thu, 12 Dec 2019 13:51:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176676; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=p7wFQu0bs7+hi18FP3kunBybyOWZxGP7tYMi7t3Oil0=; b=GpmnajeGx9+/gVS5m7laonqOWuBTg/xOHZ2kX5souIU+mZbtS0PKV8psH6/0xWHN ZkqMTUrIf56DP/KGndfPiFGDHKRP6WoWzyYS1HmSURpXHj3nCwCZTZJAKvhDg8j4Eoe ZDw+a8dkeoFQULscf7FEkLr8eEWJbQ3SHhQ6nA8A= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176676; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=p7wFQu0bs7+hi18FP3kunBybyOWZxGP7tYMi7t3Oil0=; b=VVMmiNZ34Os5h185SnPny6x01XT8JR/4Q835kKcNgCGM5fl3UMRFR+XjcbNA3Hvk LiB2arWjyZFaIBX5c/i6CuBWWAxK9BwrVC/dE9Oke52tGBAQg4N/La8AII0ZQ69L37c EMuvJxNAP+kB1nymx398HzHDPzaeVbnf3xVTA/Sk= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E5700C447A0 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 12/17] firmware: qcom_scm-32: Move SMCCC register filling to qcom_scm_call Date: Thu, 12 Dec 2019 18:51:16 +0000 Message-ID: <0101016efb736f1f-fb516cae-6275-4ae1-93fa-1abcc9e682b2-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.56 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Move SMCCC register filling to qcom_scm_call so that __scm_legacy_do only needs to concern itself with retry mechanism. qcom_scm_call then is responsible for translating qcom_scm_desc into the complete set of register arguments and passing onto qcom_scm_call_do. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index ce3a61b..acd956f 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -85,6 +85,14 @@ struct qcom_scm_res { u64 result[MAX_QCOM_SCM_RETS]; }; +/** + * struct arm_smccc_args + * @args: The array of values used in registers in smc instruction + */ +struct arm_smccc_args { + unsigned long args[8]; +}; + #define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff)) /** @@ -167,16 +175,14 @@ static inline void *scm_legacy_get_response_buffer( return (void *)rsp + le32_to_cpu(rsp->buf_offset); } -static u32 __scm_legacy_do(u32 cmd_addr) +static void __scm_legacy_do(const struct arm_smccc_args *smc, + struct arm_smccc_res *res) { - int context_id; - struct arm_smccc_res res; do { - arm_smccc_smc(1, (unsigned long)&context_id, cmd_addr, - 0, 0, 0, 0, 0, &res); - } while (res.a0 == QCOM_SCM_INTERRUPTED); - - return res.a0; + arm_smccc_smc(smc->args[0], smc->args[1], smc->args[2], + smc->args[3], smc->args[4], smc->args[5], + smc->args[6], smc->args[7], res); + } while (res->a0 == QCOM_SCM_INTERRUPTED); } /** @@ -194,10 +200,12 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, struct qcom_scm_res *res) { u8 arglen = desc->arginfo & 0xf; - int ret; + int ret = 0, context_id; unsigned int i; struct scm_legacy_command *cmd; struct scm_legacy_response *rsp; + struct arm_smccc_args smc = {0}; + struct arm_smccc_res smc_res; const size_t cmd_len = arglen * sizeof(__le32); const size_t resp_len = MAX_QCOM_SCM_RETS * sizeof(__le32); size_t alloc_len = sizeof(*cmd) + cmd_len + sizeof(*rsp) + resp_len; @@ -226,10 +234,14 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, return -ENOMEM; } + smc.args[0] = 1; + smc.args[1] = (unsigned long)&context_id; + smc.args[2] = cmd_phys; + mutex_lock(&qcom_scm_lock); - ret = __scm_legacy_do(cmd_phys); - if (ret < 0) - ret = qcom_scm_remap_error(ret); + __scm_legacy_do(&smc, &smc_res); + if (smc_res.a0) + ret = qcom_scm_remap_error(smc_res.a0); mutex_unlock(&qcom_scm_lock); if (ret) goto out; From patchwork Thu Dec 12 18:51:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289177 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 93EB4109A for ; Thu, 12 Dec 2019 18:51:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 68CBC206C3 for ; Thu, 12 Dec 2019 18:51:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="o/8urKJ7"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="PAa+DV74" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730546AbfLLSvz (ORCPT ); Thu, 12 Dec 2019 13:51:55 -0500 Received: from a27-185.smtp-out.us-west-2.amazonses.com ([54.240.27.185]:42822 "EHLO a27-185.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730641AbfLLSvS (ORCPT ); Thu, 12 Dec 2019 13:51:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176677; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=q3YgpMIFWM1yKjUq3MGxnQcA1EmaiJlWf1YaV+tco5Y=; b=o/8urKJ7d90+rWrxYlL8QaOV6lXtfnhruXo4p7ruqlXZh8x4elgj+6czEaF6Grhj b3J/iH7Wb06IvkiSyNXhNrTRwB14rzC2kWylkQXbqIwXdX/JX/lCWaN2ffPbi+eqxjL g1tf+aBiRlMTQIgcUURipxRH5emx8Ro/iStICkgU= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176677; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=q3YgpMIFWM1yKjUq3MGxnQcA1EmaiJlWf1YaV+tco5Y=; b=PAa+DV74lq4/OmJBP18CC9DKpHq8+qzX45MTuu8jPZoCq+9DVoWXgFI4Axwly8YO 3F4iB2w5BXHqPErCe+xi4+2k1PWwJnAg4drj9cizn22a3vUos9ju6/pDDu3X67cfZB2 vvOTFqD4kVQAGXUBb4lW9BzY4shscuX03LDFYBdk= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=ham autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 7E462C4479C Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 13/17] firmware: qcom_scm-32: Create common legacy atomic call Date: Thu, 12 Dec 2019 18:51:17 +0000 Message-ID: <0101016efb7371ab-53502247-3832-4caf-a960-317cf35ad109-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.185 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Per [1], legacy calling convention supports up to 5 arguments and 3 return values. Create one function to support this combination, and remove the original "atomic1" and "atomic2" variants for 1 and 2 arguments. This more closely aligns scm_legacy implementation with scm_smc implementation. [1]: https://source.codeaurora.org/quic/la/kernel/msm-4.9/tree/drivers/soc/qcom/scm.c?h=kernel.lnx.4.9.r28-rel#n1024 Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 106 ++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index acd956f..9729a8a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -266,6 +266,8 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, return ret; } +#define SCM_LEGACY_ATOMIC_N_REG_ARGS 5 +#define SCM_LEGACY_ATOMIC_FIRST_REG_IDX 2 #define SCM_LEGACY_CLASS_REGISTER (0x2 << 8) #define SCM_LEGACY_MASK_IRQS BIT(5) #define SCM_LEGACY_ATOMIC_ID(svc, cmd, n) \ @@ -275,44 +277,35 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, (n & 0xf)) /** - * qcom_scm_call_atomic1() - Send an atomic SCM command with one argument - * @svc_id: service identifier - * @cmd_id: command identifier - * @arg1: first argument + * qcom_scm_call_atomic() - Send an atomic SCM command with up to 5 arguments + * and 3 return values + * @desc: SCM call descriptor containing arguments + * @res: SCM call return values * * This shall only be used with commands that are guaranteed to be * uninterruptable, atomic and SMP safe. */ -static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1) +static int qcom_scm_call_atomic(const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { int context_id; - struct arm_smccc_res res; + struct arm_smccc_res smc_res; + size_t arglen = desc->arginfo & 0xf; - arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(svc, cmd, 1), - (unsigned long)&context_id, arg1, 0, 0, 0, 0, 0, &res); + BUG_ON(arglen > SCM_LEGACY_ATOMIC_N_REG_ARGS); - return res.a0; -} + arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(desc->svc, desc->cmd, arglen), + (unsigned long)&context_id, + desc->args[0], desc->args[1], desc->args[2], + desc->args[3], desc->args[4], 0, &smc_res); -/** - * qcom_scm_call_atomic2() - Send an atomic SCM command with two arguments - * @svc_id: service identifier - * @cmd_id: command identifier - * @arg1: first argument - * @arg2: second argument - * - * This shall only be used with commands that are guaranteed to be - * uninterruptable, atomic and SMP safe. - */ -static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2) -{ - int context_id; - struct arm_smccc_res res; - - arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(svc, cmd, 2), - (unsigned long)&context_id, arg1, 0, 0, 0, 0, 0, &res); + if (res) { + res->result[0] = smc_res.a1; + res->result[1] = smc_res.a2; + res->result[2] = smc_res.a3; + } - return res.a0; + return smc_res.a0; } /** @@ -333,6 +326,10 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) QCOM_SCM_FLAG_COLDBOOT_CPU2, QCOM_SCM_FLAG_COLDBOOT_CPU3, }; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_ADDR, + }; if (!cpus || (cpus && cpumask_empty(cpus))) return -EINVAL; @@ -344,8 +341,11 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) set_cpu_present(cpu, false); } - return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_ADDR, - flags, virt_to_phys(entry)); + desc.args[0] = flags; + desc.args[1] = virt_to_phys(entry); + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(&desc, NULL); } /** @@ -404,8 +404,14 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, */ void __qcom_scm_cpu_power_down(u32 flags) { - qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_TERMINATE_PC, - flags & QCOM_SCM_FLUSH_FLAG_MASK); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_TERMINATE_PC, + .args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK, + .arginfo = QCOM_SCM_ARGS(1), + }; + + qcom_scm_call_atomic(&desc, NULL); } int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) @@ -601,8 +607,16 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { - return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, - enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0, 0); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, + }; + + desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; + desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(&desc, NULL); } int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) @@ -664,18 +678,34 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val) { int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_READ, + }; + struct qcom_scm_res res; + + desc.args[0] = addr; + desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call_atomic1(QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, addr); + ret = qcom_scm_call_atomic(&desc, &res); if (ret >= 0) - *val = ret; + *val = res.result[0]; return ret < 0 ? ret : 0; } int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) { - return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, - addr, val); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_WRITE, + }; + + desc.args[0] = addr; + desc.args[1] = val; + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(&desc, NULL); } int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable) From patchwork Thu Dec 12 18:51:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289175 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80D50109A for ; Thu, 12 Dec 2019 18:51:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 564702073B for ; Thu, 12 Dec 2019 18:51:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="cO6UgdAP"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="WMIY9bKX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730511AbfLLSvq (ORCPT ); Thu, 12 Dec 2019 13:51:46 -0500 Received: from a27-56.smtp-out.us-west-2.amazonses.com ([54.240.27.56]:37124 "EHLO a27-56.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730658AbfLLSvV (ORCPT ); Thu, 12 Dec 2019 13:51:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176680; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=eCUEn4LD5D9VtBk5pZPvwROSrzfMyygmFCm7AbOdGgE=; b=cO6UgdAP5v/mGGsABBBrJyqRL8pwMFkhmZfhYRCLdMlCDTZixjWYPzXjyz5BcFHJ rH/DVvjQrFK8wr1faLVoxN/FANpwNomO1/SRxZaJ+TMwP7fdi+G4znZah+Iw6VUWpQR 9Iv8x8fMqcFFulVjg2Wjl/WMALDLy6qiZVS4Qhpg= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176680; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=eCUEn4LD5D9VtBk5pZPvwROSrzfMyygmFCm7AbOdGgE=; b=WMIY9bKXWvPF2Jo2/8Tt4zBBGvN42xMtvMUVIpWw/XlE+pm8F7zEhz75VEBRLJTC f0OcEGq6Ar0ncTzsRe7NOMCkBd6Wp969wGqslebm8bgAokyIG+XrJL5Yfwg4Sz3QC29 wcChHSvYzu+ervyo4Ggnt32yiyzYwYfPLmPfqpqI= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 2E43FC447A6 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 14/17] firmware: qcom_scm-32: Add device argument to atomic calls Date: Thu, 12 Dec 2019 18:51:20 +0000 Message-ID: <0101016efb737d36-0c04e30d-e728-48ac-a731-9e48130356ec-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.56 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add unused "device" parameter to reduce merge friction between SMCCC and legacy based conventions in an upcoming patch. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 18 ++++++++++-------- drivers/firmware/qcom_scm-64.c | 5 +++-- drivers/firmware/qcom_scm.c | 5 +++-- drivers/firmware/qcom_scm.h | 5 +++-- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 9729a8a..e9b396c 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -285,7 +285,8 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, * This shall only be used with commands that are guaranteed to be * uninterruptable, atomic and SMP safe. */ -static int qcom_scm_call_atomic(const struct qcom_scm_desc *desc, +static int qcom_scm_call_atomic(struct device *unused, + const struct qcom_scm_desc *desc, struct qcom_scm_res *res) { int context_id; @@ -316,7 +317,8 @@ static int qcom_scm_call_atomic(const struct qcom_scm_desc *desc, * Set the cold boot address of the cpus. Any cpu outside the supported * range would be removed from the cpu present mask. */ -int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) +int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, + const cpumask_t *cpus) { int flags = 0; int cpu; @@ -345,7 +347,7 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) desc.args[1] = virt_to_phys(entry); desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call_atomic(&desc, NULL); + return qcom_scm_call_atomic(dev, &desc, NULL); } /** @@ -402,7 +404,7 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, * the control would return from this function, otherwise, the cpu jumps to the * warm boot entry point set for this cpu upon reset. */ -void __qcom_scm_cpu_power_down(u32 flags) +void __qcom_scm_cpu_power_down(struct device *dev, u32 flags) { struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, @@ -411,7 +413,7 @@ void __qcom_scm_cpu_power_down(u32 flags) .arginfo = QCOM_SCM_ARGS(1), }; - qcom_scm_call_atomic(&desc, NULL); + qcom_scm_call_atomic(dev, &desc, NULL); } int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) @@ -616,7 +618,7 @@ int __qcom_scm_set_dload_mode(struct device *dev, bool enable) desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call_atomic(&desc, NULL); + return qcom_scm_call_atomic(dev, &desc, NULL); } int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) @@ -687,7 +689,7 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, desc.args[0] = addr; desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call_atomic(&desc, &res); + ret = qcom_scm_call_atomic(dev, &desc, &res); if (ret >= 0) *val = res.result[0]; @@ -705,7 +707,7 @@ int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) desc.args[1] = val; desc.arginfo = QCOM_SCM_ARGS(2); - return qcom_scm_call_atomic(&desc, NULL); + return qcom_scm_call_atomic(dev, &desc, NULL); } int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable) diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 6bc7f69..9507047 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -239,7 +239,8 @@ static int qcom_scm_call_atomic(struct device *dev, * Set the cold boot address of the cpus. Any cpu outside the supported * range would be removed from the cpu present mask. */ -int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) +int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, + const cpumask_t *cpus) { return -ENOTSUPP; } @@ -267,7 +268,7 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, * the control would return from this function, otherwise, the cpu jumps to the * warm boot entry point set for this cpu upon reset. */ -void __qcom_scm_cpu_power_down(u32 flags) +void __qcom_scm_cpu_power_down(struct device *dev, u32 flags) { } diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 097f8b3..5efe729 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -94,7 +94,8 @@ static void qcom_scm_clk_disable(void) */ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) { - return __qcom_scm_set_cold_boot_addr(entry, cpus); + return __qcom_scm_set_cold_boot_addr(__scm ? __scm->dev : NULL, entry, + cpus); } EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); @@ -122,7 +123,7 @@ EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); */ void qcom_scm_cpu_power_down(u32 flags) { - __qcom_scm_cpu_power_down(flags); + __qcom_scm_cpu_power_down(__scm ? __scm->dev : NULL, flags); } EXPORT_SYMBOL(qcom_scm_cpu_power_down); diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index afcca16..a022556 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -13,11 +13,12 @@ extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); -extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); +extern int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, + const cpumask_t *cpus); #define QCOM_SCM_BOOT_TERMINATE_PC 0x2 #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 -extern void __qcom_scm_cpu_power_down(u32 flags); +extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); #define QCOM_SCM_SVC_IO 0x5 #define QCOM_SCM_IO_READ 0x1 From patchwork Thu Dec 12 18:51:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289169 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F257109A for ; Thu, 12 Dec 2019 18:51:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EB3802253D for ; Thu, 12 Dec 2019 18:51:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="oJmcGMLV"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="E4bVcbkH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730693AbfLLSvZ (ORCPT ); Thu, 12 Dec 2019 13:51:25 -0500 Received: from a27-187.smtp-out.us-west-2.amazonses.com ([54.240.27.187]:41150 "EHLO a27-187.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730684AbfLLSvY (ORCPT ); Thu, 12 Dec 2019 13:51:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176683; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=AuXBw5HRp7PbniKtYIiLPGmK102wGzaSApJ0LqgZBe4=; b=oJmcGMLV0WtJYbd0fFDH2dA3ALsJmWpyiJGdY5ePDC8t/i497pgyrgD1OTgn8nLV QlxcqM0VEs5C+yPZl99RQI26bR3Qn4ekTelVxzc/WtB0O7K4dKD0Bq3bNhPQtnoHK6F xVyH49jsBW3PoEnFJbfNmfco60vULc8ztQWvFLC0= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176683; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=AuXBw5HRp7PbniKtYIiLPGmK102wGzaSApJ0LqgZBe4=; b=E4bVcbkHIwtts8uAf33xauMATJfl4Fss+MMoZPBB3H1fLnT2UQ9vWsPGz3w1WiCu Oh7orvG1HAeyh5VGprGlMgZmLf3qicwuXaKIGCGjZiBCEClfy8S0TV+oeooYdHuKQjI CgBq0OS6Q2AvhGplA/qN5ZCweD4Fud7nS9yju2Aw= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 165F2C447B0 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 15/17] firmware: qcom_scm: Order functions, definitions by service/command Date: Thu, 12 Dec 2019 18:51:23 +0000 Message-ID: <0101016efb7388fa-29f511eb-16b6-4903-ad46-225aaa9fa56d-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.187 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Definitions throughout qcom_scm are loosely grouped and loosely ordered. Sort all the functions/definitions by service ID/command ID to improve sanity when needing to add new functionality to this driver. Acked-by: Bjorn Andersson Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm.c | 376 ++++++++++++++++++++++---------------------- drivers/firmware/qcom_scm.h | 120 +++++++------- include/linux/qcom_scm.h | 111 +++++++------ 3 files changed, 309 insertions(+), 298 deletions(-) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 5efe729..5ba4c85 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -85,33 +85,33 @@ static void qcom_scm_clk_disable(void) } /** - * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus + * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus * @entry: Entry point function for the cpus * @cpus: The cpumask of cpus that will use the entry point * - * Set the cold boot address of the cpus. Any cpu outside the supported - * range would be removed from the cpu present mask. + * Set the Linux entry point for the SCM to transfer control to when coming + * out of a power down. CPU power down may be executed on cpuidle or hotplug. */ -int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) +int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) { - return __qcom_scm_set_cold_boot_addr(__scm ? __scm->dev : NULL, entry, - cpus); + return __qcom_scm_set_warm_boot_addr(__scm->dev, entry, cpus); } -EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); +EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); /** - * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus + * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus * @entry: Entry point function for the cpus * @cpus: The cpumask of cpus that will use the entry point * - * Set the Linux entry point for the SCM to transfer control to when coming - * out of a power down. CPU power down may be executed on cpuidle or hotplug. + * Set the cold boot address of the cpus. Any cpu outside the supported + * range would be removed from the cpu present mask. */ -int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) +int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) { - return __qcom_scm_set_warm_boot_addr(__scm->dev, entry, cpus); + return __qcom_scm_set_cold_boot_addr(__scm ? __scm->dev : NULL, entry, + cpus); } -EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); +EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); /** * qcom_scm_cpu_power_down() - Power down the cpu @@ -127,107 +127,33 @@ void qcom_scm_cpu_power_down(u32 flags) } EXPORT_SYMBOL(qcom_scm_cpu_power_down); -/** - * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. - * - * Return true if HDCP is supported, false if not. - */ -bool qcom_scm_hdcp_available(void) -{ - int ret = qcom_scm_clk_enable(); - - if (ret) - return ret; - - ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP, - QCOM_SCM_HDCP_INVOKE); - - qcom_scm_clk_disable(); - - return ret > 0 ? true : false; -} -EXPORT_SYMBOL(qcom_scm_hdcp_available); - -/** - * qcom_scm_hdcp_req() - Send HDCP request. - * @req: HDCP request array - * @req_cnt: HDCP request array count - * @resp: response buffer passed to SCM - * - * Write HDCP register(s) through SCM. - */ -int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) -{ - int ret = qcom_scm_clk_enable(); - - if (ret) - return ret; - - ret = __qcom_scm_hdcp_req(__scm->dev, req, req_cnt, resp); - qcom_scm_clk_disable(); - return ret; -} -EXPORT_SYMBOL(qcom_scm_hdcp_req); - -/** - * qcom_scm_pas_supported() - Check if the peripheral authentication service is - * available for the given peripherial - * @peripheral: peripheral id - * - * Returns true if PAS is supported for this peripheral, otherwise false. - */ -bool qcom_scm_pas_supported(u32 peripheral) +int qcom_scm_set_remote_state(u32 state, u32 id) { - int ret; - - ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL, - QCOM_SCM_PIL_PAS_IS_SUPPORTED); - if (ret <= 0) - return false; - - return __qcom_scm_pas_supported(__scm->dev, peripheral); + return __qcom_scm_set_remote_state(__scm->dev, state, id); } -EXPORT_SYMBOL(qcom_scm_pas_supported); +EXPORT_SYMBOL(qcom_scm_set_remote_state); -/** - * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available - */ -bool qcom_scm_ocmem_lock_available(void) +static void qcom_scm_set_download_mode(bool enable) { - return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_OCMEM, - QCOM_SCM_OCMEM_LOCK_CMD); -} -EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + bool avail; + int ret = 0; -/** - * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM - * region to the specified initiator - * - * @id: tz initiator id - * @offset: OCMEM offset - * @size: OCMEM size - * @mode: access mode (WIDE/NARROW) - */ -int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, - u32 mode) -{ - return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); -} -EXPORT_SYMBOL(qcom_scm_ocmem_lock); + avail = __qcom_scm_is_call_available(__scm->dev, + QCOM_SCM_SVC_BOOT, + QCOM_SCM_BOOT_SET_DLOAD_MODE); + if (avail) { + ret = __qcom_scm_set_dload_mode(__scm->dev, enable); + } else if (__scm->dload_mode_addr) { + ret = __qcom_scm_io_writel(__scm->dev, __scm->dload_mode_addr, + enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); + } else { + dev_err(__scm->dev, + "No available mechanism for setting download mode\n"); + } -/** - * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM - * region from the specified initiator - * - * @id: tz initiator id - * @offset: OCMEM offset - * @size: OCMEM size - */ -int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) -{ - return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); + if (ret) + dev_err(__scm->dev, "failed to set download mode: %d\n", ret); } -EXPORT_SYMBOL(qcom_scm_ocmem_unlock); /** * qcom_scm_pas_init_image() - Initialize peripheral authentication service @@ -342,6 +268,26 @@ int qcom_scm_pas_shutdown(u32 peripheral) } EXPORT_SYMBOL(qcom_scm_pas_shutdown); +/** + * qcom_scm_pas_supported() - Check if the peripheral authentication service is + * available for the given peripherial + * @peripheral: peripheral id + * + * Returns true if PAS is supported for this peripheral, otherwise false. + */ +bool qcom_scm_pas_supported(u32 peripheral) +{ + int ret; + + ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL, + QCOM_SCM_PIL_PAS_IS_SUPPORTED); + if (ret <= 0) + return false; + + return __qcom_scm_pas_supported(__scm->dev, peripheral); +} +EXPORT_SYMBOL(qcom_scm_pas_supported); + static int qcom_scm_pas_reset_assert(struct reset_controller_dev *rcdev, unsigned long idx) { @@ -365,6 +311,18 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { .deassert = qcom_scm_pas_reset_deassert, }; +int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) +{ + return __qcom_scm_io_readl(__scm->dev, addr, val); +} +EXPORT_SYMBOL(qcom_scm_io_readl); + +int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) +{ + return __qcom_scm_io_writel(__scm->dev, addr, val); +} +EXPORT_SYMBOL(qcom_scm_io_writel); + /** * qcom_scm_restore_sec_cfg_available() - Check if secure environment * supports restore security config interface. @@ -396,87 +354,6 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) } EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); -int qcom_scm_qsmmu500_wait_safe_toggle(bool en) -{ - return __qcom_scm_qsmmu500_wait_safe_toggle(__scm->dev, en); -} -EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle); - -int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) -{ - return __qcom_scm_io_readl(__scm->dev, addr, val); -} -EXPORT_SYMBOL(qcom_scm_io_readl); - -int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) -{ - return __qcom_scm_io_writel(__scm->dev, addr, val); -} -EXPORT_SYMBOL(qcom_scm_io_writel); - -static void qcom_scm_set_download_mode(bool enable) -{ - bool avail; - int ret = 0; - - avail = __qcom_scm_is_call_available(__scm->dev, - QCOM_SCM_SVC_BOOT, - QCOM_SCM_BOOT_SET_DLOAD_MODE); - if (avail) { - ret = __qcom_scm_set_dload_mode(__scm->dev, enable); - } else if (__scm->dload_mode_addr) { - ret = __qcom_scm_io_writel(__scm->dev, __scm->dload_mode_addr, - enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); - } else { - dev_err(__scm->dev, - "No available mechanism for setting download mode\n"); - } - - if (ret) - dev_err(__scm->dev, "failed to set download mode: %d\n", ret); -} - -static int qcom_scm_find_dload_address(struct device *dev, u64 *addr) -{ - struct device_node *tcsr; - struct device_node *np = dev->of_node; - struct resource res; - u32 offset; - int ret; - - tcsr = of_parse_phandle(np, "qcom,dload-mode", 0); - if (!tcsr) - return 0; - - ret = of_address_to_resource(tcsr, 0, &res); - of_node_put(tcsr); - if (ret) - return ret; - - ret = of_property_read_u32_index(np, "qcom,dload-mode", 1, &offset); - if (ret < 0) - return ret; - - *addr = res.start + offset; - - return 0; -} - -/** - * qcom_scm_is_available() - Checks if SCM is available - */ -bool qcom_scm_is_available(void) -{ - return !!__scm; -} -EXPORT_SYMBOL(qcom_scm_is_available); - -int qcom_scm_set_remote_state(u32 state, u32 id) -{ - return __qcom_scm_set_remote_state(__scm->dev, state, id); -} -EXPORT_SYMBOL(qcom_scm_set_remote_state); - /** * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership * @mem_addr: mem region whose ownership need to be reassigned @@ -559,6 +436,129 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, } EXPORT_SYMBOL(qcom_scm_assign_mem); +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_OCMEM, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, + u32 mode) +{ + return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + +/** + * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. + * + * Return true if HDCP is supported, false if not. + */ +bool qcom_scm_hdcp_available(void) +{ + int ret = qcom_scm_clk_enable(); + + if (ret) + return ret; + + ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP, + QCOM_SCM_HDCP_INVOKE); + + qcom_scm_clk_disable(); + + return ret > 0 ? true : false; +} +EXPORT_SYMBOL(qcom_scm_hdcp_available); + +/** + * qcom_scm_hdcp_req() - Send HDCP request. + * @req: HDCP request array + * @req_cnt: HDCP request array count + * @resp: response buffer passed to SCM + * + * Write HDCP register(s) through SCM. + */ +int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) +{ + int ret = qcom_scm_clk_enable(); + + if (ret) + return ret; + + ret = __qcom_scm_hdcp_req(__scm->dev, req, req_cnt, resp); + qcom_scm_clk_disable(); + return ret; +} +EXPORT_SYMBOL(qcom_scm_hdcp_req); + +int qcom_scm_qsmmu500_wait_safe_toggle(bool en) +{ + return __qcom_scm_qsmmu500_wait_safe_toggle(__scm->dev, en); +} +EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle); + +static int qcom_scm_find_dload_address(struct device *dev, u64 *addr) +{ + struct device_node *tcsr; + struct device_node *np = dev->of_node; + struct resource res; + u32 offset; + int ret; + + tcsr = of_parse_phandle(np, "qcom,dload-mode", 0); + if (!tcsr) + return 0; + + ret = of_address_to_resource(tcsr, 0, &res); + of_node_put(tcsr); + if (ret) + return ret; + + ret = of_property_read_u32_index(np, "qcom,dload-mode", 1, &offset); + if (ret < 0) + return ret; + + *addr = res.start + offset; + + return 0; +} + +/** + * qcom_scm_is_available() - Checks if SCM is available + */ +bool qcom_scm_is_available(void) +{ + return !!__scm; +} +EXPORT_SYMBOL(qcom_scm_is_available); + static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index a022556..56ace3b 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -4,64 +4,83 @@ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H -#define QCOM_SCM_SVC_BOOT 0x1 -#define QCOM_SCM_BOOT_SET_ADDR 0x1 -#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 -#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0xa -extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); -extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); - +#define QCOM_SCM_SVC_BOOT 0x01 +#define QCOM_SCM_BOOT_SET_ADDR 0x01 +#define QCOM_SCM_BOOT_TERMINATE_PC 0x02 +#define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 +#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); extern int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, const cpumask_t *cpus); - -#define QCOM_SCM_BOOT_TERMINATE_PC 0x2 -#define QCOM_SCM_FLUSH_FLAG_MASK 0x3 extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); +extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); +extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); +#define QCOM_SCM_FLUSH_FLAG_MASK 0x3 + +#define QCOM_SCM_SVC_PIL 0x02 +#define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x01 +#define QCOM_SCM_PIL_PAS_MEM_SETUP 0x02 +#define QCOM_SCM_PIL_PAS_AUTH_AND_RESET 0x05 +#define QCOM_SCM_PIL_PAS_SHUTDOWN 0x06 +#define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x07 +#define QCOM_SCM_PIL_PAS_MSS_RESET 0x0a +extern bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral); +extern int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, + dma_addr_t metadata_phys); +extern int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, + phys_addr_t addr, phys_addr_t size); +extern int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral); +extern int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral); +extern int __qcom_scm_pas_mss_reset(struct device *dev, bool reset); -#define QCOM_SCM_SVC_IO 0x5 -#define QCOM_SCM_IO_READ 0x1 -#define QCOM_SCM_IO_WRITE 0x2 +#define QCOM_SCM_SVC_IO 0x05 +#define QCOM_SCM_IO_READ 0x01 +#define QCOM_SCM_IO_WRITE 0x02 extern int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val); extern int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val); -#define QCOM_SCM_SVC_INFO 0x6 -#define QCOM_SCM_INFO_IS_CALL_AVAIL 0x1 +#define QCOM_SCM_SVC_INFO 0x06 +#define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01 extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id); -#define QCOM_SCM_SVC_HDCP 0x11 -#define QCOM_SCM_HDCP_INVOKE 0x01 -extern int __qcom_scm_hdcp_req(struct device *dev, - struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); - -extern void __qcom_scm_init(void); - -#define QCOM_SCM_SVC_OCMEM 0xf -#define QCOM_SCM_OCMEM_LOCK_CMD 0x1 -#define QCOM_SCM_OCMEM_UNLOCK_CMD 0x2 +#define QCOM_SCM_SVC_MP 0x0c +#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02 +#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 +#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04 +#define QCOM_SCM_MP_ASSIGN 0x16 +extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, + u32 spare); +extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, + size_t *size); +extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, + u32 size, u32 spare); +extern int __qcom_scm_assign_mem(struct device *dev, + phys_addr_t mem_region, size_t mem_sz, + phys_addr_t src, size_t src_sz, + phys_addr_t dest, size_t dest_sz); +#define QCOM_SCM_SVC_OCMEM 0x0f +#define QCOM_SCM_OCMEM_LOCK_CMD 0x01 +#define QCOM_SCM_OCMEM_UNLOCK_CMD 0x02 extern int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, u32 mode); extern int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size); -#define QCOM_SCM_SVC_PIL 0x2 -#define QCOM_SCM_PIL_PAS_INIT_IMAGE 0x1 -#define QCOM_SCM_PIL_PAS_MEM_SETUP 0x2 -#define QCOM_SCM_PIL_PAS_AUTH_AND_RESET 0x5 -#define QCOM_SCM_PIL_PAS_SHUTDOWN 0x6 -#define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x7 -#define QCOM_SCM_PIL_PAS_MSS_RESET 0xa -extern bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral); -extern int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, - dma_addr_t metadata_phys); -extern int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, - phys_addr_t addr, phys_addr_t size); -extern int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral); -extern int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral); -extern int __qcom_scm_pas_mss_reset(struct device *dev, bool reset); +#define QCOM_SCM_SVC_HDCP 0x11 +#define QCOM_SCM_HDCP_INVOKE 0x01 +extern int __qcom_scm_hdcp_req(struct device *dev, + struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); + +#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 +#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 +#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 +extern int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, + bool enable); + +extern void __qcom_scm_init(void); /* common error codes */ #define QCOM_SCM_V2_EBUSY -12 @@ -90,25 +109,4 @@ static inline int qcom_scm_remap_error(int err) return -EINVAL; } -#define QCOM_SCM_SVC_MP 0xc -#define QCOM_SCM_MP_RESTORE_SEC_CFG 2 -extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, - u32 spare); -#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 3 -#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 4 -#define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 -#define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x3 -#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x2 -extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, - size_t *size); -extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, - u32 size, u32 spare); -extern int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, - bool enable); -#define QCOM_SCM_MP_ASSIGN 0x16 -extern int __qcom_scm_assign_mem(struct device *dev, - phys_addr_t mem_region, size_t mem_sz, - phys_addr_t src, size_t src_sz, - phys_addr_t dest, size_t dest_sz); - #endif diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 6fb23c5..e3e382f 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2010-2015, 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. */ #ifndef __QCOM_SCM_H @@ -55,75 +55,88 @@ enum qcom_scm_sec_dev_id { #define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC) #if IS_ENABLED(CONFIG_QCOM_SCM) +extern bool qcom_scm_is_available(void); + extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); -extern bool qcom_scm_is_available(void); -extern bool qcom_scm_hdcp_available(void); -extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, - u32 *resp); -extern bool qcom_scm_ocmem_lock_available(void); -extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, - u32 size, u32 mode); -extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, - u32 size); -extern bool qcom_scm_pas_supported(u32 peripheral); +extern void qcom_scm_cpu_power_down(u32 flags); +extern int qcom_scm_set_remote_state(u32 state, u32 id); + extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size); extern int qcom_scm_pas_auth_and_reset(u32 peripheral); extern int qcom_scm_pas_shutdown(u32 peripheral); -extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, - unsigned int *src, - const struct qcom_scm_vmperm *newvm, - unsigned int dest_cnt); -extern void qcom_scm_cpu_power_down(u32 flags); -extern int qcom_scm_set_remote_state(u32 state, u32 id); +extern bool qcom_scm_pas_supported(u32 peripheral); + +extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); +extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); + extern bool qcom_scm_restore_sec_cfg_available(void); extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); +extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, + unsigned int *src, + const struct qcom_scm_vmperm *newvm, + unsigned int dest_cnt); + +extern bool qcom_scm_ocmem_lock_available(void); +extern int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, + u32 size, u32 mode); +extern int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, + u32 size); + +extern bool qcom_scm_hdcp_available(void); +extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, + u32 *resp); + extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en); -extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); -extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val); #else #include -static inline -int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) -{ - return -ENODEV; -} -static inline -int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) -{ - return -ENODEV; -} static inline bool qcom_scm_is_available(void) { return false; } -static inline bool qcom_scm_hdcp_available(void) { return false; } -static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, - u32 *resp) { return -ENODEV; } -static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; } + +static inline int qcom_scm_set_cold_boot_addr(void *entry, + const cpumask_t *cpus) { return -ENODEV; } +static inline int qcom_scm_set_warm_boot_addr(void *entry, + const cpumask_t *cpus) { return -ENODEV; } +static inline void qcom_scm_cpu_power_down(u32 flags) {} +static inline u32 qcom_scm_set_remote_state(u32 state,u32 id) + { return -ENODEV; } + static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, - size_t size) { return -ENODEV; } + size_t size) { return -ENODEV; } static inline int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, - phys_addr_t size) { return -ENODEV; } -static inline int -qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; } + phys_addr_t size) { return -ENODEV; } +static inline int qcom_scm_pas_auth_and_reset(u32 peripheral) + { return -ENODEV; } static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; } +static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; } + +static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) + { return -ENODEV; } +static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) + { return -ENODEV; } + +static inline bool qcom_scm_restore_sec_cfg_available(void) { return false; } +static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) + { return -ENODEV; } +static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) + { return -ENODEV; } +static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) + { return -ENODEV; } static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, - unsigned int *src, - const struct qcom_scm_vmperm *newvm, - unsigned int dest_cnt) { return -ENODEV; } -static inline void qcom_scm_cpu_power_down(u32 flags) {} -static inline u32 -qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; } -static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; } -static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { return -ENODEV; } -static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; } -static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en) { return -ENODEV; } -static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) { return -ENODEV; } -static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) { return -ENODEV; } + unsigned int *src, const struct qcom_scm_vmperm *newvm, + unsigned int dest_cnt) { return -ENODEV; } + +static inline bool qcom_scm_hdcp_available(void) { return false; } +static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, + u32 *resp) { return -ENODEV; } + +static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en) + { return -ENODEV; } #endif #endif From patchwork Thu Dec 12 18:51:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289171 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5000414DB for ; Thu, 12 Dec 2019 18:51:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 079CD2253D for ; Thu, 12 Dec 2019 18:51:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="kXvpP2Gm"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="hBdd5I0T" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730709AbfLLSv3 (ORCPT ); Thu, 12 Dec 2019 13:51:29 -0500 Received: from a27-56.smtp-out.us-west-2.amazonses.com ([54.240.27.56]:37124 "EHLO a27-56.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730691AbfLLSv1 (ORCPT ); Thu, 12 Dec 2019 13:51:27 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176685; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=CqcFjajQ5UBMaXVKHioia2bdd8iqKaf+3SRExQdgpO0=; b=kXvpP2Gm4tYyGSVLsGY1LZEnnekTGgIMz3CpbKSmFQzK9rAJwF4xd6RPLq2b6qXT zH3kR0obqV48HoPeHkPcOBe+xmzRiQ8I4dpHSTMuYUo788yg1nAqY27U44bkWmnPa+6 7eXzDg3BknYYsxz9CX37l/ciHt5G4j8NYO5pFLUQ= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176685; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=CqcFjajQ5UBMaXVKHioia2bdd8iqKaf+3SRExQdgpO0=; b=hBdd5I0TcFiBeNmxjdPv3PFigvKyZP3nECMlnpXXg1673WNoW4h5oDjNmvczmAiz NCk8Pi6I6JRJ49bWXytf1lYcA0gngW8kQ6Na21/4hx9DHtr2YY39q/hiUX+50xpTEgF 7r2ywReYtr1+Fv6sF1SaZIUeYP3hpDvcFRBIQHOk= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 07F37C447AA Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 16/17] firmware: qcom_scm: Remove thin wrappers Date: Thu, 12 Dec 2019 18:51:24 +0000 Message-ID: <0101016efb738f9b-12af5376-f0a6-4e52-96b7-90dab9d64dc2-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.56 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org qcom_scm-32 and qcom_scm-64 implementations are nearly identical, so make qcom_scm_call and qcom_scm_call_atomic unique to each and the SCM descriptor creation common to each. There are the following catches: - __qcom_scm_is_call_available is still in each -32,-64 implementation as the argument is unique to each convention - For some functions, only one implementation was provided in -32 or -64. The actual implementation was moved into qcom_scm.c - io_writel and io_readl in -64 were non-atomic calls and in -32 they were. Atomic is the better option, so use it. Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 461 +---------------------------------------- drivers/firmware/qcom_scm-64.c | 434 +------------------------------------- drivers/firmware/qcom_scm.c | 392 ++++++++++++++++++++++++++++++++--- drivers/firmware/qcom_scm.h | 87 ++++---- 4 files changed, 426 insertions(+), 948 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index e9b396c..08220e7 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -15,75 +15,8 @@ #include "qcom_scm.h" -#define QCOM_SCM_FLAG_COLDBOOT_CPU0 0x00 -#define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x01 -#define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x08 -#define QCOM_SCM_FLAG_COLDBOOT_CPU3 0x20 - -#define QCOM_SCM_FLAG_WARMBOOT_CPU0 0x04 -#define QCOM_SCM_FLAG_WARMBOOT_CPU1 0x02 -#define QCOM_SCM_FLAG_WARMBOOT_CPU2 0x10 -#define QCOM_SCM_FLAG_WARMBOOT_CPU3 0x40 - -struct qcom_scm_entry { - int flag; - void *entry; -}; - -static struct qcom_scm_entry qcom_scm_wb[] = { - { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 }, - { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 }, - { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 }, - { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 }, -}; - static DEFINE_MUTEX(qcom_scm_lock); -#define MAX_QCOM_SCM_ARGS 10 -#define MAX_QCOM_SCM_RETS 3 - -enum qcom_scm_arg_types { - QCOM_SCM_VAL, - QCOM_SCM_RO, - QCOM_SCM_RW, - QCOM_SCM_BUFVAL, -}; - -#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\ - (((a) & 0x3) << 4) | \ - (((b) & 0x3) << 6) | \ - (((c) & 0x3) << 8) | \ - (((d) & 0x3) << 10) | \ - (((e) & 0x3) << 12) | \ - (((f) & 0x3) << 14) | \ - (((g) & 0x3) << 16) | \ - (((h) & 0x3) << 18) | \ - (((i) & 0x3) << 20) | \ - (((j) & 0x3) << 22) | \ - ((num) & 0xf)) - -#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - -/** - * struct qcom_scm_desc - * @arginfo: Metadata describing the arguments in args[] - * @args: The array of arguments for the secure syscall - */ -struct qcom_scm_desc { - u32 svc; - u32 cmd; - u32 arginfo; - u64 args[MAX_QCOM_SCM_ARGS]; - u32 owner; -}; - -/** - * struct qcom_scm_res - * @result: The values returned by the secure syscall - */ -struct qcom_scm_res { - u64 result[MAX_QCOM_SCM_RETS]; -}; /** * struct arm_smccc_args @@ -196,7 +129,7 @@ static void __scm_legacy_do(const struct arm_smccc_args *smc, * and response buffers is taken care of by qcom_scm_call; however, callers are * responsible for any other cached buffers passed over to the secure world. */ -static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, +int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, struct qcom_scm_res *res) { u8 arglen = desc->arginfo & 0xf; @@ -285,9 +218,9 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, * This shall only be used with commands that are guaranteed to be * uninterruptable, atomic and SMP safe. */ -static int qcom_scm_call_atomic(struct device *unused, - const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) +int qcom_scm_call_atomic(struct device *unused, + const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { int context_id; struct arm_smccc_res smc_res; @@ -309,113 +242,6 @@ static int qcom_scm_call_atomic(struct device *unused, return smc_res.a0; } -/** - * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus - * @entry: Entry point function for the cpus - * @cpus: The cpumask of cpus that will use the entry point - * - * Set the cold boot address of the cpus. Any cpu outside the supported - * range would be removed from the cpu present mask. - */ -int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, - const cpumask_t *cpus) -{ - int flags = 0; - int cpu; - int scm_cb_flags[] = { - QCOM_SCM_FLAG_COLDBOOT_CPU0, - QCOM_SCM_FLAG_COLDBOOT_CPU1, - QCOM_SCM_FLAG_COLDBOOT_CPU2, - QCOM_SCM_FLAG_COLDBOOT_CPU3, - }; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_SET_ADDR, - }; - - if (!cpus || (cpus && cpumask_empty(cpus))) - return -EINVAL; - - for_each_cpu(cpu, cpus) { - if (cpu < ARRAY_SIZE(scm_cb_flags)) - flags |= scm_cb_flags[cpu]; - else - set_cpu_present(cpu, false); - } - - desc.args[0] = flags; - desc.args[1] = virt_to_phys(entry); - desc.arginfo = QCOM_SCM_ARGS(2); - - return qcom_scm_call_atomic(dev, &desc, NULL); -} - -/** - * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus - * @entry: Entry point function for the cpus - * @cpus: The cpumask of cpus that will use the entry point - * - * Set the Linux entry point for the SCM to transfer control to when coming - * out of a power down. CPU power down may be executed on cpuidle or hotplug. - */ -int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, - const cpumask_t *cpus) -{ - int ret; - int flags = 0; - int cpu; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_SET_ADDR, - }; - - /* - * Reassign only if we are switching from hotplug entry point - * to cpuidle entry point or vice versa. - */ - for_each_cpu(cpu, cpus) { - if (entry == qcom_scm_wb[cpu].entry) - continue; - flags |= qcom_scm_wb[cpu].flag; - } - - /* No change in entry function */ - if (!flags) - return 0; - - desc.args[0] = flags; - desc.args[1] = virt_to_phys(entry); - desc.arginfo = QCOM_SCM_ARGS(2); - - ret = qcom_scm_call(dev, &desc, NULL); - if (!ret) { - for_each_cpu(cpu, cpus) - qcom_scm_wb[cpu].entry = entry; - } - - return ret; -} - -/** - * qcom_scm_cpu_power_down() - Power down the cpu - * @flags - Flags to flush cache - * - * This is an end point to power down cpu. If there was a pending interrupt, - * the control would return from this function, otherwise, the cpu jumps to the - * warm boot entry point set for this cpu upon reset. - */ -void __qcom_scm_cpu_power_down(struct device *dev, u32 flags) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_TERMINATE_PC, - .args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK, - .arginfo = QCOM_SCM_ARGS(1), - }; - - qcom_scm_call_atomic(dev, &desc, NULL); -} - int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; @@ -432,285 +258,6 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) return ret ? : res.result[0]; } -int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, - u32 req_cnt, u32 *resp) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_HDCP, - .cmd = QCOM_SCM_HDCP_INVOKE, - }; - struct qcom_scm_res res; - - if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) - return -ERANGE; - - desc.args[0] = req[0].addr; - desc.args[1] = req[0].val; - desc.args[2] = req[1].addr; - desc.args[3] = req[1].val; - desc.args[4] = req[2].addr; - desc.args[5] = req[2].val; - desc.args[6] = req[3].addr; - desc.args[7] = req[3].val; - desc.args[8] = req[4].addr; - desc.args[9] = req[4].val; - desc.arginfo = QCOM_SCM_ARGS(10); - - ret = qcom_scm_call(dev, &desc, &res); - *resp = res.result[0]; - - return ret; -} - -int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, u32 size, - u32 mode) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_OCMEM, - .cmd = QCOM_SCM_OCMEM_LOCK_CMD, - }; - - desc.args[0] = id; - desc.args[1] = offset; - desc.args[2] = size; - desc.args[3] = mode; - desc.arginfo = QCOM_SCM_ARGS(4); - - return qcom_scm_call(dev, &desc, NULL); -} - -int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, u32 size) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_OCMEM, - .cmd = QCOM_SCM_OCMEM_UNLOCK_CMD, - }; - - desc.args[0] = id; - desc.args[1] = offset; - desc.args[2] = size; - desc.arginfo = QCOM_SCM_ARGS(3); - - return qcom_scm_call(dev, &desc, NULL); -} - void __qcom_scm_init(void) { } - -bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? false : !!res.result[0]; -} - -int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, - dma_addr_t metadata_phys) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.args[1] = metadata_phys; - desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, - phys_addr_t addr, phys_addr_t size) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.args[1] = addr; - desc.args[2] = size; - desc.arginfo = QCOM_SCM_ARGS(3); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = reset; - desc.args[1] = 0; - desc.arginfo = QCOM_SCM_ARGS(2); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_set_dload_mode(struct device *dev, bool enable) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, - }; - - desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; - desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; - desc.arginfo = QCOM_SCM_ARGS(2); - - return qcom_scm_call_atomic(dev, &desc, NULL); -} - -int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = state; - desc.args[1] = id; - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, - size_t mem_sz, phys_addr_t src, size_t src_sz, - phys_addr_t dest, size_t dest_sz) -{ - return -ENODEV; -} - -int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, - u32 spare) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_MP, - .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = device_id; - desc.args[1] = spare; - desc.arginfo = QCOM_SCM_ARGS(2); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, - size_t *size) -{ - return -ENODEV; -} - -int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, - u32 spare) -{ - return -ENODEV; -} - -int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, - unsigned int *val) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_IO, - .cmd = QCOM_SCM_IO_READ, - }; - struct qcom_scm_res res; - - desc.args[0] = addr; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call_atomic(dev, &desc, &res); - if (ret >= 0) - *val = res.result[0]; - - return ret < 0 ? ret : 0; -} - -int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_IO, - .cmd = QCOM_SCM_IO_WRITE, - }; - - desc.args[0] = addr; - desc.args[1] = val; - desc.arginfo = QCOM_SCM_ARGS(2); - - return qcom_scm_call_atomic(dev, &desc, NULL); -} - -int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable) -{ - return -ENODEV; -} diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 9507047..4defc7c 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -16,52 +16,6 @@ #define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) -#define MAX_QCOM_SCM_ARGS 10 -#define MAX_QCOM_SCM_RETS 3 - -enum qcom_scm_arg_types { - QCOM_SCM_VAL, - QCOM_SCM_RO, - QCOM_SCM_RW, - QCOM_SCM_BUFVAL, -}; - -#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\ - (((a) & 0x3) << 4) | \ - (((b) & 0x3) << 6) | \ - (((c) & 0x3) << 8) | \ - (((d) & 0x3) << 10) | \ - (((e) & 0x3) << 12) | \ - (((f) & 0x3) << 14) | \ - (((g) & 0x3) << 16) | \ - (((h) & 0x3) << 18) | \ - (((i) & 0x3) << 20) | \ - (((j) & 0x3) << 22) | \ - ((num) & 0xf)) - -#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - -/** - * struct qcom_scm_desc - * @arginfo: Metadata describing the arguments in args[] - * @args: The array of arguments for the secure syscall - */ -struct qcom_scm_desc { - u32 svc; - u32 cmd; - u32 arginfo; - u64 args[MAX_QCOM_SCM_ARGS]; - u32 owner; -}; - -/** - * struct qcom_scm_res - * @result: The values returned by the secure syscall - */ -struct qcom_scm_res { - u64 result[MAX_QCOM_SCM_RETS]; -}; - /** * struct arm_smccc_args * @args: The array of values used in registers in smc instruction @@ -206,8 +160,8 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, * Sends a command to the SCM and waits for the command to finish processing. * This should *only* be called in pre-emptible context. */ -static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) +int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { might_sleep(); return __scm_smc_call(dev, desc, res, false); @@ -224,54 +178,12 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, * Sends a command to the SCM and waits for the command to finish processing. * This can be called in atomic context. */ -static int qcom_scm_call_atomic(struct device *dev, - const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) +int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { return __scm_smc_call(dev, desc, res, true); } -/** - * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus - * @entry: Entry point function for the cpus - * @cpus: The cpumask of cpus that will use the entry point - * - * Set the cold boot address of the cpus. Any cpu outside the supported - * range would be removed from the cpu present mask. - */ -int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, - const cpumask_t *cpus) -{ - return -ENOTSUPP; -} - -/** - * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus - * @dev: Device pointer - * @entry: Entry point function for the cpus - * @cpus: The cpumask of cpus that will use the entry point - * - * Set the Linux entry point for the SCM to transfer control to when coming - * out of a power down. CPU power down may be executed on cpuidle or hotplug. - */ -int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, - const cpumask_t *cpus) -{ - return -ENOTSUPP; -} - -/** - * qcom_scm_cpu_power_down() - Power down the cpu - * @flags - Flags to flush cache - * - * This is an end point to power down cpu. If there was a pending interrupt, - * the control would return from this function, otherwise, the cpu jumps to the - * warm boot entry point set for this cpu upon reset. - */ -void __qcom_scm_cpu_power_down(struct device *dev, u32 flags) -{ -} - int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) { int ret; @@ -291,50 +203,6 @@ int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) return ret ? : res.result[0]; } -int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, - u32 req_cnt, u32 *resp) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_HDCP, - .cmd = QCOM_SCM_HDCP_INVOKE, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) - return -ERANGE; - - desc.args[0] = req[0].addr; - desc.args[1] = req[0].val; - desc.args[2] = req[1].addr; - desc.args[3] = req[1].val; - desc.args[4] = req[2].addr; - desc.args[5] = req[2].val; - desc.args[6] = req[3].addr; - desc.args[7] = req[3].val; - desc.args[8] = req[4].addr; - desc.args[9] = req[4].val; - desc.arginfo = QCOM_SCM_ARGS(10); - - ret = qcom_scm_call(dev, &desc, &res); - *resp = res.result[0]; - - return ret; -} - -int __qcom_scm_ocmem_lock(struct device *dev, uint32_t id, uint32_t offset, - uint32_t size, uint32_t mode) -{ - return -ENOTSUPP; -} - -int __qcom_scm_ocmem_unlock(struct device *dev, uint32_t id, uint32_t offset, - uint32_t size) -{ - return -ENOTSUPP; -} - void __qcom_scm_init(void) { struct qcom_scm_desc desc = { @@ -366,297 +234,3 @@ void __qcom_scm_init(void) out: pr_info("QCOM SCM SMC Convention: %lld\n", qcom_smccc_convention); } - -bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? false : !!res.result[0]; -} - -int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, - dma_addr_t metadata_phys) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.args[1] = metadata_phys; - desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, - phys_addr_t addr, phys_addr_t size) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.args[1] = addr; - desc.args[2] = size; - desc.arginfo = QCOM_SCM_ARGS(3); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.args[0] = peripheral; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_PIL, - .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = reset; - desc.args[1] = 0; - desc.arginfo = QCOM_SCM_ARGS(2); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = state; - desc.args[1] = id; - desc.arginfo = QCOM_SCM_ARGS(2); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, - size_t mem_sz, phys_addr_t src, size_t src_sz, - phys_addr_t dest, size_t dest_sz) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_MP, - .cmd = QCOM_SCM_MP_ASSIGN, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.args[0] = mem_region; - desc.args[1] = mem_sz; - desc.args[2] = src; - desc.args[3] = src_sz; - desc.args[4] = dest; - desc.args[5] = dest_sz; - desc.args[6] = 0; - - desc.arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL, - QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, - QCOM_SCM_VAL, QCOM_SCM_VAL); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_MP, - .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = device_id; - desc.args[1] = spare; - desc.arginfo = QCOM_SCM_ARGS(2); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, - size_t *size) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_MP, - .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = spare; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - - if (size) - *size = res.result[0]; - - return ret ? : res.result[1]; -} - -int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, - u32 spare) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_MP, - .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, - .owner = ARM_SMCCC_OWNER_SIP, - }; - int ret; - - desc.args[0] = addr; - desc.args[1] = size; - desc.args[2] = spare; - desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, - QCOM_SCM_VAL); - - ret = qcom_scm_call(dev, &desc, NULL); - - /* the pg table has been initialized already, ignore the error */ - if (ret == -EPERM) - ret = 0; - - return ret; -} - -int __qcom_scm_set_dload_mode(struct device *dev, bool enable) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_BOOT, - .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, - .owner = ARM_SMCCC_OWNER_SIP, - }; - - desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; - desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; - desc.arginfo = QCOM_SCM_ARGS(2); - - return qcom_scm_call(dev, &desc, NULL); -} - -int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, - unsigned int *val) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_IO, - .cmd = QCOM_SCM_IO_READ, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - int ret; - - desc.args[0] = addr; - desc.arginfo = QCOM_SCM_ARGS(1); - - ret = qcom_scm_call(dev, &desc, &res); - if (ret >= 0) - *val = res.result[0]; - - return ret < 0 ? ret : 0; -} - -int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_IO, - .cmd = QCOM_SCM_IO_WRITE, - .owner = ARM_SMCCC_OWNER_SIP, - }; - - desc.args[0] = addr; - desc.args[1] = val; - desc.arginfo = QCOM_SCM_ARGS(2); - - return qcom_scm_call(dev, &desc, NULL); -} - -int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_SMMU_PROGRAM, - .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1, - .owner = ARM_SMCCC_OWNER_SIP, - }; - - desc.args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL; - desc.args[1] = en; - desc.arginfo = QCOM_SCM_ARGS(2); - - return qcom_scm_call_atomic(dev, &desc, NULL); -} diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 5ba4c85..b29e6c1 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "qcom_scm.h" @@ -49,6 +50,28 @@ struct qcom_scm_mem_map_info { __le64 mem_size; }; +#define QCOM_SCM_FLAG_COLDBOOT_CPU0 0x00 +#define QCOM_SCM_FLAG_COLDBOOT_CPU1 0x01 +#define QCOM_SCM_FLAG_COLDBOOT_CPU2 0x08 +#define QCOM_SCM_FLAG_COLDBOOT_CPU3 0x20 + +#define QCOM_SCM_FLAG_WARMBOOT_CPU0 0x04 +#define QCOM_SCM_FLAG_WARMBOOT_CPU1 0x02 +#define QCOM_SCM_FLAG_WARMBOOT_CPU2 0x10 +#define QCOM_SCM_FLAG_WARMBOOT_CPU3 0x40 + +struct qcom_scm_wb_entry { + int flag; + void *entry; +}; + +static struct qcom_scm_wb_entry qcom_scm_wb[] = { + { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 }, + { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 }, + { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 }, + { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 }, +}; + static struct qcom_scm *__scm; static int qcom_scm_clk_enable(void) @@ -94,7 +117,39 @@ static void qcom_scm_clk_disable(void) */ int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) { - return __qcom_scm_set_warm_boot_addr(__scm->dev, entry, cpus); + int ret; + int flags = 0; + int cpu; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_ADDR, + .arginfo = QCOM_SCM_ARGS(2), + }; + + /* + * Reassign only if we are switching from hotplug entry point + * to cpuidle entry point or vice versa. + */ + for_each_cpu(cpu, cpus) { + if (entry == qcom_scm_wb[cpu].entry) + continue; + flags |= qcom_scm_wb[cpu].flag; + } + + /* No change in entry function */ + if (!flags) + return 0; + + desc.args[0] = flags; + desc.args[1] = virt_to_phys(entry); + + ret = qcom_scm_call(__scm->dev, &desc, NULL); + if (!ret) { + for_each_cpu(cpu, cpus) + qcom_scm_wb[cpu].entry = entry; + } + + return ret; } EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); @@ -108,8 +163,35 @@ EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); */ int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) { - return __qcom_scm_set_cold_boot_addr(__scm ? __scm->dev : NULL, entry, - cpus); + int flags = 0; + int cpu; + int scm_cb_flags[] = { + QCOM_SCM_FLAG_COLDBOOT_CPU0, + QCOM_SCM_FLAG_COLDBOOT_CPU1, + QCOM_SCM_FLAG_COLDBOOT_CPU2, + QCOM_SCM_FLAG_COLDBOOT_CPU3, + }; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_ADDR, + .arginfo = QCOM_SCM_ARGS(2), + .owner = ARM_SMCCC_OWNER_SIP, + }; + + if (!cpus || (cpus && cpumask_empty(cpus))) + return -EINVAL; + + for_each_cpu(cpu, cpus) { + if (cpu < ARRAY_SIZE(scm_cb_flags)) + flags |= scm_cb_flags[cpu]; + else + set_cpu_present(cpu, false); + } + + desc.args[0] = flags; + desc.args[1] = virt_to_phys(entry); + + return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL); } EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); @@ -123,16 +205,52 @@ EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); */ void qcom_scm_cpu_power_down(u32 flags) { - __qcom_scm_cpu_power_down(__scm ? __scm->dev : NULL, flags); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_TERMINATE_PC, + .args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK, + .arginfo = QCOM_SCM_ARGS(1), + .owner = ARM_SMCCC_OWNER_SIP, + }; + + qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL); } EXPORT_SYMBOL(qcom_scm_cpu_power_down); int qcom_scm_set_remote_state(u32 state, u32 id) { - return __qcom_scm_set_remote_state(__scm->dev, state, id); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = state, + .args[1] = id, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; } EXPORT_SYMBOL(qcom_scm_set_remote_state); +static int __qcom_scm_set_dload_mode(struct device *dev, bool enable) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; + + return qcom_scm_call(__scm->dev, &desc, NULL); +} + static void qcom_scm_set_download_mode(bool enable) { bool avail; @@ -144,8 +262,8 @@ static void qcom_scm_set_download_mode(bool enable) if (avail) { ret = __qcom_scm_set_dload_mode(__scm->dev, enable); } else if (__scm->dload_mode_addr) { - ret = __qcom_scm_io_writel(__scm->dev, __scm->dload_mode_addr, - enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); + ret = qcom_scm_io_writel(__scm->dload_mode_addr, + enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); } else { dev_err(__scm->dev, "No available mechanism for setting download mode\n"); @@ -172,6 +290,14 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) dma_addr_t mdata_phys; void *mdata_buf; int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE, + .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW), + .args[0] = peripheral, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; /* * During the scm call memory protection will be enabled for the meta @@ -190,14 +316,16 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) if (ret) goto free_metadata; - ret = __qcom_scm_pas_init_image(__scm->dev, peripheral, mdata_phys); + desc.args[1] = mdata_phys; + + ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_clk_disable(); free_metadata: dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys); - return ret; + return ret ? : res.result[0]; } EXPORT_SYMBOL(qcom_scm_pas_init_image); @@ -213,15 +341,25 @@ EXPORT_SYMBOL(qcom_scm_pas_init_image); int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) { int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP, + .arginfo = QCOM_SCM_ARGS(3), + .args[0] = peripheral, + .args[1] = addr, + .args[2] = size, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; ret = qcom_scm_clk_enable(); if (ret) return ret; - ret = __qcom_scm_pas_mem_setup(__scm->dev, peripheral, addr, size); + ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_clk_disable(); - return ret; + return ret ? : res.result[0]; } EXPORT_SYMBOL(qcom_scm_pas_mem_setup); @@ -235,15 +373,21 @@ EXPORT_SYMBOL(qcom_scm_pas_mem_setup); int qcom_scm_pas_auth_and_reset(u32 peripheral) { int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; ret = qcom_scm_clk_enable(); if (ret) return ret; - ret = __qcom_scm_pas_auth_and_reset(__scm->dev, peripheral); + ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_clk_disable(); - return ret; + return ret ? : res.result[0]; } EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset); @@ -256,15 +400,24 @@ EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset); int qcom_scm_pas_shutdown(u32 peripheral) { int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = peripheral, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; ret = qcom_scm_clk_enable(); if (ret) return ret; - ret = __qcom_scm_pas_shutdown(__scm->dev, peripheral); + ret = qcom_scm_call(__scm->dev, &desc, &res); + qcom_scm_clk_disable(); - return ret; + return ret ? : res.result[0]; } EXPORT_SYMBOL(qcom_scm_pas_shutdown); @@ -278,16 +431,44 @@ EXPORT_SYMBOL(qcom_scm_pas_shutdown); bool qcom_scm_pas_supported(u32 peripheral) { int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = peripheral, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PIL_PAS_IS_SUPPORTED); if (ret <= 0) return false; - return __qcom_scm_pas_supported(__scm->dev, peripheral); + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? false : !!res.result[0]; } EXPORT_SYMBOL(qcom_scm_pas_supported); +static int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_PIL, + .cmd = QCOM_SCM_PIL_PAS_MSS_RESET, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = reset, + .args[1] = 0, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; +} + static int qcom_scm_pas_reset_assert(struct reset_controller_dev *rcdev, unsigned long idx) { @@ -313,13 +494,38 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = { int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) { - return __qcom_scm_io_readl(__scm->dev, addr, val); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_READ, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = addr, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + + ret = qcom_scm_call(__scm->dev, &desc, &res); + if (ret >= 0) + *val = res.result[0]; + + return ret < 0 ? ret : 0; } EXPORT_SYMBOL(qcom_scm_io_readl); int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) { - return __qcom_scm_io_writel(__scm->dev, addr, val); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_WRITE, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = addr, + .args[1] = val, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + + return qcom_scm_call(__scm->dev, &desc, NULL); } EXPORT_SYMBOL(qcom_scm_io_writel); @@ -338,22 +544,101 @@ EXPORT_SYMBOL(qcom_scm_restore_sec_cfg_available); int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { - return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = device_id, + .args[1] = spare, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ? : res.result[0]; } EXPORT_SYMBOL(qcom_scm_restore_sec_cfg); int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { - return __qcom_scm_iommu_secure_ptbl_size(__scm->dev, spare, size); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE, + .arginfo = QCOM_SCM_ARGS(1), + .args[0] = spare, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + if (size) + *size = res.result[0]; + + return ret ? : res.result[1]; } EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_size); int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { - return __qcom_scm_iommu_secure_ptbl_init(__scm->dev, addr, size, spare); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT, + .arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, + QCOM_SCM_VAL), + .args[0] = addr, + .args[1] = size, + .args[2] = spare, + .owner = ARM_SMCCC_OWNER_SIP, + }; + int ret; + + desc.args[0] = addr; + desc.args[1] = size; + desc.args[2] = spare; + desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, + QCOM_SCM_VAL); + + ret = qcom_scm_call(__scm->dev, &desc, NULL); + + /* the pg table has been initialized already, ignore the error */ + if (ret == -EPERM) + ret = 0; + + return ret; } EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); +static int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, + size_t mem_sz, phys_addr_t src, size_t src_sz, + phys_addr_t dest, size_t dest_sz) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_ASSIGN, + .arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL, + QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO, + QCOM_SCM_VAL, QCOM_SCM_VAL), + .args[0] = mem_region, + .args[1] = mem_sz, + .args[2] = src, + .args[3] = src_sz, + .args[4] = dest, + .args[5] = dest_sz, + .args[6] = 0, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + + ret = qcom_scm_call(dev, &desc, &res); + + return ret ? : res.result[0]; +} + /** * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership * @mem_addr: mem region whose ownership need to be reassigned @@ -458,7 +743,17 @@ EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset, u32 size, u32 mode) { - return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_OCMEM, + .cmd = QCOM_SCM_OCMEM_LOCK_CMD, + .args[0] = id, + .args[1] = offset, + .args[2] = size, + .args[3] = mode, + .arginfo = QCOM_SCM_ARGS(4), + }; + + return qcom_scm_call(__scm->dev, &desc, NULL); } EXPORT_SYMBOL(qcom_scm_ocmem_lock); @@ -472,7 +767,16 @@ EXPORT_SYMBOL(qcom_scm_ocmem_lock); */ int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id, u32 offset, u32 size) { - return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_OCMEM, + .cmd = QCOM_SCM_OCMEM_UNLOCK_CMD, + .args[0] = id, + .args[1] = offset, + .args[2] = size, + .arginfo = QCOM_SCM_ARGS(3), + }; + + return qcom_scm_call(__scm->dev, &desc, NULL); } EXPORT_SYMBOL(qcom_scm_ocmem_unlock); @@ -507,20 +811,56 @@ EXPORT_SYMBOL(qcom_scm_hdcp_available); */ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { - int ret = qcom_scm_clk_enable(); + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_HDCP, + .cmd = QCOM_SCM_HDCP_INVOKE, + .arginfo = QCOM_SCM_ARGS(10), + .args = { + req[0].addr, + req[0].val, + req[1].addr, + req[1].val, + req[2].addr, + req[2].val, + req[3].addr, + req[3].val, + req[4].addr, + req[4].val + }, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + + if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT) + return -ERANGE; + ret = qcom_scm_clk_enable(); if (ret) return ret; - ret = __qcom_scm_hdcp_req(__scm->dev, req, req_cnt, resp); + ret = qcom_scm_call(__scm->dev, &desc, &res); + *resp = res.result[0]; + qcom_scm_clk_disable(); + return ret; } EXPORT_SYMBOL(qcom_scm_hdcp_req); int qcom_scm_qsmmu500_wait_safe_toggle(bool en) { - return __qcom_scm_qsmmu500_wait_safe_toggle(__scm->dev, en); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_SMMU_PROGRAM, + .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL, + .args[1] = en, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + + return qcom_scm_call_atomic(__scm->dev, &desc, NULL); } EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle); diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 56ace3b..9b7b357 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -3,19 +3,64 @@ */ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H +#define MAX_QCOM_SCM_ARGS 10 +#define MAX_QCOM_SCM_RETS 3 + +enum qcom_scm_arg_types { + QCOM_SCM_VAL, + QCOM_SCM_RO, + QCOM_SCM_RW, + QCOM_SCM_BUFVAL, +}; + +#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\ + (((a) & 0x3) << 4) | \ + (((b) & 0x3) << 6) | \ + (((c) & 0x3) << 8) | \ + (((d) & 0x3) << 10) | \ + (((e) & 0x3) << 12) | \ + (((f) & 0x3) << 14) | \ + (((g) & 0x3) << 16) | \ + (((h) & 0x3) << 18) | \ + (((i) & 0x3) << 20) | \ + (((j) & 0x3) << 22) | \ + ((num) & 0xf)) + +#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + + +/** + * struct qcom_scm_desc + * @arginfo: Metadata describing the arguments in args[] + * @args: The array of arguments for the secure syscall + */ +struct qcom_scm_desc { + u32 svc; + u32 cmd; + u32 arginfo; + u64 args[MAX_QCOM_SCM_ARGS]; + u32 owner; +}; + +/** + * struct qcom_scm_res + * @result: The values returned by the secure syscall + */ +struct qcom_scm_res { + u64 result[MAX_QCOM_SCM_RETS]; +}; + +extern int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res); +extern int qcom_scm_call_atomic(struct device *dev, + const struct qcom_scm_desc *desc, + struct qcom_scm_res *res); #define QCOM_SCM_SVC_BOOT 0x01 #define QCOM_SCM_BOOT_SET_ADDR 0x01 #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a -extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, - const cpumask_t *cpus); -extern int __qcom_scm_set_cold_boot_addr(struct device *dev, void *entry, - const cpumask_t *cpus); -extern void __qcom_scm_cpu_power_down(struct device *dev, u32 flags); -extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id); -extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); #define QCOM_SCM_FLUSH_FLAG_MASK 0x3 #define QCOM_SCM_SVC_PIL 0x02 @@ -25,20 +70,10 @@ extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable); #define QCOM_SCM_PIL_PAS_SHUTDOWN 0x06 #define QCOM_SCM_PIL_PAS_IS_SUPPORTED 0x07 #define QCOM_SCM_PIL_PAS_MSS_RESET 0x0a -extern bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral); -extern int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral, - dma_addr_t metadata_phys); -extern int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral, - phys_addr_t addr, phys_addr_t size); -extern int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral); -extern int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral); -extern int __qcom_scm_pas_mss_reset(struct device *dev, bool reset); #define QCOM_SCM_SVC_IO 0x05 #define QCOM_SCM_IO_READ 0x01 #define QCOM_SCM_IO_WRITE 0x02 -extern int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val); -extern int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val); #define QCOM_SCM_SVC_INFO 0x06 #define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01 @@ -50,35 +85,17 @@ extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04 #define QCOM_SCM_MP_ASSIGN 0x16 -extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, - u32 spare); -extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, - size_t *size); -extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, - u32 size, u32 spare); -extern int __qcom_scm_assign_mem(struct device *dev, - phys_addr_t mem_region, size_t mem_sz, - phys_addr_t src, size_t src_sz, - phys_addr_t dest, size_t dest_sz); #define QCOM_SCM_SVC_OCMEM 0x0f #define QCOM_SCM_OCMEM_LOCK_CMD 0x01 #define QCOM_SCM_OCMEM_UNLOCK_CMD 0x02 -extern int __qcom_scm_ocmem_lock(struct device *dev, u32 id, u32 offset, - u32 size, u32 mode); -extern int __qcom_scm_ocmem_unlock(struct device *dev, u32 id, u32 offset, - u32 size); #define QCOM_SCM_SVC_HDCP 0x11 #define QCOM_SCM_HDCP_INVOKE 0x01 -extern int __qcom_scm_hdcp_req(struct device *dev, - struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); #define QCOM_SCM_SVC_SMMU_PROGRAM 0x15 #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 -extern int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, - bool enable); extern void __qcom_scm_init(void); From patchwork Thu Dec 12 18:51:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 11289173 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 13659109A for ; Thu, 12 Dec 2019 18:51:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C85782464B for ; Thu, 12 Dec 2019 18:51:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="H/FVd886"; dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="Ib+gVQ9W" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730691AbfLLSvi (ORCPT ); Thu, 12 Dec 2019 13:51:38 -0500 Received: from a27-18.smtp-out.us-west-2.amazonses.com ([54.240.27.18]:39284 "EHLO a27-18.smtp-out.us-west-2.amazonses.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730688AbfLLSvZ (ORCPT ); Thu, 12 Dec 2019 13:51:25 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zsmsymrwgfyinv5wlfyidntwsjeeldzt; d=codeaurora.org; t=1576176684; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; bh=MirJA0v7lGICf52JDfcFqU6v/FyaNOnqWSn0MPZGtMw=; b=H/FVd886NSDU5UHSaqCaOp/2zAUP2j9RHp1qkyS4pJPquUm6+dGaGOHMwbfhWIBg hYih8pOTimFtnNIFGcqgOYmX1jsO7S7Z/OiqnjwMTlpo0Syhwrz6d+ALSpgIhQ1wlMP NC9npeZqfMvtJOdaQXk1MVbxl4vEXzFCBznyIJ+c= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1576176684; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:Feedback-ID; bh=MirJA0v7lGICf52JDfcFqU6v/FyaNOnqWSn0MPZGtMw=; b=Ib+gVQ9WKzQM4g5ScILFcmLluKYk3E72ND8JCkF3cWUDSW92rpqAm+BdE2WRZu4U cCV0B58DTFL0rRggV525hruyZK9RCYxenXU/Rc65fedoI+OCLKOKFrk0wyI06gfscFG nxSLvWoc/dbLiC64zs4696/0+IhxZ9VDrRx9bqQk= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org DB9D2C447A2 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: bjorn.andersson@linaro.org, agross@kernel.org, swboyd@chromium.org Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 17/17] firmware: qcom_scm: Dynamically support SMCCC and legacy conventions Date: Thu, 12 Dec 2019 18:51:24 +0000 Message-ID: <0101016efb738cea-f84e3fa3-3962-4389-9d6a-c1ae29cf4aa0-000000@us-west-2.amazonses.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> References: <1576176651-17089-1-git-send-email-eberman@codeaurora.org> X-SES-Outgoing: 2019.12.12-54.240.27.18 Feedback-ID: 1.us-west-2.CZuq2qbDmUIuT3qdvXlRHZZCpfZqZ4GtG9v3VKgRyF0=:AmazonSES Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Dynamically support SMCCCC and legacy conventions by detecting which convention to use at runtime. qcom_scm_call_atomic and qcom_scm_call can then be moved in qcom_scm.c and use underlying convention backend as appropriate. Thus, rename qcom_scm-64,-32 to reflect that they are backends for -smc and -legacy, respectively. Also add support for making SCM calls earlier than when SCM driver probes to support use cases such as qcom_scm_set_cold_boot_addr. Support is added by lazily initializing the convention and guarding the query with a spin lock. The limitation of these early SCM calls is that they cannot use DMA, as in the case of >4 arguments for SMC convention and any non-atomic call for legacy convention. Signed-off-by: Elliot Berman --- drivers/firmware/Kconfig | 8 -- drivers/firmware/Makefile | 4 +- .../firmware/{qcom_scm-32.c => qcom_scm-legacy.c} | 31 +---- drivers/firmware/{qcom_scm-64.c => qcom_scm-smc.c} | 95 +------------- drivers/firmware/qcom_scm.c | 146 ++++++++++++++++++++- drivers/firmware/qcom_scm.h | 27 +++- 6 files changed, 176 insertions(+), 135 deletions(-) rename drivers/firmware/{qcom_scm-32.c => qcom_scm-legacy.c} (90%) rename drivers/firmware/{qcom_scm-64.c => qcom_scm-smc.c} (57%) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index e40a77b..ea869ad 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -239,14 +239,6 @@ config QCOM_SCM depends on ARM || ARM64 select RESET_CONTROLLER -config QCOM_SCM_32 - def_bool y - depends on QCOM_SCM && ARM - -config QCOM_SCM_64 - def_bool y - depends on QCOM_SCM && ARM64 - config QCOM_SCM_DOWNLOAD_MODE_DEFAULT bool "Qualcomm download mode enabled by default" depends on QCOM_SCM diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 747fb73..e9fb838 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -17,9 +17,7 @@ obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o -obj-$(CONFIG_QCOM_SCM) += qcom_scm.o -obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o -obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o +obj-$(CONFIG_QCOM_SCM) += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o obj-$(CONFIG_TURRIS_MOX_RWTM) += turris-mox-rwtm.o diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-legacy.c similarity index 90% rename from drivers/firmware/qcom_scm-32.c rename to drivers/firmware/qcom_scm-legacy.c index 08220e7..8532e7c 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-legacy.c @@ -26,7 +26,6 @@ struct arm_smccc_args { unsigned long args[8]; }; -#define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff)) /** * struct scm_legacy_command - one SCM command buffer @@ -129,8 +128,8 @@ static void __scm_legacy_do(const struct arm_smccc_args *smc, * and response buffers is taken care of by qcom_scm_call; however, callers are * responsible for any other cached buffers passed over to the secure world. */ -int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) +int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { u8 arglen = desc->arginfo & 0xf; int ret = 0, context_id; @@ -218,9 +217,9 @@ int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, * This shall only be used with commands that are guaranteed to be * uninterruptable, atomic and SMP safe. */ -int qcom_scm_call_atomic(struct device *unused, - const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) +int scm_legacy_call_atomic(struct device *unused, + const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { int context_id; struct arm_smccc_res smc_res; @@ -241,23 +240,3 @@ int qcom_scm_call_atomic(struct device *unused, return smc_res.a0; } - -int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_INFO, - .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, - .args[0] = SCM_LEGACY_FNID(svc_id, cmd_id), - .arginfo = QCOM_SCM_ARGS(1), - }; - struct qcom_scm_res res; - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -void __qcom_scm_init(void) -{ -} diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-smc.c similarity index 57% rename from drivers/firmware/qcom_scm-64.c rename to drivers/firmware/qcom_scm-smc.c index 4defc7c..497c13b 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -14,8 +14,6 @@ #include "qcom_scm.h" -#define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) - /** * struct arm_smccc_args * @args: The array of values used in registers in smc instruction @@ -24,7 +22,6 @@ struct arm_smccc_args { unsigned long args[8]; }; -static u64 qcom_smccc_convention = -1; static DEFINE_MUTEX(qcom_scm_lock); #define QCOM_SCM_EBUSY_WAIT_MS 30 @@ -80,8 +77,8 @@ static void __scm_smc_do(const struct arm_smccc_args *smc, } while (res->a0 == QCOM_SCM_V2_EBUSY); } -static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, - struct qcom_scm_res *res, bool atomic) +int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; int i; @@ -90,6 +87,9 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, size_t alloc_len; gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL; u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL; + u32 qcom_smccc_convention = + (qcom_scm_convention == SMC_CONVENTION_ARM_32) ? + ARM_SMCCC_SMC_32 : ARM_SMCCC_SMC_64; struct arm_smccc_res smc_res; struct arm_smccc_args smc = {0}; @@ -149,88 +149,3 @@ static int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, return (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0; } - -/** - * qcom_scm_call() - Invoke a syscall in the secure world - * @dev: device - * @svc_id: service identifier - * @cmd_id: command identifier - * @desc: Descriptor structure containing arguments and return values - * - * Sends a command to the SCM and waits for the command to finish processing. - * This should *only* be called in pre-emptible context. - */ -int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) -{ - might_sleep(); - return __scm_smc_call(dev, desc, res, false); -} - -/** - * qcom_scm_call_atomic() - atomic variation of qcom_scm_call() - * @dev: device - * @svc_id: service identifier - * @cmd_id: command identifier - * @desc: Descriptor structure containing arguments and return values - * @res: Structure containing results from SMC/HVC call - * - * Sends a command to the SCM and waits for the command to finish processing. - * This can be called in atomic context. - */ -int qcom_scm_call_atomic(struct device *dev, const struct qcom_scm_desc *desc, - struct qcom_scm_res *res) -{ - return __scm_smc_call(dev, desc, res, true); -} - -int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) -{ - int ret; - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_INFO, - .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - - desc.arginfo = QCOM_SCM_ARGS(1); - desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) | - (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); - - ret = qcom_scm_call(dev, &desc, &res); - - return ret ? : res.result[0]; -} - -void __qcom_scm_init(void) -{ - struct qcom_scm_desc desc = { - .svc = QCOM_SCM_SVC_INFO, - .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, - .args[0] = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, - QCOM_SCM_INFO_IS_CALL_AVAIL) | - (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT), - .arginfo = QCOM_SCM_ARGS(1), - .owner = ARM_SMCCC_OWNER_SIP, - }; - struct qcom_scm_res res; - int ret; - - qcom_smccc_convention = ARM_SMCCC_SMC_64; - // Device isn't required as there is only one argument - no device - // needed to dma_map_single to secure world - ret = qcom_scm_call_atomic(NULL, &desc, &res); - if (!ret && res.result[0] == 1) - goto out; - - qcom_smccc_convention = ARM_SMCCC_SMC_32; - ret = qcom_scm_call_atomic(NULL, &desc, &res); - if (!ret && res.result[0] == 1) - goto out; - - qcom_smccc_convention = -1; - BUG(); -out: - pr_info("QCOM SCM SMC Convention: %lld\n", qcom_smccc_convention); -} diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index b29e6c1..77da9e6 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -72,6 +72,13 @@ static struct qcom_scm_wb_entry qcom_scm_wb[] = { { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 }, }; +static const char *qcom_scm_convention_names[] = { + [SMC_CONVENTION_UNKNOWN] = "unknown", + [SMC_CONVENTION_ARM_32] = "smc arm 32", + [SMC_CONVENTION_ARM_64] = "smc arm 64", + [SMC_CONVENTION_LEGACY] = "smc legacy", +}; + static struct qcom_scm *__scm; static int qcom_scm_clk_enable(void) @@ -107,6 +114,143 @@ static void qcom_scm_clk_disable(void) clk_disable_unprepare(__scm->bus_clk); } +static int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, + u32 cmd_id); + +enum qcom_scm_convention qcom_scm_convention; +static bool has_queried __read_mostly; +static DEFINE_SPINLOCK(query_lock); + +static void __query_convention(void) +{ + unsigned long flags; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_INFO, + .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, + .args[0] = SCM_SMC_FNID(QCOM_SCM_SVC_INFO, + QCOM_SCM_INFO_IS_CALL_AVAIL) | + (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT), + .arginfo = QCOM_SCM_ARGS(1), + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + int ret; + + spin_lock_irqsave(&query_lock, flags); + if (has_queried) + goto out; + + qcom_scm_convention = SMC_CONVENTION_ARM_64; + // Device isn't required as there is only one argument - no device + // needed to dma_map_single to secure world + ret = scm_smc_call(NULL, &desc, &res, true); + if (!ret && res.result[0] == 1) + goto out; + + qcom_scm_convention = SMC_CONVENTION_ARM_32; + ret = scm_smc_call(NULL, &desc, &res, true); + if (!ret && res.result[0] == 1) + goto out; + + qcom_scm_convention = SMC_CONVENTION_LEGACY; +out: + has_queried = true; + spin_unlock_irqrestore(&query_lock, flags); + pr_info("qcom_scm: convention: %s\n", + qcom_scm_convention_names[qcom_scm_convention]); +} + +static inline enum qcom_scm_convention __get_convention(void) +{ + if (unlikely(!has_queried)) + __query_convention(); + return qcom_scm_convention; +} + +/** + * qcom_scm_call() - Invoke a syscall in the secure world + * @dev: device + * @svc_id: service identifier + * @cmd_id: command identifier + * @desc: Descriptor structure containing arguments and return values + * + * Sends a command to the SCM and waits for the command to finish processing. + * This should *only* be called in pre-emptible context. + */ +static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) +{ + might_sleep(); + switch (__get_convention()) { + case SMC_CONVENTION_ARM_32: + case SMC_CONVENTION_ARM_64: + return scm_smc_call(dev, desc, res, false); + case SMC_CONVENTION_LEGACY: + return scm_legacy_call(dev, desc, res); + default: + pr_err("Unknown current SCM calling convention.\n"); + return -EINVAL; + } +} + +/** + * qcom_scm_call_atomic() - atomic variation of qcom_scm_call() + * @dev: device + * @svc_id: service identifier + * @cmd_id: command identifier + * @desc: Descriptor structure containing arguments and return values + * @res: Structure containing results from SMC/HVC call + * + * Sends a command to the SCM and waits for the command to finish processing. + * This can be called in atomic context. + */ +static int qcom_scm_call_atomic(struct device *dev, + const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) +{ + switch (__get_convention()) { + case SMC_CONVENTION_ARM_32: + case SMC_CONVENTION_ARM_64: + return scm_smc_call(dev, desc, res, true); + case SMC_CONVENTION_LEGACY: + return scm_legacy_call_atomic(dev, desc, res); + default: + pr_err("Unknown current SCM calling convention.\n"); + return -EINVAL; + } +} + +static int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, + u32 cmd_id) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_INFO, + .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL, + .owner = ARM_SMCCC_OWNER_SIP, + }; + struct qcom_scm_res res; + + desc.arginfo = QCOM_SCM_ARGS(1); + switch (__get_convention()) { + case SMC_CONVENTION_ARM_32: + case SMC_CONVENTION_ARM_64: + desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) | + (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT); + break; + case SMC_CONVENTION_LEGACY: + desc.args[0] = SCM_LEGACY_FNID(svc_id, cmd_id); + break; + default: + pr_err("Unknown SMC convention being used\n"); + return -EINVAL; + } + + ret = qcom_scm_call(dev, &desc, &res); + + return ret ? : res.result[0]; +} + /** * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus * @entry: Entry point function for the cpus @@ -969,7 +1113,7 @@ static int qcom_scm_probe(struct platform_device *pdev) __scm = scm; __scm->dev = &pdev->dev; - __qcom_scm_init(); + __query_convention(); /* * If requested enable "download mode", from this point on warmboot diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 9b7b357..d9ed670 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -3,6 +3,16 @@ */ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H + +enum qcom_scm_convention { + SMC_CONVENTION_UNKNOWN, + SMC_CONVENTION_LEGACY, + SMC_CONVENTION_ARM_32, + SMC_CONVENTION_ARM_64, +}; + +extern enum qcom_scm_convention qcom_scm_convention; + #define MAX_QCOM_SCM_ARGS 10 #define MAX_QCOM_SCM_RETS 3 @@ -50,11 +60,16 @@ struct qcom_scm_res { u64 result[MAX_QCOM_SCM_RETS]; }; -extern int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, - struct qcom_scm_res *res); -extern int qcom_scm_call_atomic(struct device *dev, - const struct qcom_scm_desc *desc, - struct qcom_scm_res *res); +#define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) +extern int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res, bool atomic); + +#define SCM_LEGACY_FNID(s, c) (((s) << 10) | ((c) & 0x3ff)) +extern int scm_legacy_call_atomic(struct device *dev, + const struct qcom_scm_desc *desc, + struct qcom_scm_res *res); +extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, + struct qcom_scm_res *res); #define QCOM_SCM_SVC_BOOT 0x01 #define QCOM_SCM_BOOT_SET_ADDR 0x01 @@ -77,8 +92,6 @@ extern int qcom_scm_call_atomic(struct device *dev, #define QCOM_SCM_SVC_INFO 0x06 #define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01 -extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, - u32 cmd_id); #define QCOM_SCM_SVC_MP 0x0c #define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02