Re: [PATCH v4 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
> On Apr 28, 2015, at 8:11 AM, Christopher Covington > wrote: > > Hi Kumar, > > On 04/27/2015 05:23 PM, Kumar Gala wrote: > >> --- /dev/null >> +++ b/drivers/firmware/qcom_scm-64.c >> @@ -0,0 +1,465 @@ >> +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 and >> + * only version 2 as published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * You should have received a copy of the GNU General Public License >> + * along with this program; if not, write to the Free Software >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA >> + * 02110-1301, USA. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +#include "qcom_scm.h" >> + >> +#define QCOM_SCM_SIP_FNID(s, c) (s) & 0xFF) << 8) | ((c) & 0xFF)) | >> 0x0200) >> + >> +#define MAX_QCOM_SCM_ARGS 10 >> +#define MAX_QCOM_SCM_RETS 3 >> + >> +#define QCOM_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 & 0x)) >> + >> +#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 >> + * @ret: The values returned by the secure syscall >> + * @extra_arg_buf: The buffer containing extra arguments >> + (that don't fit in available registers) >> + * @x5: The 4rd argument to the secure syscall or physical address of >> +extra_arg_buf >> + */ >> +struct qcom_scm_desc { >> +u32 arginfo; >> +u64 args[MAX_QCOM_SCM_ARGS]; >> +u64 ret[MAX_QCOM_SCM_RETS]; >> + >> +/* private */ >> +void *extra_arg_buf; >> +u64 x5; >> +}; >> + >> + >> +#define QCOM_SCM_ENOMEM -5 >> +#define QCOM_SCM_EOPNOTSUPP -4 >> +#define QCOM_SCM_EINVAL_ADDR-3 >> +#define QCOM_SCM_EINVAL_ARG -2 >> +#define QCOM_SCM_ERROR -1 >> +#define QCOM_SCM_INTERRUPTED1 >> +#define QCOM_SCM_EBUSY -55 >> +#define QCOM_SCM_V2_EBUSY -12 > > Any reason to duplicate ENOMEM through INTERRUPTED rather than put them in the > common header? No reason to duplicate them, just hadn’t noticed. >> +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 SMC_ATOMIC_SYSCALL 31 >> +#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1) >> +#define SMC64_MASK 0x4000 >> +#define SMC_ATOMIC_MASK 0x8000 >> +#define IS_CALL_AVAIL_CMD 1 >> + >> +#define R0_STR "x0" >> +#define R1_STR "x1" >> +#define R2_STR "x2" >> +#define R3_STR "x3" >> +#define R4_STR "x4" >> +#define R5_STR "x5" > > What is the purpose of these macros? Probably left over from when those code was merged between 32 and 64-bit, I’ll just inline them. Thanks for the review. - k -- Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
Hi Kumar, On 04/27/2015 05:23 PM, Kumar Gala wrote: > --- /dev/null > +++ b/drivers/firmware/qcom_scm-64.c > @@ -0,0 +1,465 @@ > +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 and > + * only version 2 as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > + * 02110-1301, USA. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include "qcom_scm.h" > + > +#define QCOM_SCM_SIP_FNID(s, c) (s) & 0xFF) << 8) | ((c) & 0xFF)) | > 0x0200) > + > +#define MAX_QCOM_SCM_ARGS 10 > +#define MAX_QCOM_SCM_RETS 3 > + > +#define QCOM_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 & 0x)) > + > +#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 > + * @ret: The values returned by the secure syscall > + * @extra_arg_buf: The buffer containing extra arguments > +(that don't fit in available registers) > + * @x5: The 4rd argument to the secure syscall or physical address of > + extra_arg_buf > + */ > +struct qcom_scm_desc { > + u32 arginfo; > + u64 args[MAX_QCOM_SCM_ARGS]; > + u64 ret[MAX_QCOM_SCM_RETS]; > + > + /* private */ > + void *extra_arg_buf; > + u64 x5; > +}; > + > + > +#define QCOM_SCM_ENOMEM -5 > +#define QCOM_SCM_EOPNOTSUPP -4 > +#define QCOM_SCM_EINVAL_ADDR -3 > +#define QCOM_SCM_EINVAL_ARG -2 > +#define QCOM_SCM_ERROR -1 > +#define QCOM_SCM_INTERRUPTED 1 > +#define QCOM_SCM_EBUSY -55 > +#define QCOM_SCM_V2_EBUSY-12 Any reason to duplicate ENOMEM through INTERRUPTED rather than put them in the common header? > +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 SMC_ATOMIC_SYSCALL 31 > +#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1) > +#define SMC64_MASK 0x4000 > +#define SMC_ATOMIC_MASK 0x8000 > +#define IS_CALL_AVAIL_CMD 1 > + > +#define R0_STR "x0" > +#define R1_STR "x1" > +#define R2_STR "x2" > +#define R3_STR "x3" > +#define R4_STR "x4" > +#define R5_STR "x5" What is the purpose of these macros? Chris -- Qualcomm Innovation Center, Inc. The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 2/2] firmware: qcom: scm: Add support for ARM64 SoCs
Add an implementation of the SCM interface that works on ARM64/64-bit SoCs Signed-off-by: Kumar Gala Signed-off-by: Lina Iyer --- * v4: - Folded in change to qcom_scm_cpu_power_down to remove HOTPLUG flag from Lina. arch/arm64/Kconfig | 1 + drivers/firmware/Makefile | 4 + drivers/firmware/qcom_scm-64.c | 465 + 3 files changed, 470 insertions(+) create mode 100644 drivers/firmware/qcom_scm-64.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 4269dba..8878800 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -190,6 +190,7 @@ config ARCH_MEDIATEK config ARCH_QCOM bool "Qualcomm Platforms" select PINCTRL + select QCOM_SCM help This enables support for the ARMv8 based Qualcomm chipsets. diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 3001f1a..c79751a 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -12,7 +12,11 @@ obj-$(CONFIG_ISCSI_IBFT_FIND)+= iscsi_ibft_find.o obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o obj-$(CONFIG_QCOM_SCM) += qcom_scm.o +ifdef CONFIG_64BIT +obj-$(CONFIG_QCOM_SCM) += qcom_scm-64.o +else obj-$(CONFIG_QCOM_SCM) += qcom_scm-32.o +endif CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c new file mode 100644 index 000..38b8360 --- /dev/null +++ b/drivers/firmware/qcom_scm-64.c @@ -0,0 +1,465 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "qcom_scm.h" + +#define QCOM_SCM_SIP_FNID(s, c) (s) & 0xFF) << 8) | ((c) & 0xFF)) | 0x0200) + +#define MAX_QCOM_SCM_ARGS 10 +#define MAX_QCOM_SCM_RETS 3 + +#define QCOM_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 & 0x)) + +#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 + * @ret: The values returned by the secure syscall + * @extra_arg_buf: The buffer containing extra arguments + (that don't fit in available registers) + * @x5: The 4rd argument to the secure syscall or physical address of + extra_arg_buf + */ +struct qcom_scm_desc { + u32 arginfo; + u64 args[MAX_QCOM_SCM_ARGS]; + u64 ret[MAX_QCOM_SCM_RETS]; + + /* private */ + void *extra_arg_buf; + u64 x5; +}; + + +#define QCOM_SCM_ENOMEM-5 +#define QCOM_SCM_EOPNOTSUPP-4 +#define QCOM_SCM_EINVAL_ADDR -3 +#define QCOM_SCM_EINVAL_ARG-2 +#define QCOM_SCM_ERROR -1 +#define QCOM_SCM_INTERRUPTED 1 +#define QCOM_SCM_EBUSY -55 +#define QCOM_SCM_V2_EBUSY -12 + +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 SMC_ATOMIC_SYSCALL 31 +#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1) +#define SMC64_MASK 0x4000 +#define SMC_ATOMIC_MASK 0x8000 +#define IS_CALL_AVAIL_CMD 1 + +#define R0_STR "x0" +#define R1_STR "x1" +#define R2_STR "x2" +#define R3_STR "x3" +#define R4_STR "x4" +#define R5_STR "x5" + +static int qcom_scm_remap_error(int err) +{ + switch (err) { + case QCOM_SCM_ERROR: + return -EIO; + case QCOM_SCM_EINVAL_ADDR: + case QCOM_SCM_EINVAL_ARG: +