Explorar o código

Merge "video: driver: Amend the internal buffer reuse logic"

qctecmdr %!s(int64=2) %!d(string=hai) anos
pai
achega
df3230b3d3

+ 55 - 0
driver/vidc/src/msm_vdec.c

@@ -32,6 +32,10 @@ static const u32 msm_vdec_internal_buffer_type[] = {
 	MSM_VIDC_BUF_PARTIAL_DATA,
 };
 
+static const u32 msm_vdec_output_internal_buffer_type[] = {
+	MSM_VIDC_BUF_DPB,
+};
+
 struct msm_vdec_prop_type_handle {
 	u32 type;
 	int (*handle)(struct msm_vidc_inst *inst, enum msm_vidc_port_type port);
@@ -732,6 +736,49 @@ static int msm_vdec_get_output_internal_buffers(struct msm_vidc_inst *inst)
 	return rc;
 }
 
+static int msm_vdec_destroy_internal_buffers(struct msm_vidc_inst *inst,
+		enum msm_vidc_port_type port)
+{
+	int rc = 0;
+	struct msm_vidc_buffers *buffers;
+	struct msm_vidc_buffer *buf, *dummy;
+	const u32 *internal_buf_type;
+	u32 i, len;
+
+	if (port == INPUT_PORT) {
+		internal_buf_type = msm_vdec_internal_buffer_type;
+		len = ARRAY_SIZE(msm_vdec_internal_buffer_type);
+	} else {
+		internal_buf_type = msm_vdec_output_internal_buffer_type;
+		len = ARRAY_SIZE(msm_vdec_output_internal_buffer_type);
+	}
+
+	for (i = 0; i < len; i++) {
+		buffers = msm_vidc_get_buffers(inst, internal_buf_type[i], __func__);
+		if (!buffers)
+			return -EINVAL;
+
+		if (buffers->reuse) {
+			i_vpr_l(inst, "%s: reuse enabled for %s\n", __func__,
+				buf_name(internal_buf_type[i]));
+			continue;
+		}
+
+		list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+			i_vpr_h(inst,
+				"%s: destroying internal buffer: type %d idx %d fd %d addr %#llx size %d\n",
+				__func__, buf->type, buf->index, buf->fd,
+				buf->device_addr, buf->buffer_size);
+
+			rc = msm_vidc_destroy_internal_buffer(inst, buf);
+			if (rc)
+				return rc;
+		}
+	}
+
+	return 0;
+}
+
 int msm_vdec_create_input_internal_buffers(struct msm_vidc_inst *inst)
 {
 	int rc = 0;
@@ -1454,6 +1501,10 @@ int msm_vdec_streamon_input(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	rc = msm_vdec_destroy_internal_buffers(inst, INPUT_PORT);
+	if (rc)
+		goto error;
+
 	rc = msm_vdec_create_input_internal_buffers(inst);
 	if (rc)
 		goto error;
@@ -1814,6 +1865,10 @@ int msm_vdec_streamon_output(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	rc = msm_vdec_destroy_internal_buffers(inst, OUTPUT_PORT);
+	if (rc)
+		goto error;
+
 	rc = msm_vdec_create_output_internal_buffers(inst);
 	if (rc)
 		goto error;

+ 51 - 0
driver/vidc/src/msm_venc.c

@@ -572,6 +572,49 @@ static int msm_venc_get_input_internal_buffers(struct msm_vidc_inst *inst)
 	return rc;
 }
 
+static int msm_venc_destroy_internal_buffers(struct msm_vidc_inst *inst,
+		enum msm_vidc_port_type port)
+{
+	int rc = 0;
+	struct msm_vidc_buffers *buffers;
+	struct msm_vidc_buffer *buf, *dummy;
+	const u32 *internal_buf_type;
+	u32 i, len;
+
+	if (port == INPUT_PORT) {
+		internal_buf_type = msm_venc_input_internal_buffer_type;
+		len = ARRAY_SIZE(msm_venc_input_internal_buffer_type);
+	} else {
+		internal_buf_type = msm_venc_output_internal_buffer_type;
+		len = ARRAY_SIZE(msm_venc_output_internal_buffer_type);
+	}
+
+	for (i = 0; i < len; i++) {
+		buffers = msm_vidc_get_buffers(inst, internal_buf_type[i], __func__);
+		if (!buffers)
+			return -EINVAL;
+
+		if (buffers->reuse) {
+			i_vpr_l(inst, "%s: reuse enabled for %s\n", __func__,
+				buf_name(internal_buf_type[i]));
+			continue;
+		}
+
+		list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+			i_vpr_h(inst,
+				"%s: destroying internal buffer: type %d idx %d fd %d addr %#llx size %d\n",
+				__func__, buf->type, buf->index, buf->fd,
+				buf->device_addr, buf->buffer_size);
+
+			rc = msm_vidc_destroy_internal_buffer(inst, buf);
+			if (rc)
+				return rc;
+		}
+	}
+
+	return 0;
+}
+
 static int msm_venc_create_input_internal_buffers(struct msm_vidc_inst *inst)
 {
 	int i, rc = 0;
@@ -922,6 +965,10 @@ int msm_venc_streamon_input(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	rc = msm_venc_destroy_internal_buffers(inst, INPUT_PORT);
+	if (rc)
+		goto error;
+
 	rc = msm_venc_create_input_internal_buffers(inst);
 	if (rc)
 		goto error;
@@ -1064,6 +1111,10 @@ int msm_venc_streamon_output(struct msm_vidc_inst *inst)
 	if (rc)
 		goto error;
 
+	rc = msm_venc_destroy_internal_buffers(inst, OUTPUT_PORT);
+	if (rc)
+		goto error;
+
 	rc = msm_venc_create_output_internal_buffers(inst);
 	if (rc)
 		goto error;

+ 4 - 14
driver/vidc/src/msm_vidc_driver.c

@@ -3054,9 +3054,6 @@ int msm_vidc_destroy_internal_buffer(struct msm_vidc_inst *inst,
 		}
 	}
 
-	buffers->size = 0;
-	buffers->min_count = buffers->extra_count = buffers->actual_count = 0;
-
 	return 0;
 }
 
@@ -3084,8 +3081,7 @@ int msm_vidc_get_internal_buffers(struct msm_vidc_inst *inst,
 	if (!buffers)
 		return -EINVAL;
 
-	if (buf_size <= buffers->size &&
-		buf_count <= buffers->min_count) {
+	if (buf_size <= buffers->size && buf_count <= buffers->min_count) {
 		buffers->reuse = true;
 	} else {
 		buffers->reuse = false;
@@ -3221,15 +3217,9 @@ int msm_vidc_queue_internal_buffers(struct msm_vidc_inst *inst,
 	if (!buffers)
 		return -EINVAL;
 
-	if (buffers->reuse) {
-		i_vpr_l(inst, "%s: reuse enabled for %s buf\n",
-			__func__, buf_name(buffer_type));
-		return 0;
-	}
-
 	list_for_each_entry_safe(buffer, dummy, &buffers->list, list) {
 		/* do not queue pending release buffers */
-		if (buffer->flags & MSM_VIDC_ATTR_PENDING_RELEASE)
+		if (buffer->attr & MSM_VIDC_ATTR_PENDING_RELEASE)
 			continue;
 		/* do not queue already queued buffers */
 		if (buffer->attr & MSM_VIDC_ATTR_QUEUED)
@@ -4451,10 +4441,10 @@ int msm_vidc_print_buffer_info(struct msm_vidc_inst *inst)
 		if (!buffers)
 			continue;
 
-		i_vpr_h(inst, "buf: type: %11s, count %2d, extra %2d, actual %2d, size %9u\n",
+		i_vpr_h(inst, "buf: type: %15s, min %2d, extra %2d, actual %2d, size %9u, reuse %d\n",
 			buf_name(i), buffers->min_count,
 			buffers->extra_count, buffers->actual_count,
-			buffers->size);
+			buffers->size, buffers->reuse);
 	}
 
 	return 0;

+ 15 - 5
driver/vidc/src/venus_hfi_response.c

@@ -1367,18 +1367,28 @@ static int handle_release_internal_buffer(struct msm_vidc_inst *inst,
 			break;
 		}
 	}
+	if (!found) {
+		i_vpr_e(inst, "%s: invalid idx %d daddr %#llx\n",
+			__func__, buffer->index, buffer->base_address);
+		return -EINVAL;
+	}
 
 	if (!is_internal_buffer(buf->type))
 		return 0;
 
-	if (found) {
+	/* remove QUEUED attribute */
+	buf->attr &= ~MSM_VIDC_ATTR_QUEUED;
+
+	/*
+	 * firmware will return/release internal buffer in two cases
+	 * - driver sent release cmd in which case driver should destroy the buffer
+	 * - as part stop cmd in which case driver can reuse the buffer, so skip
+	 *   destroying the buffer
+	 */
+	if (buf->attr & MSM_VIDC_ATTR_PENDING_RELEASE) {
 		rc = msm_vidc_destroy_internal_buffer(inst, buf);
 		if (rc)
 			return rc;
-	} else {
-		i_vpr_e(inst, "%s: invalid idx %d daddr %#llx\n",
-			__func__, buffer->index, buffer->base_address);
-		return -EINVAL;
 	}
 	return rc;
 }