Re: [PATCH v4 2/2] firmware: qcom: scm: Add support for ARM64 SoCs

2015-04-28 Thread Kumar Gala

> 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

2015-04-28 Thread Christopher Covington
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

2015-04-27 Thread Kumar Gala
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:
+