From 0213ebc079113202e2bf7748617653e65e7702a4 Mon Sep 17 00:00:00 2001 From: Siddharth Gupta Date: Fri, 18 Oct 2019 14:45:50 -0700 Subject: [PATCH] firmware: qcom_smc: Add compatibility layer for qseecom Adding a compatibility layer so that only header changes are required for qseecom. This change will exist only for Lahaina bring up. Change-Id: I5b69dd02491416e4b593c42c85a2ffcf97280020 Signed-off-by: Siddharth Gupta Signed-off-by: Elliot Berman --- drivers/firmware/Makefile | 2 +- drivers/firmware/qcom_scm-smc.c | 22 ++++++++ drivers/firmware/qcom_smc.c | 19 +++++++ include/soc/qcom/qseecom_scm.h | 99 +++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/qcom_smc.c create mode 100644 include/soc/qcom/qseecom_scm.h diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 16a080bdec9b..f678b8055598 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -18,7 +18,7 @@ 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 -_qcom_scm-y += qcom_scm.o qcom_scm-smc.o +_qcom_scm-y += qcom_scm.o qcom_scm-smc.o qcom_smc.o _qcom_scm-$(CONFIG_QTEE_SHM_BRIDGE) += qtee_shmbridge.o obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index e0d4cc8f6fcc..01e12e7bdbe1 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -15,6 +15,7 @@ #include #include +#include #include "qcom_scm.h" @@ -1832,6 +1833,27 @@ int __qcom_scm_invoke_callback_response(struct device *dev, phys_addr_t out_buf, return ret; } +int __qcom_scm_qseecom_do(u32 cmd_id, struct scm_desc *desc, bool retry) +{ + int _ret; + struct qcom_scm_desc _desc; + + memcpy(&_desc.args, desc->args, sizeof(_desc.args)); + _desc.owner = (cmd_id & 0x3f000000) >> 24; + _desc.svc = (cmd_id & 0xff00) >> 8; + _desc.cmd = (cmd_id & 0xff); + _desc.arginfo = desc->arginfo; + + if (retry) + _ret = qcom_scm_call(NULL, &_desc); + else + _ret = qcom_scm_call_noretry(NULL, &_desc); + + memcpy(desc->ret, &_desc.res, sizeof(_desc.res)); + + return _ret; +} + void __qcom_scm_init(void) { __query_convention(); diff --git a/drivers/firmware/qcom_smc.c b/drivers/firmware/qcom_smc.c new file mode 100644 index 000000000000..cf39ee557a2f --- /dev/null +++ b/drivers/firmware/qcom_smc.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2019 The Linux Foundation. All rights reserved. + */ +#include +#include +#include + +int qcom_scm_qseecom_call(u32 cmd_id, struct scm_desc *desc) +{ + return __qcom_scm_qseecom_do(cmd_id, desc, true); +} +EXPORT_SYMBOL(qcom_scm_qseecom_call); + +int qcom_scm_qseecom_call_noretry(u32 cmd_id, struct scm_desc *desc) +{ + return __qcom_scm_qseecom_do(cmd_id, desc, false); +} +EXPORT_SYMBOL(qcom_scm_qseecom_call_noretry); diff --git a/include/soc/qcom/qseecom_scm.h b/include/soc/qcom/qseecom_scm.h new file mode 100644 index 000000000000..557e7f4bc625 --- /dev/null +++ b/include/soc/qcom/qseecom_scm.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef __MACH_SCM_H +#define __MACH_SCM_H + +#define SCM_SVC_BOOT 0x1 +#define SCM_SVC_PIL 0x2 +#define SCM_SVC_UTIL 0x3 +#define SCM_SVC_TZ 0x4 +#define SCM_SVC_IO 0x5 +#define SCM_SVC_INFO 0x6 +#define SCM_SVC_SSD 0x7 +#define SCM_SVC_FUSE 0x8 +#define SCM_SVC_PWR 0x9 +#define SCM_SVC_MP 0xC +#define SCM_SVC_DCVS 0xD +#define SCM_SVC_ES 0x10 +#define SCM_SVC_HDCP 0x11 +#define SCM_SVC_MDTP 0x12 +#define SCM_SVC_LMH 0x13 +#define SCM_SVC_SMMU_PROGRAM 0x15 +#define SCM_SVC_QDSS 0x16 +#define SCM_SVC_RTIC 0x19 +#define SCM_SVC_TZSCHEDULER 0xFC + +#define SCM_FUSE_READ 0x7 +#define SCM_CMD_HDCP 0x01 + +/* SCM Features */ +#define SCM_SVC_SEC_CAMERA 0xD + +#define DEFINE_SCM_BUFFER(__n) \ +static char __n[PAGE_SIZE] __aligned(PAGE_SIZE) + +#define SCM_BUFFER_SIZE(__buf) sizeof(__buf) + +#define SCM_BUFFER_PHYS(__buf) virt_to_phys(__buf) + +#define SCM_SIP_FNID(s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) | 0x02000000) +#define SCM_QSEEOS_FNID(s, c) (((((s) & 0xFF) << 8) | ((c) & 0xFF)) | \ + 0x32000000) +#define SCM_SVC_ID(s) (((s) & 0xFF00) >> 8) + +#define MAX_SCM_ARGS 10 +#define MAX_SCM_RETS 3 + +enum scm_arg_types { + SCM_VAL, + SCM_RO, + SCM_RW, + SCM_BUFVAL, +}; + +#define SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\ + (((a) & 0xff) << 4) | \ + (((b) & 0xff) << 6) | \ + (((c) & 0xff) << 8) | \ + (((d) & 0xff) << 10) | \ + (((e) & 0xff) << 12) | \ + (((f) & 0xff) << 14) | \ + (((g) & 0xff) << 16) | \ + (((h) & 0xff) << 18) | \ + (((i) & 0xff) << 20) | \ + (((j) & 0xff) << 22) | \ + (num & 0xffff)) + +#define SCM_ARGS(...) SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +struct scm_desc { + u32 arginfo; + u64 args[MAX_SCM_ARGS]; + u64 ret[MAX_SCM_RETS]; +}; + +extern int __qcom_scm_qseecom_do(u32 cmd_id, struct scm_desc *desc, bool retry); + +#if IS_ENABLED(CONFIG_QCOM_SCM) + +int qcom_scm_qseecom_call(u32 cmd_id, struct scm_desc *desc); +int qcom_scm_qseecom_call_noretry(u32 cmd_id, struct scm_desc *desc); + +#else + +static inline int qcom_scm_qseecom_call(u32 cmd_id, struct scm_desc *desc) +{ + return -ENODEV; +} + +static inline int qcom_scm_qseecom_call_noretry(u32 cmd_id, + struct scm_desc *desc) +{ + return -ENODEV; +} + +#endif +#endif