Message ID | 20230928092040.9420-11-brgl@bgdev.pl (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | arm64: qcom: add and enable SHM Bridge support | expand |
On 9/28/2023 2:20 AM, Bartosz Golaszewski wrote: > From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> > > Add low-level primitives for enabling SHM bridge support, creating SHM > bridge pools and testing the availability of SHM bridges to qcom-scm. We > don't yet provide a way to destroy the bridges as the first user will > not require it. > > Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> After fixing the typo: Reviewed-by: Elliot Berman <quic_eberman@quicinc.com> > --- > drivers/firmware/qcom/qcom_scm.c | 43 ++++++++++++++++++++++++++ > drivers/firmware/qcom/qcom_scm.h | 2 ++ > include/linux/firmware/qcom/qcom_scm.h | 6 ++++ > 3 files changed, 51 insertions(+) > > diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c > index 1fa27c44f472..5969ff0c0beb 100644 > --- a/drivers/firmware/qcom/qcom_scm.c > +++ b/drivers/firmware/qcom/qcom_scm.c > @@ -1296,6 +1296,49 @@ bool qcom_scm_lmh_dcvsh_available(void) > } > EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available); > > +int qcom_scm_enable_shm_bridge(void) > +{ > + struct qcom_scm_desc desc = { > + .svc = QCOM_SCM_SVC_MP, > + .cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE, > + .owner = ARM_SMCCC_OWNER_SIP > + }; > + > + struct qcom_scm_res res; > + > + if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, > + QCOM_SCM_MP_SHM_BRIDGE_ENABLE)) > + return -EOPNOTSUPP; > + > + return qcom_scm_call(__scm->dev, &desc, &res) ?: res.result[0]; > +} > +EXPORT_SYMBOL_GPL(qcom_scm_enable_shm_bridge); > + > +int qcom_scm_create_shm_bridge(struct device *dev, u64 pfn_and_ns_perm_flags, > + u64 ipfn_and_s_perm_flags, u64 size_and_flags, > + u64 ns_vmids) > +{ > + struct qcom_scm_desc desc = { > + .svc = QCOM_SCM_SVC_MP, > + .cmd = QCOM_SCM_MP_SHM_BRDIGE_CREATE, s/BRDIGE/BRIDGE/g > + .owner = ARM_SMCCC_OWNER_SIP, > + .args[0] = pfn_and_ns_perm_flags, > + .args[1] = ipfn_and_s_perm_flags, > + .args[2] = size_and_flags, > + .args[3] = ns_vmids, > + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL, > + QCOM_SCM_VAL, QCOM_SCM_VAL), > + }; > + > + struct qcom_scm_res res; > + int ret; > + > + ret = qcom_scm_call(__scm->dev, &desc, &res); > + > + return ret ?: res.result[0]; > +} > +EXPORT_SYMBOL_GPL(qcom_scm_create_shm_bridge); > + > int qcom_scm_lmh_profile_change(u32 profile_id) > { > struct qcom_scm_desc desc = { > diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h > index 8c97e3906afa..f5a29bc0f549 100644 > --- a/drivers/firmware/qcom/qcom_scm.h > +++ b/drivers/firmware/qcom/qcom_scm.h > @@ -116,6 +116,8 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, > #define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE 0x05 > #define QCOM_SCM_MP_VIDEO_VAR 0x08 > #define QCOM_SCM_MP_ASSIGN 0x16 > +#define QCOM_SCM_MP_SHM_BRIDGE_ENABLE 0x1c > +#define QCOM_SCM_MP_SHM_BRDIGE_CREATE 0x1e s/BRDIGE/BRIDGE/g > > #define QCOM_SCM_SVC_OCMEM 0x0f > #define QCOM_SCM_OCMEM_LOCK_CMD 0x01 > diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h > index 291ef8fd21b0..dc26cfd6d011 100644 > --- a/include/linux/firmware/qcom/qcom_scm.h > +++ b/include/linux/firmware/qcom/qcom_scm.h > @@ -6,6 +6,7 @@ > #define __QCOM_SCM_H > > #include <linux/cleanup.h> > +#include <linux/device.h> > #include <linux/err.h> > #include <linux/gfp.h> > #include <linux/types.h> > @@ -122,6 +123,11 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, > int qcom_scm_lmh_profile_change(u32 profile_id); > bool qcom_scm_lmh_dcvsh_available(void); > > +int qcom_scm_enable_shm_bridge(void); > +int qcom_scm_create_shm_bridge(struct device *dev, u64 pfn_and_ns_perm_flags, > + u64 ipfn_and_s_perm_flags, u64 size_and_flags, > + u64 ns_vmids); > + > #ifdef CONFIG_QCOM_QSEECOM > > int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 1fa27c44f472..5969ff0c0beb 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1296,6 +1296,49 @@ bool qcom_scm_lmh_dcvsh_available(void) } EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available); +int qcom_scm_enable_shm_bridge(void) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE, + .owner = ARM_SMCCC_OWNER_SIP + }; + + struct qcom_scm_res res; + + if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_MP_SHM_BRIDGE_ENABLE)) + return -EOPNOTSUPP; + + return qcom_scm_call(__scm->dev, &desc, &res) ?: res.result[0]; +} +EXPORT_SYMBOL_GPL(qcom_scm_enable_shm_bridge); + +int qcom_scm_create_shm_bridge(struct device *dev, u64 pfn_and_ns_perm_flags, + u64 ipfn_and_s_perm_flags, u64 size_and_flags, + u64 ns_vmids) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_SHM_BRDIGE_CREATE, + .owner = ARM_SMCCC_OWNER_SIP, + .args[0] = pfn_and_ns_perm_flags, + .args[1] = ipfn_and_s_perm_flags, + .args[2] = size_and_flags, + .args[3] = ns_vmids, + .arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL, + QCOM_SCM_VAL, QCOM_SCM_VAL), + }; + + struct qcom_scm_res res; + int ret; + + ret = qcom_scm_call(__scm->dev, &desc, &res); + + return ret ?: res.result[0]; +} +EXPORT_SYMBOL_GPL(qcom_scm_create_shm_bridge); + int qcom_scm_lmh_profile_change(u32 profile_id) { struct qcom_scm_desc desc = { diff --git a/drivers/firmware/qcom/qcom_scm.h b/drivers/firmware/qcom/qcom_scm.h index 8c97e3906afa..f5a29bc0f549 100644 --- a/drivers/firmware/qcom/qcom_scm.h +++ b/drivers/firmware/qcom/qcom_scm.h @@ -116,6 +116,8 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, #define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE 0x05 #define QCOM_SCM_MP_VIDEO_VAR 0x08 #define QCOM_SCM_MP_ASSIGN 0x16 +#define QCOM_SCM_MP_SHM_BRIDGE_ENABLE 0x1c +#define QCOM_SCM_MP_SHM_BRDIGE_CREATE 0x1e #define QCOM_SCM_SVC_OCMEM 0x0f #define QCOM_SCM_OCMEM_LOCK_CMD 0x01 diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 291ef8fd21b0..dc26cfd6d011 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h @@ -6,6 +6,7 @@ #define __QCOM_SCM_H #include <linux/cleanup.h> +#include <linux/device.h> #include <linux/err.h> #include <linux/gfp.h> #include <linux/types.h> @@ -122,6 +123,11 @@ int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val, int qcom_scm_lmh_profile_change(u32 profile_id); bool qcom_scm_lmh_dcvsh_available(void); +int qcom_scm_enable_shm_bridge(void); +int qcom_scm_create_shm_bridge(struct device *dev, u64 pfn_and_ns_perm_flags, + u64 ipfn_and_s_perm_flags, u64 size_and_flags, + u64 ns_vmids); + #ifdef CONFIG_QCOM_QSEECOM int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);