Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e53a069e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: sde: cache maintenance update for dmabuf"

parents 34609e54 4a71668a
Loading
Loading
Loading
Loading
+27 −23
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, 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
@@ -670,7 +670,7 @@ static int sde_rotator_map_and_check_data(struct sde_rot_entry *entry)
	int ret;
	struct sde_layer_buffer *input;
	struct sde_layer_buffer *output;
	struct sde_mdp_format_params *fmt;
	struct sde_mdp_format_params *in_fmt, *out_fmt;
	struct sde_mdp_plane_sizes ps;
	bool rotation;
	bool secure;
@@ -693,54 +693,58 @@ static int sde_rotator_map_and_check_data(struct sde_rot_entry *entry)
		goto end;
	}

	in_fmt = sde_get_format_params(input->format);
	if (!in_fmt) {
		SDEROT_ERR("invalid input format:%d\n", input->format);
		ret = -EINVAL;
		goto end;
	}

	out_fmt = sde_get_format_params(output->format);
	if (!out_fmt) {
		SDEROT_ERR("invalid output format:%d\n", output->format);
		ret = -EINVAL;
		goto end;
	}

	/* if error during map, the caller will release the data */
	ret = sde_mdp_data_map(&entry->src_buf, true, DMA_TO_DEVICE);
	ret = sde_mdp_data_map(&entry->src_buf, true, DMA_TO_DEVICE,
			sde_mdp_is_ubwc_format(in_fmt) ||
			sde_mdp_is_tilea5x_format(in_fmt));
	if (ret) {
		SDEROT_ERR("source buffer mapping failed ret:%d\n", ret);
		goto end;
	}

	ret = sde_mdp_data_map(&entry->dst_buf, true, DMA_FROM_DEVICE);
	ret = sde_mdp_data_map(&entry->dst_buf, true, DMA_FROM_DEVICE,
			sde_mdp_is_ubwc_format(out_fmt) ||
			sde_mdp_is_tilea5x_format(out_fmt));
	if (ret) {
		SDEROT_ERR("destination buffer mapping failed ret:%d\n", ret);
		goto end;
	}

	fmt = sde_get_format_params(input->format);
	if (!fmt) {
		SDEROT_ERR("invalid input format:%d\n", input->format);
		ret = -EINVAL;
		goto end;
	}

	ret = sde_mdp_get_plane_sizes(
			fmt, input->width, input->height, &ps, 0, rotation);
			in_fmt, input->width, input->height, &ps, 0, rotation);
	if (ret) {
		SDEROT_ERR("fail to get input plane size ret=%d\n", ret);
		goto end;
	}

	ret = sde_mdp_data_check(&entry->src_buf, &ps, fmt);
	ret = sde_mdp_data_check(&entry->src_buf, &ps, in_fmt);
	if (ret) {
		SDEROT_ERR("fail to check input data ret=%d\n", ret);
		goto end;
	}

	fmt = sde_get_format_params(output->format);
	if (!fmt) {
		SDEROT_ERR("invalid output format:%d\n", output->format);
		ret = -EINVAL;
		goto end;
	}

	ret = sde_mdp_get_plane_sizes(
			fmt, output->width, output->height, &ps, 0, rotation);
	ret = sde_mdp_get_plane_sizes(out_fmt, output->width, output->height,
			&ps, 0, rotation);
	if (ret) {
		SDEROT_ERR("fail to get output plane size ret=%d\n", ret);
		goto end;
	}

	ret = sde_mdp_data_check(&entry->dst_buf, &ps, fmt);
	ret = sde_mdp_data_check(&entry->dst_buf, &ps, out_fmt);
	if (ret) {
		SDEROT_ERR("fail to check output data ret=%d\n", ret);
		goto end;
+67 −72
Original line number Diff line number Diff line
@@ -780,9 +780,6 @@ static int sde_mdp_put_img(struct sde_mdp_img_data *data, bool rotator,
		if (sde_mdp_is_map_needed(data) && data->mapped) {
			domain = sde_smmu_get_domain_type(data->flags,
				rotator);
			sde_smmu_unmap_dma_buf(data->srcp_table,
						domain, dir,
						data->srcp_dma_buf);
			data->mapped = false;
			SDEROT_DBG("unmap %pad/%lx d:%u f:%x\n", &data->addr,
					data->len, domain, data->flags);
@@ -798,6 +795,7 @@ static int sde_mdp_put_img(struct sde_mdp_img_data *data, bool rotator,
				dma_buf_put(data->srcp_dma_buf);
				data->srcp_dma_buf = NULL;
			}
			data->skip_detach = true;
		}
	} else {
		return -ENOMEM;
@@ -811,12 +809,8 @@ static int sde_mdp_get_img(struct sde_fb_data *img,
		bool rotator, int dir)
{
	int ret = -EINVAL;
	unsigned long *len;
	u32 domain;
	dma_addr_t *start;

	start = &data->addr;
	len = &data->len;
	data->flags |= img->flags;
	data->offset = img->offset;
	if (data->flags & SDE_ROT_EXT_DMA_BUF) {
@@ -846,26 +840,7 @@ static int sde_mdp_get_img(struct sde_fb_data *img,
			ret = PTR_ERR(data->srcp_attachment);
			goto err_put;
		}

		SDEROT_DBG("%d attach=%p\n", __LINE__, data->srcp_attachment);
		data->srcp_attachment->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP;
		data->srcp_table =
			dma_buf_map_attachment(data->srcp_attachment, dir);
		if (IS_ERR(data->srcp_table)) {
			SDEROT_ERR("%d Failed to map attachment\n", __LINE__);
			ret = PTR_ERR(data->srcp_table);
			goto err_detach;
		}

		SDEROT_DBG("%d table=%p\n", __LINE__, data->srcp_table);
		data->addr = 0;
		data->len = 0;
		data->mapped = false;
		data->skip_detach = false;
		/* return early, mapping will be done later */
	} else {
		struct sg_table *sgt = NULL;

		data->srcp_attachment = dma_buf_attach(
				data->srcp_dma_buf, dev);
		if (IS_ERR(data->srcp_attachment)) {
@@ -874,42 +849,16 @@ static int sde_mdp_get_img(struct sde_fb_data *img,
			ret = PTR_ERR(data->srcp_attachment);
			goto err_put;
		}

		data->srcp_attachment->dma_map_attrs |= DMA_ATTR_DELAYED_UNMAP;
		data->srcp_table = dma_buf_map_attachment(
				data->srcp_attachment, dir);
		if (IS_ERR(data->srcp_table)) {
			SDEROT_ERR(
				"Failed to map attachment for secure camera\n");
			ret = PTR_ERR(data->srcp_table);
			goto err_detach;
		}
		sgt = data->srcp_table;

		if (sgt->nents != 1) {
			SDEROT_ERR(
				"Fail ion buffer mapping for secure camera\n");
			ret = -EINVAL;
			goto err_detach;
	}

		if (((uint64_t)sg_dma_address(sgt->sgl) >=
				PHY_ADDR_4G - sgt->sgl->length)) {
			SDEROT_ERR("ion buffer mapped size invalid\n");
			ret = -EINVAL;
			goto err_detach;
		}

		data->addr = sg_dma_address(sgt->sgl);
		data->len = sgt->sgl->length;
	SDEROT_DBG("%d attach=%pK\n", __LINE__, data->srcp_attachment);
	data->addr = 0;
	data->len = 0;
	data->mapped = false;
	data->skip_detach = false;
		ret = 0;
	}
	/* return early, mapping will be done later */

	return 0;
err_detach:
	dma_buf_detach(data->srcp_dma_buf, data->srcp_attachment);
err_put:
	if (!(data->flags & SDE_ROT_EXT_DMA_BUF)) {
		dma_buf_put(data->srcp_dma_buf);
@@ -919,7 +868,7 @@ static int sde_mdp_get_img(struct sde_fb_data *img,
}

static int sde_mdp_map_buffer(struct sde_mdp_img_data *data, bool rotator,
		int dir)
		int dir, bool skip_sync)
{
	int ret = -EINVAL;
	int domain;
@@ -937,27 +886,71 @@ static int sde_mdp_map_buffer(struct sde_mdp_img_data *data, bool rotator,
	}

	if (!IS_ERR_OR_NULL(data->srcp_dma_buf)) {
		/*
		 * dma_buf_map_attachment will call into
		 * dma_map_sg_attrs, and so all cache maintenance
		 * attribute and lazy unmap attribute will be all
		 * provided here.
		 */
		data->srcp_attachment->dma_map_attrs |=
			DMA_ATTR_DELAYED_UNMAP;
		if (skip_sync)
			data->srcp_attachment->dma_map_attrs |=
				DMA_ATTR_SKIP_CPU_SYNC;

		if (sde_mdp_is_map_needed(data)) {
			domain = sde_smmu_get_domain_type(data->flags,
					rotator);
			ret = sde_smmu_map_dma_buf(data->srcp_dma_buf,
					data->srcp_table, domain,
					&data->addr, &data->len, dir);
			if (ret < 0) {
				SDEROT_ERR("smmu map buf failed:(%d)\n", ret);
				goto err_unmap;
			data->srcp_table =
				dma_buf_map_attachment(data->srcp_attachment,
						dir);
			if (IS_ERR_OR_NULL(data->srcp_table) ||
					IS_ERR_OR_NULL(data->srcp_table->sgl)) {
				SDEROT_ERR("%d Failed to map attachment\n",
						__LINE__);
				ret = PTR_ERR(data->srcp_table);
				goto err_detach;
			}
			data->addr = data->srcp_table->sgl->dma_address;
			data->len = data->srcp_table->sgl->dma_length;
			SDEROT_DBG("map %pad/%lx d:%u f:%x\n",
					&data->addr,
					data->len,
					domain,
					data->flags);
			data->mapped = true;
			ret = 0;
		} else {
			struct sg_table *sgt = NULL;

			data->srcp_table = dma_buf_map_attachment(
					data->srcp_attachment, dir);
			if (IS_ERR_OR_NULL(data->srcp_table) ||
					IS_ERR_OR_NULL(data->srcp_table->sgl)) {
				SDEROT_ERR(
					"Failed to map attachment for secure camera\n");
				ret = PTR_ERR(data->srcp_table);
				goto err_detach;
			}
			sgt = data->srcp_table;

			if (sgt->nents != 1) {
				SDEROT_ERR(
					"Fail ion buffer mapping for secure camera\n");
				ret = -EINVAL;
				goto err_unmap;
			}

			if (((uint64_t)sg_dma_address(sgt->sgl) >=
					PHY_ADDR_4G - sgt->sgl->length)) {
				SDEROT_ERR(
					"ion buffer mapped size invalid, size=%d\n",
					sgt->sgl->length);
				ret = -EINVAL;
				goto err_unmap;
			}

			data->addr = sg_phys(data->srcp_table->sgl);
			data->len = 0;
			table = data->srcp_table;
			for_each_sg(table->sgl, sg, table->nents, i) {
			for_each_sg(sgt->sgl, sg, sgt->nents, i) {
				data->len += sg->length;
			}
			ret = 0;
@@ -985,6 +978,7 @@ static int sde_mdp_map_buffer(struct sde_mdp_img_data *data, bool rotator,

err_unmap:
	dma_buf_unmap_attachment(data->srcp_attachment, data->srcp_table, dir);
err_detach:
	dma_buf_detach(data->srcp_dma_buf, data->srcp_attachment);
	if (!(data->flags & SDE_ROT_EXT_DMA_BUF)) {
		dma_buf_put(data->srcp_dma_buf);
@@ -1022,7 +1016,8 @@ static int sde_mdp_data_get(struct sde_mdp_data *data,
	return rc;
}

int sde_mdp_data_map(struct sde_mdp_data *data, bool rotator, int dir)
int sde_mdp_data_map(struct sde_mdp_data *data, bool rotator, int dir,
		bool skip_sync)
{
	int i, rc = 0;

@@ -1030,7 +1025,7 @@ int sde_mdp_data_map(struct sde_mdp_data *data, bool rotator, int dir)
		return -EINVAL;

	for (i = 0; i < data->num_planes; i++) {
		rc = sde_mdp_map_buffer(&data->p[i], rotator, dir);
		rc = sde_mdp_map_buffer(&data->p[i], rotator, dir, skip_sync);
		if (rc) {
			SDEROT_ERR("failed to map buf p=%d\n", i);
			while (i > 0) {
+3 −2
Original line number Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, 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
@@ -194,7 +194,8 @@ int sde_mdp_get_plane_sizes(struct sde_mdp_format_params *fmt, u32 w, u32 h,
	struct sde_mdp_plane_sizes *ps, u32 bwc_mode,
	bool rotation);

int sde_mdp_data_map(struct sde_mdp_data *data, bool rotator, int dir);
int sde_mdp_data_map(struct sde_mdp_data *data, bool rotator, int dir,
		bool skip_sync);

int sde_mdp_data_check(struct sde_mdp_data *data,
			struct sde_mdp_plane_sizes *ps,