diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 2a5f3dd17e2d..32be03f3225b 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -155,6 +155,7 @@ enum mdss_hw_quirk { MDSS_QUIRK_DOWNSCALE_HANG, MDSS_QUIRK_DSC_RIGHT_ONLY_PU, MDSS_QUIRK_DSC_2SLICE_PU_THRPUT, + MDSS_QUIRK_DMA_BI_DIR, MDSS_QUIRK_MAX, }; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 7eaaf3481bff..39b1c4c2c766 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1289,6 +1289,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map); mdss_mdp_init_default_prefill_factors(mdata); set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map); + mdss_set_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR); break; default: mdata->max_target_zorder = 4; /* excluding base layer */ diff --git a/drivers/video/fbdev/msm/mdss_mdp_splash_logo.c b/drivers/video/fbdev/msm/mdss_mdp_splash_logo.c index 4596b46464ca..7cc94447efdc 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_splash_logo.c +++ b/drivers/video/fbdev/msm/mdss_mdp_splash_logo.c @@ -88,7 +88,7 @@ static int mdss_mdp_splash_alloc_memory(struct msm_fb_data_type *mfd, } sinfo->size = buf_size; - dma_buf_begin_cpu_access(sinfo->dma_buf, 0, size, DMA_FROM_DEVICE); + dma_buf_begin_cpu_access(sinfo->dma_buf, 0, size, DMA_BIDIRECTIONAL); sinfo->splash_buffer = dma_buf_kmap(sinfo->dma_buf, 0); if (IS_ERR(sinfo->splash_buffer)) { pr_err("ion kernel memory mapping failed\n"); @@ -132,7 +132,8 @@ static void mdss_mdp_splash_free_memory(struct msm_fb_data_type *mfd) if (!mdata || !mdata->iclient || !sinfo->dma_buf) return; - dma_buf_end_cpu_access(sinfo->dma_buf, 0, sinfo->size, DMA_FROM_DEVICE); + dma_buf_end_cpu_access(sinfo->dma_buf, 0, sinfo->size, + DMA_BIDIRECTIONAL); dma_buf_kunmap(sinfo->dma_buf, 0, sinfo->splash_buffer); mdss_smmu_unmap_dma_buf(sinfo->table, MDSS_IOMMU_DOMAIN_UNSECURE, 0, diff --git a/drivers/video/fbdev/msm/mdss_mdp_util.c b/drivers/video/fbdev/msm/mdss_mdp_util.c index 74813f201dbb..6142f009c8f5 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_util.c +++ b/drivers/video/fbdev/msm/mdss_mdp_util.c @@ -1047,7 +1047,8 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator, } if (!data->skip_detach) { dma_buf_unmap_attachment(data->srcp_attachment, - data->srcp_table, dir); + data->srcp_table, + mdss_smmu_dma_data_direction(dir)); dma_buf_detach(data->srcp_dma_buf, data->srcp_attachment); dma_buf_put(data->srcp_dma_buf); @@ -1121,7 +1122,8 @@ static int mdss_mdp_get_img(struct msmfb_data *img, } data->srcp_table = - dma_buf_map_attachment(data->srcp_attachment, dir); + dma_buf_map_attachment(data->srcp_attachment, + mdss_smmu_dma_data_direction(dir)); if (IS_ERR(data->srcp_table)) { ret = PTR_ERR(data->srcp_table); goto err_detach; @@ -1252,7 +1254,8 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data, bool rotator, return ret; err_unmap: - dma_buf_unmap_attachment(data->srcp_attachment, data->srcp_table, dir); + dma_buf_unmap_attachment(data->srcp_attachment, data->srcp_table, + mdss_smmu_dma_data_direction(dir)); dma_buf_detach(data->srcp_dma_buf, data->srcp_attachment); dma_buf_put(data->srcp_dma_buf); return ret; diff --git a/drivers/video/fbdev/msm/mdss_smmu.h b/drivers/video/fbdev/msm/mdss_smmu.h index a12e759c90ab..a7b95f5742b6 100644 --- a/drivers/video/fbdev/msm/mdss_smmu.h +++ b/drivers/video/fbdev/msm/mdss_smmu.h @@ -41,6 +41,14 @@ struct mdss_smmu_domain { void mdss_smmu_register(struct device *dev); int mdss_smmu_init(struct mdss_data_type *mdata, struct device *dev); +static inline int mdss_smmu_dma_data_direction(int dir) +{ + struct mdss_data_type *mdata = mdss_mdp_get_mdata(); + + return (mdss_has_quirk(mdata, MDSS_QUIRK_DMA_BI_DIR)) ? + DMA_BIDIRECTIONAL : dir; +} + static inline bool is_mdss_smmu_compatible_device(const char *str) { /* check the prefix */ @@ -177,7 +185,8 @@ static inline int mdss_smmu_map_dma_buf(struct dma_buf *dma_buf, return -ENOSYS; return mdata->smmu_ops.smmu_map_dma_buf(dma_buf, table, - domain, iova, size, dir); + domain, iova, size, + mdss_smmu_dma_data_direction(dir)); } static inline void mdss_smmu_unmap_dma_buf(struct sg_table *table, int domain, @@ -185,7 +194,8 @@ static inline void mdss_smmu_unmap_dma_buf(struct sg_table *table, int domain, { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (mdata->smmu_ops.smmu_unmap_dma_buf) - mdata->smmu_ops.smmu_unmap_dma_buf(table, domain, dir, dma_buf); + mdata->smmu_ops.smmu_unmap_dma_buf(table, domain, + mdss_smmu_dma_data_direction(dir), dma_buf); } static inline int mdss_smmu_dma_alloc_coherent(struct device *dev, size_t size, @@ -246,7 +256,8 @@ static inline int mdss_smmu_dsi_map_buffer(phys_addr_t phys, return -ENOSYS; return mdata->smmu_ops.smmu_dsi_map_buffer(phys, domain, size, - dma_addr, cpu_addr, dir); + dma_addr, cpu_addr, + mdss_smmu_dma_data_direction(dir)); } static inline void mdss_smmu_dsi_unmap_buffer(dma_addr_t dma_addr, int domain, @@ -255,7 +266,7 @@ static inline void mdss_smmu_dsi_unmap_buffer(dma_addr_t dma_addr, int domain, struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (mdata->smmu_ops.smmu_dsi_unmap_buffer) mdata->smmu_ops.smmu_dsi_unmap_buffer(dma_addr, domain, - size, dir); + size, mdss_smmu_dma_data_direction(dir)); } static inline void mdss_smmu_deinit(struct mdss_data_type *mdata)