소스 검색

disp: msm: sde: add new support for digital dimming

Add new properties to support dynamically turning on and off digital
dimming and setting new minimum backlight.

Change-Id: I3b94190877d556768ba2c92ec59432dec44de0de
Signed-off-by: Ping Li <[email protected]>
Ping Li 3 년 전
부모
커밋
629228c353
6개의 변경된 파일117개의 추가작업 그리고 9개의 파일을 삭제
  1. 4 0
      include/uapi/display/drm/msm_drm_pp.h
  2. 4 4
      msm/dsi/dsi_display.c
  3. 3 0
      msm/dsi/dsi_panel.c
  4. 4 0
      msm/dsi/dsi_panel.h
  5. 2 0
      msm/msm_drv.h
  6. 100 5
      msm/sde/sde_connector.c

+ 4 - 0
include/uapi/display/drm/msm_drm_pp.h

@@ -719,6 +719,8 @@ struct drm_msm_fp16_csc {
 	__u32 cfg_param_1[FP16_CSC_CFG1_PARAM_LEN];
 };
 
+#define DIMMING_ENABLE (1 << 0)
+#define DIMMING_MIN_BL_VALID (1 << 1)
 struct drm_msm_backlight_info {
 	__u32 brightness_max;
 	__u32 brightness;
@@ -726,6 +728,8 @@ struct drm_msm_backlight_info {
 	__u32 bl_level;
 	__u32 bl_scale;
 	__u32 bl_scale_sv;
+	__u32 status;
+	__u32 min_bl;
 };
 
 #define DIMMING_BL_LUT_LEN 8192

+ 4 - 4
msm/dsi/dsi_display.c

@@ -249,7 +249,7 @@ int dsi_display_set_backlight(struct drm_connector *connector,
 	/* use bl_temp as index of dimming bl lut to find the dimming panel backlight */
 	if (bl_temp != 0 && panel->bl_config.dimming_bl_lut &&
 	    bl_temp < panel->bl_config.dimming_bl_lut->length) {
-		pr_debug("before dimming bl_temp = %u, after dimming bl_temp = %lu\n",
+		DSI_DEBUG("before dimming bl_temp = %u, after dimming bl_temp = %lu\n",
 			bl_temp, panel->bl_config.dimming_bl_lut->mapped_bl[bl_temp]);
 		bl_temp = panel->bl_config.dimming_bl_lut->mapped_bl[bl_temp];
 	}
@@ -257,10 +257,10 @@ int dsi_display_set_backlight(struct drm_connector *connector,
 	if (bl_temp > panel->bl_config.bl_max_level)
 		bl_temp = panel->bl_config.bl_max_level;
 
-        if (bl_temp && (bl_temp < panel->bl_config.bl_min_level))
-                bl_temp = panel->bl_config.bl_min_level;
+	if (bl_temp && (bl_temp < panel->bl_config.bl_min_level))
+		bl_temp = panel->bl_config.bl_min_level;
 
-	pr_debug("bl_scale = %u, bl_scale_sv = %u, bl_lvl = %u\n",
+	DSI_DEBUG("bl_scale = %u, bl_scale_sv = %u, bl_lvl = %u\n",
 		bl_scale, bl_scale_sv, (u32)bl_temp);
 
 	rc = dsi_panel_set_backlight(panel, (u32)bl_temp);

+ 3 - 0
msm/dsi/dsi_panel.c

@@ -2445,6 +2445,9 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel)
 
 	panel->bl_config.bl_scale = MAX_BL_SCALE_LEVEL;
 	panel->bl_config.bl_scale_sv = MAX_SV_BL_SCALE_LEVEL;
+	panel->bl_config.dimming_min_bl = 0;
+	panel->bl_config.dimming_status = DIMMING_ENABLE;
+	panel->bl_config.user_disable_notification = false;
 
 	rc = utils->read_u32(utils->data, "qcom,mdss-dsi-bl-min-level", &val);
 	if (rc) {

+ 4 - 0
msm/dsi/dsi_panel.h

@@ -13,6 +13,7 @@
 #include <linux/backlight.h>
 #include <drm/drm_panel.h>
 #include <drm/msm_drm.h>
+#include <drm/msm_drm_pp.h>
 
 #include "dsi_defs.h"
 #include "dsi_ctrl_hw.h"
@@ -134,6 +135,9 @@ struct dsi_backlight_config {
 	bool bl_inverted_dbv;
 	/* digital dimming backlight LUT */
 	struct drm_msm_dimming_bl_lut *dimming_bl_lut;
+	u32 dimming_min_bl;
+	u32 dimming_status;
+	bool user_disable_notification;
 
 	int en_gpio;
 	/* PWM params */

+ 2 - 0
msm/msm_drv.h

@@ -216,6 +216,8 @@ enum msm_mdp_conn_property {
 	CONNECTOR_PROP_SV_BL_SCALE,
 	CONNECTOR_PROP_SUPPORTED_COLORSPACES,
 	CONNECTOR_PROP_DYN_BIT_CLK,
+	CONNECTOR_PROP_DIMMING_CTRL,
+	CONNECTOR_PROP_DIMMING_MIN_BL,
 
 	/* enum/bitmask properties */
 	CONNECTOR_PROP_TOPOLOGY_NAME,

+ 100 - 5
msm/sde/sde_connector.c

@@ -106,7 +106,10 @@ static void sde_dimming_bl_notify(struct sde_connector *conn, struct dsi_backlig
 
 	if (!conn || !config)
 		return;
-	if (!conn->dimming_bl_notify_enabled)
+
+	SDE_DEBUG("bl_config.dimming_status 0x%x user_disable_notify %d\n",
+		  config->dimming_status, config->user_disable_notification);
+	if (!conn->dimming_bl_notify_enabled || config->user_disable_notification)
 		return;
 
 	bl_info.brightness_max = config->brightness_max_level;
@@ -115,10 +118,13 @@ static void sde_dimming_bl_notify(struct sde_connector *conn, struct dsi_backlig
 	bl_info.bl_level = config->bl_level;
 	bl_info.bl_scale = config->bl_scale;
 	bl_info.bl_scale_sv = config->bl_scale_sv;
+	bl_info.status = config->dimming_status;
+	bl_info.min_bl = config->dimming_min_bl;
 	event.type = DRM_EVENT_DIMMING_BL;
 	event.length = sizeof(bl_info);
-	SDE_DEBUG("dimming BL event bl_level %d bl_scale %d, bl_scale_sv = %d\n",
-		  bl_info.bl_level, bl_info.bl_scale, bl_info.bl_scale_sv);
+	SDE_DEBUG("dimming BL event bl_level %d bl_scale %d, bl_scale_sv = %d "
+		  "min_bl %d status 0x%x\n", bl_info.bl_level, bl_info.bl_scale,
+		  bl_info.bl_scale_sv, bl_info.min_bl, bl_info.status);
 	msm_mode_object_event_notify(&conn->base.base, conn->base.dev, &event, (u8 *)&bl_info);
 }
 
@@ -181,7 +187,8 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
 		}
 		rc = c_conn->ops.set_backlight(&c_conn->base,
 				c_conn->display, bl_lvl);
-		sde_dimming_bl_notify(c_conn, &display->panel->bl_config);
+		if (!rc)
+			sde_dimming_bl_notify(c_conn, &display->panel->bl_config);
 		c_conn->unset_bl_level = 0;
 	}
 
@@ -693,6 +700,7 @@ static int _sde_connector_update_dimming_bl_lut(struct sde_connector *c_conn,
 	size_t sz = 0;
 	struct dsi_display *dsi_display;
 	struct dsi_backlight_config *bl_config;
+	int rc = 0;
 
 	if (!c_conn || !c_state) {
 		SDE_ERROR("invalid arguments\n");
@@ -716,6 +724,81 @@ static int _sde_connector_update_dimming_bl_lut(struct sde_connector *c_conn,
 	bl_config = &dsi_display->panel->bl_config;
 	bl_config->dimming_bl_lut = msm_property_get_blob(&c_conn->property_info,
 			&c_state->property_state, &sz, CONNECTOR_PROP_DIMMING_BL_LUT);
+	rc = c_conn->ops.set_backlight(&c_conn->base,
+			dsi_display, bl_config->bl_level);
+	if (!rc)
+		c_conn->unset_bl_level = 0;
+
+	return 0;
+}
+
+static int _sde_connector_update_dimming_ctrl(struct sde_connector *c_conn,
+		struct sde_connector_state *c_state, uint64_t val)
+{
+	struct dsi_display *dsi_display;
+	struct dsi_backlight_config *bl_config;
+	bool prev, curr = (bool)val;
+
+	if (!c_conn || !c_state) {
+		SDE_ERROR("invalid arguments\n");
+		return -EINVAL;
+	}
+
+	dsi_display = c_conn->display;
+	if (!dsi_display || !dsi_display->panel) {
+		SDE_ERROR("Invalid params(s) dsi_display %pK, panel %pK\n",
+			dsi_display,
+			((dsi_display) ? dsi_display->panel : NULL));
+		return -EINVAL;
+	}
+
+	bl_config = &dsi_display->panel->bl_config;
+	prev = (bool)(bl_config->dimming_status & DIMMING_ENABLE);
+	if (curr == prev)
+		return 0;
+
+	if(val) {
+		bl_config->dimming_status |= DIMMING_ENABLE;
+	} else {
+		bl_config->dimming_status &= ~DIMMING_ENABLE;
+	}
+	bl_config->user_disable_notification = false;
+	sde_dimming_bl_notify(c_conn, bl_config);
+	if (!val)
+		bl_config->user_disable_notification = true;
+
+	return 0;
+}
+
+static int _sde_connector_update_dimming_min_bl(struct sde_connector *c_conn,
+		struct sde_connector_state *c_state, uint64_t val)
+{
+	struct dsi_display *dsi_display;
+	struct dsi_backlight_config *bl_config;
+	uint32_t tmp = 0;
+
+	if (!c_conn || !c_state) {
+		SDE_ERROR("invalid arguments\n");
+		return -EINVAL;
+	}
+
+	dsi_display = c_conn->display;
+	if (!dsi_display || !dsi_display->panel) {
+		SDE_ERROR("Invalid params(s) dsi_display %pK, panel %pK\n",
+			dsi_display,
+			((dsi_display) ? dsi_display->panel : NULL));
+		return -EINVAL;
+	}
+
+	bl_config = &dsi_display->panel->bl_config;
+	tmp = (uint32_t)val;
+	if (tmp == bl_config->dimming_min_bl)
+		return 0;
+	bl_config->dimming_min_bl = tmp;
+	bl_config->dimming_status |= DIMMING_MIN_BL_VALID;
+	sde_dimming_bl_notify(c_conn, bl_config);
+	bl_config->dimming_status &= ~DIMMING_MIN_BL_VALID;
+
 	return 0;
 }
 
@@ -1673,6 +1756,12 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
 	case CONNECTOR_PROP_DIMMING_BL_LUT:
 		rc = _sde_connector_update_dimming_bl_lut(c_conn, c_state);
 		break;
+	case CONNECTOR_PROP_DIMMING_CTRL:
+		rc = _sde_connector_update_dimming_ctrl(c_conn, c_state, val);
+		break;
+	case CONNECTOR_PROP_DIMMING_MIN_BL:
+		rc = _sde_connector_update_dimming_min_bl(c_conn, c_state, val);
+		break;
 	case CONNECTOR_PROP_HDR_METADATA:
 		rc = _sde_connector_set_ext_hdr_info(c_conn,
 			c_state, (void *)(uintptr_t)val);
@@ -2911,10 +3000,16 @@ static int _sde_connector_install_properties(struct drm_device *dev,
 
 	if (connector_type == DRM_MODE_CONNECTOR_DSI) {
 		dsi_display = (struct dsi_display *)(display);
-		if (dsi_display && dsi_display->panel)
+		if (dsi_display && dsi_display->panel) {
 			msm_property_install_blob(&c_conn->property_info,
 				"dimming_bl_lut", DRM_MODE_PROP_BLOB,
 				CONNECTOR_PROP_DIMMING_BL_LUT);
+			msm_property_install_range(&c_conn->property_info, "dimming_dyn_ctrl",
+					0x0, 0, ~0, 0, CONNECTOR_PROP_DIMMING_CTRL);
+			msm_property_install_range(&c_conn->property_info, "dimming_min_bl",
+					0x0, 0, dsi_display->panel->bl_config.brightness_max_level, 0,
+					CONNECTOR_PROP_DIMMING_MIN_BL);
+		}
 
 		if (dsi_display && dsi_display->panel &&
 			dsi_display->panel->hdr_props.hdr_enabled == true) {