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

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

Merge changes...

Merge changes Ia9eebd02,Ia8ab0ef2,Ia6cf3b3f,I6272d756,I66e7ea18,I2e82ae22,I9b10f4ff into dev/msm-4.14-display

* changes:
  drm/msm/sde: concurrent writeback support
  drm/msm: atomic seamless connector change
  drm/msm/sde: add CWB custom property support
  drm/msm/sde: relax crtc for driving multiple connectors
  drm/msm/sde: avoid partial update when DS is enabled
  drm/msm/sde: extend frame retire event handling
  drm/msm/sde: propagate frame error through fence
parents 9056c9c0 b3964520
Loading
Loading
Loading
Loading
+87 −20
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.
 * Copyright (C) 2014 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
@@ -25,6 +25,8 @@
#include "msm_fence.h"
#include "sde_trace.h"

#define MULTIPLE_CONN_DETECTED(x) (x > 1)

struct msm_commit {
	struct drm_device *dev;
	struct drm_atomic_state *state;
@@ -111,6 +113,66 @@ static void commit_destroy(struct msm_commit *c)
		kfree(c);
}

static inline bool _msm_seamless_for_crtc(struct drm_atomic_state *state,
			struct drm_crtc_state *crtc_state, bool enable)
{
	struct drm_connector *connector = NULL;
	struct drm_connector_state  *conn_state = NULL;
	int i = 0;
	int conn_cnt = 0;

	if (msm_is_mode_seamless(&crtc_state->mode) ||
		msm_is_mode_seamless_vrr(&crtc_state->adjusted_mode))
		return true;

	if (msm_is_mode_seamless_dms(&crtc_state->adjusted_mode) && !enable)
		return true;

	if (!crtc_state->mode_changed && crtc_state->connectors_changed) {
		for_each_connector_in_state(state, connector, conn_state, i) {
			if ((conn_state->crtc == crtc_state->crtc) ||
					(connector->state->crtc ==
					 crtc_state->crtc))
				conn_cnt++;

			if (MULTIPLE_CONN_DETECTED(conn_cnt))
				return true;
		}
	}

	return false;
}

static inline bool _msm_seamless_for_conn(struct drm_connector *connector,
		struct drm_connector_state *old_conn_state, bool enable)
{
	if (!old_conn_state || !old_conn_state->crtc)
		return false;

	if (!old_conn_state->crtc->state->mode_changed &&
			!old_conn_state->crtc->state->active_changed &&
			old_conn_state->crtc->state->connectors_changed) {
		if (old_conn_state->crtc == connector->state->crtc)
			return true;
	}

	if (enable)
		return false;

	if (msm_is_mode_seamless(&connector->encoder->crtc->state->mode))
		return true;

	if (msm_is_mode_seamless_vrr(
			&connector->encoder->crtc->state->adjusted_mode))
		return true;

	if (msm_is_mode_seamless_dms(
			&connector->encoder->crtc->state->adjusted_mode))
		return true;

	return false;
}

static void msm_atomic_wait_for_commit_done(
		struct drm_device *dev,
		struct drm_atomic_state *old_state)
@@ -169,14 +231,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
		if (WARN_ON(!encoder))
			continue;

		if (msm_is_mode_seamless(
			&connector->encoder->crtc->state->mode) ||
			msm_is_mode_seamless_vrr(
			&connector->encoder->crtc->state->adjusted_mode))
			continue;

		if (msm_is_mode_seamless_dms(
			&connector->encoder->crtc->state->adjusted_mode))
		if (_msm_seamless_for_conn(connector, old_conn_state, false))
			continue;

		funcs = encoder->helper_private;
@@ -218,11 +273,7 @@ msm_disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
		if (!old_crtc_state->active)
			continue;

		if (msm_is_mode_seamless(&crtc->state->mode) ||
			msm_is_mode_seamless_vrr(&crtc->state->adjusted_mode))
			continue;

		if (msm_is_mode_seamless_dms(&crtc->state->adjusted_mode))
		if (_msm_seamless_for_crtc(old_state, crtc->state, false))
			continue;

		funcs = crtc->helper_private;
