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

Commit 9a857bf3 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/sde: enable lm misr after frame trigger"

parents 1164ef78 79041933
Loading
Loading
Loading
Loading
+66 −48
Original line number Diff line number Diff line
@@ -3640,8 +3640,7 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
	struct sde_crtc_state *cstate;
	struct drm_plane *plane;
	struct drm_encoder *encoder;
	struct sde_crtc_mixer *m;
	u32 i, misr_status, power_on;
	u32 power_on;
	unsigned long flags;
	struct sde_crtc_irq_info *node = NULL;
	int ret = 0;
@@ -3689,16 +3688,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
		spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);

		sde_cp_crtc_post_ipc(crtc);

		for (i = 0; i < sde_crtc->num_mixers; ++i) {
			m = &sde_crtc->mixers[i];
			if (!m->hw_lm || !m->hw_lm->ops.setup_misr ||
					!sde_crtc->misr_enable)
				continue;

			m->hw_lm->ops.setup_misr(m->hw_lm, true,
					sde_crtc->misr_frame_count);
		}
		break;
	case SDE_POWER_EVENT_PRE_DISABLE:
		/* enable mdp LUT memory retention */
@@ -3721,17 +3710,6 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg)
			sde_encoder_control_te(encoder, false);
		}

		for (i = 0; i < sde_crtc->num_mixers; ++i) {
			m = &sde_crtc->mixers[i];
			if (!m->hw_lm || !m->hw_lm->ops.collect_misr ||
					!sde_crtc->misr_enable)
				continue;

			misr_status = m->hw_lm->ops.collect_misr(m->hw_lm);
			sde_crtc->misr_data[i] = misr_status ? misr_status :
							sde_crtc->misr_data[i];
		}

		spin_lock_irqsave(&sde_crtc->spin_lock, flags);
		node = NULL;
		list_for_each_entry(node, &sde_crtc->user_event_list, list) {
@@ -5236,10 +5214,9 @@ void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count)
	}
	sde_crtc = to_sde_crtc(crtc);

	sde_crtc->misr_enable = enable;
	sde_crtc->misr_enable_sui = enable;
	sde_crtc->misr_frame_count = frame_count;
	for (i = 0; i < sde_crtc->num_mixers; ++i) {
		sde_crtc->misr_data[i] = 0;
		m = &sde_crtc->mixers[i];
		if (!m->hw_lm || !m->hw_lm->ops.setup_misr)
			continue;
@@ -5248,6 +5225,40 @@ void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count)
	}
}

void sde_crtc_get_misr_info(struct drm_crtc *crtc,
			struct sde_crtc_misr_info *crtc_misr_info)
{
	struct sde_crtc *sde_crtc;
	struct sde_kms *sde_kms;

	if (!crtc_misr_info) {
		SDE_ERROR("invalid misr info\n");
		return;
	}

	crtc_misr_info->misr_enable = false;
	crtc_misr_info->misr_frame_count = 0;

	if (!crtc) {
		SDE_ERROR("invalid crtc\n");
		return;
	}

	sde_kms = _sde_crtc_get_kms(crtc);
	if (!sde_kms) {
		SDE_ERROR("invalid sde_kms\n");
		return;
	}

	if (sde_kms_is_secure_session_inprogress(sde_kms))
		return;

	sde_crtc = to_sde_crtc(crtc);
	crtc_misr_info->misr_enable =
			sde_crtc->misr_enable_debugfs ? true : false;
	crtc_misr_info->misr_frame_count = sde_crtc->misr_frame_count;
}

