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

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

Merge "msm: mdss: Add atomic commit compat support for PP"

parents 1779195e e467a121
Loading
Loading
Loading
Loading
+443 −3
Original line number Diff line number Diff line
@@ -55,6 +55,9 @@
#define MSMFB_ASYNC_POSITION_UPDATE_32 _IOWR(MDP_IOCTL_MAGIC, 129, \
		struct mdp_position_update32)

static int __copy_layer_pp_info_params(struct mdp_input_layer *layer,
				struct mdp_input_layer32 *layer32);

static unsigned int __do_compat_ioctl_nr(unsigned int cmd32)
{
	unsigned int cmd;
@@ -225,7 +228,6 @@ static struct mdp_input_layer *__create_layer_list(
		layer->src_rect = layer32->src_rect;
		layer->dst_rect = layer32->dst_rect;
		layer->buffer = layer32->buffer;
		layer->pp_info = compat_ptr(layer32->pp_info);
		memcpy(&layer->reserved, &layer32->reserved,
			sizeof(layer->reserved));

@@ -233,11 +235,18 @@ static struct mdp_input_layer *__create_layer_list(
		ret = __copy_scale_params(layer, layer32);
		if (ret)
			break;

		layer->pp_info = NULL;
		ret = __copy_layer_pp_info_params(layer, layer32);
		if (ret)
			break;
	}

	if (ret) {
		for (i--; i >= 0; i--)
		for (i--; i >= 0; i--) {
			kfree(layer_list[i].scale);
			mdss_mdp_free_layer_pp_info(&layer_list[i]);
		}
		kfree(layer_list);
		layer_list = ERR_PTR(ret);
	}
@@ -360,8 +369,10 @@ static int __compat_atomic_commit(struct fb_info *info, unsigned int cmd,
		__copy_to_user_atomic_commit(&commit, &commit32, layer_list32,
			argp, layer_count);

	for (i = 0; i < layer_count; i++)
	for (i = 0; i < layer_count; i++) {
		kfree(layer[i].scale);
		mdss_mdp_free_layer_pp_info(&layer[i]);
	}
	kfree(layer_list);
layer_list_err:
	kfree(layer_list32);
@@ -3377,6 +3388,435 @@ histo_compat_err:
	return ret;
}

static int __copy_layer_pp_info_qseed_params(
			struct mdp_overlay_pp_params *pp_info,
			struct mdp_overlay_pp_params32 *pp_info32)
{
	pp_info->qseed_cfg[0].table_num = pp_info32->qseed_cfg[0].table_num;
	pp_info->qseed_cfg[0].ops = pp_info32->qseed_cfg[0].ops;
	pp_info->qseed_cfg[0].len = pp_info32->qseed_cfg[0].len;
	pp_info->qseed_cfg[0].data = compat_ptr(pp_info32->qseed_cfg[0].data);

	pp_info->qseed_cfg[1].table_num = pp_info32->qseed_cfg[1].table_num;
	pp_info->qseed_cfg[1].ops = pp_info32->qseed_cfg[1].ops;
	pp_info->qseed_cfg[1].len = pp_info32->qseed_cfg[1].len;
	pp_info->qseed_cfg[1].data = compat_ptr(pp_info32->qseed_cfg[1].data);

	return 0;
}

static int __copy_layer_igc_lut_data_v1_7(
			struct mdp_igc_lut_data_v1_7 *cfg_payload,
			struct mdp_igc_lut_data_v1_7_32 __user *cfg_payload32)
{
	struct mdp_igc_lut_data_v1_7_32 local_cfg_payload32;
	int ret = 0;

	ret = copy_from_user(&local_cfg_payload32,
			cfg_payload32,
			sizeof(struct mdp_igc_lut_data_v1_7_32));
	if (ret) {
		pr_err("copy from user failed, IGC cfg payload = %p\n",
			cfg_payload32);
		ret = -EFAULT;
		goto exit;
	}

	cfg_payload->table_fmt = local_cfg_payload32.table_fmt;
	cfg_payload->len = local_cfg_payload32.len;
	cfg_payload->c0_c1_data = compat_ptr(local_cfg_payload32.c0_c1_data);
	cfg_payload->c2_data = compat_ptr(local_cfg_payload32.c2_data);

exit:
	return ret;
}

static int __copy_layer_pp_info_igc_params(
			struct mdp_overlay_pp_params *pp_info,
			struct mdp_overlay_pp_params32 *pp_info32)
{
	void *cfg_payload = NULL;
	uint32_t payload_size = 0;
	int ret = 0;

	pp_info->igc_cfg.block = pp_info32->igc_cfg.block;
	pp_info->igc_cfg.version = pp_info32->igc_cfg.version;
	pp_info->igc_cfg.ops = pp_info32->igc_cfg.ops;

	if (pp_info->igc_cfg.version != 0) {
		payload_size = __pp_compat_size_igc();

		cfg_payload = kmalloc(payload_size, GFP_KERNEL);
		if (!cfg_payload) {
			ret = -ENOMEM;
			goto exit;
		}
	}

	switch (pp_info->igc_cfg.version) {
	case mdp_igc_v1_7:
		ret = __copy_layer_igc_lut_data_v1_7(cfg_payload,
				compat_ptr(pp_info32->igc_cfg.cfg_payload));
		if (ret) {
			pr_err("compat copy of IGC cfg payload failed, ret %d\n",
				ret);
			kfree(cfg_payload);
			cfg_payload = NULL;
			goto exit;
		}
		break;
	default:
		pr_debug("No version set, fallback to legacy IGC version\n");
		pp_info->igc_cfg.len = pp_info32->igc_cfg.len;
		pp_info->igc_cfg.c0_c1_data =
			compat_ptr(pp_info32->igc_cfg.c0_c1_data);
		pp_info->igc_cfg.c2_data =
			compat_ptr(pp_info32->igc_cfg.c2_data);
		cfg_payload = NULL;
		break;
	}
exit:
	pp_info->igc_cfg.cfg_payload = cfg_payload;
	return ret;
}

static int __copy_layer_hist_lut_data_v1_7(
			struct mdp_hist_lut_data_v1_7 *cfg_payload,
			struct mdp_hist_lut_data_v1_7_32 __user *cfg_payload32)
{
	struct mdp_hist_lut_data_v1_7_32 local_cfg_payload32;
	int ret = 0;

	ret = copy_from_user(&local_cfg_payload32,
			cfg_payload32,
			sizeof(struct mdp_hist_lut_data_v1_7_32));
	if (ret) {
		pr_err("copy from user failed, hist lut cfg_payload = %p\n",
			cfg_payload32);
		ret = -EFAULT;
		goto exit;
	}

	cfg_payload->len = local_cfg_payload32.len;
	cfg_payload->data = compat_ptr(local_cfg_payload32.data);
exit:
	return ret;
}

static int __copy_layer_pp_info_hist_lut_params(
			struct mdp_overlay_pp_params *pp_info,
			struct mdp_overlay_pp_params32 *pp_info32)
{
	void *cfg_payload = NULL;
	uint32_t payload_size = 0;
	int ret = 0;

	pp_info->hist_lut_cfg.block = pp_info32->hist_lut_cfg.block;
	pp_info->hist_lut_cfg.version = pp_info32->hist_lut_cfg.version;
	pp_info->hist_lut_cfg.ops = pp_info32->hist_lut_cfg.ops;
	pp_info->hist_lut_cfg.hist_lut_first =
			pp_info32->hist_lut_cfg.hist_lut_first;

	if (pp_info->hist_lut_cfg.version != 0) {
		payload_size = __pp_compat_size_hist_lut();

		cfg_payload = kmalloc(payload_size, GFP_KERNEL);
		if (!cfg_payload) {
			ret = -ENOMEM;
			goto exit;
		}
	}

	switch (pp_info->hist_lut_cfg.version) {
	case mdp_hist_lut_v1_7:
		ret = __copy_layer_hist_lut_data_v1_7(cfg_payload,
			compat_ptr(pp_info32->hist_lut_cfg.cfg_payload));
		if (ret) {
			pr_err("compat copy of Hist LUT cfg payload failed, ret %d\n",
				ret);
			kfree(cfg_payload);
			cfg_payload = NULL;
			goto exit;
		}
		break;
	default:
		pr_debug("version invalid, fallback to legacy\n");
		pp_info->hist_lut_cfg.len = pp_info32->hist_lut_cfg.len;
		pp_info->hist_lut_cfg.data =
				compat_ptr(pp_info32->hist_lut_cfg.data);
		cfg_payload = NULL;
		break;
	}
exit:
	pp_info->hist_lut_cfg.cfg_payload = cfg_payload;
	return ret;
}

static int __copy_layer_pa_data_v1_7(
			struct mdp_pa_data_v1_7 *cfg_payload,
			struct mdp_pa_data_v1_7_32 __user *cfg_payload32)
{
	struct mdp_pa_data_v1_7_32 local_cfg_payload32;
	int ret = 0;

	ret = copy_from_user(&local_cfg_payload32,
			cfg_payload32,
			sizeof(struct mdp_pa_data_v1_7_32));
	if (ret) {
		pr_err("copy from user failed, pa cfg_payload = %p\n",
			cfg_payload32);
		ret = -EFAULT;
		goto exit;
	}

	cfg_payload->mode = local_cfg_payload32.mode;
	cfg_payload->global_hue_adj = local_cfg_payload32.global_hue_adj;
	cfg_payload->global_sat_adj = local_cfg_payload32.global_sat_adj;
	cfg_payload->global_val_adj = local_cfg_payload32.global_val_adj;
	cfg_payload->global_cont_adj = local_cfg_payload32.global_cont_adj;

	memcpy(&cfg_payload->skin_cfg, &local_cfg_payload32.skin_cfg,
			sizeof(struct mdp_pa_mem_col_data_v1_7));
	memcpy(&cfg_payload->sky_cfg, &local_cfg_payload32.sky_cfg,
			sizeof(struct mdp_pa_mem_col_data_v1_7));
	memcpy(&cfg_payload->fol_cfg, &local_cfg_payload32.fol_cfg,
			sizeof(struct mdp_pa_mem_col_data_v1_7));

	cfg_payload->six_zone_thresh = local_cfg_payload32.six_zone_thresh;
	cfg_payload->six_zone_adj_p0 = local_cfg_payload32.six_zone_adj_p0;
	cfg_payload->six_zone_adj_p1 = local_cfg_payload32.six_zone_adj_p1;
	cfg_payload->six_zone_sat_hold = local_cfg_payload32.six_zone_sat_hold;
	cfg_payload->six_zone_val_hold = local_cfg_payload32.six_zone_val_hold;
	cfg_payload->six_zone_len = local_cfg_payload32.six_zone_len;

	cfg_payload->six_zone_curve_p0 =
			compat_ptr(local_cfg_payload32.six_zone_curve_p0);
	cfg_payload->six_zone_curve_p1 =
			compat_ptr(local_cfg_payload32.six_zone_curve_p1);
exit:
	return ret;
}

static int __copy_layer_pp_info_pa_v2_params(
			struct mdp_overlay_pp_params *pp_info,
			struct mdp_overlay_pp_params32 *pp_info32)
{
	void *cfg_payload = NULL;
	uint32_t payload_size = 0;
	int ret = 0;

	pp_info->pa_v2_cfg_data.block = pp_info32->pa_v2_cfg_data.block;
	pp_info->pa_v2_cfg_data.version = pp_info32->pa_v2_cfg_data.version;
	pp_info->pa_v2_cfg_data.flags = pp_info32->pa_v2_cfg_data.flags;

	if (pp_info->pa_v2_cfg_data.version != 0) {
		payload_size = __pp_compat_size_pa();

		cfg_payload = kmalloc(payload_size, GFP_KERNEL);
		if (!cfg_payload) {
			ret = -ENOMEM;
			goto exit;
		}
	}

	switch (pp_info->pa_v2_cfg_data.version) {
	case mdp_pa_v1_7:
		ret = __copy_layer_pa_data_v1_7(cfg_payload,
			compat_ptr(pp_info32->pa_v2_cfg_data.cfg_payload));
		if (ret) {
			pr_err("compat copy of PA cfg payload failed, ret %d\n",
				ret);
			kfree(cfg_payload);
			cfg_payload = NULL;
			goto exit;
		}
		break;
	default:
		pr_debug("version invalid\n");
		cfg_payload = NULL;
		break;
	}
exit:
	pp_info->pa_v2_cfg_data.cfg_payload = cfg_payload;
	return ret;
}

static int __copy_layer_pp_info_legacy_pa_v2_params(
			struct mdp_overlay_pp_params *pp_info,
			struct mdp_overlay_pp_params32 *pp_info32)
{
	pp_info->pa_v2_cfg.global_hue_adj =
		pp_info32->pa_v2_cfg.global_hue_adj;
	pp_info->pa_v2_cfg.global_sat_adj =
		pp_info32->pa_v2_cfg.global_sat_adj;
	pp_info->pa_v2_cfg.global_val_adj =
		pp_info32->pa_v2_cfg.global_val_adj;
	pp_info->pa_v2_cfg.global_cont_adj =
		pp_info32->pa_v2_cfg.global_cont_adj;

	memcpy(&pp_info->pa_v2_cfg.skin_cfg,
			&pp_info32->pa_v2_cfg.skin_cfg,
			sizeof(struct mdp_pa_mem_col_cfg));
	memcpy(&pp_info->pa_v2_cfg.sky_cfg,
			&pp_info32->pa_v2_cfg.sky_cfg,
			sizeof(struct mdp_pa_mem_col_cfg));
	memcpy(&pp_info->pa_v2_cfg.fol_cfg,
			&pp_info32->pa_v2_cfg.fol_cfg,
			sizeof(struct mdp_pa_mem_col_cfg));

	pp_info->pa_v2_cfg.six_zone_thresh =
		pp_info32->pa_v2_cfg.six_zone_thresh;
	pp_info->pa_v2_cfg.six_zone_len =
		pp_info32->pa_v2_cfg.six_zone_len;

	pp_info->pa_v2_cfg.six_zone_curve_p0 =
		compat_ptr(pp_info32->pa_v2_cfg.six_zone_curve_p0);
	pp_info->pa_v2_cfg.six_zone_curve_p1 =
		compat_ptr(pp_info32->pa_v2_cfg.six_zone_curve_p1);

	return 0;
}

static int __copy_layer_pp_info_pcc_params(
			struct mdp_overlay_pp_params *pp_info,
			struct mdp_overlay_pp_params32 *pp_info32)
{
	void *cfg_payload = NULL;
	uint32_t payload_size = 0;
	int ret = 0;

	pp_info->pcc_cfg_data.block = pp_info32->pcc_cfg_data.block;
	pp_info->pcc_cfg_data.version = pp_info32->pcc_cfg_data.version;
	pp_info->pcc_cfg_data.ops = pp_info32->pcc_cfg_data.ops;

	if (pp_info->pcc_cfg_data.version != 0) {
		payload_size = __pp_compat_size_pcc();

		cfg_payload = kmalloc(payload_size, GFP_KERNEL);
		if (!cfg_payload) {
			ret = -ENOMEM;
			goto exit;
		}
	}

	switch (pp_info->pcc_cfg_data.version) {
	case mdp_pcc_v1_7:
		ret = copy_from_user(cfg_payload,
			compat_ptr(pp_info32->pcc_cfg_data.cfg_payload),
			sizeof(struct mdp_pcc_data_v1_7));
		if (ret) {
			pr_err("compat copy of PCC cfg payload failed, ptr %p\n",
				compat_ptr(
				pp_info32->pcc_cfg_data.cfg_payload));
			ret = -EFAULT;
			kfree(cfg_payload);
			cfg_payload = NULL;
			goto exit;
		}
		break;
	default:
		pr_debug("version invalid, fallback to legacy\n");
		cfg_payload = NULL;
		break;
	}
exit:
	pp_info->pcc_cfg_data.cfg_payload = cfg_payload;
	return ret;
}


static int __copy_layer_pp_info_params(struct mdp_input_layer *layer,
				struct mdp_input_layer32 *layer32)
{
	struct mdp_overlay_pp_params *pp_info;
	struct mdp_overlay_pp_params32 pp_info32;
	int ret = 0;

	if (!(layer->flags & MDP_LAYER_PP))
		return 0;

	ret = copy_from_user(&pp_info32,
			compat_ptr(layer32->pp_info),
			sizeof(struct mdp_overlay_pp_params32));
	if (ret) {
		pr_err("pp info copy from user failed, pp_info %p\n",
			compat_ptr(layer32->pp_info));
		ret = -EFAULT;
		goto exit;
	}

	pp_info = kmalloc(sizeof(struct mdp_overlay_pp_params), GFP_KERNEL);
	if (!pp_info) {
		ret = -ENOMEM;
		goto exit;
	}
	memset(pp_info, 0, sizeof(struct mdp_overlay_pp_params));

	pp_info->config_ops = pp_info32.config_ops;

	memcpy(&pp_info->csc_cfg, &pp_info32.csc_cfg,
		sizeof(struct mdp_csc_cfg));
	memcpy(&pp_info->sharp_cfg, &pp_info32.sharp_cfg,
		sizeof(struct mdp_sharp_cfg));
	memcpy(&pp_info->hist_cfg, &pp_info32.hist_cfg,
		sizeof(struct mdp_histogram_cfg));
	memcpy(&pp_info->pa_cfg, &pp_info32.pa_cfg,
		sizeof(struct mdp_pa_cfg));

	ret = __copy_layer_pp_info_qseed_params(pp_info, &pp_info32);
	if (ret) {
		pr_err("compat copy pp_info QSEED params failed, ret %d\n",
			ret);
		goto exit_pp_info;
	}
	ret = __copy_layer_pp_info_legacy_pa_v2_params(pp_info, &pp_info32);
	if (ret) {
		pr_err("compat copy pp_info Legacy PAv2 params failed, ret %d\n",
			ret);
		goto exit_pp_info;
	}
	ret = __copy_layer_pp_info_igc_params(pp_info, &pp_info32);
	if (ret) {
		pr_err("compat copy pp_info IGC params failed, ret %d\n",
			ret);
		goto exit_pp_info;
	}
	ret = __copy_layer_pp_info_hist_lut_params(pp_info, &pp_info32);
	if (ret) {
		pr_err("compat copy pp_info Hist LUT params failed, ret %d\n",
			ret);
		goto exit_igc;
	}
	ret = __copy_layer_pp_info_pa_v2_params(pp_info, &pp_info32);
	if (ret) {
		pr_err("compat copy pp_info PAv2 params failed, ret %d\n",
			ret);
		goto exit_hist_lut;
	}
	ret = __copy_layer_pp_info_pcc_params(pp_info, &pp_info32);
	if (ret) {
		pr_err("compat copy pp_info PCC params failed, ret %d\n",
			ret);
		goto exit_pa;
	}

	layer->pp_info = pp_info;

	return ret;

exit_pa:
	kfree(pp_info->pa_v2_cfg_data.cfg_payload);
exit_hist_lut:
	kfree(pp_info->hist_lut_cfg.cfg_payload);
exit_igc:
	kfree(pp_info->igc_cfg.cfg_payload);
exit_pp_info:
	kfree(pp_info);
exit:
	return ret;
}


static int __to_user_mdp_overlay(struct mdp_overlay32 __user *ov32,
				 struct mdp_overlay __user *ov)
{
+24 −6
Original line number Diff line number Diff line
@@ -3790,7 +3790,7 @@ static int mdss_fb_display_commit(struct fb_info *info,
static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
						unsigned long *argp)
{
	int ret, i = 0, rc;
	int ret, i = 0, j = 0, rc;
	struct mdp_layer_commit  commit;
	u32 buffer_size, layer_count;
	struct mdp_input_layer *layer, *layer_list = NULL;
@@ -3849,6 +3849,17 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
		for (i = 0; i < layer_count; i++) {
			layer = &layer_list[i];

			if (!(layer->flags & MDP_LAYER_PP)) {
				layer->pp_info = NULL;
			} else {
				ret = mdss_mdp_copy_layer_pp_info(layer);
				if (ret) {
					pr_err("failure to copy pp_info data for layer %d, ret = %d\n",
						i, ret);
					goto err;
				}
			}

			if (!(layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT)) {
				layer->scale = NULL;
				continue;
@@ -3865,8 +3876,10 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
			ret = copy_from_user(scale, layer->scale,
					sizeof(struct mdp_scale_data));
			if (ret) {
				pr_err("layer list copy from user failed\n");
				pr_err("layer list copy from user failed, scale = %p\n",
						layer->scale);
				kfree(scale);
				ret = -EFAULT;
				goto err;
			}
			layer->scale = scale;
@@ -3878,9 +3891,12 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
		pr_err("atomic commit failed ret:%d\n", ret);

	if (layer_count) {
		rc = copy_to_user(input_layer_list, layer_list, buffer_size);
		for (j = 0; j < layer_count; j++) {
			rc = copy_to_user(&input_layer_list[i].error_code,
					&layer_list[i].error_code, sizeof(int));
			if (rc)
				pr_err("layer error code copy to user failed\n");
		}

		commit.commit_v1.input_layers = input_layer_list;
		commit.commit_v1.output_layer = output_layer_user;
@@ -3891,8 +3907,10 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info,
	}

err:
	for (i--; i >= 0; i--)
	for (i--; i >= 0; i--) {
		kfree(layer_list[i].scale);
		mdss_mdp_free_layer_pp_info(&layer_list[i]);
	}
	kfree(layer_list);
	kfree(output_layer);

+2 −0
Original line number Diff line number Diff line
@@ -1085,6 +1085,8 @@ int mdss_mdp_pipe_pp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
void mdss_mdp_pipe_pp_clear(struct mdss_mdp_pipe *pipe);
int mdss_mdp_pipe_sspp_setup(struct mdss_mdp_pipe *pipe, u32 *op);
int mdss_mdp_pp_sspp_config(struct mdss_mdp_pipe *pipe);
int mdss_mdp_copy_layer_pp_info(struct mdp_input_layer *layer);
void mdss_mdp_free_layer_pp_info(struct mdp_input_layer *layer);

int mdss_mdp_smp_setup(struct mdss_data_type *mdata, u32 cnt, u32 size);

+22 −0
Original line number Diff line number Diff line
@@ -451,6 +451,8 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
		pipe->flags |= MDP_DEINTERLACE;
	if (layer->flags & MDP_LAYER_BWC)
		pipe->flags |= MDP_BWC_EN;
	if (layer->flags & MDP_LAYER_PP)
		pipe->flags |= MDP_OVERLAY_PP_CFG_EN;

	pipe->scale.enable_pxl_ext = layer->flags & MDP_LAYER_ENABLE_PIXEL_EXT;
	pipe->is_fg = layer->flags & MDP_LAYER_FORGROUND;
@@ -593,6 +595,16 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd,
		goto end;
	}

	if (layer->flags & MDP_LAYER_PP) {
		memcpy(&pipe->pp_cfg, layer->pp_info,
				sizeof(struct mdp_overlay_pp_params));
		ret = mdss_mdp_pp_sspp_config(pipe);
		if (ret) {
			pr_err("pp setup failed %d\n", ret);
			goto end;
		}
	}

	if (pipe->type == MDSS_MDP_PIPE_TYPE_CURSOR)
		goto end;

@@ -1105,6 +1117,16 @@ static int __validate_layers(struct msm_fb_data_type *mfd,
				right_plist[right_cnt++] = pipe;
			else
				left_plist[left_cnt++] = pipe;

			if (layer->flags & MDP_LAYER_PP) {
				memcpy(&pipe->pp_cfg, layer->pp_info,
					sizeof(struct mdp_overlay_pp_params));
				ret = mdss_mdp_pp_sspp_config(pipe);
				if (ret)
					pr_err("pp setup failed %d\n", ret);
				else
					pipe->params_changed++;
			}
			continue;
		}

+89 −5
Original line number Diff line number Diff line
@@ -6039,9 +6039,10 @@ int mdss_mdp_pp_sspp_config(struct mdss_mdp_pipe *pipe)
	int ret = 0;

	if (!pipe) {
		pr_err("invalid params %p\n", pipe);
		pr_err("invalid params, pipe %p\n", pipe);
		return -EINVAL;
	}

	cache_res.mdss_pp_res = NULL;
	cache_res.pipe_res = pipe;
	ret = sspp_cache_location(pipe->type, &cache_res.block);
@@ -6050,8 +6051,8 @@ int mdss_mdp_pp_sspp_config(struct mdss_mdp_pipe *pipe)
			ret);
		goto exit_fail;
	}
	len = pipe->pp_cfg.igc_cfg.len;
	if ((pipe->pp_cfg.config_ops & MDP_OVERLAY_PP_IGC_CFG)) {
		len = pipe->pp_cfg.igc_cfg.len;
		if (pp_ops[IGC].pp_set_config) {
			ret = pp_igc_lut_cache_params(&pipe->pp_cfg.igc_cfg,
						      &cache_res, false);
@@ -6114,9 +6115,6 @@ int mdss_mdp_pp_sspp_config(struct mdss_mdp_pipe *pipe)
			}
			pipe->pp_cfg.hist_lut_cfg.data = pipe->pp_res.hist_lut;
		} else {
			cache_res.block = SSPP_VIG;
			cache_res.mdss_pp_res = NULL;
			cache_res.pipe_res = pipe;
			ret = pp_hist_lut_cache_params(
					&pipe->pp_cfg.hist_lut_cfg,
					&cache_res);
@@ -6288,3 +6286,89 @@ static void mdss_mdp_hist_intr_notify(u32 disp)
	mdp5_data->hist_events++;
	sysfs_notify_dirent(mdp5_data->hist_event_sd);
}

int mdss_mdp_copy_layer_pp_info(struct mdp_input_layer *layer)
{
	struct mdp_overlay_pp_params *pp_info = NULL;
	int ret = 0;
	uint32_t ops;

	if (!layer) {
		pr_err("invalid layer pointer passed %p\n", layer);
		return -EFAULT;
	}

	pp_info = kmalloc(sizeof(struct mdp_overlay_pp_params),
			GFP_KERNEL);
	if (!pp_info)
		return -ENOMEM;

	ret = copy_from_user(pp_info, layer->pp_info,
			sizeof(struct mdp_overlay_pp_params));
	if (ret) {
		pr_err("layer list copy from user failed, pp_info = %p\n",
			layer->pp_info);
		ret = -EFAULT;
		goto exit_pp_info;
	}

	ops = pp_info->config_ops;
	if (ops & MDP_OVERLAY_PP_IGC_CFG) {
		ret = pp_copy_layer_igc_payload(pp_info);
		if (ret) {
			pr_err("Failed to copy IGC payload, ret = %d\n", ret);
			goto exit_pp_info;
		}
	}
	if (ops & MDP_OVERLAY_PP_HIST_LUT_CFG) {
		ret = pp_copy_layer_hist_lut_payload(pp_info);
		if (ret) {
			pr_err("Failed to copy Hist LUT payload, ret = %d\n",
				ret);
			goto exit_igc;
		}
	}
	if (ops & MDP_OVERLAY_PP_PA_V2_CFG) {
		ret = pp_copy_layer_pa_payload(pp_info);
		if (ret) {
			pr_err("Failed to copy PA payload, ret = %d\n", ret);
			goto exit_hist_lut;
		}
	}
	if (ops & MDP_OVERLAY_PP_PCC_CFG) {
		ret = pp_copy_layer_pcc_payload(pp_info);
		if (ret) {
			pr_err("Failed to copy PCC payload, ret = %d\n", ret);
			goto exit_pa;
		}
	}

	layer->pp_info = pp_info;

	return ret;

exit_pa:
	kfree(pp_info->pa_v2_cfg_data.cfg_payload);
exit_hist_lut:
	kfree(pp_info->hist_lut_cfg.cfg_payload);
exit_igc:
	kfree(pp_info->igc_cfg.cfg_payload);
exit_pp_info:
	kfree(pp_info);
	return ret;
}

void mdss_mdp_free_layer_pp_info(struct mdp_input_layer *layer)
{
	struct mdp_overlay_pp_params *pp_info =
		(struct mdp_overlay_pp_params *) layer->pp_info;

	if (!pp_info)
		return;

	kfree(pp_info->igc_cfg.cfg_payload);
	kfree(pp_info->hist_lut_cfg.cfg_payload);
	kfree(pp_info->pa_v2_cfg_data.cfg_payload);
	kfree(pp_info->pcc_cfg_data.cfg_payload);
	kfree(pp_info);
}
Loading