From db8f59fe06bf5da509158a0d2917787f4399c953 Mon Sep 17 00:00:00 2001 From: Anmolpreet Kaur Date: Tue, 9 Feb 2021 17:23:32 +0530 Subject: [PATCH] qcom: scm: Define new api to support legacy functionality of smcinvoke Before the advent of cache coherent buffers, cmd_id 0 was used for invoke functionality that required CMO operations. On later targets which support cache coherent buffer, a new cmd_id 0x2 was used that eliminated the need for CMO operations. However, some targets such as MDM still dont support cache coherent buffers. So we still have to use older command i.e. cmd_id 0. Introducing a new API to take care of both targets i.e. which supports cache coherency and non-cache coherency. Change-Id: If044725616cde01274a19b0310e309186f7d782b Signed-off-by: Anmolpreet Kaur --- drivers/firmware/qcom_scm-smc.c | 34 ++++++++++++++++++++++++++++++++- drivers/firmware/qcom_scm.c | 9 +++++++++ drivers/firmware/qcom_scm.h | 6 +++++- include/linux/qcom_scm.h | 6 ++++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 27cce454c86a..3d736c74a60d 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015,2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2015,2020-2021 The Linux Foundation. All rights reserved. */ #include @@ -2020,6 +2020,38 @@ int __qcom_scm_request_encrypted_log(struct device *dev, phys_addr_t buf, return ret ? : desc.res[0]; } +int __qcom_scm_invoke_smc_legacy(struct device *dev, phys_addr_t in_buf, + size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, + int32_t *result, u64 *response_type, unsigned int *data) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_SMCINVOKE, + .cmd = QCOM_SCM_SMCINVOKE_INVOKE_LEGACY, + .owner = ARM_SMCCC_OWNER_TRUSTED_OS + }; + + desc.args[0] = in_buf; + desc.args[1] = in_buf_size; + desc.args[2] = out_buf; + desc.args[3] = out_buf_size; + desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, + QCOM_SCM_VAL); + + ret = qcom_scm_call(dev, &desc); + + if (result) + *result = desc.res[1]; + + if (response_type) + *response_type = desc.res[0]; + + if (data) + *data = desc.res[2]; + + return ret; +} + int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *response_type, unsigned int *data) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 0b20d4af4c09..33b3c188bb81 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -980,6 +980,15 @@ int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len, } EXPORT_SYMBOL(qcom_scm_request_encrypted_log); +int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size, + phys_addr_t out_buf, size_t out_buf_size, int32_t *result, + u64 *response_type, unsigned int *data) +{ + return __qcom_scm_invoke_smc_legacy(__scm->dev, in_buf, in_buf_size, out_buf, + out_buf_size, result, response_type, data); +} +EXPORT_SYMBOL(qcom_scm_invoke_smc_legacy); + int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *response_type, unsigned int *data) diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 60ba9b8a67a9..9406a82f23bc 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2010-2015,2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2015,2020-2021 The Linux Foundation. All rights reserved. */ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H @@ -260,8 +260,12 @@ extern int __qcom_scm_request_encrypted_log(struct device *dev, phys_addr_t buf, extern int __qcom_scm_ice_restore_cfg(struct device *dev); #define QCOM_SCM_SVC_SMCINVOKE 0x06 +#define QCOM_SCM_SMCINVOKE_INVOKE_LEGACY 0x00 #define QCOM_SCM_SMCINVOKE_INVOKE 0x02 #define QCOM_SCM_SMCINVOKE_CB_RSP 0x01 +extern int __qcom_scm_invoke_smc_legacy(struct device *dev, phys_addr_t in_buf, + size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, + int32_t *result, u64 *response_type, unsigned int *data); extern int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *response_type, unsigned int *data); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 2f73d491dc71..cb799791f626 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -192,6 +192,9 @@ extern int qcom_scm_register_qsee_log_buf(phys_addr_t buf, size_t len); extern int qcom_scm_query_encrypted_log_feature(u64 *enabled); extern int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len, uint32_t log_id); +extern int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size, + phys_addr_t out_buf, size_t out_buf_size, int32_t *result, + u64 *response_type, unsigned int *data); extern int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *response_type, unsigned int *data); @@ -365,6 +368,9 @@ static inline int qcom_scm_query_encrypted_log_feature(u64 *enabled) static inline int qcom_scm_request_encrypted_log(phys_addr_t buf, size_t len, uint32_t log_id) { return -ENODEV; } +static inline int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size, + phys_addr_t out_buf, size_t out_buf_size, int32_t *result, + u64 *request_type, unsigned int *data) { return -ENODEV; } static inline int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size, int32_t *result, u64 *request_type, unsigned int *data) { return -ENODEV; }