weston: add interface with meson display [1/1]

PD#SWPL-155659

Problem:
support interface for meson display to call

Solution:
support interface for meson display to call

Verify:
ah212

Change-Id: Ie86052dee3da6b6da509e99f08dbe361861ab14c
Signed-off-by: leng.fang <leng.fang@amlogic.com>
diff --git a/aml-weston/aml-backend.c b/aml-weston/aml-backend.c
index d7665d8..b07ce19 100644
--- a/aml-weston/aml-backend.c
+++ b/aml-weston/aml-backend.c
@@ -233,10 +233,20 @@
 #endif
 
 #ifdef MESON_DRM_FIX_UI_SIZE
-		// for scale to full screen
-		//// TODO: Need consider different aspect_ration
-		scanout_state->dest_w = output->display_size.width;
-		scanout_state->dest_h = output->display_size.height;
+		int scaling = mode_policy_get_scaling();
+		if (scaling > 40 && scaling < 100) {
+			int x_margin = output->display_size.width * (100 - scaling) / 100;
+			int y_margin = output->display_size.height * (100 - scaling) / 100;
+			scanout_state->dest_x = x_margin / 2;
+			scanout_state->dest_y = y_margin / 2;
+			scanout_state->dest_w = output->display_size.width - x_margin;
+			scanout_state->dest_h = output->display_size.height - y_margin;
+		} else {
+			// for scale to full screen
+			//// TODO: Need consider different aspect_ration
+			scanout_state->dest_w = output->display_size.width;
+			scanout_state->dest_h = output->display_size.height;
+		}
 #endif
 	}
 }
@@ -254,8 +264,8 @@
 			output->base.current_mode->height = output->display_size.height;
 		}
 		//Save the orgin size of next current_mode
-		output->display_size.width = drm_mode->base.width;
-		output->display_size.height = drm_mode->base.height;
+		output->display_size.width = drm_mode->mode_info.hdisplay;
+		output->display_size.height = drm_mode->mode_info.vdisplay;
 		//Set the fixed ui size to current_mode
 		drm_mode->base.width = b->fixed_ui_size.width;
 		drm_mode->base.height = b->fixed_ui_size.height;
@@ -318,6 +328,17 @@
 	}
 }
 
+static int drm_set_property(const char *name, int value)
+{
+	int ret = 0;
+
+#ifdef ENABLE_MODE_POLICY
+	ret = mode_policy_set_property(name, value);
+#endif
+
+	return ret;
+}
+
 void drm_enable_aml_output_config(struct drm_output* output,
 			struct weston_output *base, struct drm_backend *b)
 {
@@ -348,6 +369,8 @@
 			if (head->connector.conn->connector_type == DRM_MODE_CONNECTOR_HDMIA)
 			{
 				help_set_switch_mode_function((output_ctx)base, drm_output_switch_mode_helper);
+				help_set_force_refresh_function(drm_output_force_refresh);
+				help_set_property_function(drm_set_property);
 			}
 		}
 #endif
@@ -810,6 +833,12 @@
 	weston_compositor_damage_all(compositor);
 }
 
+int drm_output_force_refresh(output_ctx ctx)
+{
+	drm_output_refresh_force(((struct weston_output *)ctx)->compositor);
+	return 0;
+}
+
 int drm_output_switch_mode_helper(output_ctx ctx, drm_helper_mode* mode)
 {
 	struct weston_mode m;
@@ -826,7 +855,12 @@
 	m.aspect_ratio = 0;
 
 #ifdef ENABLE_MODE_POLICY
-	wst_mode = mode_policy_choose_mode(&m);
+	mode_policy_update_bestmode(mode->auto_mode);
+	if (!mode->auto_mode)
+		wst_mode = &m;
+	else
+		mode_policy_set_hotplug(AML_WESTON_HOTPLUG_SET);
+	wst_mode = mode_policy_choose_mode(wst_mode);
 #endif
 	if (!wst_mode)
 		wst_mode = &m;
diff --git a/aml-weston/aml-backend.h b/aml-weston/aml-backend.h
index a82c643..83dab6f 100644
--- a/aml-weston/aml-backend.h
+++ b/aml-weston/aml-backend.h
@@ -21,6 +21,7 @@
 
 void weston_print_info(struct weston_compositor* ec, int count);
 int drm_output_switch_mode_helper(output_ctx ctx, drm_helper_mode* mode);
+int drm_output_force_refresh(output_ctx ctx);
 #endif
 
 void drm_output_render_aml_config(struct drm_output *output, struct drm_plane_state *scanout_state);
diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c
index da739f5..3d777d4 100644
--- a/libweston/backend-drm/kms.c
+++ b/libweston/backend-drm/kms.c
@@ -976,10 +976,6 @@
 						  WDRM_CONNECTOR_CRTC_ID, 0);
 	}
 
