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

Commit cae88843 authored by Ping Li's avatar Ping Li Committed by Yuchao Ma
Browse files

drm/msm/sde: Add property for AD vsync count



On command mode panel, vsync notification will triggered for each
TE, not actual vsync commit. This change adds an AD property to
track vsync event count for AD, so that AD feature can converge
with the correct display commit count.

Change-Id: I6c87ce989203f8bb121723465c661e2b2f27c179
Signed-off-by: default avatarPing Li <pingli@codeaurora.org>
parent 9b0f7eab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum ad_property {
	AD_IPC_SUSPEND,
	AD_IPC_RESUME,
	AD_IPC_RESET,
	AD_VSYNC_UPDATE,
	AD_PROPMAX,
};

+70 −1
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ static void sde_cp_ad_set_prop(struct sde_crtc *sde_crtc,
		enum ad_property ad_prop);

static void sde_cp_notify_hist_event(struct drm_crtc *crtc_drm, void *arg);
static void sde_cp_update_ad_vsync_prop(struct sde_crtc *sde_crtc, u32 val);

#define setup_dspp_prop_install_funcs(func) \
do { \
@@ -138,6 +139,7 @@ enum {
	SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS,
	SDE_CP_CRTC_DSPP_AD_BACKLIGHT,
	SDE_CP_CRTC_DSPP_AD_STRENGTH,
	SDE_CP_CRTC_DSPP_AD_VSYNC_COUNT,
	SDE_CP_CRTC_DSPP_MAX,
	/* DSPP features end */

@@ -407,6 +409,7 @@ void sde_cp_crtc_init(struct drm_crtc *crtc)
	if (IS_ERR(sde_crtc->hist_blob))
		sde_crtc->hist_blob = NULL;

	sde_crtc->ad_vsync_count = 0;
	mutex_init(&sde_crtc->crtc_cp_lock);
	INIT_LIST_HEAD(&sde_crtc->active_list);
	INIT_LIST_HEAD(&sde_crtc->dirty_list);
@@ -789,6 +792,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_MODE;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		case SDE_CP_CRTC_DSPP_AD_INIT:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
@@ -798,6 +804,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_INIT;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		case SDE_CP_CRTC_DSPP_AD_CFG:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
@@ -807,6 +816,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_CFG;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		case SDE_CP_CRTC_DSPP_AD_INPUT:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
@@ -816,6 +828,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_INPUT;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		case SDE_CP_CRTC_DSPP_AD_ASSERTIVENESS:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
@@ -825,6 +840,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_ASSERTIVE;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		case SDE_CP_CRTC_DSPP_AD_BACKLIGHT:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
@@ -834,6 +852,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_BACKLIGHT;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		case SDE_CP_CRTC_DSPP_AD_STRENGTH:
			if (!hw_dspp || !hw_dspp->ops.setup_ad) {
@@ -843,6 +864,9 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
			ad_cfg.prop = AD_STRENGTH;
			ad_cfg.hw_cfg = &hw_cfg;
			hw_dspp->ops.setup_ad(hw_dspp, &ad_cfg);
			sde_crtc->ad_vsync_count = 0;
			sde_cp_update_ad_vsync_prop(sde_crtc,
					sde_crtc->ad_vsync_count);
			break;
		default:
			ret = -EINVAL;
@@ -924,10 +948,15 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
			DRM_DEBUG_DRIVER("Dirty list is empty\n");
			goto exit;
		}
		sde_cp_ad_set_prop(sde_crtc, AD_IPC_RESET);
		set_dspp_flush = true;
	}

	if (!list_empty(&sde_crtc->ad_active)) {
		sde_cp_ad_set_prop(sde_crtc, AD_IPC_RESET);
		sde_cp_ad_set_prop(sde_crtc, AD_VSYNC_UPDATE);
		sde_cp_update_ad_vsync_prop(sde_crtc, sde_crtc->ad_vsync_count);
	}

	list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list,
				dirty_list) {
		sde_dspp_feature = crtc_feature_map[prop_node->feature];
@@ -1449,6 +1478,9 @@ static void dspp_ad_install_property(struct drm_crtc *crtc)
				"SDE_DSPP_AD_V4_BACKLIGHT",
			SDE_CP_CRTC_DSPP_AD_BACKLIGHT, 0, (BIT(16) - 1),
			0);
		sde_cp_crtc_install_range_property(crtc,
			"SDE_DSPP_AD_V4_VSYNC_COUNT",
			SDE_CP_CRTC_DSPP_AD_VSYNC_COUNT, 0, U32_MAX, 0);
		break;
	default:
		DRM_ERROR("version %d not supported\n", version);
