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

Commit dd0d1bd5 authored by Jin Li's avatar Jin Li Committed by Gerrit - the friendly Code Review server
Browse files

drm/sde: report connector id based on display type



User space client creates displays based on the order of connector
IDs reported by kernel. So driver needs to report the correct
connector IDs based on display_type defined in DTS file.

CRs-Fixed: 1084253
Change-Id: I771a300bc5322ee4f87f417534267636d84891c6
Signed-off-by: default avatarJin Li <jinl@codeaurora.org>
parent 26df0a2a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2145,6 +2145,7 @@ int dsi_display_get_info(struct msm_display_info *info, void *disp)
	info->max_width = 1920;
	info->max_height = 1080;
	info->compression = MSM_DISPLAY_COMPRESS_NONE;
	info->display_id = msm_get_display_id(display->display_type);

	switch (display->panel[0]->mode.panel_mode) {
	case DSI_OP_VIDEO_MODE:
+1 −0
Original line number Diff line number Diff line
@@ -772,6 +772,7 @@ int sde_hdmi_get_info(struct msm_display_info *info,
	info->max_width = 4096;
	info->max_height = 2160;
	info->compression = MSM_DISPLAY_COMPRESS_NONE;
	info->display_id = msm_get_display_id(hdmi_display->display_type);

	mutex_unlock(&hdmi_display->display_lock);
	return rc;
+29 −0
Original line number Diff line number Diff line
@@ -131,6 +131,15 @@ enum msm_mdp_conn_property {
	CONNECTOR_PROP_COUNT
};

enum msm_mdp_display_id {
	DISPLAY_ID_NONE,
	DISPLAY_ID_PRIMARY,
	DISPLAY_ID_SECONDARY,
	DISPLAY_ID_TERTIARY,
	DISPLAY_ID_QUATERNARY,
	DISPLAY_ID_MAX
};

struct msm_vblank_ctrl {
	struct work_struct work;
	struct list_head event_list;
@@ -180,6 +189,7 @@ enum msm_display_caps {
 * @max_height:         Max height of display. In case of hot pluggable display
 *                      this is max height supported by controller
 * @compression:        Compression supported by the display
 * @display_id:         Display ID such as primary, secondary, etc.
 */
struct msm_display_info {
	int intf_type;
@@ -197,6 +207,8 @@ struct msm_display_info {
	uint32_t max_height;

	enum msm_display_compression compression;

	enum msm_mdp_display_id display_id;
};

struct display_manager;
@@ -466,6 +478,23 @@ static inline int align_pitch(int width, int bpp)
	return bytespp * ALIGN(width, 32);
}

static inline enum msm_mdp_display_id msm_get_display_id(
	const char *display_type)
{
	if (!display_type)
		return DISPLAY_ID_NONE;
	else if (!strcmp(display_type, "primary"))
		return DISPLAY_ID_PRIMARY;
	else if (!strcmp(display_type, "secondary"))
		return DISPLAY_ID_SECONDARY;
	else if (!strcmp(display_type, "tertiary"))
		return DISPLAY_ID_TERTIARY;
	else if (!strcmp(display_type, "quaternary"))
		return DISPLAY_ID_QUATERNARY;
	else
		return DISPLAY_ID_NONE;
};

/* for the generated headers: */
#define INVALID_IDX(idx) ({BUG(); 0;})
#define fui(x)                ({BUG(); 0;})
+59 −5
Original line number Diff line number Diff line
@@ -156,6 +156,28 @@ static void bs_set(struct sde_encoder_virt *sde_enc, int idx)
}
#endif

static inline void sde_encoder_add_display_id(enum msm_mdp_display_id id,
	int display_index, int *id_list, u32 num_of_id_list)
{
	u32 i = 0;

	if (id == DISPLAY_ID_NONE) {
		/* add it to spare place */
		for (i = 0; i < num_of_id_list; i++) {
			if (id_list[i] < 0) {
				id_list[i] = display_index;
				break;
			}
		}
	} else {
		/*
		 * To reduce complexity, don't do sorting. Caller should always
		 * add fixed dislay ID first, then add unknown ones.
		 */
		id_list[id - 1] = display_index;
	}
}

void sde_encoder_get_hw_resources(struct drm_encoder *drm_enc,
		struct sde_encoder_hw_resources *hw_res,
		struct drm_connector_state *conn_state)
@@ -863,6 +885,7 @@ void sde_encoders_init(struct drm_device *dev)
	struct display_manager *disp_man = NULL;
	u32 i = 0;
	u32 num_displays = 0;
	int *id_list;

	DBG("");

@@ -888,29 +911,60 @@ void sde_encoders_init(struct drm_device *dev)
				num_displays);
	}

	id_list = kcalloc(num_displays, sizeof(int), GFP_KERNEL);
	if (!id_list) {
		DRM_ERROR("id_list out of memory");
		return;
	}
	memset(id_list, 0xFF, sizeof(int) * num_displays);

	/* Add fixed display id list */
	for (i = 0; i < num_displays; i++) {
		struct msm_display_info info = { 0 };
		struct drm_encoder *enc = NULL;
		u32 ret = 0;

		ret = display_manager_get_info_by_index(disp_man, i, &info);
		if (ret) {
			DRM_ERROR("Failed to get display info, %d", ret);
			return;
			goto error;
		}
		if (info.display_id != DISPLAY_ID_NONE)
			sde_encoder_add_display_id(info.display_id, i, id_list,
				num_displays);
	}

	/* Add unknown display id list */
	for (i = 0; i < num_displays; i++) {
		struct msm_display_info info = { 0 };

		display_manager_get_info_by_index(disp_man, i, &info);
		if (info.display_id == DISPLAY_ID_NONE)
			sde_encoder_add_display_id(info.display_id, i, id_list,
				num_displays);
	}

	for (i = 0; i < num_displays; i++) {
		struct msm_display_info info = { 0 };
		struct drm_encoder *enc = NULL;
		u32 ret = 0;

		display_manager_get_info_by_index(disp_man, id_list[i], &info);
		enc = sde_encoder_virt_init(dev, &info);
		if (IS_ERR_OR_NULL(enc)) {
			DRM_ERROR("Encoder initialization failed");
			return;
			goto error;
		}

		ret = display_manager_drm_init_by_index(disp_man, i, enc);
		ret = display_manager_drm_init_by_index(disp_man, id_list[i],
			enc);
		if (ret) {
			DRM_ERROR("Display drm_init failed, %d", ret);
			return;
			goto error;
		}

		priv->encoders[priv->num_encoders++] = enc;
	}

error:
	kfree(id_list);
}