@@ -281,8 +332,14 @@ msm_crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
		mode = &new_crtc_state->mode;
		adjusted_mode = &new_crtc_state->adjusted_mode;

		if (!new_crtc_state->mode_changed)
		if (!new_crtc_state->mode_changed &&
				new_crtc_state->connectors_changed) {
			if (_msm_seamless_for_conn(connector,
					old_conn_state, false))
				continue;
		} else if (!new_crtc_state->mode_changed) {
			continue;
		}

		DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n",
				 encoder->base.id, encoder->name);
@@ -362,9 +419,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
		if (!new_crtc_state->active)
			continue;

		if (msm_is_mode_seamless(&new_crtc_state->mode) ||
				msm_is_mode_seamless_vrr(
				&new_crtc_state->adjusted_mode))
		if (_msm_seamless_for_crtc(old_state, crtc->state, true))
			continue;

		funcs = crtc->helper_private;
@@ -389,6 +444,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
			new_conn_state, i) {
		const struct drm_encoder_helper_funcs *funcs;
		struct drm_encoder *encoder;
		struct drm_connector_state *old_conn_state;

		if (!new_conn_state->best_encoder)
			continue;
@@ -398,7 +454,12 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
					new_conn_state->crtc->state))
			continue;

		encoder = new_conn_state->best_encoder;
		old_conn_state = drm_atomic_get_old_connector_state(
				old_state, connector);
		if (_msm_seamless_for_conn(connector, old_conn_state, true))
			continue;

		encoder = connector->state->best_encoder;
		funcs = encoder->helper_private;

		DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
@@ -437,6 +498,7 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
	for_each_new_connector_in_state(old_state, connector,
			new_conn_state, i) {
		struct drm_encoder *encoder;
		struct drm_connector_state *old_conn_state;

		if (!new_conn_state->best_encoder)
			continue;
@@ -446,7 +508,12 @@ static void msm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
				    new_conn_state->crtc->state))
			continue;

		encoder = new_conn_state->best_encoder;
		old_conn_state = drm_atomic_get_old_connector_state(
				old_state, connector);
		if (_msm_seamless_for_conn(connector, old_conn_state, true))
			continue;

		encoder = connector->state->best_encoder;

		DRM_DEBUG_ATOMIC("bridge enable enabling [ENCODER:%d:%s]\n",
				 encoder->base.id, encoder->name);
+1 −0
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ enum msm_mdp_crtc_property {
	CRTC_PROP_SECURITY_LEVEL,
	CRTC_PROP_IDLE_TIMEOUT,
	CRTC_PROP_DEST_SCALER,
	CRTC_PROP_CAPTURE_OUTPUT,

	/* total # of properties */
	CRTC_PROP_COUNT
+5 −3
Original line number Diff line number Diff line
@@ -1219,7 +1219,7 @@ void sde_connector_prepare_fence(struct drm_connector *connector)
}

void sde_connector_complete_commit(struct drm_connector *connector,
		ktime_t ts)
		ktime_t ts, enum sde_fence_event fence_event)
{
	if (!connector) {
		SDE_ERROR("invalid connector\n");
@@ -1227,7 +1227,8 @@ void sde_connector_complete_commit(struct drm_connector *connector,
	}

	/* signal connector's retire fence */
	sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, false);
	sde_fence_signal(&to_sde_connector(connector)->retire_fence,
			ts, fence_event);
}

void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts)
@@ -1238,7 +1239,8 @@ void sde_connector_commit_reset(struct drm_connector *connector, ktime_t ts)
	}

	/* signal connector's retire fence */
	sde_fence_signal(&to_sde_connector(connector)->retire_fence, ts, true);
	sde_fence_signal(&to_sde_connector(connector)->retire_fence,
			ts, SDE_FENCE_RESET_TIMELINE);
}