#ifdef CONFIG_DEBUG_FS
static int _sde_debugfs_status_show(struct seq_file *s, void *data)
{
@@ -5427,20 +5438,18 @@ static ssize_t _sde_crtc_misr_setup(struct file *file,
	if (sscanf(buf, "%u %u", &enable, &frame_count) != 2)
		return -EINVAL;

	rc = _sde_crtc_power_enable(sde_crtc, true);
	if (rc)
		return rc;

	mutex_lock(&sde_crtc->crtc_lock);
	if (sde_kms_is_secure_session_inprogress(sde_kms)) {
		SDE_DEBUG("crtc:%d misr enable/disable not allowed\n",
				DRMID(crtc));
		goto end;
		return -EINVAL;
	}
	sde_crtc_misr_setup(crtc, enable, frame_count);

end:
	mutex_unlock(&sde_crtc->crtc_lock);
	rc = _sde_crtc_power_enable(sde_crtc, true);
	if (rc)
		return rc;

	sde_crtc->misr_enable_debugfs = enable;
	sde_crtc_misr_setup(crtc, enable, frame_count);
	_sde_crtc_power_enable(sde_crtc, false);

	return count;
@@ -5454,7 +5463,6 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
	struct sde_kms *sde_kms;
	struct sde_crtc_mixer *m;
	int i = 0, rc;
	u32 misr_status;
	ssize_t len = 0;
	char buf[MISR_BUFF_SIZE + 1] = {'\0'};

@@ -5474,30 +5482,41 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
	if (rc)
		return rc;

	mutex_lock(&sde_crtc->crtc_lock);
	if (sde_kms_is_secure_session_inprogress(sde_kms)) {
		SDE_DEBUG("crtc:%d misr read not allowed\n", DRMID(crtc));
		goto end;
	}

	if (!sde_crtc->misr_enable) {
		len += snprintf(buf + len, MISR_BUFF_SIZE - len,
	if (!sde_crtc->misr_enable_debugfs) {
		len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
				"disabled\n");
		goto buff_check;
	}

	for (i = 0; i < sde_crtc->num_mixers; ++i) {
		u32 misr_value = 0;

		m = &sde_crtc->mixers[i];
		if (!m->hw_lm || !m->hw_lm->ops.collect_misr)
		if (!m->hw_lm || !m->hw_lm->ops.collect_misr) {
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"invalid\n");
			SDE_ERROR("crtc:%d invalid misr ops\n", DRMID(crtc));
			continue;
		}

		misr_status = m->hw_lm->ops.collect_misr(m->hw_lm);
		sde_crtc->misr_data[i] = misr_status ? misr_status :
							sde_crtc->misr_data[i];
		len += snprintf(buf + len, MISR_BUFF_SIZE - len, "lm idx:%d\n",
					m->hw_lm->idx - LM_0);
		len += snprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n",
							sde_crtc->misr_data[i]);
		rc = m->hw_lm->ops.collect_misr(m->hw_lm, false, &misr_value);
		if (rc) {
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"invalid\n");
			SDE_ERROR("crtc:%d failed to collect misr %d\n",
					DRMID(crtc), rc);
			continue;
		} else {
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"lm idx:%d\n", m->hw_lm->idx - LM_0);
			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
					"0x%x\n", misr_value);
		}
	}

buff_check:
@@ -5514,7 +5533,6 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
	*ppos += len;   /* increase offset */

end:
	mutex_unlock(&sde_crtc->crtc_lock);
	_sde_crtc_power_enable(sde_crtc, false);
	return len;
}
+25 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2019 The Linux Foundation. All rights reserved.
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -185,6 +185,16 @@ struct sde_ltm_buffer {
	struct list_head node;
};

/**
 * struct sde_crtc_misr_info - structure for misr information
 * @misr_enable : enable/disable flag
 * @misr_frame_count : Number of frames for misr calculation.
 */
struct sde_crtc_misr_info {
	bool misr_enable;
	u32 misr_frame_count;
};

/*
 * Maximum number of free event structures to cache
 */
@@ -235,7 +245,10 @@ struct sde_ltm_buffer {
 * @event_cache   : Local cache of event worker structures
 * @event_free_list : List of available event structures
 * @event_lock    : Spinlock around event handling code
 * @misr_enable   : boolean entry indicates misr enable/disable status.
 * @misr_enable_sui : boolean entry indicates misr enable/disable status
 *                    for secure cases.
 * @misr_enable_debugfs : boolean entry indicates misr enable/disable status
 *                        from debugfs.
 * @misr_frame_count  : misr frame count provided by client
 * @misr_data     : store misr data before turning off the clocks.
 * @idle_notify_work: delayed worker to notify idle timeout to user space
@@ -305,10 +318,9 @@ struct sde_crtc {
	struct sde_crtc_event event_cache[SDE_CRTC_MAX_EVENT_COUNT];
	struct list_head event_free_list;
	spinlock_t event_lock;
	bool misr_enable;
	bool misr_enable_sui;
	bool misr_enable_debugfs;
	u32 misr_frame_count;
	u32 misr_data[CRTC_DUAL_MIXERS];

	struct kthread_delayed_work idle_notify_work;

	struct sde_power_event *power_event;
@@ -752,4 +764,12 @@ void sde_crtc_update_cont_splash_settings(
 */
void sde_crtc_misr_setup(struct drm_crtc *crtc, bool enable, u32 frame_count);

/**
 * sde_crtc_get_misr_info - to configure and enable/disable MISR
 * @crtc: Pointer to drm crtc structure
 * @crtc_misr_info: Pointer to crtc misr info structure
 */
void sde_crtc_get_misr_info(struct drm_crtc *crtc,
		struct sde_crtc_misr_info *crtc_misr_info);

#endif /* _SDE_CRTC_H_ */
+100 −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)
{
@@ -3884,6 +3906,7 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
	struct msm_drm_private *priv = NULL;
	struct sde_kms *sde_kms = NULL;
	bool is_vid_mode = false;
	struct sde_crtc_misr_info crtc_misr_info = {false, 0};

	if (!sde_enc) {
		SDE_ERROR("invalid encoder\n");
@@ -3949,6 +3972,15 @@ 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_crtc_get_misr_info(sde_enc->crtc, &crtc_misr_info);
	if (crtc_misr_info.misr_enable)
		sde_crtc_misr_setup(sde_enc->crtc, true,
				crtc_misr_info.misr_frame_count);

	_sde_encoder_trigger_start(sde_enc->cur_master);

	if (sde_enc->elevated_ahb_vote) {
@@ -4790,6 +4822,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 +4900,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 +4935,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 +4946,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 +4959,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 +5019,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__
@@ -1663,6 +1663,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(
Loading