Loading drivers/media/platform/msm/vidc/msm_smem.c +45 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,13 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, * Mapping of sg is taken care by map attachment */ attach->dma_map_attrs = DMA_ATTR_DELAYED_UNMAP; /* * We do not need dma_map function to perform cache operations * on the whole buffer size and hence pass skip sync flag. * We do the required cache operations separately for the * required buffer size */ attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; if (res->sys_cache_present) attach->dma_map_attrs |= DMA_ATTR_IOMMU_USE_UPSTREAM_HINT; Loading Loading @@ -511,6 +518,44 @@ int msm_smem_free(struct msm_smem *smem) return rc; }; int msm_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size) { int rc = 0; if (!dbuf) { dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); return -EINVAL; } switch (cache_op) { case SMEM_CACHE_CLEAN: case SMEM_CACHE_CLEAN_INVALIDATE: rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, offset, size); if (rc) break; rc = dma_buf_end_cpu_access_partial(dbuf, DMA_TO_DEVICE, offset, size); break; case SMEM_CACHE_INVALIDATE: rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, offset, size); if (rc) break; rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE, offset, size); break; default: dprintk(VIDC_ERR, "%s: cache (%d) operation not supported\n", __func__, cache_op); rc = -EINVAL; break; } return rc; } struct context_bank_info *msm_smem_get_context_bank(u32 session_type, bool is_secure, struct msm_vidc_platform_resources *res, enum hal_buffer buffer_type) Loading drivers/media/platform/msm/vidc/msm_vidc_common.c +143 −0 Original line number Diff line number Diff line Loading @@ -2416,6 +2416,11 @@ static void handle_ebd(enum hal_command_response cmd, void *data) update_recon_stats(inst, &empty_buf_done->recon_stats); msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr); /* * dma cache operations need to be performed before dma_unmap * which is done inside msm_comm_put_vidc_buffer() */ msm_comm_dqbuf_cache_operations(inst, mbuf); /* * put_buffer should be done before vb2_buffer_done else * client might queue the same buffer before it is unmapped Loading Loading @@ -2601,6 +2606,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data) } mutex_unlock(&inst->registeredbufs.lock); /* * dma cache operations need to be performed before dma_unmap * which is done inside msm_comm_put_vidc_buffer() */ msm_comm_dqbuf_cache_operations(inst, mbuf); /* * put_buffer should be done before vb2_buffer_done else * client might queue the same buffer before it is unmapped Loading Loading @@ -6103,6 +6113,137 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, return rc; } int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { int rc = 0, i; struct vb2_buffer *vb; bool skip; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } vb = &mbuf->vvb.vb2_buf; for (i = 0; i < vb->num_planes; i++) { unsigned long offset, size; enum smem_cache_ops cache_op; skip = true; if (inst->session_type == MSM_VIDC_DECODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (!i) { /* bitstream */ skip = false; offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* yuv */ skip = false; offset = 0; size = vb->planes[i].length; cache_op = SMEM_CACHE_INVALIDATE; } } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (!i) { /* yuv */ skip = false; offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* bitstream */ skip = false; offset = 0; size = vb->planes[i].length; cache_op = SMEM_CACHE_INVALIDATE; } } } if (!skip) { rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, cache_op, offset, size); if (rc) print_vidc_buffer(VIDC_ERR, "qbuf cache ops failed", inst, mbuf); } } return rc; } int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { int rc = 0, i; struct vb2_buffer *vb; bool skip; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } vb = &mbuf->vvb.vb2_buf; for (i = 0; i < vb->num_planes; i++) { unsigned long offset, size; enum smem_cache_ops cache_op; skip = true; if (inst->session_type == MSM_VIDC_DECODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* bitstream and extradata */ /* we do not need cache operations */ } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* yuv */ skip = false; offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_INVALIDATE; } } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* yuv and extradata */ /* we do not need cache operations */ } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* bitstream */ skip = false; /* * Include vp8e header bytes as well * by making offset equal to zero */ offset = 0; size = vb->planes[i].bytesused + vb->planes[i].data_offset; cache_op = SMEM_CACHE_INVALIDATE; } } } if (!skip) { rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, cache_op, offset, size); if (rc) print_vidc_buffer(VIDC_ERR, "dqbuf cache ops failed", inst, mbuf); } } return rc; } struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) { Loading Loading @@ -6191,6 +6332,8 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, goto exit; } } /* dma cache operations need to be performed after dma_map */ msm_comm_qbuf_cache_operations(inst, mbuf); /* special handling for decoder */ if (inst->session_type == MSM_VIDC_DECODER) { Loading drivers/media/platform/msm/vidc/msm_vidc_common.h +2 −2 Original line number Diff line number Diff line Loading @@ -204,9 +204,9 @@ bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, u32 *planes); int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, struct v4l2_buffer *b); struct msm_vidc_buffer *mbuf); int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, struct v4l2_buffer *b); struct msm_vidc_buffer *mbuf); void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, Loading drivers/media/platform/msm/vidc/msm_vidc_internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -514,6 +514,8 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); struct dma_buf *msm_smem_get_dma_buf(int fd); void msm_smem_put_dma_buf(void *dma_buf); int msm_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size); void msm_vidc_fw_unload_handler(struct work_struct *work); void msm_vidc_ssr_handler(struct work_struct *work); /* Loading drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +11 −0 Original line number Diff line number Diff line Loading @@ -981,6 +981,17 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, goto release_mapping; } /* * configure device segment size and segment boundary to ensure * iommu mapping returns one mapping (which is required for partial * cache operations) */ if (!dev->dma_parms) dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); dprintk(VIDC_DBG, "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, mapping: %pK", Loading Loading
drivers/media/platform/msm/vidc/msm_smem.c +45 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,13 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, unsigned long align, * Mapping of sg is taken care by map attachment */ attach->dma_map_attrs = DMA_ATTR_DELAYED_UNMAP; /* * We do not need dma_map function to perform cache operations * on the whole buffer size and hence pass skip sync flag. * We do the required cache operations separately for the * required buffer size */ attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; if (res->sys_cache_present) attach->dma_map_attrs |= DMA_ATTR_IOMMU_USE_UPSTREAM_HINT; Loading Loading @@ -511,6 +518,44 @@ int msm_smem_free(struct msm_smem *smem) return rc; }; int msm_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size) { int rc = 0; if (!dbuf) { dprintk(VIDC_ERR, "%s: Invalid params\n", __func__); return -EINVAL; } switch (cache_op) { case SMEM_CACHE_CLEAN: case SMEM_CACHE_CLEAN_INVALIDATE: rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, offset, size); if (rc) break; rc = dma_buf_end_cpu_access_partial(dbuf, DMA_TO_DEVICE, offset, size); break; case SMEM_CACHE_INVALIDATE: rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, offset, size); if (rc) break; rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE, offset, size); break; default: dprintk(VIDC_ERR, "%s: cache (%d) operation not supported\n", __func__, cache_op); rc = -EINVAL; break; } return rc; } struct context_bank_info *msm_smem_get_context_bank(u32 session_type, bool is_secure, struct msm_vidc_platform_resources *res, enum hal_buffer buffer_type) Loading
drivers/media/platform/msm/vidc/msm_vidc_common.c +143 −0 Original line number Diff line number Diff line Loading @@ -2416,6 +2416,11 @@ static void handle_ebd(enum hal_command_response cmd, void *data) update_recon_stats(inst, &empty_buf_done->recon_stats); msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr); /* * dma cache operations need to be performed before dma_unmap * which is done inside msm_comm_put_vidc_buffer() */ msm_comm_dqbuf_cache_operations(inst, mbuf); /* * put_buffer should be done before vb2_buffer_done else * client might queue the same buffer before it is unmapped Loading Loading @@ -2601,6 +2606,11 @@ static void handle_fbd(enum hal_command_response cmd, void *data) } mutex_unlock(&inst->registeredbufs.lock); /* * dma cache operations need to be performed before dma_unmap * which is done inside msm_comm_put_vidc_buffer() */ msm_comm_dqbuf_cache_operations(inst, mbuf); /* * put_buffer should be done before vb2_buffer_done else * client might queue the same buffer before it is unmapped Loading Loading @@ -6103,6 +6113,137 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst, return rc; } int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { int rc = 0, i; struct vb2_buffer *vb; bool skip; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } vb = &mbuf->vvb.vb2_buf; for (i = 0; i < vb->num_planes; i++) { unsigned long offset, size; enum smem_cache_ops cache_op; skip = true; if (inst->session_type == MSM_VIDC_DECODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (!i) { /* bitstream */ skip = false; offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* yuv */ skip = false; offset = 0; size = vb->planes[i].length; cache_op = SMEM_CACHE_INVALIDATE; } } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (!i) { /* yuv */ skip = false; offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_CLEAN_INVALIDATE; } } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* bitstream */ skip = false; offset = 0; size = vb->planes[i].length; cache_op = SMEM_CACHE_INVALIDATE; } } } if (!skip) { rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, cache_op, offset, size); if (rc) print_vidc_buffer(VIDC_ERR, "qbuf cache ops failed", inst, mbuf); } } return rc; } int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf) { int rc = 0, i; struct vb2_buffer *vb; bool skip; if (!inst || !mbuf) { dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n", __func__, inst, mbuf); return -EINVAL; } vb = &mbuf->vvb.vb2_buf; for (i = 0; i < vb->num_planes; i++) { unsigned long offset, size; enum smem_cache_ops cache_op; skip = true; if (inst->session_type == MSM_VIDC_DECODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* bitstream and extradata */ /* we do not need cache operations */ } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* yuv */ skip = false; offset = vb->planes[i].data_offset; size = vb->planes[i].bytesused; cache_op = SMEM_CACHE_INVALIDATE; } } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { /* yuv and extradata */ /* we do not need cache operations */ } else if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (!i) { /* bitstream */ skip = false; /* * Include vp8e header bytes as well * by making offset equal to zero */ offset = 0; size = vb->planes[i].bytesused + vb->planes[i].data_offset; cache_op = SMEM_CACHE_INVALIDATE; } } } if (!skip) { rc = msm_smem_cache_operations(mbuf->smem[i].dma_buf, cache_op, offset, size); if (rc) print_vidc_buffer(VIDC_ERR, "dqbuf cache ops failed", inst, mbuf); } } return rc; } struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, struct vb2_buffer *vb2) { Loading Loading @@ -6191,6 +6332,8 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst, goto exit; } } /* dma cache operations need to be performed after dma_map */ msm_comm_qbuf_cache_operations(inst, mbuf); /* special handling for decoder */ if (inst->session_type == MSM_VIDC_DECODER) { Loading
drivers/media/platform/msm/vidc/msm_vidc_common.h +2 −2 Original line number Diff line number Diff line Loading @@ -204,9 +204,9 @@ bool msm_comm_compare_device_plane(struct msm_vidc_buffer *mbuf, bool msm_comm_compare_device_planes(struct msm_vidc_buffer *mbuf, u32 *planes); int msm_comm_qbuf_cache_operations(struct msm_vidc_inst *inst, struct v4l2_buffer *b); struct msm_vidc_buffer *mbuf); int msm_comm_dqbuf_cache_operations(struct msm_vidc_inst *inst, struct v4l2_buffer *b); struct msm_vidc_buffer *mbuf); void print_vidc_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, struct msm_vidc_buffer *mbuf); void print_vb2_buffer(u32 tag, const char *str, struct msm_vidc_inst *inst, Loading
drivers/media/platform/msm/vidc/msm_vidc_internal.h +2 −0 Original line number Diff line number Diff line Loading @@ -514,6 +514,8 @@ int msm_smem_map_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem); struct dma_buf *msm_smem_get_dma_buf(int fd); void msm_smem_put_dma_buf(void *dma_buf); int msm_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size); void msm_vidc_fw_unload_handler(struct work_struct *work); void msm_vidc_ssr_handler(struct work_struct *work); /* Loading
drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +11 −0 Original line number Diff line number Diff line Loading @@ -981,6 +981,17 @@ static int msm_vidc_setup_context_bank(struct msm_vidc_platform_resources *res, goto release_mapping; } /* * configure device segment size and segment boundary to ensure * iommu mapping returns one mapping (which is required for partial * cache operations) */ if (!dev->dma_parms) dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); dprintk(VIDC_DBG, "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, mapping: %pK", Loading