static void sde_connector_update_hdr_props(struct drm_connector *connector)
+3 −1
Original line number Diff line number Diff line
@@ -632,8 +632,10 @@ void sde_connector_prepare_fence(struct drm_connector *connector);
 * sde_connector_complete_commit - signal completion of current commit
 * @connector: Pointer to drm connector object
 * @ts: timestamp to be updated in the fence signalling
 * @fence_event: enum value to indicate nature of fence event
 */
void sde_connector_complete_commit(struct drm_connector *connector, ktime_t ts);
void sde_connector_complete_commit(struct drm_connector *connector,
		ktime_t ts, enum sde_fence_event fence_event);

/**
 * sde_connector_commit_reset - reset the completion signal
+134 −152
Original line number Diff line number Diff line
@@ -937,7 +937,9 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc,
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *crtc_state;
	struct sde_rect *crtc_roi;
	int i, num_attached_conns = 0;
	struct msm_mode_info mode_info;
	int i = 0;
	int rc;
	bool is_crtc_roi_dirty;
	bool is_any_conn_roi_dirty;

@@ -959,13 +961,14 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc,
		if (!conn_state || conn_state->crtc != crtc)
			continue;

		if (num_attached_conns) {
			SDE_ERROR(
				"crtc%d: unsupported: roi on crtc w/ >1 connectors\n",
					DRMID(crtc));
		rc = sde_connector_get_mode_info(conn_state, &mode_info);
		if (rc) {
			SDE_ERROR("failed to get mode info\n");
			return -EINVAL;
		}
		++num_attached_conns;

		if (!mode_info.roi_caps.enabled)
			continue;

		sde_conn = to_sde_connector(conn_state->connector);
		sde_conn_state = to_sde_connector_state(conn_state);
@@ -1286,13 +1289,6 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc,
	sde_crtc = to_sde_crtc(crtc);
	sde_crtc_state = to_sde_crtc_state(state);

	if (hweight_long(state->connector_mask) != 1) {
		SDE_ERROR("invalid connector count(%d) for crtc: %d\n",
			(int)hweight_long(state->connector_mask),
			crtc->base.id);
		return -EINVAL;
	}

	/*
	 * check connector array cached at modeset time since incoming atomic
	 * state may not include any connectors if they aren't modified
@@ -1308,29 +1304,18 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc,
			SDE_ERROR("failed to get mode info\n");
			return -EINVAL;
		}
		break;
	}

		if (!mode_info.roi_caps.enabled)
		return 0;
			continue;

		if (sde_crtc_state->user_roi_list.num_rects >
				mode_info.roi_caps.num_roi) {
		SDE_ERROR("roi count is more than supported limit, %d > %d\n",
			SDE_ERROR("roi count is exceeding limit, %d > %d\n",
					sde_crtc_state->user_roi_list.num_rects,
					mode_info.roi_caps.num_roi);
			return -E2BIG;
		}

	/**
	 * TODO: Need to check against ROI alignment restrictions if partial
	 * update support is added for destination scalar configurations
	 */
	if (sde_crtc_state->num_ds_enabled) {
		SDE_ERROR("DS and PU concurrency is not supported\n");
		return -EINVAL;
	}

		rc = _sde_crtc_set_crtc_roi(crtc, state);
		if (rc)
			return rc;
@@ -1352,6 +1337,7 @@ static int _sde_crtc_check_rois(struct drm_crtc *crtc,
		rc = _sde_crtc_check_planes_within_crtc_roi(crtc, state);
		if (rc)
			return rc;
	}

	return 0;
}
@@ -2126,6 +2112,55 @@ static void _sde_crtc_dest_scaler_setup(struct drm_crtc *crtc)
	}
}

