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

Commit 5a928716 authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: sde: Provide better error logging in SDE rotator" into msm-4.8

parents 50eba9de 59a06057
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -96,6 +96,7 @@ enum sde_bus_clients {
enum sde_rot_regdump_access {
	SDE_ROT_REGDUMP_READ,
	SDE_ROT_REGDUMP_WRITE,
	SDE_ROT_REGDUMP_VBIF,
	SDE_ROT_REGDUMP_MAX
};

+121 −47
Original line number Diff line number Diff line
@@ -1523,20 +1523,20 @@ static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,
	u8 out_v_subsample, out_h_subsample;

	if (!sde_rotator_is_valid_pixfmt(mgr, in_fmt->format, true)) {
		SDEROT_DBG("Invalid input format %x\n", in_fmt->format);
		return false;
		SDEROT_ERR("Invalid input format %x\n", in_fmt->format);
		goto verify_error;
	}

	if (!sde_rotator_is_valid_pixfmt(mgr, out_fmt->format, false)) {
		SDEROT_DBG("Invalid output format %x\n", out_fmt->format);
		return false;
		SDEROT_ERR("Invalid output format %x\n", out_fmt->format);
		goto verify_error;
	}

	if ((in_fmt->is_yuv != out_fmt->is_yuv) ||
		(in_fmt->pixel_mode != out_fmt->pixel_mode) ||
		(in_fmt->unpack_tight != out_fmt->unpack_tight)) {
		SDEROT_DBG("Rotator does not support CSC\n");
		return false;
		SDEROT_ERR("Rotator does not support CSC\n");
		goto verify_error;
	}

	/* Forcing same pixel depth */
@@ -1546,8 +1546,8 @@ static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,
			(in_fmt->bits[C2_R_Cr] != out_fmt->bits[C2_R_Cr]) ||
			(in_fmt->bits[C0_G_Y] != out_fmt->bits[C0_G_Y]) ||
			(in_fmt->bits[C1_B_Cb] != out_fmt->bits[C1_B_Cb])) {
			SDEROT_DBG("Bit format does not match\n");
			return false;
			SDEROT_ERR("Bit format does not match\n");
			goto verify_error;
		}
	}

@@ -1560,86 +1560,160 @@ static bool sde_rotator_verify_format(struct sde_rot_mgr *mgr,

		if ((in_v_subsample != out_h_subsample) ||
				(in_h_subsample != out_v_subsample)) {
			SDEROT_DBG("Rotation has invalid subsampling\n");
			return false;
			SDEROT_ERR("Rotation has invalid subsampling\n");
			goto verify_error;
		}
	} else {
		if (in_fmt->chroma_sample != out_fmt->chroma_sample) {
			SDEROT_DBG("Format subsampling mismatch\n");
			return false;
			SDEROT_ERR("Format subsampling mismatch\n");
			goto verify_error;
		}
	}

	SDEROT_DBG("in_fmt=%0d, out_fmt=%d\n", in_fmt->format, out_fmt->format);
	return true;

verify_error:
	SDEROT_ERR("in_fmt=0x%x, out_fmt=0x%x\n",
			in_fmt->format, out_fmt->format);
	return false;
}

