This adds the Peripheral Authentication Service (PAS) interface to the
Qualcomm SCM interface. The API is used to authenticate and boot a range
of external processors in various Qualcomm platforms.
Signed-off-by: Bjorn Andersson
---
Depends on Andy's platformization of the scm code.
Changes since v2:
- Attached the dma allocation in init_image to the scm dev
- Requesting scm clocks
- Fixed some more big endian stuff
- Added stubs for ARM64
Changes since v1:
- Big endian compatibility
drivers/firmware/qcom_scm-32.c | 82 +
drivers/firmware/qcom_scm-64.c | 25
drivers/firmware/qcom_scm.c| 136 +
drivers/firmware/qcom_scm.h| 12
include/linux/qcom_scm.h | 6 ++
5 files changed, 261 insertions(+)
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 29e6850665eb..e9c306bcd371 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -499,3 +499,85 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32
req_cnt, u32 *resp)
return qcom_scm_call(QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP,
req, req_cnt * sizeof(*req), resp, sizeof(*resp));
}
+
+bool __qcom_scm_pas_supported(u32 peripheral)
+{
+ __le32 out;
+ __le32 in;
+ int ret;
+
+ in = cpu_to_le32(peripheral);
+ ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_IS_SUPPORTED_CMD,
+ , sizeof(in),
+ , sizeof(out));
+
+ return ret ? false : !!out;
+}
+
+int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys)
+{
+ __le32 scm_ret;
+ int ret;
+ struct {
+ __le32 proc;
+ __le32 image_addr;
+ } request;
+
+ request.proc = cpu_to_le32(peripheral);
+ request.image_addr = cpu_to_le32(metadata_phys);
+
+ ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
+ , sizeof(request),
+ _ret, sizeof(scm_ret));
+
+ return ret ? : le32_to_cpu(scm_ret);
+}
+
+int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t
size)
+{
+ __le32 scm_ret;
+ int ret;
+ struct {
+ __le32 proc;
+ __le32 addr;
+ __le32 len;
+ } request;
+
+ request.proc = cpu_to_le32(peripheral);
+ request.addr = cpu_to_le32(addr);
+ request.len = cpu_to_le32(size);
+
+ ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD,
+ , sizeof(request),
+ _ret, sizeof(scm_ret));
+
+ return ret ? : le32_to_cpu(scm_ret);
+}
+
+int __qcom_scm_pas_auth_and_reset(u32 peripheral)
+{
+ __le32 out;
+ __le32 in;
+ int ret;
+
+ in = cpu_to_le32(peripheral);
+ ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_AUTH_AND_RESET_CMD,
+ , sizeof(in),
+ , sizeof(out));
+
+ return ret ? : le32_to_cpu(out);
+}
+
+int __qcom_scm_pas_shutdown(u32 peripheral)
+{
+ __le32 out;
+ __le32 in;
+ int ret;
+
+ in = cpu_to_le32(peripheral);
+ ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD,
+ , sizeof(in),
+ , sizeof(out));
+
+ return ret ? : le32_to_cpu(out);
+}
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index bb6555f6d63b..e64fd927e5ae 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -61,3 +61,28 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32
req_cnt, u32 *resp)
{
return -ENOTSUPP;
}
+
+bool __qcom_scm_pas_supported(u32 peripheral)
+{
+ return false;
+}
+
+int __qcom_scm_pas_init_image(u32 peripheral, dma_addr_t metadata_phys)
+{
+ return -ENOTSUPP;
+}
+
+int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t
size)
+{
+ return -ENOTSUPP;
+}
+
+int __qcom_scm_pas_auth_and_reset(u32 peripheral)
+{
+ return -ENOTSUPP;
+}
+
+int __qcom_scm_pas_shutdown(u32 peripheral)
+{
+ return -ENOTSUPP;
+}
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 5dd05142069d..118df0ae242b 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -28,6 +29,7 @@
#include "qcom_scm.h"
struct qcom_scm {
+ struct device *dev;
struct clk *core_clk;
struct clk *iface_clk;
struct clk *bus_clk;
@@ -152,6 +154,138 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32
req_cnt, u32 *resp)
EXPORT_SYMBOL(qcom_scm_hdcp_req);
/**
+ * qcom_scm_pas_supported() - Check if the peripheral authentication service is
+ * available