Merge "disp: msm: sde: add support for digital dimming"
Tento commit je obsažen v:

odevzdal
Gerrit - the friendly Code Review server

revize
1b9345b3af
@@ -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_ */
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
@@ -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]);
|
||||
|
@@ -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 */
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele