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

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

Merge "drm/msm/shd: fix null atomic state during mode_fixup"

parents dff03ed4 61720f0c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2020, 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
@@ -153,7 +153,7 @@ int sde_core_irq_enable(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count)

	counts = atomic_read(&sde_kms->irq_obj.enable_counts[irq_idxs[0]]);
	if (counts) {
		SDE_ERROR("%pS: irq_idx=%d enable_count=%d\n",
		SDE_DEBUG("%pS: irq_idx=%d enable_count=%d\n",
			__builtin_return_address(0), irq_idxs[0], counts);
		SDE_EVT32(irq_idxs[0], counts, SDE_EVTLOG_ERROR);
	}
@@ -212,7 +212,7 @@ int sde_core_irq_disable(struct sde_kms *sde_kms, int *irq_idxs, u32 irq_count)

	counts = atomic_read(&sde_kms->irq_obj.enable_counts[irq_idxs[0]]);
	if (counts == 2) {
		SDE_ERROR("%pS: irq_idx=%d enable_count=%d\n",
		SDE_DEBUG("%pS: irq_idx=%d enable_count=%d\n",
			__builtin_return_address(0), irq_idxs[0], counts);
		SDE_EVT32(irq_idxs[0], counts, SDE_EVTLOG_ERROR);
	}
+17 −59
Original line number Diff line number Diff line
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2020, 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
@@ -135,56 +135,14 @@ static int _sde_encoder_phys_shd_register_irq(
		enum sde_intr_idx intr_idx,
		bool enable)
{
	struct sde_encoder_irq *irq = &phys_enc->irq[intr_idx];
	int ret = 0;

	SDE_DEBUG("%d enable %d\n", DRMID(phys_enc->parent), enable);

	if (enable) {
		if (irq->irq_idx >= 0) {
			SDE_DEBUG_PHYS(phys_enc,
				"skipping already registered irq %s type %d\n",
				irq->name, irq->intr_type);
			return 0;
		}

		irq->irq_idx = sde_core_irq_idx_lookup(phys_enc->sde_kms,
				irq->intr_type, irq->hw_idx);
		if (irq->irq_idx < 0) {
			SDE_ERROR_PHYS(phys_enc,
				"failed to lookup IRQ index for %s type:%d\n",
				irq->name, irq->intr_type);
			return -EINVAL;
		}

		ret = sde_core_irq_register_callback(phys_enc->sde_kms,
				irq->irq_idx, &irq->cb);
		if (ret) {
			SDE_ERROR_PHYS(phys_enc,
				"failed to register IRQ callback for %s\n",
				irq->name);
			irq->irq_idx = -EINVAL;
		}
	} else {
		if (irq->irq_idx < 0) {
			SDE_DEBUG_PHYS(phys_enc,
				"extra unregister irq, enc%d intr_idx:0x%x\n",
				DRMID(phys_enc->parent), INTR_IDX_VSYNC);
			return 0;
		}

		ret = sde_core_irq_unregister_callback(phys_enc->sde_kms,
				irq->irq_idx, &irq->cb);
		if (ret) {
			SDE_ERROR_PHYS(phys_enc,
				"failed to unregister IRQ callback for %s\n",
				irq->name);
		}

		irq->irq_idx = -EINVAL;
	}

	return ret;
	if (enable)
		return sde_encoder_helper_register_irq(phys_enc,
				INTR_IDX_VSYNC);
	else
		return sde_encoder_helper_unregister_irq(phys_enc,
				INTR_IDX_VSYNC);
}

static inline
@@ -309,7 +267,6 @@ static void sde_encoder_phys_shd_mode_set(
		struct drm_display_mode *adj_mode)
{
	struct drm_connector *connector;
	struct sde_connector *sde_conn;
	struct shd_display *display;
	struct drm_encoder *encoder;
	struct sde_rm_hw_iter iter;
@@ -325,8 +282,7 @@ static void sde_encoder_phys_shd_mode_set(
		return;
	}

	sde_conn = to_sde_connector(connector);
	display = sde_conn->display;
	display = sde_connector_get_display(connector);
	encoder = display->base->encoder;

	if (_sde_encoder_phys_shd_rm_reserve(phys_enc, display))
@@ -570,7 +526,6 @@ static void sde_encoder_phys_shd_single_vblank_wait(

static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)
{
	struct sde_connector *sde_conn;
	struct shd_display *display;
	unsigned long lock_flags;

@@ -595,6 +550,14 @@ static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)

	sde_encoder_helper_reset_mixers(phys_enc, NULL);

	display = sde_connector_get_display(phys_enc->connector);
	if (!display)
		goto next;

	/* if base display is already disabled, skip vsync check */
	if (!display->base->crtc->state->active)
		goto next;

	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
	sde_encoder_phys_shd_trigger_flush(phys_enc);
	sde_encoder_phys_inc_pending(phys_enc);
@@ -602,14 +565,9 @@ static void sde_encoder_phys_shd_disable(struct sde_encoder_phys *phys_enc)

	sde_encoder_phys_shd_single_vblank_wait(phys_enc);

next:
	phys_enc->enable_state = SDE_ENC_DISABLED;

	if (!phys_enc->connector)
		return;

	sde_conn = to_sde_connector(phys_enc->connector);
	display = sde_conn->display;

	_sde_encoder_phys_shd_rm_release(phys_enc, display);

	SDE_EVT32(DRMID(phys_enc->parent),
+84 −385
Original line number Diff line number Diff line
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, 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
@@ -134,6 +134,8 @@ static int shd_display_init_base_encoder(struct drm_device *dev,
				break;
			}
		}
		if (base->encoder)
			break;
	}

	if (!base->encoder) {
@@ -203,317 +205,6 @@ static int shd_display_init_base_crtc(struct drm_device *dev,
	return 0;
}

static void shd_display_setup_base_mixer_out(struct shd_display_base *base)
{
	struct sde_crtc *sde_crtc;
	struct sde_hw_mixer_cfg lm_cfg;
	struct sde_hw_mixer *hw_lm;
	int i;

	sde_crtc = to_sde_crtc(base->crtc);
	if (!sde_crtc->num_mixers) {
		SDE_ERROR("no layer mixer found\n");
		return;
	}

	lm_cfg.out_width = base->mode.hdisplay / sde_crtc->num_mixers;
	lm_cfg.out_height = base->mode.vdisplay;
	lm_cfg.flags = 0;
	for (i = 0; i < sde_crtc->num_mixers; i++) {
		lm_cfg.right_mixer = i;
		hw_lm = sde_crtc->mixers[i].hw_lm;
		hw_lm->cfg.out_width = lm_cfg.out_width;
		hw_lm->cfg.out_height = lm_cfg.out_height;
		hw_lm->cfg.right_mixer = lm_cfg.right_mixer;
		hw_lm->ops.setup_mixer_out(hw_lm, &lm_cfg);
		if (sde_crtc->mixers[i].hw_ctl->ops.clear_all_blendstages)
			sde_crtc->mixers[i].hw_ctl->ops.clear_all_blendstages(
					sde_crtc->mixers[i].hw_ctl);
		if (hw_lm->ops.clear_dim_layer)
			hw_lm->ops.clear_dim_layer(hw_lm);
	}
}

static void shd_display_enable_base(struct drm_device *dev,
				struct shd_display_base *base)
{
	const struct drm_encoder_helper_funcs *enc_funcs;
	const struct drm_connector_helper_funcs *conn_funcs;
	struct drm_connector *connector;
	struct drm_crtc_state *crtc_state;
	struct drm_connector_state *conn_state;
	int ret;

	SDE_DEBUG("enable base display %d\n", base->intf_idx);

	enc_funcs = base->encoder->helper_private;
	if (!enc_funcs) {
		SDE_ERROR("failed to find encoder helper\n");
		return;
	}

	conn_funcs = base->connector->helper_private;
	if (!conn_funcs) {
		SDE_ERROR("failed to find connector helper\n");
		return;
	}

	connector = base->connector;
	crtc_state = base->crtc->state;
	conn_state = connector->state;

	crtc_state->active = true;
	crtc_state->active_changed = true;
	crtc_state->mode_changed = true;
	crtc_state->connectors_changed = true;

	base->encoder->crtc = base->crtc;
	crtc_state->encoder_mask = (1 << drm_encoder_index(base->encoder));

	conn_state->crtc = base->crtc;
	drm_connector_get(connector);
	conn_state->best_encoder = base->encoder;
	connector->encoder = base->encoder;

	ret = drm_atomic_set_mode_for_crtc(crtc_state, &base->mode);
	if (ret) {
		SDE_ERROR("failed to set mode for crtc\n");
		goto out;
	}

	drm_mode_copy(&crtc_state->adjusted_mode, &base->mode);
	drm_mode_copy(&base->crtc->mode, &base->mode);

	if (conn_funcs->atomic_best_encoder) {
		conn_funcs->atomic_best_encoder(base->connector,
			conn_state);
	}

	drm_bridge_mode_fixup(base->encoder->bridge,
		&crtc_state->mode,
		&crtc_state->adjusted_mode);

	if (enc_funcs->atomic_check) {
		enc_funcs->atomic_check(base->encoder,
			crtc_state,
			conn_state);
	}

	if (enc_funcs->mode_fixup) {
		enc_funcs->mode_fixup(base->encoder,
			&crtc_state->mode,
			&crtc_state->adjusted_mode);
	}

	if (enc_funcs->mode_set) {
		enc_funcs->mode_set(base->encoder,
			&crtc_state->mode,
			&crtc_state->adjusted_mode);
	}

	sde_crtc_update_cont_splash_settings(base->crtc);

	shd_display_setup_base_mixer_out(base);

	drm_bridge_mode_set(base->encoder->bridge,
		&crtc_state->mode,
		&crtc_state->adjusted_mode);

	drm_bridge_pre_enable(base->encoder->bridge);

	if (enc_funcs->enable)
		enc_funcs->enable(base->encoder);

	sde_encoder_kickoff(base->encoder, false);

	drm_bridge_enable(base->encoder->bridge);

	base->enabled = true;
	base->enable_changed = true;
out:
	return;
}

static void shd_display_disable_base(struct drm_device *dev,
						struct shd_display_base *base)
{
	const struct drm_encoder_helper_funcs *enc_funcs;

	SDE_DEBUG("disable base display %d\n", base->intf_idx);

	enc_funcs = base->encoder->helper_private;
	if (!enc_funcs) {
		SDE_ERROR("failed to find encoder helper\n");
		return;
	}

	drm_bridge_disable(base->encoder->bridge);

	if (enc_funcs->disable)
		enc_funcs->disable(base->encoder);

	drm_bridge_post_disable(base->encoder->bridge);

	base->enabled = false;
	base->connector->state->crtc = NULL;
	base->connector->state->best_encoder = NULL;
	drm_connector_put(base->connector);
}

static void shd_display_enable(struct shd_display *display)
{
	struct drm_device *dev = display->drm_dev;
	struct shd_display_base *base = display->base;

	SDE_DEBUG("enable %s conn %d\n", display->name,
					DRMID(base->connector));

	mutex_lock(&base->base_mutex);

	display->enabled = true;
	display->enable_changed = true;

	if (!base->enabled)
		shd_display_enable_base(dev, base);

	mutex_unlock(&base->base_mutex);
}

static void shd_display_disable(struct shd_display *display)
{
	struct drm_device *dev = display->drm_dev;
	struct shd_display_base *base = display->base;
	struct shd_display *p;
	bool enabled = false;

	SDE_DEBUG("disable %s conn %d\n", display->name,
					DRMID(base->connector));

	mutex_lock(&base->base_mutex);

	display->enabled = false;

	if (!base->enabled)
		goto end;

	list_for_each_entry(p, &base->disp_list, head) {
		if (p->enabled) {
			enabled = true;
			break;
		}
	}

	if (!enabled)
		shd_display_disable_base(dev, base);

end:
	mutex_unlock(&base->base_mutex);
}

static void shd_display_complete(struct sde_kms *sde_kms,
		struct shd_display *display)
{
	if (display->enable_changed) {
		struct shd_display_base *base = display->base;

		display->enable_changed = false;

		mutex_lock(&base->base_mutex);

		if (base->enable_changed) {
			base->enable_changed = false;
			sde_kms_release_splash_resource(sde_kms, base->crtc);

			/*
			 * Base display is invisible to both user space
			 * and kernel, here we mark all state as inactive
			 * to avoid update from suspend and resume.
			 */
			base->crtc->enabled = false;
			drm_atomic_set_mode_prop_for_crtc(base->crtc->state,
					NULL);
			base->crtc->state->active = false;
			base->connector->state->crtc = NULL;
			base->connector->state->best_encoder = NULL;
		}

		mutex_unlock(&base->base_mutex);
	}
}

static int shd_display_pm_suspend(struct device *dev)
{
	struct drm_device *ddev;
	struct drm_crtc_state *crtc_state;
	struct drm_connector_state *conn_state;
	struct sde_kms *sde_kms;
	struct shd_display_base *base;
	struct drm_atomic_state *state;
	struct drm_atomic_state *suspend_state;
	int ret;

	if (!dev)
		return -EINVAL;

	ret = g_shd_kms->orig_funcs->pm_suspend(dev);
	if (ret)
		return ret;

	ddev = dev_get_drvdata(dev);
	if (!ddev || !ddev_to_msm_kms(ddev))
		return -EINVAL;

	sde_kms = to_sde_kms(ddev_to_msm_kms(ddev));

	state = drm_atomic_state_alloc(ddev);
	if (!state)
		return -ENOMEM;

	suspend_state = sde_kms->suspend_state;

	/* initialize connectors structure */
	state->connectors = kcalloc(suspend_state->num_connector,
			sizeof(*state->connectors), GFP_KERNEL);
	if (!state->connectors) {
		ret = -ENOMEM;
		goto clear;
	}
	state->num_connector = suspend_state->num_connector;

	/*
	 * move base states to temp state and clear later
	 */
	list_for_each_entry(base, &g_base_list, head) {
		crtc_state = drm_atomic_get_existing_crtc_state(
			suspend_state, base->crtc);
		if (crtc_state) {
			int index = drm_crtc_index(base->crtc);

			state->crtcs[index] =
				suspend_state->crtcs[index];
			memset(&suspend_state->crtcs[index],
				0, sizeof(*suspend_state->crtcs));
		}

		conn_state = drm_atomic_get_existing_connector_state(
			suspend_state, base->connector);
		if (conn_state) {
			int index = drm_connector_index(base->connector);

			state->connectors[index] =
				suspend_state->connectors[index];
			memset(&suspend_state->connectors[index],
				0, sizeof(*suspend_state->connectors));
		}
	}

clear:
	/* clear base states */
	drm_atomic_state_put(state);

	return ret;
}

static int shd_crtc_validate_shared_display(struct drm_crtc *crtc,
		struct drm_crtc_state *state)
{
@@ -662,98 +353,112 @@ void shd_skip_shared_plane_update(struct drm_plane *plane,
			sde_crtc->mixers[i].hw_ctl, sspp, is_virtual);
}

static void shd_display_prepare_commit(struct msm_kms *kms,
static int shd_display_atomic_check(struct msm_kms *kms,
		struct drm_atomic_state *state)
{
	struct msm_drm_private *priv;
	struct drm_crtc *crtc;
	struct drm_crtc_state *crtc_state;
	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
	struct drm_connector_state *conn_state;
	struct sde_crtc *sde_crtc;
	struct shd_crtc *shd_crtc;
	struct sde_kms *sde_kms;
	struct drm_device *dev;
	struct msm_drm_private *priv;
	int i;

	if (!kms)
		return;
	sde_kms = to_sde_kms(kms);
	dev = sde_kms->dev;

	if (!dev || !dev->dev_private)
		return;
	priv = dev->dev_private;

	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);

	if (sde_kms->first_kickoff) {
		sde_power_scale_reg_bus(&priv->phandle, sde_kms->core_client,
			VOTE_INDEX_HIGH, false);
		sde_kms->first_kickoff = false;
	}
	struct shd_display *display;
	struct shd_display_base *base;
	u32 base_mask = 0, enable_mask = 0, disable_mask = 0;
	u32 crtc_mask, active_mask;
	bool active;
	int i, rc;

	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
			new_crtc_state, i) {
		if (crtc->helper_private->atomic_check !=
				shd_crtc_atomic_check)
			continue;

		if (!crtc_state->active ||
		    !drm_atomic_crtc_needs_modeset(crtc_state))
		if (old_crtc_state->active == new_crtc_state->active)
			continue;

		sde_crtc = to_sde_crtc(crtc);
		shd_crtc = sde_crtc->priv_handle;
		shd_display_enable(shd_crtc->display);
		base = shd_crtc->display->base;
		base_mask |= drm_crtc_mask(base->crtc);

		if (new_crtc_state->active)
			enable_mask |= drm_crtc_mask(crtc);
		else
			disable_mask |= drm_crtc_mask(crtc);
	}

	g_shd_kms->orig_funcs->prepare_commit(kms, state);
	if (!base_mask)
		return g_shd_kms->orig_funcs->atomic_check(kms, state);

	/*
	 * If base display need to be enabled/disabled, add state
	 * changes to the same atomic state. As base crtc is always
	 * ahead of shared crtc in the crtc list, base crtc is
	 * enabled/disabled before shared crtcs.
	 */
	list_for_each_entry(base, &g_base_list, head) {
		if (!(drm_crtc_mask(base->crtc) & base_mask))
			continue;

	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
		/* read old crtc state from all shared displays */
		crtc_mask = active_mask = 0;
		list_for_each_entry(display, &base->disp_list, head) {
			crtc_mask |= drm_crtc_mask(display->crtc);
			if (display->crtc->state->active)
				active_mask |= drm_crtc_mask(display->crtc);
		}

static void shd_display_complete_commit(struct msm_kms *kms,
		struct drm_atomic_state *state)
{
	struct drm_crtc *crtc;
	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
	struct sde_crtc *sde_crtc;
	struct shd_crtc *shd_crtc;
	struct sde_kms *sde_kms;
	struct drm_device *dev;
	struct msm_drm_private *priv;
	int i;
		/* apply changes in state */
		active_mask |= (enable_mask & crtc_mask);
		active_mask &= ~disable_mask;
		active = !!active_mask;

	if (!kms)
		return;
	sde_kms = to_sde_kms(kms);
	dev = sde_kms->dev;
		/* skip if there is no change */
		if (base->crtc->state->active == active)
			continue;

	if (!dev || !dev->dev_private)
		return;
	priv = dev->dev_private;
		new_crtc_state = drm_atomic_get_crtc_state(state,
				base->crtc);
		if (IS_ERR(new_crtc_state))
			return PTR_ERR(new_crtc_state);

	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, true);
		new_crtc_state->active = active;

	g_shd_kms->orig_funcs->complete_commit(kms, state);
		conn_state = drm_atomic_get_connector_state(state,
				base->connector);
		if (IS_ERR(conn_state))
			return PTR_ERR(conn_state);

	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
						new_crtc_state, i) {
		if (crtc->helper_private->atomic_check !=
				shd_crtc_atomic_check)
			continue;
		rc = drm_atomic_set_mode_for_crtc(new_crtc_state,
				active ? &base->mode : NULL);
		if (rc) {
			SDE_ERROR("failed to set mode for crtc\n");
			return rc;
		}

		sde_crtc = to_sde_crtc(crtc);
		shd_crtc = sde_crtc->priv_handle;
		shd_display_complete(sde_kms, shd_crtc->display);
		rc = drm_atomic_set_crtc_for_connector(conn_state,
				active ? base->crtc : NULL);
		if (rc) {
			SDE_ERROR("failed to set crtc for connector\n");
			return rc;
		}
	}

		if (!old_crtc_state->active ||
		    new_crtc_state->active ||
		    !drm_atomic_crtc_needs_modeset(new_crtc_state))
			continue;
	rc = g_shd_kms->orig_funcs->atomic_check(kms, state);
	if (rc)
		return rc;

		shd_display_disable(shd_crtc->display);
	}
	/* wait if there is base thread running */
	priv = state->dev->dev_private;
	spin_lock(&priv->pending_crtcs_event.lock);
	wait_event_interruptible_locked(
			priv->pending_crtcs_event,
			!(priv->pending_crtcs & base_mask));
	spin_unlock(&priv->pending_crtcs_event.lock);

	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
	return 0;
}

static int shd_connector_get_info(struct drm_connector *connector,
@@ -815,13 +520,11 @@ enum drm_connector_status shd_connector_detect(struct drm_connector *conn,
		goto end;
	}

	mutex_lock(&disp->base->base_mutex);
	if (disp->base->connector) {
		sde_conn = to_sde_connector(disp->base->connector);
		status = disp->base->ops.detect(disp->base->connector,
						force, sde_conn->display);
	}
	mutex_unlock(&disp->base->base_mutex);

end:
	return status;
@@ -1128,6 +831,7 @@ static int shd_drm_obj_init(struct shd_display *display)
	sde_crtc->priv_handle = shd_crtc;
	crtc->helper_private = &shd_crtc->helper_funcs;
	crtc->funcs = &shd_crtc->funcs;
	display->crtc = crtc;

	/* initialize display thread */
	i = priv->num_crtcs - 1;
@@ -1210,9 +914,7 @@ static int shd_drm_base_init(struct drm_device *ddev,
		g_shd_kms = kzalloc(sizeof(*g_shd_kms), GFP_KERNEL);
		g_shd_kms->funcs = *priv->kms->funcs;
		g_shd_kms->orig_funcs = priv->kms->funcs;
		g_shd_kms->funcs.prepare_commit = shd_display_prepare_commit;
		g_shd_kms->funcs.complete_commit = shd_display_complete_commit;
		g_shd_kms->funcs.pm_suspend = shd_display_pm_suspend;
		g_shd_kms->funcs.atomic_check = shd_display_atomic_check;
		priv->kms->funcs = &g_shd_kms->funcs;
	}

@@ -1500,7 +1202,6 @@ static int sde_shd_probe(struct platform_device *pdev)
		goto error;
	}

	mutex_init(&base->base_mutex);
	INIT_LIST_HEAD(&base->disp_list);
	base->of_node = shd_dev->base_of;

@@ -1556,11 +1257,9 @@ static int sde_shd_remove(struct platform_device *pdev)
	if (!shd_dev)
		return 0;

	mutex_lock(&shd_dev->base->base_mutex);
	list_del_init(&shd_dev->head);
	if (list_empty(&shd_dev->base->disp_list))
		list_del_init(&shd_dev->base->head);
	mutex_unlock(&shd_dev->base->base_mutex);

	platform_set_drvdata(pdev, NULL);

+2 −8
Original line number Diff line number Diff line
/*
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2018-2020, 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
@@ -35,7 +35,6 @@ struct shd_stage_range {
};

struct shd_display_base {
	struct mutex           base_mutex;
	struct drm_display_mode mode;
	struct drm_crtc       *crtc;
	struct drm_encoder    *encoder;
@@ -48,8 +47,6 @@ struct shd_display_base {
	int intf_idx;
	int connector_type;
	bool mst_port;
	bool enabled;
	bool enable_changed;
};

struct shd_display {
@@ -67,11 +64,8 @@ struct shd_display {
	struct shd_stage_range stage_range;

	struct platform_device *pdev;
	struct completion vsync_comp;
	struct list_head head;

	bool enabled;
	bool enable_changed;
	struct drm_crtc *crtc;
};

/* drm internal header */