firmware: qcom: scm: Introduce CP_SMMU_APERTURE_ID
authorBjorn Andersson <bjorn.andersson@oss.qualcomm.com>
Sun, 10 Nov 2024 17:33:40 +0000 (09:33 -0800)
committerBjorn Andersson <andersson@kernel.org>
Mon, 11 Nov 2024 18:03:26 +0000 (12:03 -0600)
The QCOM_SCM_SVC_MP service provides QCOM_SCM_MP_CP_SMMU_APERTURE_ID,
which is used to trigger the mapping of register banks into the SMMU
context for per-processes page tables to function (in case this isn't
statically setup by firmware).

This is necessary on e.g. QCS6490 Rb3Gen2, in order to avoid "CP | AHB
bus error"-errors from the GPU.

Introduce a function to allow the msm driver to invoke this call.

Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
Reviewed-by: Rob Clark <robdclark@gmail.com>
Link: https://lore.kernel.org/r/20241110-adreno-smmu-aparture-v2-1-9b1fb2ee41d4@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
drivers/firmware/qcom/qcom_scm.c
drivers/firmware/qcom/qcom_scm.h
include/linux/firmware/qcom/qcom_scm.h

index bdb42eb..596a8ac 100644 (file)
@@ -903,6 +903,32 @@ int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)
 }
 EXPORT_SYMBOL_GPL(qcom_scm_restore_sec_cfg);
 
+#define QCOM_SCM_CP_APERTURE_CONTEXT_MASK      GENMASK(7, 0)
+
+bool qcom_scm_set_gpu_smmu_aperture_is_available(void)
+{
+       return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+                                           QCOM_SCM_MP_CP_SMMU_APERTURE_ID);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_set_gpu_smmu_aperture_is_available);
+
+int qcom_scm_set_gpu_smmu_aperture(unsigned int context_bank)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_MP,
+               .cmd = QCOM_SCM_MP_CP_SMMU_APERTURE_ID,
+               .arginfo = QCOM_SCM_ARGS(4),
+               .args[0] = 0xffff0000 | FIELD_PREP(QCOM_SCM_CP_APERTURE_CONTEXT_MASK, context_bank),
+               .args[1] = 0xffffffff,
+               .args[2] = 0xffffffff,
+               .args[3] = 0xffffffff,
+               .owner = ARM_SMCCC_OWNER_SIP
+       };
+
+       return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_set_gpu_smmu_aperture);
+
 int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
 {
        struct qcom_scm_desc desc = {
index 685b8f5..e36b2f6 100644 (file)
@@ -116,6 +116,7 @@ struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
 #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_CP_SMMU_APERTURE_ID                0x1b
 #define QCOM_SCM_MP_SHM_BRIDGE_ENABLE          0x1c
 #define QCOM_SCM_MP_SHM_BRIDGE_DELETE          0x1d
 #define QCOM_SCM_MP_SHM_BRIDGE_CREATE          0x1e
index 9f14976..4621aec 100644 (file)
@@ -85,6 +85,8 @@ int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
 
 bool qcom_scm_restore_sec_cfg_available(void);
 int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
+int qcom_scm_set_gpu_smmu_aperture(unsigned int context_bank);
+bool qcom_scm_set_gpu_smmu_aperture_is_available(void);
 int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
 int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
 int qcom_scm_iommu_set_cp_pool_size(u32 spare, u32 size);