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

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

Merge "drm/msm/sde: Add property for AD vsync count" into msm-4.9

parents 2e11ff3e cae88843
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
@@ -4144,6 +4144,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