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

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

Merge changes I86a655d3,Ieeb0fbf3 into dev/msm-4.14-display

* changes:
  drm/msm: add sde recovery dump data support
  drm/msm/sde: add support for hw recovery event notification
parents e0f66106 f8338fed
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -2220,6 +2220,23 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
	return ERR_PTR(rc);
}

static int _sde_conn_hw_recovery_handler(
		struct drm_connector *connector, bool val)
{
	struct sde_connector *c_conn;

	if (!connector) {
		SDE_ERROR("invalid connector\n");
		return -EINVAL;
	}
	c_conn = to_sde_connector(connector);

	if (c_conn->encoder)
		sde_encoder_recovery_events_handler(c_conn->encoder, val);

	return 0;
}

int sde_connector_register_custom_event(struct sde_kms *kms,
		struct drm_connector *conn_drm, u32 event, bool val)
{
@@ -2232,8 +2249,46 @@ int sde_connector_register_custom_event(struct sde_kms *kms,
	case DRM_EVENT_PANEL_DEAD:
		ret = 0;
		break;
	case DRM_EVENT_SDE_HW_RECOVERY:
		ret = _sde_conn_hw_recovery_handler(conn_drm, val);
		break;
	default:
		break;
	}
	return ret;
}

int sde_connector_event_notify(struct drm_connector *connector, uint32_t type,
		uint32_t len, uint32_t val)
{
	struct drm_event event;
	int ret;

	if (!connector) {
		SDE_ERROR("invalid connector\n");
		return -EINVAL;
	}

	switch (type) {
	case DRM_EVENT_SYS_BACKLIGHT:
	case DRM_EVENT_PANEL_DEAD:
	case DRM_EVENT_SDE_HW_RECOVERY:
		ret = 0;
		break;
	default:
		SDE_ERROR("connector %d, Unsupported event %d\n",
				connector->base.id, type);
		return -EINVAL;
	}

	event.type = type;
	event.length = len;
	msm_mode_object_event_notify(&connector->base, connector->dev, &event,
			(u8 *)&val);

	SDE_EVT32(connector->base.id, type, len, val);
	SDE_DEBUG("connector:%d hw recovery event(%d) value (%d) notified\n",
			connector->base.id, type, val);

	return ret;
}
+10 −0
Original line number Diff line number Diff line
@@ -817,4 +817,14 @@ void sde_connector_helper_bridge_disable(struct drm_connector *connector);
 */
void sde_connector_destroy(struct drm_connector *connector);

/**
 * sde_connector_event_notify - signal hw recovery event to client
 * @connector: pointer to connector
 * @type:     event type
 * @len:     length of the value of the event
 * @val:     value
 */
int sde_connector_event_notify(struct drm_connector *connector, uint32_t type,
		uint32_t len, uint32_t val);

#endif /* _SDE_CONNECTOR_H_ */
+12 −12
Original line number Diff line number Diff line
@@ -3434,11 +3434,12 @@ static void _sde_crtc_remove_pipe_flush(struct drm_crtc *crtc)
 * _sde_crtc_reset_hw - attempt hardware reset on errors
 * @crtc: Pointer to DRM crtc instance
 * @old_state: Pointer to crtc state for previous commit
 * @dump_status: Whether or not to dump debug status before reset
 * @recovery_events: Whether or not recovery events are enabled
 * Returns: Zero if current commit should still be attempted
 */
