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

Commit a4f0340b authored by Gurpreet Singh Dhami's avatar Gurpreet Singh Dhami
Browse files

drm/msm/sde: enable intf misr after frame trigger



Perform MISR enable after frame trigger and then collect misr after misr
status bit is set. Previously misr was enabled through debugfs, so if
system goes into idle power collapse before commit, then misr enable
status was not retained. Also it was not waiting for misr status bit.

Change-Id: I36f638845af9b67cf67f3719a0254f82b06d33ae
Signed-off-by: default avatarGurpreet Singh Dhami <gdhami@codeaurora.org>
parent 3b3e314b
Loading
Loading
Loading
Loading
+94 −26
Original line number Diff line number Diff line
@@ -2157,6 +2157,28 @@ static int _sde_encoder_resource_control_helper(struct drm_encoder *drm_enc,
	return 0;
}

static void sde_encoder_misr_configure(struct drm_encoder *drm_enc,
		bool enable, u32 frame_count)
{
	struct sde_encoder_virt *sde_enc;
	int i;

	if (!drm_enc) {
		SDE_ERROR("invalid encoder\n");
		return;
	}
	sde_enc = to_sde_encoder_virt(drm_enc);

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (!phys || !phys->ops.setup_misr)
			continue;

		phys->ops.setup_misr(phys, enable, frame_count);
	}
}

static void sde_encoder_input_event_handler(struct input_handle *handle,
	unsigned int type, unsigned int code, int value)
{
@@ -3949,6 +3971,10 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
		}
	}

	if (sde_enc->misr_enable)
		sde_encoder_misr_configure(&sde_enc->base, true,
				sde_enc->misr_frame_count);

	_sde_encoder_trigger_start(sde_enc->cur_master);

	if (sde_enc->elevated_ahb_vote) {
@@ -4790,6 +4816,28 @@ void sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
	}
}

void sde_encoder_helper_setup_misr(struct sde_encoder_phys *phys_enc,
						bool enable, u32 frame_count)
{
	if (!phys_enc)
		return;

	if (phys_enc->hw_intf && phys_enc->hw_intf->ops.setup_misr)
		phys_enc->hw_intf->ops.setup_misr(phys_enc->hw_intf,
				enable, frame_count);
}

int sde_encoder_helper_collect_misr(struct sde_encoder_phys *phys_enc,
		bool nonblock, u32 *misr_value)
{
	if (!phys_enc)
		return -EINVAL;

	return phys_enc->hw_intf && phys_enc->hw_intf->ops.collect_misr ?
			phys_enc->hw_intf->ops.collect_misr(phys_enc->hw_intf,
			nonblock, misr_value) : -ENOTSUPP;
}

#ifdef CONFIG_DEBUG_FS
static int _sde_encoder_status_show(struct seq_file *s, void *data)
{
@@ -4846,15 +4894,27 @@ static ssize_t _sde_encoder_misr_setup(struct file *file,
		const char __user *user_buf, size_t count, loff_t *ppos)
{
	struct sde_encoder_virt *sde_enc;
	int i = 0, rc;
	int rc;
	char buf[MISR_BUFF_SIZE + 1];
	size_t buff_copy;
	u32 frame_count, enable;
	struct msm_drm_private *priv = NULL;
	struct sde_kms *sde_kms = NULL;

	if (!file || !file->private_data)
		return -EINVAL;

	sde_enc = file->private_data;
	priv = sde_enc->base.dev->dev_private;
	if (!sde_enc || !priv || !priv->kms)
		return -EINVAL;

	sde_kms = to_sde_kms(priv->kms);

	if (sde_kms_is_secure_session_inprogress(sde_kms)) {
		SDE_DEBUG_ENC(sde_enc, "misr enable/disable not allowed\n");
		return -ENOTSUPP;
	}

	buff_copy = min_t(size_t, count, MISR_BUFF_SIZE);
	if (copy_from_user(buf, user_buf, buff_copy))
@@ -4869,20 +4929,10 @@ static ssize_t _sde_encoder_misr_setup(struct file *file,
	if (rc)
		return rc;

	mutex_lock(&sde_enc->enc_lock);
	sde_enc->misr_enable = enable;
	sde_enc->misr_frame_count = frame_count;
	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];

		if (!phys || !phys->ops.setup_misr)
			continue;

		phys->ops.setup_misr(phys, enable, frame_count);
	}
	mutex_unlock(&sde_enc->enc_lock);
	sde_encoder_misr_configure(&sde_enc->base, enable, frame_count);
	_sde_encoder_power_enable(sde_enc, false);

	return count;
}