@@ -1867,6 +1899,11 @@ static void sde_cp_ad_set_prop(struct sde_crtc *sde_crtc,
		hw_cfg.displayh = num_mixers * hw_lm->cfg.out_width;
		hw_cfg.displayv = hw_lm->cfg.out_height;
		hw_cfg.mixer_info = hw_lm;

		if (ad_prop == AD_VSYNC_UPDATE) {
			hw_cfg.payload = &sde_crtc->ad_vsync_count;
			hw_cfg.len = sizeof(sde_crtc->ad_vsync_count);
		}
		ad_cfg.prop = ad_prop;
		ad_cfg.hw_cfg = &hw_cfg;
		ret = hw_dspp->ops.validate_ad(hw_dspp, (u32 *)&ad_prop);
@@ -2118,3 +2155,35 @@ int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
exit:
	return ret;
}

void sde_cp_update_ad_vsync_count(struct drm_crtc *crtc, u32 val)
{
	struct sde_crtc *sde_crtc;

	if (!crtc) {
		DRM_ERROR("invalid crtc %pK\n", crtc);
		return;
	}

	sde_crtc = to_sde_crtc(crtc);
	if (!sde_crtc) {
		DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
		return;
	}

	sde_crtc->ad_vsync_count = val;
	sde_cp_update_ad_vsync_prop(sde_crtc, val);
}

static void sde_cp_update_ad_vsync_prop(struct sde_crtc *sde_crtc, u32 val)
{
	struct sde_cp_node *prop_node = NULL;

	list_for_each_entry(prop_node, &sde_crtc->feature_list, feature_list) {
		if (prop_node->feature == SDE_CP_CRTC_DSPP_AD_VSYNC_COUNT) {
			prop_node->prop_val = val;
			pr_debug("AD vsync count updated to %d\n", val);
			return;
		}
	}
}
+8 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-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
@@ -146,4 +146,11 @@ void sde_cp_crtc_post_ipc(struct drm_crtc *crtc);
 */
int sde_cp_hist_interrupt(struct drm_crtc *crtc_drm, bool en,
	struct sde_irq_callback *hist_irq);

/**
 * sde_cp_update_ad_vsync_count: Api to update AD vsync count
 * @crtc: Pointer to crtc.
 * @val: vsync count value
 */
void sde_cp_update_ad_vsync_count(struct drm_crtc *crtc, u32 val);
#endif /*_SDE_COLOR_PROCESSING_H */
+1 −0
Original line number Diff line number Diff line
@@ -4125,6 +4125,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
	event.type = DRM_EVENT_CRTC_POWER;
	event.length = sizeof(u32);
	sde_cp_crtc_suspend(crtc);
	sde_cp_update_ad_vsync_count(crtc, 0);
	power_on = 0;
	msm_mode_object_event_notify(&crtc->base, crtc->dev, &event,
			(u8 *)&power_on);
+2 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ struct sde_crtc_event {
 * @dirty_list    : list of color processing features are dirty
 * @ad_dirty: list containing ad properties that are dirty
 * @ad_active: list containing ad properties that are active
 * @ad_vsync_count : count of vblank since last reset for AD
 * @crtc_lock     : crtc lock around create, destroy and access.
 * @frame_pending : Whether or not an update is pending
 * @frame_events  : static allocation of in-flight frame events
@@ -224,6 +225,7 @@ struct sde_crtc {
	struct list_head ad_dirty;
	struct list_head ad_active;
	struct list_head user_event_list;
	u32 ad_vsync_count;

	struct mutex crtc_lock;
	struct mutex crtc_cp_lock;
Loading