static void sde_crtc_frame_event_cb(void *data, u32 event)
{
	struct drm_crtc *crtc = (struct drm_crtc *)data;
	struct sde_crtc *sde_crtc;
	struct msm_drm_private *priv;
	struct sde_crtc_frame_event *fevent;
	struct sde_crtc_frame_event_cb_data *cb_data;
	unsigned long flags;
	u32 crtc_id;

	cb_data = (struct sde_crtc_frame_event_cb_data *)data;
	if (!data) {
		SDE_ERROR("invalid parameters\n");
		return;
	}

	crtc = cb_data->crtc;
	if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
		SDE_ERROR("invalid parameters\n");
		return;
	}
	sde_crtc = to_sde_crtc(crtc);
	priv = crtc->dev->dev_private;
	crtc_id = drm_crtc_index(crtc);

	SDE_DEBUG("crtc%d\n", crtc->base.id);
	SDE_EVT32_VERBOSE(DRMID(crtc), event);

	spin_lock_irqsave(&sde_crtc->spin_lock, flags);
	fevent = list_first_entry_or_null(&sde_crtc->frame_event_list,
			struct sde_crtc_frame_event, list);
	if (fevent)
		list_del_init(&fevent->list);
	spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);

	if (!fevent) {
		SDE_ERROR("crtc%d event %d overflow\n",
				crtc->base.id, event);
		SDE_EVT32(DRMID(crtc), event);
		return;
	}

	fevent->event = event;
	fevent->crtc = crtc;
	fevent->connector = cb_data->connector;
	fevent->ts = ktime_get();
	kthread_queue_work(&priv->event_thread[crtc_id].worker, &fevent->work);
}

void sde_crtc_prepare_commit(struct drm_crtc *crtc,
		struct drm_crtc_state *old_state)
{
@@ -2133,10 +2168,8 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc,
	struct sde_crtc *sde_crtc;
	struct sde_crtc_state *cstate;
	struct drm_connector *conn;
	struct drm_encoder *encoder;
	struct drm_connector_list_iter conn_iter;
	struct sde_crtc_retire_event *retire_event = NULL;
	unsigned long flags;
	int i;

	if (!crtc || !crtc->state) {
		SDE_ERROR("invalid crtc\n");
@@ -2155,32 +2188,18 @@ void sde_crtc_prepare_commit(struct drm_crtc *crtc,
	drm_for_each_connector_iter(conn, &conn_iter)
		if (conn->state && conn->state->crtc == crtc &&
				cstate->num_connectors < MAX_CONNECTORS) {
			encoder = conn->state->best_encoder;
			if (encoder)
				sde_encoder_register_frame_event_callback(
						encoder,
						sde_crtc_frame_event_cb,
						crtc);

			cstate->connectors[cstate->num_connectors++] = conn;
			sde_connector_prepare_fence(conn);
		}
	drm_connector_list_iter_end(&conn_iter);

	for (i = 0; i < SDE_CRTC_FRAME_EVENT_SIZE; i++) {
		retire_event = &sde_crtc->retire_events[i];
		if (list_empty(&retire_event->list))
			break;
		retire_event = NULL;
	}

	if (retire_event) {
		retire_event->num_connectors = cstate->num_connectors;
		for (i = 0; i < cstate->num_connectors; i++)
			retire_event->connectors[i] = cstate->connectors[i];

		spin_lock_irqsave(&sde_crtc->spin_lock, flags);
		list_add_tail(&retire_event->list,
						&sde_crtc->retire_event_list);
		spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);
	} else {
		SDE_ERROR("crtc%d retire event overflow\n", crtc->base.id);
		SDE_EVT32(DRMID(crtc), SDE_EVTLOG_ERROR);
	}

	/* prepare main output fence */
	sde_fence_prepare(&sde_crtc->output_fence);
}
@@ -2231,9 +2250,16 @@ enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc)
		return INTF_MODE_NONE;
	}

	drm_for_each_encoder(encoder, crtc->dev)
		if (encoder->crtc == crtc)
	drm_for_each_encoder(encoder, crtc->dev) {
		if (encoder->crtc != crtc)
			continue;

		/* continue if copy encoder is encountered */
		if (sde_encoder_in_clone_mode(encoder))
			continue;

		return sde_encoder_get_intf_mode(encoder);
	}

	return INTF_MODE_NONE;
}
@@ -2258,38 +2284,16 @@ static void sde_crtc_vblank_cb(void *data)
	SDE_EVT32_VERBOSE(DRMID(crtc));
}

