diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index b4b64b925409..3ada61be5311 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -1008,6 +1008,33 @@ int __qcom_scm_mem_protect_region_id(struct device *dev, phys_addr_t paddr, return ret; } +int __qcom_scm_mem_protect_lock_id2_flat(struct device *dev, + phys_addr_t list_addr, size_t list_size, + size_t chunk_size, size_t memory_usage, + int lock) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_MEM_PROTECT_LOCK_ID2_FLAT, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = list_addr; + desc.args[1] = list_size; + desc.args[2] = chunk_size; + desc.args[3] = memory_usage; + desc.args[4] = lock; + desc.args[5] = 0; + + desc.arginfo = QCOM_SCM_ARGS(6, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL, + QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL); + + ret = qcom_scm_call(dev, &desc); + + return ret; +} + int __qcom_scm_iommu_secure_map(struct device *dev, phys_addr_t sg_list_addr, size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx, unsigned long iova, size_t total_len) @@ -1088,6 +1115,28 @@ int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, return ret ? : desc.res[0]; } +int __qcom_scm_kgsl_set_smmu_aperture(struct device *dev, + unsigned int num_context_bank) +{ + int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_MP, + .cmd = QCOM_SCM_MP_CP_SMMU_APERTURE_ID, + .owner = ARM_SMCCC_OWNER_SIP + }; + + desc.args[0] = 0xffff0000 | ((QCOM_SCM_CP_APERTURE_REG & 0xff) << 8) | + (num_context_bank & 0xff); + desc.args[1] = 0xffffffff; + desc.args[2] = 0xffffffff; + desc.args[3] = 0xffffffff; + desc.arginfo = QCOM_SCM_ARGS(4); + + ret = qcom_scm_call(dev, &desc); + + return ret; +} + int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 1eab6f19fc6d..58a5d435fada 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -378,6 +378,15 @@ int qcom_scm_mem_protect_region_id(phys_addr_t paddr, size_t size) } EXPORT_SYMBOL(qcom_scm_mem_protect_region_id); +int qcom_scm_mem_protect_lock_id2_flat(phys_addr_t list_addr, + size_t list_size, size_t chunk_size, + size_t memory_usage, int lock) +{ + return __qcom_scm_mem_protect_lock_id2_flat(__scm->dev, list_addr, + list_size, chunk_size, memory_usage, lock); +} +EXPORT_SYMBOL(qcom_scm_mem_protect_lock_id2_flat); + int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx, unsigned long iova, size_t total_len) @@ -477,6 +486,24 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, } EXPORT_SYMBOL(qcom_scm_assign_mem); +bool qcom_scm_kgsl_set_smmu_aperture_available(void) +{ + int ret; + + ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP, + QCOM_SCM_MP_CP_SMMU_APERTURE_ID); + + return ret > 0; +} +EXPORT_SYMBOL(qcom_scm_kgsl_set_smmu_aperture_available); + +int qcom_scm_kgsl_set_smmu_aperture(unsigned int num_context_bank) +{ + return __qcom_scm_kgsl_set_smmu_aperture(__scm->dev, + num_context_bank); +} +EXPORT_SYMBOL(qcom_scm_kgsl_set_smmu_aperture); + /** * qcom_scm_hdcp_available() - Check if secure environment supports HDCP. * diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 47c8b8f8174b..46e5bd640bb7 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -65,9 +65,11 @@ extern void __qcom_scm_mmu_sync(struct device *dev, bool sync); #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03 #define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04 #define QCOM_SCM_MP_MEM_PROTECT_REGION_ID 0x10 +#define QCOM_SCM_MP_MEM_PROTECT_LOCK_ID2_FLAT 0x11 #define QCOM_SCM_MP_IOMMU_SECURE_MAP2_FLAT 0x12 #define QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT 0x13 #define QCOM_SCM_MP_ASSIGN 0x16 +#define QCOM_SCM_MP_CP_SMMU_APERTURE_ID 0x1b extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare); extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, @@ -76,6 +78,10 @@ extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, u32 spare); extern int __qcom_scm_mem_protect_region_id(struct device *dev, phys_addr_t paddr, size_t size); +extern int __qcom_scm_mem_protect_lock_id2_flat(struct device *dev, + phys_addr_t list_addr, size_t list_size, + size_t chunk_size, size_t memory_usage, + int lock); extern int __qcom_scm_iommu_secure_map(struct device *dev, phys_addr_t sg_list_addr, size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx, @@ -87,7 +93,10 @@ extern int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region, size_t mem_sz, phys_addr_t src, size_t src_sz, phys_addr_t dest, size_t dest_sz); +extern int __qcom_scm_kgsl_set_smmu_aperture(struct device *dev, + unsigned int num_context_bank); #define QCOM_SCM_IOMMU_TLBINVAL_FLAG 0x00000001 +#define QCOM_SCM_CP_APERTURE_REG 0x0 #define QCOM_SCM_SVC_HDCP 0x11 #define QCOM_SCM_HDCP_INVOKE 0x01 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index ea3ca01baad6..a3aead9fedf9 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -56,6 +56,9 @@ extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); extern int qcom_scm_mem_protect_region_id(phys_addr_t paddr, size_t size); +extern int qcom_scm_mem_protect_lock_id2_flat(phys_addr_t list_addr, + size_t list_size, size_t chunk_size, + size_t memory_usage, int lock); extern int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx, unsigned long iova, size_t total_len); @@ -65,6 +68,9 @@ extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *src, const struct qcom_scm_vmperm *newvm, unsigned int dest_cnt); +extern bool qcom_scm_kgsl_set_smmu_aperture_available(void); +extern int qcom_scm_kgsl_set_smmu_aperture( + unsigned int num_context_bank); extern bool qcom_scm_hdcp_available(void); extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp); @@ -110,6 +116,9 @@ static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; } static inline int qcom_scm_mem_protect_region_id(phys_addr_t paddr, size_t size) { return -ENODEV; } +static inline int qcom_scm_mem_protect_lock_id2_flat(phys_addr_t list_addr, + size_t list_size, size_t chunk_size, size_t memory_usage, + int lock) { return -ENODEV; } static inline int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx, unsigned long iova, size_t total_len) { return -ENODEV; } @@ -119,6 +128,10 @@ static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz, unsigned int *src, const struct qcom_scm_vmperm *newvm, unsigned int dest_cnt) { return -ENODEV; } +static inline bool qcom_scm_kgsl_set_smmu_aperture_available(void) + { return false; } +static inline int qcom_scm_kgsl_set_smmu_aperture( + unsigned int num_context_bank) { return -ENODEV; } static inline bool qcom_scm_hdcp_available(void) { return false; } static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) { return -ENODEV; }