-	wl_list_for_each(head, &output->base.head_list, base.output_link)
-		drm_connector_set_hdcp_property(&head->connector,
-						state->protection, req);
-
 	if (ret != 0) {
 		weston_log("couldn't set atomic CRTC/connector state\n");
 		return ret;
@@ -1183,7 +1179,10 @@
 #endif
 
 #ifdef ENABLE_MODE_POLICY
-	ret |= mode_policy_add_prop(req);
+	if (mode != DRM_STATE_TEST_ONLY &&
+		mode_policy_add_prop(req) > 0) {
+		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
+	}
 #endif
 
 	ret = drmModeAtomicCommit(b->drm.fd, req, flags, b);
diff --git a/libweston/modepolicy/modepolicy_aml.cpp b/libweston/modepolicy/modepolicy_aml.cpp
index 8258ea3..de11399 100644
--- a/libweston/modepolicy/modepolicy_aml.cpp
+++ b/libweston/modepolicy/modepolicy_aml.cpp
@@ -12,6 +12,7 @@
 	if (!gCtx) {
 		gCtx = (weston_ctx *)calloc(1, sizeof(*gCtx));
 		gCtx->need_update_hdmi_param = false;
+		gCtx->scaling = -1;
 		wl_list_init(&gCtx->prop_list);
 	}
 	return gCtx;
@@ -400,10 +401,8 @@
 	if (value)
 		scaling = atoi(value);
 
-	if (ctx && ctx->head && ctx->head->output) {
-		if (ctx->head->output->current_scale != scaling)
-			ctx->head->output->current_scale = scaling;
-	}
+	if (ctx && ctx->scaling != scaling)
+		ctx->scaling = scaling;
 }
 
 CompositorFunctionCallBack callback = {
@@ -415,6 +414,118 @@
 	.set_scaling_position = weston_set_scaling_position,
 };
 
+static char *get_color_space_by_value(int value)
+{
+	char *str;
+
+	switch ( value ) {
+		case 0:
+			str = "rgb";
+			break;
+		case 1:
+			str = "422";
+			break;
+		case 2:
+			str = "444";
+			break;
+		case 3:
+		default:
+			str = "420";
+			break;
+	}
+	return str;
+}
+
+static int get_property_value(char *name)
+{
+	prop_info *info;
+	weston_ctx *ctx = weston_get_ctx();
+
+	wl_list_for_each(info, &ctx->prop_list, link) {
+		if (!strcmp(name, info->name)) {
+			if (info->need_change == 1)
+				return info->value;
+		}
+	}
+	return -1;
+}
+
+static int get_id_by_name(const char *name)
+{
+	prop_info *info;
+	weston_ctx *ctx = weston_get_ctx();
+
+	wl_list_for_each(info, &ctx->prop_list, link) {
+		if (!strcmp(name, info->name))
+				return info->item_id;
+	}
+	return -1;
+}
+
+static int mode_policy_parse_other(const char *name, int value)
+{
+	weston_ctx *ctx = weston_get_ctx();
+	char attrvalue[32] = { 0 };
+
+	if (STRCMPS(name, "scaling") == 0) {
+		if (ctx && ctx->scaling != value)
+			ctx->scaling = value;
+
+		sprintf(attrvalue, "%d", value);
+		bootenv_update("scaling", attrvalue);
+		return 0;
+	}
+	return -1;
+}
+
+int mode_policy_set_property(const char *name, int value)
+{
+	char attrvalue[32] = { 0 };
+	int color_space = 0;
+	int color_depth = 0;
+	int id = get_id_by_name(name);
+	MESON_LOGI("id: %d, name: %s, value: %d", id, name, value);
+
+	if (value < 0 || id < 0)
+		return mode_policy_parse_other(name, value);
+
+	if (strncmp(name, "dv_mode", sizeof("dv_mode")) == 0) {
+		setDvMode(value == 0 ? 1 : (value == 1 ? 2 : 0));
+		return 0;
+	} else if (strncmp(name, "color_depth", sizeof("color_depth")) == 0) {
+		color_space = get_property_value("color_space");
+		if (color_space >= 0) {
+			sprintf(attrvalue, "%s,%dbit", get_color_space_by_value(color_space), value);
+			setColorSpace(attrvalue);
+			mode_policy_update_bestmode(false);
+			return 0;
+		}
+	} else if (strncmp(name, "color_space", sizeof("color_space")) == 0) {
+		color_depth = get_property_value("color_depth");
+		if (color_depth >= 0) {
+			sprintf(attrvalue, "%s,%dbit", get_color_space_by_value(value), color_depth);
+			setColorSpace(attrvalue);
+			mode_policy_update_bestmode(false);
+			return 0;
+		}
+	} else if (strncmp(name, "meson.crtc.hdr_policy", sizeof("meson.crtc.hdr_policy")) == 0) {
+		sprintf(attrvalue, "%d", value);
+		bootenv_update("hdr_policy", attrvalue);
+	}
+
+	return weston_set_property(id, name, value);
+}
+
+int mode_policy_get_scaling()
+{
+	weston_ctx *ctx = weston_get_ctx();
+
+	if (ctx->scaling < 0)
+		return 100;
+
+	return ctx->scaling;
+}
+
 static drmModeCrtc *weston_get_crtc_for_conn(int drm_fd, drmModeConnector *conn)
 {
 	drmModeEncoder *encoder;
@@ -470,6 +581,7 @@
 	weston_ctx *ctx = weston_get_ctx();
 	prop_info *info;
 	int err = 0, ret = 0;
+	int count = 0;
 
 	wl_list_for_each(info, &ctx->prop_list, link) {
 		if (info->need_change) {
@@ -479,10 +591,12 @@
 					info->name, err, errno);
 			info->need_change = 0;
 			ret |= (err <= 0) ? -1 : 0;
+			if (!ret)
+				count++;
 			ctx->need_update_hdmi_param = true;
 		}
 	}