static void _sde_crtc_retire_event(struct drm_crtc *crtc, ktime_t ts)
static void _sde_crtc_retire_event(struct drm_connector *connector,
		ktime_t ts, bool is_error)
{
	struct sde_crtc_retire_event *retire_event;
	struct sde_crtc *sde_crtc;
	unsigned long flags;
	int i;

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

	sde_crtc = to_sde_crtc(crtc);
	spin_lock_irqsave(&sde_crtc->spin_lock, flags);
	retire_event = list_first_entry_or_null(&sde_crtc->retire_event_list,
				struct sde_crtc_retire_event, list);
	if (retire_event)
		list_del_init(&retire_event->list);
	spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);

	if (!retire_event) {
		SDE_ERROR("crtc%d retire event without kickoff\n",
								crtc->base.id);
		SDE_EVT32(DRMID(crtc), SDE_EVTLOG_ERROR);
		return;
	}

	SDE_ATRACE_BEGIN("signal_retire_fence");
	for (i = 0; (i < retire_event->num_connectors) &&
					retire_event->connectors[i]; ++i)
		sde_connector_complete_commit(
					retire_event->connectors[i], ts);
	sde_connector_complete_commit(connector, ts, is_error);
	SDE_ATRACE_END("signal_retire_fence");
}