int sde_rotator_verify_config(struct sde_rot_mgr *mgr,
static struct sde_mdp_format_params *__verify_input_config(
		struct sde_rot_mgr *mgr,
		struct sde_rotation_config *config)
{
	struct sde_mdp_format_params *in_fmt, *out_fmt;
	struct sde_mdp_format_params *in_fmt;
	u8 in_v_subsample, in_h_subsample;
	u8 out_v_subsample, out_h_subsample;
	u32 input, output;
	bool rotation;
	u32 input;
	int verify_input_only;

	if (!mgr || !config) {
		SDEROT_ERR("null parameters\n");
		return -EINVAL;
		return NULL;
	}

	input = config->input.format;
	output = config->output.format;
	rotation = (config->flags & SDE_ROTATION_90) ? true : false;
	verify_input_only =
		(config->flags & SDE_ROTATION_VERIFY_INPUT_ONLY) ? 1 : 0;

	in_fmt = sde_get_format_params(input);
	if (!in_fmt) {
		SDEROT_DBG("Unrecognized input format:%u\n", input);
		return -EINVAL;
	}

	out_fmt = sde_get_format_params(output);
	if (!out_fmt) {
		SDEROT_DBG("Unrecognized output format:%u\n", output);
		return -EINVAL;
		if (!verify_input_only)
			SDEROT_ERR("Unrecognized input format:0x%x\n", input);
		return NULL;
	}

	sde_mdp_get_v_h_subsample_rate(in_fmt->chroma_sample,
		&in_v_subsample, &in_h_subsample);
	sde_mdp_get_v_h_subsample_rate(out_fmt->chroma_sample,
		&out_v_subsample, &out_h_subsample);

	/* Dimension of image needs to be divisible by subsample rate  */
	if ((config->input.height % in_v_subsample) ||
			(config->input.width % in_h_subsample)) {
		SDEROT_DBG(
		if (!verify_input_only)
			SDEROT_ERR(
				"In ROI, subsample mismatch, w=%d, h=%d, vss%d, hss%d\n",
					config->input.width,
					config->input.height,
					in_v_subsample, in_h_subsample);
		return -EINVAL;
		return NULL;
	}

	return in_fmt;
}

static struct sde_mdp_format_params *__verify_output_config(
		struct sde_rot_mgr *mgr,
		struct sde_rotation_config *config)
{
	struct sde_mdp_format_params *out_fmt;
	u8 out_v_subsample, out_h_subsample;
	u32 output;
	int verify_input_only;

	if (!mgr || !config) {
		SDEROT_ERR("null parameters\n");
		return NULL;
	}

	output = config->output.format;
	verify_input_only =
		(config->flags & SDE_ROTATION_VERIFY_INPUT_ONLY) ? 1 : 0;

	out_fmt = sde_get_format_params(output);
	if (!out_fmt) {
		if (!verify_input_only)
			SDEROT_ERR("Unrecognized output format:0x%x\n", output);
		return NULL;
	}

	sde_mdp_get_v_h_subsample_rate(out_fmt->chroma_sample,
		&out_v_subsample, &out_h_subsample);

	/* Dimension of image needs to be divisible by subsample rate  */
	if ((config->output.height % out_v_subsample) ||
			(config->output.width % out_h_subsample)) {
		SDEROT_DBG(
		if (!verify_input_only)
			SDEROT_ERR(
				"Out ROI, subsample mismatch, w=%d, h=%d, vss%d, hss%d\n",
					config->output.width,
					config->output.height,
					out_v_subsample, out_h_subsample);
		if (!verify_input_only)
		return NULL;
	}

	return out_fmt;
}

int sde_rotator_verify_config_input(struct sde_rot_mgr *mgr,
		struct sde_rotation_config *config)
{
	struct sde_mdp_format_params *in_fmt;

	in_fmt = __verify_input_config(mgr, config);
	if (!in_fmt)
		return -EINVAL;

	return 0;
}

	if (!sde_rotator_verify_format(mgr, in_fmt,
			out_fmt, rotation)) {
		SDEROT_DBG(
			"Rot format pairing invalid, in_fmt:%d, out_fmt:%d\n",
					input, output);
		if (!verify_input_only)
int sde_rotator_verify_config_output(struct sde_rot_mgr *mgr,
		struct sde_rotation_config *config)
{
	struct sde_mdp_format_params *out_fmt;

	out_fmt = __verify_output_config(mgr, config);
	if (!out_fmt)
		return -EINVAL;

	return 0;
}

int sde_rotator_verify_config_all(struct sde_rot_mgr *mgr,
	struct sde_rotation_config *config)
{
	struct sde_mdp_format_params *in_fmt, *out_fmt;
	bool rotation;

	if (!mgr || !config) {
		SDEROT_ERR("null parameters\n");
		return -EINVAL;
	}

	rotation = (config->flags & SDE_ROTATION_90) ? true : false;

	in_fmt = __verify_input_config(mgr, config);
	if (!in_fmt)
		return -EINVAL;

	out_fmt = __verify_output_config(mgr, config);
	if (!out_fmt)
		return -EINVAL;

	if (!sde_rotator_verify_format(mgr, in_fmt, out_fmt, rotation)) {
		SDEROT_ERR(
			"Rot format pairing invalid, in_fmt:0x%x, out_fmt:0x%x\n",
					config->input.format,
					config->output.format);
		return -EINVAL;
	}

@@ -2049,7 +2123,7 @@ static int sde_rotator_config_session(struct sde_rot_mgr *mgr,
	int ret = 0;
	struct sde_rot_perf *perf;

	ret = sde_rotator_verify_config(mgr, config);
	ret = sde_rotator_verify_config_all(mgr, config);
	if (ret) {
		SDEROT_ERR("Rotator verify format failed\n");
		return ret;
+8 −2
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -413,7 +413,13 @@ void sde_rotator_remove_request(struct sde_rot_mgr *mgr,
	struct sde_rot_file_private *private,
	struct sde_rot_entry_container *req);

int sde_rotator_verify_config(struct sde_rot_mgr *rot_dev,
int sde_rotator_verify_config_all(struct sde_rot_mgr *rot_dev,
	struct sde_rotation_config *config);

int sde_rotator_verify_config_input(struct sde_rot_mgr *rot_dev,
	struct sde_rotation_config *config);

int sde_rotator_verify_config_output(struct sde_rot_mgr *rot_dev,
	struct sde_rotation_config *config);

int sde_rotator_validate_request(struct sde_rot_mgr *rot_dev,
+16 −6
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -246,11 +246,13 @@ static void sde_rot_dump_vbif_debug_bus(u32 bus_dump_flag,
 * sde_rot_dump_reg - helper function for dumping rotator register set content
 * @dump_name - register set name
 * @reg_dump_flag - dumping flag controlling in-log/memory dump location
 * @access - access type, sde registers or vbif registers
 * @addr - starting address offset for dumping
 * @len - range of the register set
 * @dump_mem - output buffer for memory dump location option
 */
void sde_rot_dump_reg(const char *dump_name, u32 reg_dump_flag, u32 addr,
void sde_rot_dump_reg(const char *dump_name, u32 reg_dump_flag,
	enum sde_rot_regdump_access access, u32 addr,
	int len, u32 **dump_mem)
{
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();
@@ -258,6 +260,7 @@ void sde_rot_dump_reg(const char *dump_name, u32 reg_dump_flag, u32 addr,
	u32 *dump_addr = NULL;
	phys_addr_t phys = 0;
	int i;
	void __iomem *base;

	in_log = (reg_dump_flag & SDE_ROT_DBG_DUMP_IN_LOG);
	in_mem = (reg_dump_flag & SDE_ROT_DBG_DUMP_IN_MEM);
@@ -285,14 +288,20 @@ void sde_rot_dump_reg(const char *dump_name, u32 reg_dump_flag, u32 addr,
		}
	}

	base = mdata->sde_io.base;
	/*
	 * VBIF NRT base handling
	 */
	if (access == SDE_ROT_REGDUMP_VBIF)
		base = mdata->vbif_nrt_io.base;

	for (i = 0; i < len; i++) {
		u32 x0, x4, x8, xc;

		x0 = readl_relaxed(mdata->sde_io.base + addr+0x0);
		x4 = readl_relaxed(mdata->sde_io.base + addr+0x4);
		x8 = readl_relaxed(mdata->sde_io.base + addr+0x8);
		xc = readl_relaxed(mdata->sde_io.base + addr+0xc);
		x0 = readl_relaxed(base + addr+0x0);
		x4 = readl_relaxed(base + addr+0x4);
		x8 = readl_relaxed(base + addr+0x8);
		xc = readl_relaxed(base + addr+0xc);

		if (in_log)
			pr_info("0x%08X : %08x %08x %08x %08x\n",
@@ -338,6 +347,7 @@ static void sde_rot_dump_reg_all(void)
		} else {
			sde_rot_dump_reg(head->name,
					sde_rot_dbg_evtlog.enable_reg_dump,
					head->access,
					head->offset, head->len,
					&sde_rot_dbg_evtlog.reg_dump_array[i]);
		}
+7 −5
Original line number Diff line number Diff line
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -1216,7 +1216,8 @@ static int sde_rotator_try_fmt_vid_cap(struct file *file,
	config.output.format = f->fmt.pix.pixelformat;
	config.output.width = f->fmt.pix.width;
	config.output.height = f->fmt.pix.height;
	ret = sde_rotator_verify_config(rot_dev->mgr, &config);
	config.flags |= SDE_ROTATION_VERIFY_INPUT_ONLY;
	ret = sde_rotator_verify_config_output(rot_dev->mgr, &config);
	sde_rot_mgr_unlock(rot_dev->mgr);
	if (ret) {
		if ((config.output.width == f->fmt.pix.width) &&
@@ -1233,7 +1234,7 @@ static int sde_rotator_try_fmt_vid_cap(struct file *file,
	}

	sde_rotator_format_recalc(f);
	return 0;
	return ret;
}

/*
@@ -1263,7 +1264,7 @@ static int sde_rotator_try_fmt_vid_out(struct file *file,
	config.input.width = f->fmt.pix.width;
	config.input.height = f->fmt.pix.height;
	config.flags |= SDE_ROTATION_VERIFY_INPUT_ONLY;
	ret = sde_rotator_verify_config(rot_dev->mgr, &config);
	ret = sde_rotator_verify_config_input(rot_dev->mgr, &config);
	sde_rot_mgr_unlock(rot_dev->mgr);
	if (ret) {
		if ((config.input.width == f->fmt.pix.width) &&
@@ -1280,7 +1281,7 @@ static int sde_rotator_try_fmt_vid_out(struct file *file,
	}

	sde_rotator_format_recalc(f);
	return 0;
	return ret;
}

/*
@@ -1510,6 +1511,7 @@ static int sde_rotator_streamon(struct file *file,
	if (vb2_is_streaming(vq)) {
		sde_rot_mgr_lock(rot_dev->mgr);
		sde_rotator_get_config_from_ctx(ctx, &config);
		config.flags &= ~SDE_ROTATION_VERIFY_INPUT_ONLY;
		ret = sde_rotator_session_config(rot_dev->mgr, ctx->private,
				&config);
		sde_rot_mgr_unlock(rot_dev->mgr);
Loading