drm: drm supports a new connector type framework [1/1]

PD#SWPL-166619

Problem:
DRM needs to support mode switching for lcd tablet

Solution:
1.drm extend private connector type for hdmitx
2.modify the found connector flow in the logo
3.add connector type property for hwc to get private type
4.remove old lcd rate hint flow

Verify:
t7c, t3x

Test:
DRM-OSD-44, DRM-OSD-5

Change-Id: I192c29c9f2c8c2936810103407cd7cd219a85401
Signed-off-by: congyang.huang <congyang.huang@amlogic.com>
diff --git a/drivers/drm/meson_crtc.c b/drivers/drm/meson_crtc.c
index 13a01e8..a7b2e4c 100644
--- a/drivers/drm/meson_crtc.c
+++ b/drivers/drm/meson_crtc.c
@@ -11,6 +11,7 @@
 #include <linux/amlogic/gki_module.h>
 
 #include <linux/amlogic/media/vout/vout_notify.h>
+#include <linux/amlogic/media/vout/lcd/lcd_vout.h>
 #include <vout/vout_serve/vout_func.h>
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT
 #include <linux/amlogic/media/amvecm/amvecm.h>
@@ -754,10 +755,11 @@
 		crtc->state->event = NULL;
 	}
 
+	/*0=tv, 1=tablet, 2=invalid*/
 	if ((meson_crtc_state->vmode & VMODE_MASK) == VMODE_LCD &&
-		!strstr(old_mode->name, "panel")) {
-		DRM_INFO("%s[%d], lcd skip setting null vmode\n", __func__,
-			 meson_crtc_state->vmode);
+		get_vout_lcd_mode(amcrtc->crtc_index) == 0) {
+		DRM_INFO("%s[%d], lcd skip setting null vmode\n",
+				 __func__, meson_crtc_state->vmode);
 		return;
 	}
 
diff --git a/drivers/drm/meson_drm_bind.c b/drivers/drm/meson_drm_bind.c
index 8d1b091..e17f1d5 100644
--- a/drivers/drm/meson_drm_bind.c
+++ b/drivers/drm/meson_drm_bind.c
@@ -26,6 +26,16 @@
 #endif
 	}
 
+	if (type > DRM_MODE_MESON_CONNECTOR_HDMI_START &&
+			type < DRM_MODE_MESON_CONNECTOR_HDMI_END) {
+#ifndef CONFIG_AMLOGIC_DRM_CUT_HDMI
+		return meson_hdmitx_dev_bind(drm, type, intf);
+#else
+	pr_err("hdmi connector is not supported!\n");
+			return -1;
+#endif
+	}
+
 	switch (type) {
 #ifndef CONFIG_AMLOGIC_DRM_CUT_HDMI
 	case DRM_MODE_CONNECTOR_HDMIA:
diff --git a/drivers/drm/meson_drv.c b/drivers/drm/meson_drv.c
index 628dfe8..625afc5 100644
--- a/drivers/drm/meson_drv.c
+++ b/drivers/drm/meson_drv.c
@@ -140,7 +140,7 @@
 	}
 
 	if (!num_group) {
-		DRM_ERROR("get vrr error or not support qms\n");
+		DRM_DEBUG("get vrr error or not support qms\n");
 		return -EINVAL;
 	}
 
diff --git a/drivers/drm/meson_hdmi.c b/drivers/drm/meson_hdmi.c
index 9e64a80..92ae536 100644
--- a/drivers/drm/meson_hdmi.c
+++ b/drivers/drm/meson_hdmi.c
@@ -767,6 +767,9 @@
 	} else if (property == am_hdmi->ready_prop) {
 		*val = hdmitx_common_get_ready_state(tx_comm);
 		return 0;
+	} else if (property == am_hdmi->type_prop) {
+		*val = am_hdmi->hdmi_type;
+		return 0;
 	}
 
 	return -EINVAL;
@@ -2131,6 +2134,10 @@
 	struct connector_hpd_cb hpd_cb;
 	struct hdmitx_common *tx_comm;
 	int ret;
