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

Commit 6e5b9051 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 : cache crtc in sde phys wb encoder"

parents 6bae5f29 fae4d81e
Loading
Loading
Loading
Loading
+79 −32
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ enum sde_enc_rc_states {
 * @rsc_config:			rsc configuration for display vtotal, fps, etc.
 * @cur_conn_roi:		current connector roi
 * @prv_conn_roi:		previous connector roi to optimize if unchanged
 * @crtc			pointer to drm_crtc
 */
struct sde_encoder_virt {
	struct drm_encoder base;
@@ -243,6 +244,7 @@ struct sde_encoder_virt {
	struct sde_rsc_cmd_config rsc_config;
	struct sde_rect cur_conn_roi;
	struct sde_rect prv_conn_roi;
	struct drm_crtc *crtc;
};

#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
@@ -1315,14 +1317,23 @@ static int _sde_encoder_update_roi(struct drm_encoder *drm_enc)
	struct drm_display_mode *adj_mode;
	struct sde_rect roi;

	if (!drm_enc || !drm_enc->crtc || !drm_enc->crtc->state)
	if (!drm_enc) {
		SDE_ERROR("invalid encoder parameter\n");
		return -EINVAL;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	if (!sde_enc->crtc || !sde_enc->crtc->state) {
		SDE_ERROR("invalid crtc parameter\n");
		return -EINVAL;
	}

	if (!sde_enc->cur_master)
	if (!sde_enc->cur_master) {
		SDE_ERROR("invalid cur_master parameter\n");
		return -EINVAL;
	}

	adj_mode = &sde_enc->base.crtc->state->adjusted_mode;
	adj_mode = &sde_enc->cur_master->cached_mode;
	drm_conn = sde_enc->cur_master->connector;

	_sde_encoder_get_connector_roi(sde_enc, &roi);
@@ -1367,8 +1378,8 @@ static int _sde_encoder_dsc_setup(struct sde_encoder_virt *sde_enc,
			sde_enc->prv_conn_roi.y,
			sde_enc->prv_conn_roi.w,
			sde_enc->prv_conn_roi.h,
			sde_enc->base.crtc->state->adjusted_mode.hdisplay,
			sde_enc->base.crtc->state->adjusted_mode.vdisplay);
			sde_enc->cur_master->cached_mode.hdisplay,
			sde_enc->cur_master->cached_mode.vdisplay);

	if (sde_kms_rect_is_equal(&sde_enc->cur_conn_roi,
			&sde_enc->prv_conn_roi))
@@ -1502,13 +1513,18 @@ static int _sde_encoder_update_rsc_client(
	int pipe = -1;
	int rc = 0;

	if (!drm_enc || !drm_enc->crtc || !drm_enc->dev) {
		SDE_ERROR("invalid arguments\n");
	if (!drm_enc || !drm_enc->dev) {
		SDE_ERROR("invalid encoder arguments\n");
		return -EINVAL;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	crtc = drm_enc->crtc;
	crtc = sde_enc->crtc;

	if (!sde_enc->crtc) {
		SDE_ERROR("invalid crtc parameter\n");
		return -EINVAL;
	}
	disp_info = &sde_enc->disp_info;
	rsc_config = &sde_enc->rsc_config;

@@ -1697,10 +1713,21 @@ static void _sde_encoder_resource_control_rsc_update(
		struct drm_encoder *drm_enc, bool enable)
{
	struct sde_encoder_rsc_config rsc_cfg = { 0 };
	struct sde_encoder_virt *sde_enc;

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

	if (enable) {
		rsc_cfg.inline_rotate_prefill =
				sde_crtc_get_inline_prefill(drm_enc->crtc);
				sde_crtc_get_inline_prefill(sde_enc->crtc);

		_sde_encoder_update_rsc_client(drm_enc, &rsc_cfg, true);
	} else {
@@ -1788,9 +1815,9 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
	int ret;
	bool is_vid_mode = false;

	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
			!drm_enc->crtc) {
		SDE_ERROR("invalid parameters\n");
	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
		SDE_ERROR("invalid encoder parameters, sw_event:%u\n",
				sw_event);
		return -EINVAL;
	}
	sde_enc = to_sde_encoder_virt(drm_enc);
@@ -1798,12 +1825,6 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
	is_vid_mode = sde_enc->disp_info.capabilities &
						MSM_DISPLAY_CAP_VID_MODE;

	if (drm_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
		SDE_ERROR("invalid crtc index\n");
		return -EINVAL;
	}
	disp_thread = &priv->disp_thread[drm_enc->crtc->index];

	/*
	 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
	 * events and return early for other events (ie wb display).
@@ -1877,6 +1898,18 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
		break;

	case SDE_ENC_RC_EVENT_FRAME_DONE:
		if (!sde_enc->crtc) {
			SDE_ERROR("invalid crtc, sw_event:%u\n", sw_event);
			return -EINVAL;
		}

		if (sde_enc->crtc->index >= ARRAY_SIZE(priv->disp_thread)) {
			SDE_ERROR("invalid crtc index :%u\n",
					sde_enc->crtc->index);
			return -EINVAL;
		}
		disp_thread = &priv->disp_thread[sde_enc->crtc->index];

		/*
		 * mutex lock is not used as this event happens at interrupt
		 * context. And locking is not required as, the other events
@@ -1895,7 +1928,7 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
		 * schedule off work item only when there are no
		 * frames pending
		 */
		if (sde_crtc_frame_pending(drm_enc->crtc) > 1) {
		if (sde_crtc_frame_pending(sde_enc->crtc) > 1) {
			SDE_DEBUG_ENC(sde_enc, "skip schedule work");
			SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
				SDE_EVTLOG_FUNC_CASE2);
@@ -2380,6 +2413,16 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc)
		return;
	}

	/*
	 * cache the crtc in sde_enc on enable for duration of use case
	 * for correctly servicing asynchronous irq events and timers
	 */
	if (!drm_enc->crtc) {
		SDE_ERROR("invalid crtc\n");
		return;
	}
	sde_enc->crtc = drm_enc->crtc;

	ret = _sde_encoder_get_mode_info(drm_enc, &mode_info);
	if (ret) {
		SDE_ERROR_ENC(sde_enc, "failed to get mode info\n");
@@ -2539,6 +2582,11 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
	}

	sde_enc->cur_master = NULL;
	/*
	 * clear the cached crtc in sde_enc on use case finish, after all the
	 * outstanding events and timers have been completed
	 */
	sde_enc->crtc = NULL;

	SDE_DEBUG_ENC(sde_enc, "encoder disabled\n");

@@ -3264,12 +3312,7 @@ static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
	ktime_t cur_time;

	sde_enc = to_sde_encoder_virt(drm_enc);

	if (!drm_enc->crtc || !drm_enc->crtc->state) {
		SDE_ERROR("crtc/crtc state object is NULL\n");
		return -EINVAL;
	}
	mode = &drm_enc->crtc->state->adjusted_mode;
	mode = &sde_enc->cur_master->cached_mode;

	line_time = _sde_encoder_calculate_linetime(sde_enc, mode);
	if (!line_time)
@@ -3307,23 +3350,27 @@ static void sde_encoder_vsync_event_handler(unsigned long data)
	struct msm_drm_private *priv;
	struct msm_drm_thread *event_thread;

	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private ||
			!drm_enc->crtc) {
		SDE_ERROR("invalid parameters\n");
	if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) {
		SDE_ERROR("invalid encoder parameters\n");
		return;
	}

	sde_enc = to_sde_encoder_virt(drm_enc);
	priv = drm_enc->dev->dev_private;
	if (!sde_enc->crtc) {
		SDE_ERROR("invalid crtc");
		return;
	}

	if (drm_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
		SDE_ERROR("invalid crtc index\n");
	if (sde_enc->crtc->index >= ARRAY_SIZE(priv->event_thread)) {
		SDE_ERROR("invalid crtc index:%u\n",
				sde_enc->crtc->index);
		return;
	}
	event_thread = &priv->event_thread[drm_enc->crtc->index];
	event_thread = &priv->event_thread[sde_enc->crtc->index];
	if (!event_thread) {
		SDE_ERROR("event_thread not found for crtc:%d\n",
				drm_enc->crtc->index);
				sde_enc->crtc->index);
		return;
	}

+2 −0
Original line number Diff line number Diff line
@@ -379,6 +379,7 @@ struct sde_encoder_phys_cmd {
 * @end_time:		End time of writeback latest request
 * @bo_disable:		Buffer object(s) to use during the disabling state
 * @fb_disable:		Frame buffer to use during the disabling state
 * @crtc		Pointer to drm_crtc
 */
struct sde_encoder_phys_wb {
	struct sde_encoder_phys base;
@@ -403,6 +404,7 @@ struct sde_encoder_phys_wb {
	ktime_t end_time;
	struct drm_gem_object *bo_disable[SDE_MAX_PLANES];
	struct drm_framebuffer *fb_disable;
	struct drm_crtc *crtc;
};

/**
+13 −1
Original line number Diff line number Diff line
@@ -124,7 +124,12 @@ static void sde_encoder_phys_wb_set_qos_remap(
	}

	wb_enc = to_sde_encoder_phys_wb(phys_enc);
	crtc = phys_enc->parent->crtc;
	if (!wb_enc->crtc) {
		SDE_ERROR("invalid crtc");
		return;
	}

	crtc = wb_enc->crtc;

	if (!wb_enc->hw_wb || !wb_enc->hw_wb->caps) {
		SDE_ERROR("invalid writeback hardware\n");
@@ -1141,6 +1146,12 @@ static void sde_encoder_phys_wb_enable(struct sde_encoder_phys *phys_enc)
	wb_enc->wb_dev = sde_wb_connector_get_wb(connector);

	phys_enc->enable_state = SDE_ENC_ENABLED;

	/*
	 * cache the crtc in wb_enc on enable for duration of use case
	 * for correctly servicing asynchronous irq events and timers
	 */
	wb_enc->crtc = phys_enc->parent->crtc;
}

/**
@@ -1186,6 +1197,7 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc)
	sde_encoder_phys_wb_wait_for_commit_done(phys_enc);
exit:
	phys_enc->enable_state = SDE_ENC_DISABLED;
	wb_enc->crtc = NULL;
}

/**