@@ -2301,6 +2305,7 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
	struct sde_crtc *sde_crtc;
	struct sde_kms *sde_kms;
	unsigned long flags;
	bool in_clone_mode = false;

	if (!work) {
		SDE_ERROR("invalid work handle\n");
@@ -2329,10 +2334,11 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)

	SDE_EVT32_VERBOSE(DRMID(crtc), fevent->event, SDE_EVTLOG_FUNC_ENTRY);

	if (fevent->event & (SDE_ENCODER_FRAME_EVENT_DONE
				| SDE_ENCODER_FRAME_EVENT_ERROR
				| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
	in_clone_mode = sde_encoder_in_clone_mode(fevent->connector->encoder);

	if (!in_clone_mode && (fevent->event & (SDE_ENCODER_FRAME_EVENT_ERROR
					| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD
					| SDE_ENCODER_FRAME_EVENT_DONE))) {
		if (atomic_read(&sde_crtc->frame_pending) < 1) {
			/* this should not happen */
			SDE_ERROR("crtc%d ts:%lld invalid frame_pending:%d\n",
@@ -2357,13 +2363,17 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)

	if (fevent->event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE) {
		SDE_ATRACE_BEGIN("signal_release_fence");
		sde_fence_signal(&sde_crtc->output_fence, fevent->ts, false);
		sde_fence_signal(&sde_crtc->output_fence, fevent->ts,
				(fevent->event & SDE_ENCODER_FRAME_EVENT_ERROR)
				? SDE_FENCE_SIGNAL_ERROR : SDE_FENCE_SIGNAL);
		SDE_ATRACE_END("signal_release_fence");
	}

	if (fevent->event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE)
		/* this api should be called without spin_lock */
		_sde_crtc_retire_event(crtc, fevent->ts);
		_sde_crtc_retire_event(fevent->connector, fevent->ts,
				(fevent->event & SDE_ENCODER_FRAME_EVENT_ERROR)
				? SDE_FENCE_SIGNAL_ERROR : SDE_FENCE_SIGNAL);

	if (fevent->event & SDE_ENCODER_FRAME_EVENT_PANEL_DEAD)
		SDE_ERROR("crtc%d ts:%lld received panel dead event\n",
@@ -2375,46 +2385,6 @@ static void sde_crtc_frame_event_work(struct kthread_work *work)
	SDE_ATRACE_END("crtc_frame_event");
}

static void sde_crtc_frame_event_cb(void *data, u32 event)
{
	struct drm_crtc *crtc = (struct drm_crtc *)data;
	struct sde_crtc *sde_crtc;
	struct msm_drm_private *priv;
	struct sde_crtc_frame_event *fevent;
	unsigned long flags;
	u32 crtc_id;

	if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
		SDE_ERROR("invalid parameters\n");
		return;
	}
	sde_crtc = to_sde_crtc(crtc);
	priv = crtc->dev->dev_private;
	crtc_id = drm_crtc_index(crtc);

	SDE_DEBUG("crtc%d\n", crtc->base.id);
	SDE_EVT32_VERBOSE(DRMID(crtc), event);

	spin_lock_irqsave(&sde_crtc->spin_lock, flags);
	fevent = list_first_entry_or_null(&sde_crtc->frame_event_list,
			struct sde_crtc_frame_event, list);
	if (fevent)
		list_del_init(&fevent->list);
	spin_unlock_irqrestore(&sde_crtc->spin_lock, flags);

	if (!fevent) {
		SDE_ERROR("crtc%d event %d overflow\n",
				crtc->base.id, event);
		SDE_EVT32(DRMID(crtc), event);
		return;
	}

	fevent->event = event;
	fevent->crtc = crtc;
	fevent->ts = ktime_get();
	kthread_queue_work(&priv->event_thread[crtc_id].worker, &fevent->work);
}

void sde_crtc_complete_commit(struct drm_crtc *crtc,
		struct drm_crtc_state *old_state)
{
@@ -2986,6 +2956,10 @@ static void _sde_crtc_setup_mixers(struct drm_crtc *crtc)
		if (enc->crtc != crtc)
			continue;

		/* avoid overwriting mixers info from a copy encoder */
		if (sde_encoder_in_clone_mode(enc))
			continue;

		_sde_crtc_setup_mixer_for_encoder(crtc, enc);
	}

@@ -4198,7 +4172,8 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
	 * reset the fence timeline if crtc will not be enabled for this commit
	 */
	if (!crtc->state->active || !crtc->state->enable) {
		sde_fence_signal(&sde_crtc->output_fence, ktime_get(), true);
		sde_fence_signal(&sde_crtc->output_fence,
				ktime_get(), SDE_FENCE_RESET_TIMELINE);
		for (i = 0; i < cstate->num_connectors; ++i)
			sde_connector_commit_reset(cstate->connectors[i],
					ktime_get());
@@ -4264,7 +4239,7 @@ static void sde_crtc_enable(struct drm_crtc *crtc,
		if (encoder->crtc != crtc)
			continue;
		sde_encoder_register_frame_event_callback(encoder,
				sde_crtc_frame_event_cb, (void *)crtc);
				sde_crtc_frame_event_cb, crtc);
	}

	if (!sde_crtc->enabled && !sde_crtc->suspend &&
@@ -4933,6 +4908,11 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
		{SDE_DRM_SEC_ONLY, "sec_only"},
	};

	static const struct drm_prop_enum_list e_cwb_data_points[] = {
		{CAPTURE_MIXER_OUT, "capture_mixer_out"},
		{CAPTURE_DSPP_OUT, "capture_pp_out"},
	};

	SDE_DEBUG("\n");

	if (!crtc || !catalog) {
@@ -5008,6 +4988,12 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
		"idle_time", 0, 0, U64_MAX, 0,
		CRTC_PROP_IDLE_TIMEOUT);

	if (catalog->has_cwb_support)
		msm_property_install_enum(&sde_crtc->property_info,
				"capture_mode", 0, 0, e_cwb_data_points,
				ARRAY_SIZE(e_cwb_data_points),
				CRTC_PROP_CAPTURE_OUTPUT);

	msm_property_install_blob(&sde_crtc->property_info, "capabilities",
		DRM_MODE_PROP_IMMUTABLE, CRTC_PROP_INFO);

@@ -5928,10 +5914,6 @@ static int _sde_crtc_init_events(struct sde_crtc *sde_crtc)
		list_add_tail(&sde_crtc->event_cache[i].list,
				&sde_crtc->event_free_list);

	INIT_LIST_HEAD(&sde_crtc->retire_event_list);
	for (i = 0; i < ARRAY_SIZE(sde_crtc->retire_events); i++)
		INIT_LIST_HEAD(&sde_crtc->retire_events[i].list);

	return rc;
}

Loading