+	int connector_type = type;
+	char *connector_name = NULL;
+	int encoder_type = DRM_MODE_ENCODER_TMDS;
+	struct drm_property *type_prop = NULL;
 #ifdef CONFIG_CEC_NOTIFIER
 	struct edid *pedid;
 #endif
@@ -2176,6 +2183,38 @@
 	mesonconn->update = meson_hdmitx_update;
 	encoder = &am_hdmi->encoder;
 	connector = &am_hdmi->base.connector;
+	am_hdmi->hdmi_type = type;
+
+	switch (type) {
+	case DRM_MODE_CONNECTOR_MESON_HDMIA_A:
+		connector_type = DRM_MODE_CONNECTOR_HDMIA;
+		connector_name = "HDMI-A-A";
+		break;
+	case DRM_MODE_CONNECTOR_MESON_HDMIA_B:
+		connector_type = DRM_MODE_CONNECTOR_HDMIA;
+		connector_name = "HDMI-A-B";
+		break;
+	case DRM_MODE_CONNECTOR_MESON_HDMIA_C:
+		connector_type = DRM_MODE_CONNECTOR_HDMIA;
+		connector_name = "HDMI-A-C";
+		break;
+	case DRM_MODE_CONNECTOR_MESON_HDMIB_A:
+		connector_type = DRM_MODE_CONNECTOR_HDMIB;
+		connector_name = "HDMI-B-A";
+		break;
+	case DRM_MODE_CONNECTOR_MESON_HDMIB_B:
+		connector_type = DRM_MODE_CONNECTOR_HDMIB;
+		connector_name = "HDMI-B-B";
+		break;
+	case DRM_MODE_CONNECTOR_MESON_HDMIB_C:
+		connector_type = DRM_MODE_CONNECTOR_HDMIB;
+		connector_name = "HDMI-B-C";
+		break;
+	default:
+		connector_type = DRM_MODE_CONNECTOR_Unknown;
+		encoder_type = DRM_MODE_ENCODER_NONE;
+		break;
+	};
 
 	/* Connector */
 	connector->polled = DRM_CONNECTOR_POLL_HPD;
@@ -2183,18 +2222,26 @@
 				 &am_hdmi_connector_helper_funcs);
 
 	ret = drm_connector_init(drm, connector, &am_hdmi_connector_funcs,
-				 DRM_MODE_CONNECTOR_HDMIA);
+				 connector_type);
 	if (ret) {
 		dev_err(priv->dev, "Failed to init hdmi tx connector\n");
 		return ret;
 	}
 	connector->interlace_allowed = 1;
 
+	/*update name to amlogic name*/
+	if (connector_name) {
+		kfree(connector->name);
+		connector->name = kasprintf(GFP_KERNEL, "%s", connector_name);
+		if (!connector->name)
+			DRM_ERROR("[%s]: alloc name failed\n", __func__);
+	}
+
 	/* Encoder */
 	encoder->possible_crtcs = priv->of_conf.crtc_masks[ENCODER_HDMI];
 	drm_encoder_helper_add(encoder, &meson_hdmitx_encoder_helper_funcs);
 	ret = drm_encoder_init(drm, encoder, &meson_hdmitx_encoder_funcs,
-			       DRM_MODE_ENCODER_TMDS, "am_hdmi_encoder");
+			       encoder_type, "am_hdmi_encoder");
 	if (ret) {
 		dev_err(priv->dev, "Failed to init hdmi encoder\n");
 		return ret;
@@ -2254,6 +2301,19 @@
 					   CEC_PHYS_ADDR_INVALID);
 	}
 #endif
+
+	/*prop for userspace to acquire prop*/
+	type_prop = drm_property_create_range(drm, DRM_MODE_PROP_IMMUTABLE,
+		MESON_CONNECTOR_TYPE_PROP_NAME, 0, INT_MAX);
+	if (type_prop) {
+		am_hdmi->type_prop = type_prop;
+		drm_object_attach_property(&am_hdmi->base.connector.base,
+			type_prop, type);
+	} else {
+		DRM_ERROR("%s: Failed to create property %s\n",
+			__func__, MESON_CONNECTOR_TYPE_PROP_NAME);
+	}
+
 	DRM_DEBUG("%s out[%d]\n", __func__, __LINE__);
 	return 0;
 }
