]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
firmware: qcom: scm: Add 64 bit PAS APIs
authorAndy Gross <agross@codeaurora.org>
Fri, 3 Jul 2015 20:44:05 +0000 (15:44 -0500)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Mon, 14 Aug 2017 10:51:30 +0000 (12:51 +0200)
Signed-off-by: Andy Gross <agross@codeaurora.org>
drivers/firmware/qcom_scm-64.c

index 7f985ca78eaa33a4f0a82fec35c2a5c8702c9cdb..751e2ef8ba41c47005d7cc81fb1c0ff6c65f7b8e 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/qcom_scm.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/cacheflush.h>
 #include <asm/compiler.h>
 #define MAX_QCOM_SCM_ARGS 10
 #define MAX_QCOM_SCM_RETS 3
 
+enum qcom_scm_arg_types {
+       QCOM_SCM_VAL,
+       QCOM_SCM_RO,
+       QCOM_SCM_RW,
+       QCOM_SCM_BUFVAL,
+};
+
 #define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
                        (((a) & 0xff) << 4) | \
                        (((b) & 0xff) << 6) | \
@@ -438,6 +446,102 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
        return ret;
 }
 
+bool __qcom_scm_pas_supported(u32 peripheral)
+{
+       int ret;
+       struct qcom_scm_desc desc = {0};
+
+       desc.args[0] = peripheral;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_IS_SUPPORTED_CMD,
+                               &desc);
+
+       return ret ? false : !!desc.ret[0];
+}
+
+int __qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
+{
+       int ret;
+       struct qcom_scm_desc desc = {0};
+       u32 scm_ret;
+       dma_addr_t mdata_phys;
+       void *mdata_buf;
+
+       /*
+        * During the scm call memory protection will be enabled for the meta
+        * data blob, so make sure it's physically contiguous, 4K aligned and
+        * non-cachable to avoid XPU violations.
+        */
+       mdata_buf = dma_alloc_coherent(NULL, size, &mdata_phys, GFP_KERNEL);
+       if (!mdata_buf) {
+               pr_err("Allocation of metadata buffer failed.\n");
+               return -ENOMEM;
+       }
+       memcpy(mdata_buf, metadata, size);
+
+       desc.args[0] = peripheral;
+       desc.args[1] = mdata_phys;
+       desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
+                               &desc);
+       scm_ret = desc.ret[0];
+
+       dma_free_coherent(NULL, size, mdata_buf, mdata_phys);
+       return ret ? : scm_ret;
+}
+
+int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+{
+       int ret;
+       struct qcom_scm_desc desc = {0};
+       u32 scm_ret;
+
+       desc.args[0] = peripheral;
+       desc.args[1] = addr;
+       desc.args[2] = size;
+       desc.arginfo = QCOM_SCM_ARGS(3);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD,
+                               &desc);
+       scm_ret = desc.ret[0];
+
+       return ret ? : scm_ret;
+}
+
+int __qcom_scm_pas_auth_and_reset(u32 peripheral)
+{
+       int ret;
+       struct qcom_scm_desc desc = {0};
+       u32 scm_ret;
+
+       desc.args[0] = peripheral;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_AUTH_AND_RESET_CMD,
+                               &desc);
+       scm_ret = desc.ret[0];
+
+       return ret ? : scm_ret;
+}
+
+int __qcom_scm_pas_shutdown(u32 peripheral)
+{
+       int ret;
+       struct qcom_scm_desc desc = {0};
+       u32 scm_ret;
+
+       desc.args[0] = peripheral;
+       desc.arginfo = QCOM_SCM_ARGS(1);
+
+       ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD,
+                       &desc);
+       scm_ret = desc.ret[0];
+
+       return ret ? : scm_ret;
+}
+
 #define QCOM_SCM_SVC_INFO              0x6
 static int __init qcom_scm_init(void)
 {