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 <pingli@codeaurora.org>
This commit is contained in:
Ping Li
2021-08-25 13:23:41 -07:00
parent 5f5c61faa0
commit 629228c353
6 changed files with 117 additions and 9 deletions

View File

@@ -719,6 +719,8 @@ struct drm_msm_fp16_csc {
__u32 cfg_param_1[FP16_CSC_CFG1_PARAM_LEN]; __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 { struct drm_msm_backlight_info {
__u32 brightness_max; __u32 brightness_max;
__u32 brightness; __u32 brightness;
@@ -726,6 +728,8 @@ struct drm_msm_backlight_info {
__u32 bl_level; __u32 bl_level;
__u32 bl_scale; __u32 bl_scale;
__u32 bl_scale_sv; __u32 bl_scale_sv;
__u32 status;
__u32 min_bl;
}; };
#define DIMMING_BL_LUT_LEN 8192 #define DIMMING_BL_LUT_LEN 8192

View File

@@ -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 */ /* 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 && if (bl_temp != 0 && panel->bl_config.dimming_bl_lut &&
bl_temp < panel->bl_config.dimming_bl_lut->length) { 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]);
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) if (bl_temp > panel->bl_config.bl_max_level)
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)) if (bl_temp && (bl_temp < panel->bl_config.bl_min_level))
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); bl_scale, bl_scale_sv, (u32)bl_temp);
rc = dsi_panel_set_backlight(panel, (u32)bl_temp); rc = dsi_panel_set_backlight(panel, (u32)bl_temp);

View File

@@ -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 = MAX_BL_SCALE_LEVEL;
panel->bl_config.bl_scale_sv = MAX_SV_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); rc = utils->read_u32(utils->data, "qcom,mdss-dsi-bl-min-level", &val);
if (rc) { if (rc) {

View File

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

View File

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

View File

@@ -106,7 +106,10 @@ static void sde_dimming_bl_notify(struct sde_connector *conn, struct dsi_backlig
if (!conn || !config) if (!conn || !config)
return; 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; return;
bl_info.brightness_max = config->brightness_max_level; 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_level = config->bl_level;
bl_info.bl_scale = config->bl_scale; bl_info.bl_scale = config->bl_scale;
bl_info.bl_scale_sv = config->bl_scale_sv; 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.type = DRM_EVENT_DIMMING_BL;
event.length = sizeof(bl_info); event.length = sizeof(bl_info);
SDE_DEBUG("dimming BL event bl_level %d bl_scale %d, bl_scale_sv = %d\n", SDE_DEBUG("dimming BL event bl_level %d bl_scale %d, bl_scale_sv = %d "
bl_info.bl_level, bl_info.bl_scale, bl_info.bl_scale_sv); "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); 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, rc = c_conn->ops.set_backlight(&c_conn->base,
c_conn->display, bl_lvl); 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; 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; size_t sz = 0;
struct dsi_display *dsi_display; struct dsi_display *dsi_display;
struct dsi_backlight_config *bl_config; struct dsi_backlight_config *bl_config;
int rc = 0;
if (!c_conn || !c_state) { if (!c_conn || !c_state) {
SDE_ERROR("invalid arguments\n"); 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 = &dsi_display->panel->bl_config;
bl_config->dimming_bl_lut = msm_property_get_blob(&c_conn->property_info, bl_config->dimming_bl_lut = msm_property_get_blob(&c_conn->property_info,
&c_state->property_state, &sz, CONNECTOR_PROP_DIMMING_BL_LUT); &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; return 0;
} }
@@ -1673,6 +1756,12 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
case CONNECTOR_PROP_DIMMING_BL_LUT: case CONNECTOR_PROP_DIMMING_BL_LUT:
rc = _sde_connector_update_dimming_bl_lut(c_conn, c_state); rc = _sde_connector_update_dimming_bl_lut(c_conn, c_state);
break; 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: case CONNECTOR_PROP_HDR_METADATA:
rc = _sde_connector_set_ext_hdr_info(c_conn, rc = _sde_connector_set_ext_hdr_info(c_conn,
c_state, (void *)(uintptr_t)val); 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) { if (connector_type == DRM_MODE_CONNECTOR_DSI) {
dsi_display = (struct dsi_display *)(display); 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, msm_property_install_blob(&c_conn->property_info,
"dimming_bl_lut", DRM_MODE_PROP_BLOB, "dimming_bl_lut", DRM_MODE_PROP_BLOB,
CONNECTOR_PROP_DIMMING_BL_LUT); 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 && if (dsi_display && dsi_display->panel &&
dsi_display->panel->hdr_props.hdr_enabled == true) { dsi_display->panel->hdr_props.hdr_enabled == true) {