static int _sde_crtc_reset_hw(struct drm_crtc *crtc,
		struct drm_crtc_state *old_state, bool dump_status)
		struct drm_crtc_state *old_state,
		bool recovery_events)
{
	struct drm_plane *plane_halt[MAX_PLANES];
	struct drm_plane *plane;
@@ -3458,10 +3459,7 @@ static int _sde_crtc_reset_hw(struct drm_crtc *crtc,

	old_rot_op_mode = to_sde_crtc_state(old_state)->sbuf_cfg.rot_op_mode;
	SDE_EVT32(DRMID(crtc), old_rot_op_mode,
			dump_status, SDE_EVTLOG_FUNC_ENTRY);

	if (dump_status)
		SDE_DBG_DUMP("all", "dbg_bus", "vbif_dbg_bus");
			recovery_events, SDE_EVTLOG_FUNC_ENTRY);

	/* optionally generate a panic instead of performing a h/w reset */
	SDE_DBG_CTRL("stop_ftrace", "reset_hw_panic");
@@ -3493,7 +3491,7 @@ static int _sde_crtc_reset_hw(struct drm_crtc *crtc,
	 */
	if (i == sde_crtc->num_ctls &&
			old_rot_op_mode == SDE_CTL_ROT_OP_MODE_OFFLINE)
		return false;
		return 0;

	SDE_DEBUG("crtc%d: issuing hard reset\n", DRMID(crtc));

@@ -3570,7 +3568,8 @@ static int _sde_crtc_reset_hw(struct drm_crtc *crtc,
			sde_encoder_kickoff(encoder, false);
	}

	return -EAGAIN;
	/* panic the device if VBIF is not in good state */
	return !recovery_events ? 0 : -EAGAIN;
}

/**
@@ -3637,7 +3636,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
	struct msm_drm_private *priv;
	struct sde_kms *sde_kms;
	struct sde_crtc_state *cstate;
	bool is_error, reset_req;
	bool is_error, reset_req, recovery_events;

	if (!crtc) {
		SDE_ERROR("invalid argument\n");
@@ -3683,6 +3682,9 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
				crtc->state);
		if (sde_encoder_prepare_for_kickoff(encoder, &params))
			reset_req = true;

		recovery_events =
			sde_encoder_recovery_events_enabled(encoder);
	}

	/*
@@ -3690,11 +3692,9 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
	 * preparing for the kickoff
	 */
	if (reset_req) {
		if (_sde_crtc_reset_hw(crtc, old_state,
					!sde_crtc->reset_request))
		if (_sde_crtc_reset_hw(crtc, old_state, recovery_events))
			is_error = true;
	}
	sde_crtc->reset_request = reset_req;

	SDE_ATRACE_BEGIN("flush_event_thread");
	_sde_crtc_flush_event_thread(crtc);
+0 −3
Original line number Diff line number Diff line
@@ -143,8 +143,6 @@ struct sde_crtc_event {
 * @enabled       : whether the SDE CRTC is currently enabled. updated in the
 *                  commit-thread, not state-swap time which is earlier, so
 *                  safe to make decisions on during VBLANK on/off work
 * @reset_request : whether or not a h/w request was requested for the previous
 *                  frame
 * @ds_reconfig   : force reconfiguration of the destination scaler block
 * @feature_list  : list of color processing features supported on a crtc
 * @active_list   : list of color processing features are active
@@ -208,7 +206,6 @@ struct sde_crtc {
	bool vblank_requested;
	bool suspend;
	bool enabled;
	bool reset_request;

	bool ds_reconfig;
	struct list_head feature_list;
+31 −0
Original line number Diff line number Diff line
@@ -216,6 +216,7 @@ enum sde_enc_rc_states {
 * @cur_conn_roi:		current connector roi
 * @prv_conn_roi:		previous connector roi to optimize if unchanged
 * @crtc			pointer to drm_crtc
 * @recovery_events_enabled:	status of hw recovery feature enable by client
 */
struct sde_encoder_virt {
	struct drm_encoder base;
@@ -265,6 +266,8 @@ struct sde_encoder_virt {
	struct sde_rect cur_conn_roi;
	struct sde_rect prv_conn_roi;
	struct drm_crtc *crtc;

	bool recovery_events_enabled;
};

#define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base)
@@ -5243,3 +5246,31 @@ int sde_encoder_display_failure_notification(struct drm_encoder *enc)

	return 0;
}

bool sde_encoder_recovery_events_enabled(struct drm_encoder *encoder)
{
	struct sde_encoder_virt *sde_enc;

	if (!encoder) {
		SDE_ERROR("invalid drm enc\n");
		return false;
	}

	sde_enc = to_sde_encoder_virt(encoder);

	return sde_enc->recovery_events_enabled;
}

void sde_encoder_recovery_events_handler(struct drm_encoder *encoder,
		bool enabled)
{
	struct sde_encoder_virt *sde_enc;

	if (!encoder) {
		SDE_ERROR("invalid drm enc\n");
		return;
	}

	sde_enc = to_sde_encoder_virt(encoder);
	sde_enc->recovery_events_enabled = enabled;
}
Loading