Merge "disp: msm: sde: add support for digital dimming"

This commit is contained in:
qctecmdr
2021-06-02 17:20:03 -07:00
committed by Gerrit - the friendly Code Review server
8 changed files with 113 additions and 0 deletions

View File

@@ -719,4 +719,19 @@ struct drm_msm_fp16_csc {
__u32 cfg_param_1[FP16_CSC_CFG1_PARAM_LEN];
};
struct drm_msm_backlight_info {
__u32 brightness_max;
__u32 brightness;
__u32 bl_level_max;
__u32 bl_level;
__u32 bl_scale;
__u32 bl_scale_sv;
};
#define DIMMING_BL_LUT_LEN 8192
struct drm_msm_dimming_bl_lut {
__u32 length;
__u32 mapped_bl[DIMMING_BL_LUT_LEN];
};
#endif /* _MSM_DRM_PP_H_ */

View File

@@ -813,6 +813,7 @@ struct drm_msm_noise_layer_cfg {
#define DRM_EVENT_LTM_OFF 0X8000000A
#define DRM_EVENT_MMRM_CB 0X8000000B
#define DRM_EVENT_FRAME_DATA 0x8000000C
#define DRM_EVENT_DIMMING_BL 0X8000000D
#ifndef DRM_MODE_FLAG_VID_MODE_PANEL
#define DRM_MODE_FLAG_VID_MODE_PANEL 0x01

View File

@@ -243,6 +243,14 @@ 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;
/* 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) {
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];
}
DSI_DEBUG("bl_scale = %u, bl_scale_sv = %u, bl_lvl = %u\n",
bl_scale, bl_scale_sv, (u32)bl_temp);
rc = dsi_display_clk_ctrl(dsi_display->dsi_clk_handle,

View File

@@ -772,6 +772,9 @@ int dsi_conn_set_info_blob(struct drm_connector *connector,
break;
}
sde_kms_info_add_keyint(info, "max os brightness", panel->bl_config.brightness_max_level);
sde_kms_info_add_keyint(info, "max panel backlight", panel->bl_config.bl_max_level);
if (panel->spr_info.enable)
sde_kms_info_add_keystr(info, "spr_pack_type",
msm_spr_pack_type_str[panel->spr_info.pack_type]);

View File

@@ -126,10 +126,14 @@ struct dsi_backlight_config {
u32 bl_min_level;
u32 bl_max_level;
u32 brightness_max_level;
/* current brightness value */
u32 brightness;
u32 bl_level;
u32 bl_scale;
u32 bl_scale_sv;
bool bl_inverted_dbv;
/* digital dimming backlight LUT */
struct drm_msm_dimming_bl_lut *dimming_bl_lut;
int en_gpio;
/* PWM params */

View File

@@ -198,6 +198,7 @@ enum msm_mdp_conn_property {
CONNECTOR_PROP_PP_CWB_DITHER,
CONNECTOR_PROP_HDR_METADATA,
CONNECTOR_PROP_DEMURA_PANEL_ID,
CONNECTOR_PROP_DIMMING_BL_LUT,
/* # of blob properties */
CONNECTOR_PROP_BLOBCOUNT,

View File

@@ -99,6 +99,29 @@ static inline struct sde_kms *_sde_connector_get_kms(struct drm_connector *conn)
return to_sde_kms(priv->kms);
}
static void sde_dimming_bl_notify(struct sde_connector *conn, struct dsi_backlight_config *config)
{
struct drm_event event;
struct drm_msm_backlight_info bl_info;
if (!conn || !config)
return;
if (!conn->dimming_bl_notify_enabled)
return;
bl_info.brightness_max = config->brightness_max_level;
bl_info.brightness = config->brightness;
bl_info.bl_level_max = config->bl_max_level;
bl_info.bl_level = config->bl_level;
bl_info.bl_scale = config->bl_scale;
bl_info.bl_scale_sv = config->bl_scale_sv;
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);
msm_mode_object_event_notify(&conn->base.base, conn->base.dev, &event, (u8 *)&bl_info);
}
static int sde_backlight_device_update_status(struct backlight_device *bd)
{
int brightness;
@@ -129,6 +152,7 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
if (brightness > c_conn->thermal_max_brightness)
brightness = c_conn->thermal_max_brightness;
display->panel->bl_config.brightness = brightness;
/* map UI brightness into driver backlight level with rounding */
bl_lvl = mult_frac(brightness, display->panel->bl_config.bl_max_level,
display->panel->bl_config.brightness_max_level);
@@ -159,6 +183,7 @@ 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);
c_conn->unset_bl_level = 0;
}
@@ -649,6 +674,39 @@ static int _sde_connector_update_power_locked(struct sde_connector *c_conn)
return rc;
}
static int _sde_connector_update_dimming_bl_lut(struct sde_connector *c_conn,
struct sde_connector_state *c_state)
{
bool is_dirty;
size_t sz = 0;
struct dsi_display *dsi_display;
struct dsi_backlight_config *bl_config;
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;
}
is_dirty = msm_property_is_dirty(&c_conn->property_info,
&c_state->property_state,
CONNECTOR_PROP_DIMMING_BL_LUT);
if (!is_dirty)
return -ENODATA;
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);
return 0;
}
static int _sde_connector_update_bl_scale(struct sde_connector *c_conn)
{
struct dsi_display *dsi_display;
@@ -687,6 +745,8 @@ static int _sde_connector_update_bl_scale(struct sde_connector *c_conn)
bl_config->bl_level);
rc = c_conn->ops.set_backlight(&c_conn->base,
dsi_display, bl_config->bl_level);
if (!rc)
sde_dimming_bl_notify(c_conn, bl_config);
c_conn->unset_bl_level = 0;
return rc;
@@ -1595,6 +1655,9 @@ static int sde_connector_atomic_set_property(struct drm_connector *connector,
c_conn->bl_scale_sv = val;
c_conn->bl_scale_dirty = true;
break;
case CONNECTOR_PROP_DIMMING_BL_LUT:
rc = _sde_connector_update_dimming_bl_lut(c_conn, c_state);
break;
case CONNECTOR_PROP_HDR_METADATA:
rc = _sde_connector_set_ext_hdr_info(c_conn,
c_state, (void *)(uintptr_t)val);
@@ -2829,6 +2892,11 @@ 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)
msm_property_install_blob(&c_conn->property_info,
"dimming_bl_lut", DRM_MODE_PROP_BLOB,
CONNECTOR_PROP_DIMMING_BL_LUT);
if (dsi_display && dsi_display->panel &&
dsi_display->panel->hdr_props.hdr_enabled == true) {
msm_property_install_blob(&c_conn->property_info,
@@ -3176,11 +3244,21 @@ int sde_connector_register_custom_event(struct sde_kms *kms,
struct drm_connector *conn_drm, u32 event, bool val)
{
int ret = -EINVAL;
struct sde_connector *c_conn;
switch (event) {
case DRM_EVENT_SYS_BACKLIGHT:
ret = 0;
break;
case DRM_EVENT_DIMMING_BL:
if (!conn_drm) {
SDE_ERROR("invalid connector\n");
return -EINVAL;
}
c_conn = to_sde_connector(conn_drm);
c_conn->dimming_bl_notify_enabled = val;
ret = 0;
break;
case DRM_EVENT_PANEL_DEAD:
ret = 0;
break;
@@ -3206,6 +3284,7 @@ int sde_connector_event_notify(struct drm_connector *connector, uint32_t type,
switch (type) {
case DRM_EVENT_SYS_BACKLIGHT:
case DRM_EVENT_DIMMING_BL:
case DRM_EVENT_PANEL_DEAD:
case DRM_EVENT_SDE_HW_RECOVERY:
ret = 0;

View File

@@ -502,6 +502,7 @@ struct sde_connector_dyn_hdr_metadata {
* @hdr_supported: does the sink support HDR content
* @color_enc_fmt: Colorimetry encoding formats of sink
* @allow_bl_update: Flag to indicate if BL update is allowed currently or not
* @dimming_bl_notify_enabled: Flag to indicate if dimming bl notify is enabled or not
* @qsync_mode: Cached Qsync mode, 0=disabled, 1=continuous mode
* @qsync_updated: Qsync settings were updated
* @avr_step: fps rate for fixed steps in AVR mode; 0 means step is disabled
@@ -561,6 +562,7 @@ struct sde_connector {
u32 bl_scale_sv;
u32 unset_bl_level;
bool allow_bl_update;
bool dimming_bl_notify_enabled;
u32 hdr_eotf;
bool hdr_metadata_type_one;