@@ -4890,6 +4940,8 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
		char __user *user_buff, size_t count, loff_t *ppos)
{
	struct sde_encoder_virt *sde_enc;
	struct msm_drm_private *priv = NULL;
	struct sde_kms *sde_kms = NULL;
	int i = 0, len = 0;
	char buf[MISR_BUFF_SIZE + 1] = {'\0'};
	int rc;
@@ -4901,33 +4953,50 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
		return -EINVAL;

	sde_enc = file->private_data;
	priv = sde_enc->base.dev->dev_private;
	if (priv != NULL)
		sde_kms = to_sde_kms(priv->kms);

	if (sde_kms_is_secure_session_inprogress(sde_kms)) {
		SDE_DEBUG_ENC(sde_enc, "misr read not allowed\n");
		return -ENOTSUPP;
	}

	rc = _sde_encoder_power_enable(sde_enc, true);
	if (rc)
		return rc;

	mutex_lock(&sde_enc->enc_lock);
	if (!sde_enc->misr_enable) {
		len += snprintf(buf + len, MISR_BUFF_SIZE - len,
		len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
				"disabled\n");
		goto buff_check;
	} else if (sde_enc->disp_info.capabilities &
						~MSM_DISPLAY_CAP_VID_MODE) {
		len += snprintf(buf + len, MISR_BUFF_SIZE - len,
			"unsupported\n");
		goto buff_check;
	}

	for (i = 0; i < sde_enc->num_phys_encs; i++) {
		struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
		u32 misr_value = 0;

		if (!phys || !phys->ops.collect_misr)
		if (!phys || !phys->ops.collect_misr) {
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"invalid\n");
			SDE_ERROR_ENC(sde_enc, "invalid misr ops\n");
			continue;
		}

		len += snprintf(buf + len, MISR_BUFF_SIZE - len,
			"Intf idx:%d\n", phys->intf_idx - INTF_0);
		len += snprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n",
					phys->ops.collect_misr(phys));
		rc = phys->ops.collect_misr(phys, false, &misr_value);
		if (rc) {
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"invalid\n");
			SDE_ERROR_ENC(sde_enc, "failed to collect misr %d\n",
					rc);
			continue;
		} else {
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"Intf idx:%d\n",
					phys->intf_idx - INTF_0);
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"0x%x\n", misr_value);
		}
	}

buff_check:
@@ -4944,7 +5013,6 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
	*ppos += len;   /* increase offset */

end:
	mutex_unlock(&sde_enc->enc_lock);
	_sde_encoder_power_enable(sde_enc, false);
	return len;
}
+20 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved.
 */