diff --git a/drivers/drm/meson_hdmi.h b/drivers/drm/meson_hdmi.h
index 9a4cfbb..8a831af 100644
--- a/drivers/drm/meson_hdmi.h
+++ b/drivers/drm/meson_hdmi.h
@@ -74,6 +74,8 @@
 	struct drm_property *contenttype_cap_prop;
 	struct drm_property *allm_prop;
 	struct drm_property *ready_prop;
+	struct drm_property *type_prop;
+	int hdmi_type;
 
 #ifdef CONFIG_CEC_NOTIFIER
 	struct cec_notifier	*cec_notifier;
diff --git a/drivers/drm/meson_lcd.c b/drivers/drm/meson_lcd.c
index 7a28ae0..3b70a5c 100644
--- a/drivers/drm/meson_lcd.c
+++ b/drivers/drm/meson_lcd.c
@@ -276,16 +276,6 @@
 		return;
 	}
 
-	if (crtc->enabled && !crtc->state->active_changed &&
-	    meson_crtc_state->prev_height == mode->vdisplay &&
-	    meson_crtc_state->prev_vrefresh != vrefresh) {
-		lcd_frac_hint = find_frac_hint_by_fps(vrefresh);
-		vout_func_set_vframe_rate_hint(amcrtc->vout_index, lcd_frac_hint);
-		meson_crtc_state->prev_vrefresh = vrefresh;
-		DRM_INFO("skip set_vmode, use set_vframe_rate_hint\n");
-		return;
-	}
-
 	meson_crtc_state->prev_vrefresh = vrefresh;
 	meson_crtc_state->prev_height = mode->vdisplay;
 	meson_vout_notify_mode_change(amcrtc->vout_index,
diff --git a/drivers/drm/meson_logo.c b/drivers/drm/meson_logo.c
index 10d7e73..0fbeb97 100644
--- a/drivers/drm/meson_logo.c
+++ b/drivers/drm/meson_logo.c
@@ -698,6 +698,7 @@
 	struct drm_modeset_acquire_ctx *ctx;
 	struct meson_drm *private = dev->dev_private;
 	struct am_meson_fb *meson_fb;
+	char *connector_type = NULL;
 	u32 found, num_modes;
 
 	DRM_DEBUG("%s idx[%d]\n", __func__, idx);
@@ -712,10 +713,35 @@
 		return;
 	}
 
+	switch (idx) {
+	case 0:
+		connector_type = get_uboot_connector0_type();
+		DRM_DEBUG("[%s-%d]: connector_type %s\n", __func__, idx, connector_type);
+		break;
+	case 1:
+		connector_type = get_uboot_connector1_type();
+		DRM_DEBUG("[%s-%d]: connector_type %s\n", __func__, idx, connector_type);
+		break;
+	case 2:
+		connector_type = get_uboot_connector2_type();
+		DRM_DEBUG("[%s-%d]: connector_type %s\n", __func__, idx, connector_type);
+		break;
+	default:
+		DRM_DEBUG("[%s]: connector_type not found\n", __func__);
+		break;
+	}
+
 	meson_fb = to_am_meson_fb(fb);
 	/*init all connector and found matched uboot mode.*/
 	found = 0;
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		/*connector->name is same as connector_type char*/
+		if (connector_type && strcmp(connector->name, connector_type)) {
+			DRM_DEBUG("[%s-%d]: %s != %s, jump\n", __func__, idx,
+				connector->name, connector_type);
+			continue;
+		}
+
 		drm_modeset_lock_all(dev);
 		if (drm_modeset_is_locked(&dev->mode_config.connection_mutex))
 			drm_modeset_unlock(&dev->mode_config.connection_mutex);