-	return ret;
+	return ret >= 0 ? count : ret;
 }
 
 void mode_policy_set_hotplug(int plug)
@@ -519,7 +633,7 @@
 	} else {
 		if (ctx->hotplug & (AML_WESTON_HOTPLUG_PLUG | AML_WESTON_HOTPLUG_UNPLUG))
 			onHotplug(ctx->hotplug & AML_WESTON_HOTPLUG_PLUG);
-		else if (ctx->hotplug & AML_WESTON_HOTPLUG_BOOT)
+		else if (ctx->hotplug & (AML_WESTON_HOTPLUG_BOOT | AML_WESTON_HOTPLUG_SET))
 			initModePolicy(NULL, NULL, callback);
 		ctx->hotplug = AML_WESTON_HOTPLUG_INIT;
 	}
@@ -528,6 +642,11 @@
 	return NULL;
 }
 
+void mode_policy_update_bestmode(bool bestmode)
+{
+	bootenv_update("is.bestmode", bestmode ? "true" : "false");
+}
+
 static void * wstUpdatenvThread(void *arg )
 {
 	long long delay = 16667LL;
diff --git a/libweston/modepolicy/modepolicy_aml.h b/libweston/modepolicy/modepolicy_aml.h
index ea64a64..f2999ff 100644
--- a/libweston/modepolicy/modepolicy_aml.h
+++ b/libweston/modepolicy/modepolicy_aml.h
@@ -29,6 +29,7 @@
 	struct weston_head *head;
 	struct weston_mode current_mode;
 	struct weston_mode next_mode;
+	int scaling;
 	bool mode_update;
 	int hotplug;  // 0: init 2: hotplug 4: unplug
 	struct wl_list prop_list;
@@ -38,15 +39,21 @@
 	AML_WESTON_HOTPLUG_INIT = 0x0,
 	AML_WESTON_HOTPLUG_BOOT = 0x1,
 	AML_WESTON_HOTPLUG_PLUG = 0x2,
-	AML_WESTON_HOTPLUG_UNPLUG = 0x4
+	AML_WESTON_HOTPLUG_UNPLUG = 0x4,
+	AML_WESTON_HOTPLUG_SET = 0x8
 };
 
+#define STRCMPS(str1, str2) strncmp(str1, str2, sizeof(str2))
+
 void init_mode_policy_without_mode(struct weston_head *head, int fd, drmModeConnector *conn);
 void weston_start_update_env_thread();
 int mode_policy_add_prop(drmModeAtomicReq *req);
 void mode_policy_set_hotplug(int plug);
 struct weston_mode *mode_policy_choose_mode(struct weston_mode *mode);
+void mode_policy_update_bestmode(bool bestmode);
 void mode_policy_update_mode(struct weston_mode *mode);
+int mode_policy_set_property(const char *name, int value);
+int mode_policy_get_scaling();
 
 #ifdef __cplusplus
 }