From 52af26e33e700158e6549f1465fcf9da099fabfa Mon Sep 17 00:00:00 2001 From: Jeffrey Hugo Date: Wed, 6 Nov 2019 15:05:11 -0800 Subject: soc: qcom: qmi: Return EPROBE_DEFER if no address family If a client comes up early in the boot process (perhaps was a built-in driver), qmi_handle_init() will likely fail with a EAFNOSUPPORT since the underlying ipc router hasn't init'd and registered the address family. This should not be a fatal error since chances are, the router will come up later, so recode the error to EPROBE_DEFER so that clients will retry later. Signed-off-by: Jeffrey Hugo Link: https://lore.kernel.org/r/20191106230511.1290-1-jeffrey.l.hugo@gmail.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/qmi_interface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c index f9e309f0acd3..1a03eaa38c46 100644 --- a/drivers/soc/qcom/qmi_interface.c +++ b/drivers/soc/qcom/qmi_interface.c @@ -655,8 +655,12 @@ int qmi_handle_init(struct qmi_handle *qmi, size_t recv_buf_size, qmi->sock = qmi_sock_create(qmi, &qmi->sq); if (IS_ERR(qmi->sock)) { - pr_err("failed to create QMI socket\n"); - ret = PTR_ERR(qmi->sock); + if (PTR_ERR(qmi->sock) == -EAFNOSUPPORT) { + ret = -EPROBE_DEFER; + } else { + pr_err("failed to create QMI socket\n"); + ret = PTR_ERR(qmi->sock); + } goto err_destroy_wq; } -- cgit v1.2.3 From 4e6a2011fdbeba69cc2b54c20400036b47120a7a Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Mon, 18 Nov 2019 17:40:11 +0000 Subject: soc: qcom: rpmhpd: Add SM8150 RPMH power-domains Add support for cx/mx/gfx/mss/ebi/mmcx/lmx/lcx power-domains found on SM8150 SoCs. Reviewed-by: Stephen Boyd Reviewed-by: Bjorn Andersson Reviewed-by: Rajendra Nayak Signed-off-by: Sibi Sankar Link: https://lore.kernel.org/r/0101016e7f99b98b-4a436053-3da0-4011-a41c-de064fb44d7e-000000@us-west-2.amazonses.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/rpmhpd.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index 5741ec3fa814..3f6b19648018 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -129,8 +129,44 @@ static const struct rpmhpd_desc sdm845_desc = { .num_pds = ARRAY_SIZE(sdm845_rpmhpds), }; +/* SM8150 RPMH powerdomains */ + +static struct rpmhpd sm8150_mmcx_ao; +static struct rpmhpd sm8150_mmcx = { + .pd = { .name = "mmcx", }, + .peer = &sm8150_mmcx_ao, + .res_name = "mmcx.lvl", +}; + +static struct rpmhpd sm8150_mmcx_ao = { + .pd = { .name = "mmcx_ao", }, + .active_only = true, + .peer = &sm8150_mmcx, + .res_name = "mmcx.lvl", +}; + +static struct rpmhpd *sm8150_rpmhpds[] = { + [SM8150_MSS] = &sdm845_mss, + [SM8150_EBI] = &sdm845_ebi, + [SM8150_LMX] = &sdm845_lmx, + [SM8150_LCX] = &sdm845_lcx, + [SM8150_GFX] = &sdm845_gfx, + [SM8150_MX] = &sdm845_mx, + [SM8150_MX_AO] = &sdm845_mx_ao, + [SM8150_CX] = &sdm845_cx, + [SM8150_CX_AO] = &sdm845_cx_ao, + [SM8150_MMCX] = &sm8150_mmcx, + [SM8150_MMCX_AO] = &sm8150_mmcx_ao, +}; + +static const struct rpmhpd_desc sm8150_desc = { + .rpmhpds = sm8150_rpmhpds, + .num_pds = ARRAY_SIZE(sm8150_rpmhpds), +}; + static const struct of_device_id rpmhpd_match_table[] = { { .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc }, + { .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc }, { } }; -- cgit v1.2.3 From a30657b6387b821e31d4a7d8ad5bc32ae532cfe9 Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Mon, 18 Nov 2019 17:40:19 +0000 Subject: soc: qcom: rpmhpd: Add SC7180 RPMH power-domains Add support for cx/mx/gfx/lcx/lmx/mss power-domains found on SC7180 SoCs. Reviewed-by: Bjorn Andersson Reviewed-by: Rajendra Nayak Reviewed-by: Stephen Boyd Signed-off-by: Sibi Sankar Link: https://lore.kernel.org/r/0101016e7f99d9ec-1a5d07da-0a61-4627-bf95-fa9ae06265ca-000000@us-west-2.amazonses.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/rpmhpd.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index 3f6b19648018..b600cfbc74e6 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -164,7 +164,25 @@ static const struct rpmhpd_desc sm8150_desc = { .num_pds = ARRAY_SIZE(sm8150_rpmhpds), }; +/* SC7180 RPMH powerdomains */ +static struct rpmhpd *sc7180_rpmhpds[] = { + [SC7180_CX] = &sdm845_cx, + [SC7180_CX_AO] = &sdm845_cx_ao, + [SC7180_GFX] = &sdm845_gfx, + [SC7180_MX] = &sdm845_mx, + [SC7180_MX_AO] = &sdm845_mx_ao, + [SC7180_LMX] = &sdm845_lmx, + [SC7180_LCX] = &sdm845_lcx, + [SC7180_MSS] = &sdm845_mss, +}; + +static const struct rpmhpd_desc sc7180_desc = { + .rpmhpds = sc7180_rpmhpds, + .num_pds = ARRAY_SIZE(sc7180_rpmhpds), +}; + static const struct of_device_id rpmhpd_match_table[] = { + { .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc }, { .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc }, { .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc }, { } -- cgit v1.2.3 From a9e8fce61a787f8d4340c8b728dd4c13be0430ba Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 20 Nov 2019 21:39:25 +0800 Subject: soc: qcom: Fix Kconfig indentation Adjust indentation from spaces to tab (+optional two spaces) as in coding style with command like: $ sed -e 's/^ /\t/' -i */Kconfig Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20191120133925.13712-1-krzk@kernel.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/Kconfig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 79d826553ac8..d0a73e76d563 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -45,13 +45,13 @@ config QCOM_GLINK_SSR neighboring subsystems going up or down. config QCOM_GSBI - tristate "QCOM General Serial Bus Interface" - depends on ARCH_QCOM || COMPILE_TEST - select MFD_SYSCON - help - Say y here to enable GSBI support. The GSBI provides control - functions for connecting the underlying serial UART, SPI, and I2C - devices to the output pins. + tristate "QCOM General Serial Bus Interface" + depends on ARCH_QCOM || COMPILE_TEST + select MFD_SYSCON + help + Say y here to enable GSBI support. The GSBI provides control + functions for connecting the underlying serial UART, SPI, and I2C + devices to the output pins. config QCOM_LLCC tristate "Qualcomm Technologies, Inc. LLCC driver" @@ -71,10 +71,10 @@ config QCOM_OCMEM depends on ARCH_QCOM select QCOM_SCM help - The On Chip Memory (OCMEM) allocator allows various clients to - allocate memory from OCMEM based on performance, latency and power - requirements. This is typically used by the GPU, camera/video, and - audio components on some Snapdragon SoCs. + The On Chip Memory (OCMEM) allocator allows various clients to + allocate memory from OCMEM based on performance, latency and power + requirements. This is typically used by the GPU, camera/video, and + audio components on some Snapdragon SoCs. config QCOM_PM bool "Qualcomm Power Management" @@ -198,8 +198,8 @@ config QCOM_APR depends on ARCH_QCOM || COMPILE_TEST depends on RPMSG help - Enable APR IPC protocol support between - application processor and QDSP6. APR is - used by audio driver to configure QDSP6 - ASM, ADM and AFE modules. + Enable APR IPC protocol support between + application processor and QDSP6. APR is + used by audio driver to configure QDSP6 + ASM, ADM and AFE modules. endmenu -- cgit v1.2.3 From 5d0d4d42bed0090d3139e7c5ca1587d76d48add6 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 14 Feb 2019 09:36:33 -0800 Subject: soc: qcom: rpmhpd: Set 'active_only' for active only power domains The 'active_only' attribute was accidentally never set to true for any power domains meaning that all the code handling this attribute was dead. NOTE that the RPM power domain code (as opposed to the RPMh one) gets this right. Acked-by: Rajendra Nayak Reviewed-by: Stephen Boyd Fixes: 279b7e8a62cc ("soc: qcom: rpmhpd: Add RPMh power domain driver") Signed-off-by: Douglas Anderson Link: https://lore.kernel.org/r/20190214173633.211000-1-dianders@chromium.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/rpmhpd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index b600cfbc74e6..4d264d0672c4 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -93,6 +93,7 @@ static struct rpmhpd sdm845_mx = { static struct rpmhpd sdm845_mx_ao = { .pd = { .name = "mx_ao", }, + .active_only = true, .peer = &sdm845_mx, .res_name = "mx.lvl", }; @@ -107,6 +108,7 @@ static struct rpmhpd sdm845_cx = { static struct rpmhpd sdm845_cx_ao = { .pd = { .name = "cx_ao", }, + .active_only = true, .peer = &sdm845_cx, .parent = &sdm845_mx_ao.pd, .res_name = "cx.lvl", -- cgit v1.2.3 From e0aa153965041c6e795666b995055b35c00d5609 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 7 Jan 2020 13:04:10 -0800 Subject: firmware: qcom_scm: Rename macros and structures 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. Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman Link: https://lore.kernel.org/r/1578431066-19600-2-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm-32.c | 71 ++++++++++++++++++++++-------------------- drivers/firmware/qcom_scm-64.c | 53 +++++++++++++++---------------- 2 files changed, 64 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 48e2ef794ea3..2542c424498d 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 @@ out: 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 3c5850350974..9c7ea745c6cc 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, -- cgit v1.2.3 From 5443cc5f12b1178ccdc414843aea7f0d2e14d03c Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 7 Jan 2020 13:04:11 -0800 Subject: firmware: qcom_scm: Apply consistent naming scheme to command IDs 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 Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman Link: https://lore.kernel.org/r/1578431066-19600-3-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson --- 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(-) (limited to 'drivers') diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 2542c424498d..6e62f73627ba 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 9c7ea745c6cc..976c2b9a3cde 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 1ba0df4b97ab..097f8b3c62b3 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 81dcf5f1138e..afcca1659548 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, -- cgit v1.2.3 From 9a1108d2b001cda1af17160c78afedfff92e2202 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 7 Jan 2020 13:04:12 -0800 Subject: firmware: qcom_scm: Remove unused qcom_scm_get_version Remove unused qcom_scm_get_version. Reviewed-by: Bjorn Andersson Reviewed-by: Vinod Koul Reviewed-by: Stephen Boyd Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman Link: https://lore.kernel.org/r/1578431066-19600-4-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm-32.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index 6e62f73627ba..8b5724069f27 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 -- cgit v1.2.3 From 4a9f1e13b7ed89e66ca9f7c46e48e305402e0732 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 7 Jan 2020 13:04:13 -0800 Subject: firmware: qcom_scm-64: Make SMC macros less magical 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 Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman Link: https://lore.kernel.org/r/1578431066-19600-5-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm-64.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 976c2b9a3cde..3101f3615693 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, -- cgit v1.2.3 From b30a2a72b84e2355b4db12393407ca48be89e267 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 7 Jan 2020 13:04:14 -0800 Subject: firmware: qcom_scm-64: Move svc/cmd/owner into qcom_scm_desc 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 Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman Link: https://lore.kernel.org/r/1578431066-19600-6-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm-64.c | 195 +++++++++++++++++++++++++---------------- 1 file changed, 121 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 3101f3615693..7b7aa880af47 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); } -- cgit v1.2.3 From 1f7166fdae55b52803d1f381e017ecbd45142a2d Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 7 Jan 2020 13:04:15 -0800 Subject: firmware: qcom_scm-64: Add SCM results struct 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. Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman Link: https://lore.kernel.org/r/1578431066-19600-7-git-send-email-eberman@codeaurora.org Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom_scm-64.c | 93 +++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index 7b7aa880af47..e0e6530ec6f3 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, allo