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

Commit 41e653b9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "disp: msm: sde: add msm_preclose operation as part of msm_release"

parents 5a29ee8c 721d4f1a
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -1497,6 +1497,13 @@ static int msm_release(struct inode *inode, struct file *filp)
		kfree(node);
	}

	/**
	 * Handle preclose operation here for removing fb's whose
	 * refcount > 1. This operation is not triggered from upstream
	 * drm as msm_driver does not support DRIVER_LEGACY feature.
	 */
	msm_preclose(dev, file_priv);

	return drm_release(inode, filp);
}

@@ -1657,7 +1664,6 @@ static struct drm_driver msm_driver = {
				DRIVER_ATOMIC |
				DRIVER_MODESET,
	.open               = msm_open,
	.preclose           = msm_preclose,
	.postclose          = msm_postclose,
	.lastclose          = msm_lastclose,
	.irq_handler        = msm_irq,
+6 −7
Original line number Diff line number Diff line
@@ -2480,17 +2480,16 @@ static void _sde_crtc_set_input_fence_timeout(struct sde_crtc_state *cstate)
	cstate->input_fence_timeout_ns *= NSEC_PER_MSEC;
}

/**
 * _sde_crtc_clear_dim_layers_v1 - clear all dim layer settings
 * @cstate:      Pointer to sde crtc state
 */
static void _sde_crtc_clear_dim_layers_v1(struct sde_crtc_state *cstate)
void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state)
{
	u32 i;
	struct sde_crtc_state *cstate;

	if (!cstate)
	if (!state)
		return;

	cstate = to_sde_crtc_state(state);

	for (i = 0; i < cstate->num_dim_layers; i++)
		memset(&cstate->dim_layer[i], 0, sizeof(cstate->dim_layer[i]));

@@ -2519,7 +2518,7 @@ static void _sde_crtc_set_dim_layer_v1(struct drm_crtc *crtc,

	if (!usr_ptr) {
		/* usr_ptr is null when setting the default property value */
		_sde_crtc_clear_dim_layers_v1(cstate);
		_sde_crtc_clear_dim_layers_v1(&cstate->base);
		SDE_DEBUG("dim_layer data removed\n");
		return;
	}
+6 −0
Original line number Diff line number Diff line
@@ -861,6 +861,12 @@ void sde_crtc_get_misr_info(struct drm_crtc *crtc,
int sde_crtc_get_num_datapath(struct drm_crtc *crtc,
		struct drm_connector *connector);

/**
 * _sde_crtc_clear_dim_layers_v1 - clear all dim layer settings
 * @cstate:      Pointer to drm crtc state
 */
void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state);

/*
 * sde_crtc_set_compression_ratio - set compression ratio src_bpp/target_bpp
 * @msm_mode_info: Mode info
+64 −35
Original line number Diff line number Diff line
@@ -2031,6 +2031,48 @@ static void sde_kms_destroy(struct msm_kms *kms)
	kfree(sde_kms);
}

static int sde_kms_set_crtc_for_conn(struct drm_device *dev,
		struct drm_encoder *enc, struct drm_atomic_state *state)
{
	struct drm_connector *conn = NULL;
	struct drm_connector *tmp_conn = NULL;
	struct drm_connector_list_iter conn_iter;
	struct drm_crtc_state *crtc_state = NULL;
	struct drm_connector_state *conn_state = NULL;
	int ret = 0;

	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(tmp_conn, &conn_iter) {
		if (enc == tmp_conn->state->best_encoder) {
			conn = tmp_conn;
			break;
		}
	}
	drm_connector_list_iter_end(&conn_iter);

	if (!conn) {
		SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc));
		return -EINVAL;
	}

	crtc_state = drm_atomic_get_crtc_state(state, enc->crtc);
	conn_state = drm_atomic_get_connector_state(state, conn);
	if (IS_ERR(conn_state)) {
		SDE_ERROR("error %d getting connector %d state\n",
				ret, DRMID(conn));
		return -EINVAL;
	}

	crtc_state->active = true;
	ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc);
	if (ret)
		SDE_ERROR("error %d setting the crtc\n", ret);

	_sde_crtc_clear_dim_layers_v1(crtc_state);

	return 0;
}

static void _sde_kms_plane_force_remove(struct drm_plane *plane,
			struct drm_atomic_state *state)
{
@@ -2062,8 +2104,9 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file,
	struct drm_framebuffer *fb, *tfb;
	struct list_head fbs;
	struct drm_plane *plane;
	struct drm_crtc *crtc = NULL;
	unsigned int crtc_mask = 0;
	int ret = 0;
	u32 plane_mask = 0;

	INIT_LIST_HEAD(&fbs);

@@ -2072,9 +2115,11 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file,
			list_move_tail(&fb->filp_head, &fbs);

			drm_for_each_plane(plane, dev) {
				if (plane->fb == fb) {
					plane_mask |=
						1 << drm_plane_index(plane);
				if (plane->state &&
					plane->state->fb == fb) {
					if (plane->state->crtc)
						crtc_mask |= drm_crtc_mask(
							plane->state->crtc);
					 _sde_kms_plane_force_remove(
								plane, state);
				}
@@ -2087,11 +2132,22 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file,

	if (list_empty(&fbs)) {
		SDE_DEBUG("skip commit as no fb(s)\n");
		drm_atomic_state_put(state);
		return 0;
	}

	SDE_DEBUG("committing after removing all the pipes\n");
	drm_for_each_crtc(crtc, dev) {
		if ((crtc_mask & drm_crtc_mask(crtc)) && crtc->state->active) {
			struct drm_encoder *drm_enc;

			drm_for_each_encoder_mask(drm_enc, crtc->dev,
					crtc->state->encoder_mask)
				ret = sde_kms_set_crtc_for_conn(
					dev, drm_enc, state);
		}
	}

	SDE_EVT32(state, crtc_mask);
	SDE_DEBUG("null commit after removing all the pipes\n");
	ret = drm_atomic_commit(state);

	if (ret) {
@@ -2746,12 +2802,7 @@ static void _sde_kms_null_commit(struct drm_device *dev,
		struct drm_encoder *enc)
{
	struct drm_modeset_acquire_ctx ctx;
	struct drm_connector *conn = NULL;
	struct drm_connector *tmp_conn = NULL;
	struct drm_connector_list_iter conn_iter;
	struct drm_atomic_state *state = NULL;
	struct drm_crtc_state *crtc_state = NULL;
	struct drm_connector_state *conn_state = NULL;
	int retry_cnt = 0;
	int ret = 0;

@@ -2775,32 +2826,10 @@ static void _sde_kms_null_commit(struct drm_device *dev,
	}

	state->acquire_ctx = &ctx;
	drm_connector_list_iter_begin(dev, &conn_iter);
	drm_for_each_connector_iter(tmp_conn, &conn_iter) {
		if (enc == tmp_conn->state->best_encoder) {
			conn = tmp_conn;
			break;
		}
	}
	drm_connector_list_iter_end(&conn_iter);

	if (!conn) {
		SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc));
		goto end;
	}

	crtc_state = drm_atomic_get_crtc_state(state, enc->crtc);
	conn_state = drm_atomic_get_connector_state(state, conn);
	if (IS_ERR(conn_state)) {
		SDE_ERROR("error %d getting connector %d state\n",
				ret, DRMID(conn));
		goto end;
	}

	crtc_state->active = true;
	ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc);
	ret = sde_kms_set_crtc_for_conn(dev, enc, state);
	if (ret)
		SDE_ERROR("error %d setting the crtc\n", ret);
		goto end;

	ret = drm_atomic_commit(state);
	if (ret)