summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/msm/vidc/msm_smem.c15
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c58
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c10
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.h4
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_internal.h4
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c2
6 files changed, 60 insertions, 33 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index c9dfb52861bc..1d30a869d754 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -490,11 +490,13 @@ bool msm_smem_compare_buffers(void *clt, int fd, void *priv)
}
static int ion_cache_operations(struct smem_client *client,
- struct msm_smem *mem, enum smem_cache_ops cache_op)
+ struct msm_smem *mem, enum smem_cache_ops cache_op,
+ int size)
{
unsigned long ionflag = 0;
int rc = 0;
int msm_cache_ops = 0;
+ int op_size = 0;
if (!mem || !client) {
dprintk(VIDC_ERR, "Invalid params: %pK, %pK\n",
mem, client);
@@ -523,10 +525,15 @@ static int ion_cache_operations(struct smem_client *client,
rc = -EINVAL;
goto cache_op_failed;
}
+ if (size <= 0)
+ op_size = mem->size;
+ else
+ op_size = mem->size < size ? mem->size : size;
+
rc = msm_ion_do_cache_offset_op(client->clnt,
(struct ion_handle *)mem->smem_priv,
0, mem->offset,
- (unsigned long)mem->size, msm_cache_ops);
+ (unsigned long)op_size, msm_cache_ops);
if (rc) {
dprintk(VIDC_ERR,
"cache operation failed %d\n", rc);
@@ -538,7 +545,7 @@ cache_op_failed:
}
int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
- enum smem_cache_ops cache_op)
+ enum smem_cache_ops cache_op, int size)
{
struct smem_client *client = clt;
int rc = 0;
@@ -549,7 +556,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
}
switch (client->mem_type) {
case SMEM_ION:
- rc = ion_cache_operations(client, mem, cache_op);
+ rc = ion_cache_operations(client, mem, cache_op, size);
if (rc)
dprintk(VIDC_ERR,
"Failed cache operations: %d\n", rc);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 1d878555e0a7..3e4be4418f80 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -670,10 +670,11 @@ int qbuf_dynamic_buf(struct msm_vidc_inst *inst,
}
int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
- struct buffer_info *binfo)
+ struct buffer_info *binfo, struct v4l2_buffer *b)
{
int i = 0;
int rc = 0;
+ int size = -1;
if (!inst) {
dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst);
@@ -686,23 +687,34 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
return -EINVAL;
}
- for (i = 0; i < binfo->num_planes; i++) {
- if (binfo->handle[i]) {
- struct msm_smem smem = *binfo->handle[i];
-
- smem.offset = (unsigned int)(binfo->buff_off[i]);
- smem.size = binfo->size[i];
- rc = msm_comm_smem_cache_operations(inst,
- &smem, SMEM_CACHE_INVALIDATE);
- if (rc) {
- dprintk(VIDC_ERR,
- "%s: Failed to clean caches: %d\n",
- __func__, rc);
- return -EINVAL;
- }
- } else
- dprintk(VIDC_DBG, "%s: NULL handle for plane %d\n",
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ for (i = 0; i < binfo->num_planes; i++) {
+ if (binfo->handle[i]) {
+ struct msm_smem smem = *binfo->handle[i];
+
+ if (inst->session_type == MSM_VIDC_ENCODER &&
+ !i)
+ size = b->m.planes[i].bytesused;
+ else
+ size = -1;
+
+ smem.offset =
+ (unsigned int)(binfo->buff_off[i]);
+ smem.size = binfo->size[i];
+ rc = msm_comm_smem_cache_operations(inst,
+ &smem, SMEM_CACHE_INVALIDATE,
+ size);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s: Failed to clean caches: %d\n",
+ __func__, rc);
+ return -EINVAL;
+ }
+ } else
+ dprintk(VIDC_DBG,
+ "%s: NULL handle for plane %d\n",
__func__, i);
+ }
}
return 0;
}
@@ -858,6 +870,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
int plane = 0;
int rc = 0;
int i;
+ int size = -1;
if (!inst || !inst->core || !b || !valid_v4l2_buffer(b, inst))
return -EINVAL;
@@ -905,7 +918,7 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
V4L2_PIX_FMT_HEVC_HYBRID && binfo->handle[i] &&
b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
rc = msm_comm_smem_cache_operations(inst,
- binfo->handle[i], SMEM_CACHE_INVALIDATE);
+ binfo->handle[i], SMEM_CACHE_INVALIDATE, -1);
if (rc) {
dprintk(VIDC_ERR,
"Failed to inv caches: %d\n", rc);
@@ -915,8 +928,13 @@ int msm_vidc_qbuf(void *instance, struct v4l2_buffer *b)
if (binfo->handle[i] &&
(b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) {
+ if (inst->session_type == MSM_VIDC_DECODER && !i)
+ size = b->m.planes[i].bytesused;
+ else
+ size = -1;
rc = msm_comm_smem_cache_operations(inst,
- binfo->handle[i], SMEM_CACHE_CLEAN);
+ binfo->handle[i], SMEM_CACHE_CLEAN,
+ size);
if (rc) {
dprintk(VIDC_ERR,
"Failed to clean caches: %d\n", rc);
@@ -985,7 +1003,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
return -EINVAL;
}
- rc = output_buffer_cache_invalidate(inst, buffer_info);
+ rc = output_buffer_cache_invalidate(inst, buffer_info, b);
if (rc)
return rc;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index fc817dc57351..c9a871bae25b 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -3174,7 +3174,7 @@ static int set_output_buffers(struct msm_vidc_inst *inst,
goto err_no_mem;
}
rc = msm_comm_smem_cache_operations(inst,
- handle, SMEM_CACHE_CLEAN);
+ handle, SMEM_CACHE_CLEAN, -1);
if (rc) {
dprintk(VIDC_WARN,
"Failed to clean cache may cause undefined behavior\n");
@@ -3265,7 +3265,7 @@ static int set_internal_buf_on_fw(struct msm_vidc_inst *inst,
hdev = inst->core->device;
rc = msm_comm_smem_cache_operations(inst,
- handle, SMEM_CACHE_CLEAN);
+ handle, SMEM_CACHE_CLEAN, -1);
if (rc) {
dprintk(VIDC_WARN,
"Failed to clean cache. Undefined behavior\n");
@@ -5159,14 +5159,16 @@ void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem)
}
int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
- struct msm_smem *mem, enum smem_cache_ops cache_ops)
+ struct msm_smem *mem, enum smem_cache_ops cache_ops,
+ int size)
{
if (!inst || !mem) {
dprintk(VIDC_ERR,
"%s: invalid params: %pK %pK\n", __func__, inst, mem);
return -EINVAL;
}
- return msm_smem_cache_operations(inst->mem_client, mem, cache_ops);
+ return msm_smem_cache_operations(inst->mem_client, mem,
+ cache_ops, size);
}
struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.h b/drivers/media/platform/msm/vidc/msm_vidc_common.h
index eac7f658eb31..01c1890bf5e1 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -76,7 +76,7 @@ struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst,
enum hal_buffer buffer_type, int map_kernel);
void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem);
int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst,
- struct msm_smem *mem, enum smem_cache_ops cache_ops);
+ struct msm_smem *mem, enum smem_cache_ops cache_ops, int size);
struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst,
int fd, u32 offset, enum hal_buffer buffer_type);
enum hal_video_codec get_hal_codec(int fourcc);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 690a61f4824f..4cb900bbca10 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -355,7 +355,7 @@ struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list,
int buf_ref_get(struct msm_vidc_inst *inst, struct buffer_info *binfo);
int buf_ref_put(struct msm_vidc_inst *inst, struct buffer_info *binfo);
int output_buffer_cache_invalidate(struct msm_vidc_inst *inst,
- struct buffer_info *binfo);
+ struct buffer_info *binfo, struct v4l2_buffer *b);
int qbuf_dynamic_buf(struct msm_vidc_inst *inst,
struct buffer_info *binfo);
int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
@@ -369,7 +369,7 @@ struct msm_smem *msm_smem_alloc(void *clt, size_t size, u32 align, u32 flags,
void msm_smem_free(void *clt, struct msm_smem *mem);
void msm_smem_delete_client(void *clt);
int msm_smem_cache_operations(void *clt, struct msm_smem *mem,
- enum smem_cache_ops);
+ enum smem_cache_ops, int size);
struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
enum hal_buffer buffer_type);
struct context_bank_info *msm_smem_get_context_bank(void *clt,
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index bc72c4a56c91..52b56f615da9 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -582,7 +582,7 @@ static int __smem_alloc(struct venus_hfi_device *dev,
dprintk(VIDC_DBG, "__smem_alloc: ptr = %pK, size = %d\n",
alloc->kvaddr, size);
rc = msm_smem_cache_operations(dev->hal_client, alloc,
- SMEM_CACHE_CLEAN);
+ SMEM_CACHE_CLEAN, -1);
if (rc) {
dprintk(VIDC_WARN, "Failed to clean cache\n");
dprintk(VIDC_WARN, "This may result in undefined behavior\n");