#ifndef __SDE_ENCODER_PHYS_H__
@@ -169,7 +169,8 @@ struct sde_encoder_phys_ops {

	void (*setup_misr)(struct sde_encoder_phys *phys_encs,
				bool enable, u32 frame_count);
	u32 (*collect_misr)(struct sde_encoder_phys *phys_enc);
	int (*collect_misr)(struct sde_encoder_phys *phys_enc, bool nonblock,
			u32 *misr_value);
	void (*hw_reset)(struct sde_encoder_phys *phys_enc);
	void (*irq_control)(struct sde_encoder_phys *phys, bool enable);
	void (*update_split_role)(struct sde_encoder_phys *phys_enc,
@@ -702,4 +703,21 @@ static inline bool sde_encoder_phys_needs_single_flush(
void sde_encoder_helper_phys_disable(struct sde_encoder_phys *phys_enc,
		struct sde_encoder_phys_wb *wb_enc);

/**
 * sde_encoder_helper_setup_misr - helper function to setup misr
 * @enable: enable/disable flag
 * @frame_count: frame count for misr
 */
void sde_encoder_helper_setup_misr(struct sde_encoder_phys *phys_enc,
		bool enable, u32 frame_count);

/**
 * sde_encoder_helper_collect_misr - helper function to collect misr
 * @nonblock:  blocking/non-blocking flag
 * @misr_value:  pointer to misr value
 * @Return: zero on success
 */
int sde_encoder_helper_collect_misr(struct sde_encoder_phys *phys_enc,
		bool nonblock, u32 *misr_value);

#endif /* __sde_encoder_phys_H__ */
+3 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
@@ -1662,6 +1662,8 @@ static void sde_encoder_phys_cmd_init_ops(struct sde_encoder_phys_ops *ops)
	ops->get_wr_line_count = sde_encoder_phys_cmd_get_write_line_count;
	ops->wait_for_active = NULL;
	ops->setup_vsync_source = sde_encoder_phys_cmd_setup_vsync_source;
	ops->setup_misr = sde_encoder_helper_setup_misr;
	ops->collect_misr = sde_encoder_helper_collect_misr;
}

struct sde_encoder_phys *sde_encoder_phys_cmd_init(
+2 −22
Original line number Diff line number Diff line
@@ -1108,26 +1108,6 @@ static void sde_encoder_phys_vid_irq_control(struct sde_encoder_phys *phys_enc,
	}
}

static void sde_encoder_phys_vid_setup_misr(struct sde_encoder_phys *phys_enc,
						bool enable, u32 frame_count)
{
	if (!phys_enc)
		return;

	if (phys_enc->hw_intf && phys_enc->hw_intf->ops.setup_misr)
		phys_enc->hw_intf->ops.setup_misr(phys_enc->hw_intf,
							enable, frame_count);
}

static u32 sde_encoder_phys_vid_collect_misr(struct sde_encoder_phys *phys_enc)
{
	if (!phys_enc)
		return 0;

	return phys_enc->hw_intf && phys_enc->hw_intf->ops.collect_misr ?
		phys_enc->hw_intf->ops.collect_misr(phys_enc->hw_intf) : 0;
}

static int sde_encoder_phys_vid_get_line_count(
		struct sde_encoder_phys *phys_enc)
{
@@ -1228,8 +1208,8 @@ static void sde_encoder_phys_vid_init_ops(struct sde_encoder_phys_ops *ops)
	ops->prepare_for_kickoff = sde_encoder_phys_vid_prepare_for_kickoff;
	ops->handle_post_kickoff = sde_encoder_phys_vid_handle_post_kickoff;
	ops->needs_single_flush = sde_encoder_phys_needs_single_flush;
	ops->setup_misr = sde_encoder_phys_vid_setup_misr;
	ops->collect_misr = sde_encoder_phys_vid_collect_misr;
	ops->setup_misr = sde_encoder_helper_setup_misr;
	ops->collect_misr = sde_encoder_helper_collect_misr;
	ops->trigger_flush = sde_encoder_helper_trigger_flush;
	ops->hw_reset = sde_encoder_helper_hw_reset;
	ops->get_line_count = sde_encoder_phys_vid_get_line_count;
+28 −4
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 */
#include <linux/iopoll.h>

@@ -389,16 +389,40 @@ static void sde_hw_intf_setup_misr(struct sde_hw_intf *intf,

	if (enable)
		config = (frame_count & MISR_FRAME_COUNT_MASK) |
			MISR_CTRL_ENABLE | INTF_MISR_CTRL_FREE_RUN_MASK;
				MISR_CTRL_ENABLE |
				INTF_MISR_CTRL_FREE_RUN_MASK |
				INTF_MISR_CTRL_INPUT_SEL_DATA;

	SDE_REG_WRITE(c, INTF_MISR_CTRL, config);
}

static u32 sde_hw_intf_collect_misr(struct sde_hw_intf *intf)
static int sde_hw_intf_collect_misr(struct sde_hw_intf *intf, bool nonblock,
		 u32 *misr_value)
{
	struct sde_hw_blk_reg_map *c = &intf->hw;
	u32 ctrl = 0;

	return SDE_REG_READ(c, INTF_MISR_SIGNATURE);
	if (!misr_value)
		return -EINVAL;

	ctrl = SDE_REG_READ(c, INTF_MISR_CTRL);
	if (!nonblock) {
		if (ctrl & MISR_CTRL_ENABLE) {
			int rc;

			rc = readl_poll_timeout(c->base_off + c->blk_off +
					INTF_MISR_CTRL, ctrl,
					(ctrl & MISR_CTRL_STATUS) > 0, 500,
					84000);
			if (rc)
				return rc;
		} else {
			return -EINVAL;
		}
	}

	*misr_value =  SDE_REG_READ(c, INTF_MISR_SIGNATURE);
	return 0;
}

static u32 sde_hw_intf_get_line_count(struct sde_hw_intf *intf)
Loading