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

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

Merge changes If6f92b3f,Ied7d9010 into msm-4.14

* changes:
  drm/msm/sde: fix the crash in sde connector destroy
  drm/msm: add new connector ops and mst cap in sde
parents 285008ac 3d2019e9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ enum msm_display_compression_type {
 * @MSM_DISPLAY_CAP_HOT_PLUG:           Hot plug detection supported
 * @MSM_DISPLAY_CAP_EDID:               EDID supported
 * @MSM_DISPLAY_ESD_ENABLED:            ESD feature enabled
 * @MSM_DISPLAY_CAP_MST_MODE:           Display with MST support
 */
enum msm_display_caps {
	MSM_DISPLAY_CAP_VID_MODE	= BIT(0),
@@ -232,6 +233,7 @@ enum msm_display_caps {
	MSM_DISPLAY_CAP_HOT_PLUG	= BIT(2),
	MSM_DISPLAY_CAP_EDID		= BIT(3),
	MSM_DISPLAY_ESD_ENABLED		= BIT(4),
	MSM_DISPLAY_CAP_MST_MODE	= BIT(5),
};

/**
+55 −3
Original line number Diff line number Diff line
@@ -638,7 +638,7 @@ int sde_connector_clk_ctrl(struct drm_connector *connector, bool enable)
	return rc;
}

static void sde_connector_destroy(struct drm_connector *connector)
void sde_connector_destroy(struct drm_connector *connector)
{
	struct sde_connector *c_conn;

@@ -665,7 +665,6 @@ static void sde_connector_destroy(struct drm_connector *connector)
		drm_property_blob_put(c_conn->blob_mode_info);
	if (c_conn->blob_ext_hdr)
		drm_property_blob_put(c_conn->blob_ext_hdr);
	msm_property_destroy(&c_conn->property_info);

	if (c_conn->bl_device)
		backlight_device_unregister(c_conn->bl_device);
@@ -673,6 +672,7 @@ static void sde_connector_destroy(struct drm_connector *connector)
	mutex_destroy(&c_conn->lock);
	sde_fence_deinit(&c_conn->retire_fence);
	drm_connector_cleanup(connector);
	msm_property_destroy(&c_conn->property_info);
	kfree(c_conn);
}

@@ -1638,6 +1638,46 @@ sde_connector_best_encoder(struct drm_connector *connector)
	return c_conn->encoder;
}

static struct drm_encoder *
sde_connector_atomic_best_encoder(struct drm_connector *connector,
		struct drm_connector_state *connector_state)
{
	struct sde_connector *c_conn;
	struct drm_encoder *encoder = NULL;

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

	c_conn = to_sde_connector(connector);

	if (c_conn->ops.atomic_best_encoder)
		encoder = c_conn->ops.atomic_best_encoder(connector,
				c_conn->display, connector_state);

	return encoder;
}

static int sde_connector_atomic_check(struct drm_connector *connector,
		struct drm_connector_state *new_conn_state)
{
	struct sde_connector *c_conn;

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

	c_conn = to_sde_connector(connector);

	if (c_conn->ops.atomic_check)
		return c_conn->ops.atomic_check(connector,
				c_conn->display, new_conn_state);

	return 0;
}

static void sde_connector_check_status_work(struct work_struct *work)
{
	struct sde_connector *conn;
@@ -1694,6 +1734,14 @@ static const struct drm_connector_helper_funcs sde_connector_helper_ops = {
	.best_encoder = sde_connector_best_encoder,
};

static const struct drm_connector_helper_funcs sde_connector_helper_ops_v2 = {
	.get_modes =    sde_connector_get_modes,
	.mode_valid =   sde_connector_mode_valid,
	.best_encoder = sde_connector_best_encoder,
	.atomic_best_encoder = sde_connector_atomic_best_encoder,
	.atomic_check = sde_connector_atomic_check,
};

static int sde_connector_populate_mode_info(struct drm_connector *conn,
	struct sde_kms_info *info)
{
@@ -1918,7 +1966,11 @@ struct drm_connector *sde_connector_init(struct drm_device *dev,
	if (ops)
		c_conn->ops = *ops;

	if (ops && ops->atomic_best_encoder && ops->atomic_check)
		c_conn->base.helper_private = &sde_connector_helper_ops_v2;
	else
		c_conn->base.helper_private = &sde_connector_helper_ops;

	c_conn->base.polled = connector_poll;
	c_conn->base.interlace_allowed = 0;
	c_conn->base.doublescan_allowed = 0;
+30 −0
Original line number Diff line number Diff line
@@ -270,6 +270,28 @@ struct sde_connector_ops {
	int (*config_hdr)(struct drm_connector *connector, void *display,
		struct sde_connector_state *c_state);

	/**
	 * atomic_best_encoder - atomic best encoder selection for connector
	 * @connector: Pointer to drm connector structure
	 * @display: Pointer to private display handle
	 * @c_state: Pointer to connector state
	 * Returns: valid drm_encoder for success
	 */
	struct drm_encoder *(*atomic_best_encoder)(
			struct drm_connector *connector,
			void *display,
			struct drm_connector_state *c_state);

	/**
	 * atomic_check - atomic check handling for connector
	 * @connector: Pointer to drm connector structure
	 * @display: Pointer to private display handle
	 * @c_state: Pointer to connector state
	 * Returns: valid drm_encoder for success
	 */
	int (*atomic_check)(struct drm_connector *connector,
			void *display,
			struct drm_connector_state *c_state);
};

/**
@@ -305,6 +327,7 @@ struct sde_connector_evt {
 * @panel: Pointer to drm panel, if present
 * @display: Pointer to private display data structure
 * @drv_panel: Pointer to interface driver's panel module, if present
 * @mst_port: Pointer to mst port, if present
 * @mmu_secure: MMU id for secure buffers
 * @mmu_unsecure: MMU id for unsecure buffers
 * @name: ASCII name of connector
@@ -341,6 +364,7 @@ struct sde_connector {
	struct drm_panel *panel;
	void *display;
	void *drv_panel;
	void *mst_port;

	struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX];

@@ -763,4 +787,10 @@ void sde_conn_timeline_status(struct drm_connector *conn);
 */
void sde_connector_helper_bridge_disable(struct drm_connector *connector);

/**
 * sde_connector_destroy - destroy drm connector object
 * @connector: Pointer to DRM connector object
 */
void sde_connector_destroy(struct drm_connector *connector);

#endif /* _SDE_CONNECTOR_H_ */
+4 −1
Original line number Diff line number Diff line
@@ -4505,6 +4505,9 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc,
		*drm_enc_mode = DRM_MODE_ENCODER_TMDS;
		intf_type = INTF_HDMI;
	} else if (disp_info->intf_type == DRM_MODE_CONNECTOR_DisplayPort) {
		if (disp_info->capabilities & MSM_DISPLAY_CAP_MST_MODE)
			*drm_enc_mode = DRM_MODE_ENCODER_DPMST;
		else
			*drm_enc_mode = DRM_MODE_ENCODER_TMDS;
		intf_type = INTF_DP;
	} else if (disp_info->intf_type == DRM_MODE_CONNECTOR_VIRTUAL) {
+5 −1
Original line number Diff line number Diff line
@@ -856,11 +856,14 @@ static int _sde_kms_get_displays(struct sde_kms *sde_kms)
		sde_kms->dp_display_count =
			dp_display_get_displays(sde_kms->dp_displays,
					sde_kms->dp_display_count);

		sde_kms->dp_stream_count = 0;
	}
	return 0;

exit_deinit_dp:
	kfree(sde_kms->dp_displays);
	sde_kms->dp_stream_count = 0;
	sde_kms->dp_display_count = 0;
	sde_kms->dp_displays = NULL;

@@ -964,7 +967,8 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
	}

	max_encoders = sde_kms->dsi_display_count + sde_kms->wb_display_count +
				sde_kms->dp_display_count;
				sde_kms->dp_display_count +
				sde_kms->dp_stream_count;
	if (max_encoders > ARRAY_SIZE(priv->encoders)) {
		max_encoders = ARRAY_SIZE(priv->encoders);
		SDE_ERROR("capping number of displays to %d", max_encoders);
Loading