diff --git a/msm/dsi/dsi_parser.c b/msm/dsi/dsi_parser.c index 5e830e0621..4bc2094a4f 100644 --- a/msm/dsi/dsi_parser.c +++ b/msm/dsi/dsi_parser.c @@ -897,8 +897,13 @@ end: return -EINVAL; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) int dsi_parser_get_named_gpio(const struct device_node *np, const char *propname, int index) +#else +int dsi_parser_get_named_gpio(struct device_node *np, + const char *propname, int index) +#endif { int gpio = -EINVAL; diff --git a/msm/dsi/dsi_parser.h b/msm/dsi/dsi_parser.h index 4b163fc373..d660e7b74b 100644 --- a/msm/dsi/dsi_parser.h +++ b/msm/dsi/dsi_parser.h @@ -8,6 +8,7 @@ #include #include +#include #ifdef CONFIG_DSI_PARSER void *dsi_parser_get(struct device *dev); @@ -45,8 +46,13 @@ int dsi_parser_count_strings(const struct device_node *np, int dsi_parser_read_string_index(const struct device_node *np, const char *propname, int index, const char **output); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) int dsi_parser_get_named_gpio(const struct device_node *np, const char *propname, int index); +#else +int dsi_parser_get_named_gpio(struct device_node *np, + const char *propname, int index); +#endif #else /* CONFIG_DSI_PARSER */ static inline void *dsi_parser_get(struct device *dev) { @@ -155,11 +161,19 @@ static inline int dsi_parser_read_string_index(const struct device_node *np, return -ENODEV; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) static inline int dsi_parser_get_named_gpio(const struct device_node *np, const char *propname, int index) { return -ENODEV; } +#else +static inline int dsi_parser_get_named_gpio(struct device_node *np, + char *propname, int index) +{ + return -ENODEV; +} +#endif #endif /* CONFIG_DSI_PARSER */ @@ -201,8 +215,13 @@ struct dsi_parser_utils { const char *propname); int (*count_strings)(const struct device_node *np, const char *propname); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) int (*get_named_gpio)(const struct device_node *np, const char *propname, int index); +#else + int (*get_named_gpio)(struct device_node *np, + const char *propname, int index); +#endif int (*get_available_child_count)(const struct device_node *np); }; diff --git a/msm/msm_drv.h b/msm/msm_drv.h index ad6bfa57db..58c329d952 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -1150,6 +1150,8 @@ int msm_gem_get_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace, uint64_t *iova); uint64_t msm_gem_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace); +void msm_gem_unpin_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace); struct page **msm_gem_get_pages(struct drm_gem_object *obj); void msm_gem_put_pages(struct drm_gem_object *obj); void msm_gem_put_iova(struct drm_gem_object *obj, diff --git a/msm/msm_gem.c b/msm/msm_gem.c index 374c0bea31..6860989cbe 100644 --- a/msm/msm_gem.c +++ b/msm/msm_gem.c @@ -557,6 +557,27 @@ uint64_t msm_gem_iova(struct drm_gem_object *obj, return vma ? vma->iova : 0; } +/* + * Unpin a iova by updating the reference counts. The memory isn't actually + * purged until something else (shrinker, mm_notifier, destroy, etc) decides + * to get rid of it + */ +void msm_gem_unpin_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct msm_gem_vma *vma; + + mutex_lock(&msm_obj->lock); + vma = lookup_vma(obj, aspace); + + if (!WARN_ON(!vma)) + msm_gem_unmap_vma(vma->aspace, vma, msm_obj->sgt, + msm_obj->flags); + + mutex_unlock(&msm_obj->lock); +} + void msm_gem_put_iova(struct drm_gem_object *obj, struct msm_gem_address_space *aspace) { diff --git a/msm/msm_mmu.h b/msm/msm_mmu.h index feb7febd9b..b41a1d46b0 100644 --- a/msm/msm_mmu.h +++ b/msm/msm_mmu.h @@ -50,7 +50,12 @@ struct msm_mmu_funcs { int dir, u32 flags); void (*destroy)(struct msm_mmu *mmu); bool (*is_domain_secure)(struct msm_mmu *mmu); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) int (*enable_smmu_translations)(struct msm_mmu *mmu); +#else + int (*set_attribute)(struct msm_mmu *mmu, + enum iommu_attr attr, void *data); +#endif int (*one_to_one_map)(struct msm_mmu *mmu, uint32_t iova, uint32_t dest_address, uint32_t size, int prot); int (*one_to_one_unmap)(struct msm_mmu *mmu, uint32_t dest_address, diff --git a/msm/msm_smmu.c b/msm/msm_smmu.c index 29de50ead0..ec078362d2 100644 --- a/msm/msm_smmu.c +++ b/msm/msm_smmu.c @@ -129,6 +129,7 @@ static void msm_smmu_detach(struct msm_mmu *mmu, const char * const *names, dev_dbg(client->dev, "iommu domain detached\n"); } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) static int msm_enable_smmu_translations(struct msm_mmu *mmu) { struct msm_smmu *smmu = to_msm_smmu(mmu); @@ -144,6 +145,24 @@ static int msm_enable_smmu_translations(struct msm_mmu *mmu) return ret; } +#else +static int msm_smmu_set_attribute(struct msm_mmu *mmu, + enum iommu_attr attr, void *data) +{ + struct msm_smmu *smmu = to_msm_smmu(mmu); + struct msm_smmu_client *client = msm_smmu_to_client(smmu); + int ret = 0; + + if (!client || !client->domain) + return -ENODEV; + + ret = iommu_domain_set_attr(client->domain, attr, data); + if (ret) + DRM_ERROR("set domain attribute failed:%d\n", ret); + + return ret; +} +#endif static int msm_smmu_one_to_one_unmap(struct msm_mmu *mmu, uint32_t dest_address, uint32_t size) @@ -306,7 +325,11 @@ static const struct msm_mmu_funcs funcs = { .unmap_dma_buf = msm_smmu_unmap_dma_buf, .destroy = msm_smmu_destroy, .is_domain_secure = msm_smmu_is_domain_secure, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) .enable_smmu_translations = msm_enable_smmu_translations, +#else + .set_attribute = msm_smmu_set_attribute, +#endif .one_to_one_map = msm_smmu_one_to_one_map, .one_to_one_unmap = msm_smmu_one_to_one_unmap, .get_dev = msm_smmu_get_dev, diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index bf375e488c..7ae572c9fd 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -4060,6 +4060,10 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms) struct msm_mmu *mmu; int i, ret; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + int early_map = 0; +#endif + if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) return -EINVAL; @@ -4099,11 +4103,22 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms) * disable early-map which would have been enabled during * bootup by smmu through the device-tree hint for cont-spash */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) ret = mmu->funcs->enable_smmu_translations(mmu); if (ret) { SDE_ERROR("failed to enable_s1_translations ret:%d\n", ret); goto enable_trans_fail; } +#else + ret = mmu->funcs->set_attribute(mmu, DOMAIN_ATTR_EARLY_MAP, + &early_map); + if (ret) { + SDE_ERROR("failed to set_att ret:%d, early_map:%d\n", + ret, early_map); + goto enable_trans_fail; + } +#endif } sde_kms->base.aspace = sde_kms->aspace[0]; diff --git a/msm/sde/sde_vm_common.c b/msm/sde/sde_vm_common.c index 51f2a95b65..aad4f8baef 100644 --- a/msm/sde/sde_vm_common.c +++ b/msm/sde/sde_vm_common.c @@ -48,6 +48,7 @@ struct gh_acl_desc *sde_vm_populate_acl(enum gh_vm_names vm_name) return acl_desc; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) int __mem_sort_cmp(void *priv, const struct list_head *a, const struct list_head *b) { const struct msm_io_mem_entry *left = @@ -57,6 +58,17 @@ int __mem_sort_cmp(void *priv, const struct list_head *a, const struct list_head return (left->base - right->base); } +#else +int __mem_sort_cmp(void *priv, struct list_head *a, struct list_head *b) +{ + struct msm_io_mem_entry *left = + container_of(a, struct msm_io_mem_entry, list); + struct msm_io_mem_entry *right = + container_of(b, struct msm_io_mem_entry, list); + + return (left->base - right->base); +} +#endif bool __merge_on_overlap(struct msm_io_mem_entry *res, const struct msm_io_mem_entry *left, diff --git a/msm/sde_dbg.c b/msm/sde_dbg.c index 4bc58b37ca..f580af6f96 100755 --- a/msm/sde_dbg.c +++ b/msm/sde_dbg.c @@ -667,8 +667,13 @@ void sde_mini_dump_add_va_region(const char *name, u32 size, void *virt_addr) } #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) static int _sde_dump_reg_range_cmp(void *priv, const struct list_head *a, const struct list_head *b) +#else +static int _sde_dump_reg_range_cmp(void *priv, struct list_head *a, + struct list_head *b) +#endif { struct sde_dbg_reg_range *ar, *br; @@ -681,8 +686,13 @@ static int _sde_dump_reg_range_cmp(void *priv, const struct list_head *a, return ar->offset.start - br->offset.start; } +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)) static int _sde_dump_blk_phys_addr_cmp(void *priv, const struct list_head *a, const struct list_head *b) +#else +static int _sde_dump_blk_phys_addr_cmp(void *priv, struct list_head *a, + struct list_head *b) +#endif { struct sde_dbg_reg_base *ar, *br;