diff --git a/include/uapi/display/drm/sde_drm.h b/include/uapi/display/drm/sde_drm.h index 67fc98b4152c..bd8e8c219a43 100644 --- a/include/uapi/display/drm/sde_drm.h +++ b/include/uapi/display/drm/sde_drm.h @@ -690,6 +690,27 @@ struct drm_msm_display_hint { #define DRM_IOCTL_MSM_DISPLAY_HINT DRM_IOW((DRM_COMMAND_BASE + \ DRM_MSM_DISPLAY_HINT), struct drm_msm_display_hint) +/* panel feature */ +typedef enum { + PARAM_HBM = 0, + PARAM_CABC, + PARAM_ACL, + PARAM_DC, + POWER_MODE_MAX_NUM, + PARAM_COLOR = POWER_MODE_MAX_NUM, + PARAM_MAX_NUM +} paramId_t; + +struct panel_param_info { + paramId_t param_idx; + __u32 value; +}; + +#define DRM_SET_PANEL_FEATURE (DRM_COMMAND_END -1) +#define DRM_IOCTL_SET_PANEL_FEATURE DRM_IOWR(DRM_SET_PANEL_FEATURE, struct panel_param_info) +#define DRM_GET_PANEL_FEATURE (DRM_COMMAND_END-2) +#define DRM_IOCTL_GET_PANEL_FEATURE DRM_IOWR(DRM_GET_PANEL_FEATURE, struct panel_param_info) + #if defined(__cplusplus) } #endif diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 2c3e81f7cabf..870a7e4cbdbc 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1746,6 +1746,38 @@ int msm_ioctl_display_hint_ops(struct drm_device *dev, void *data, return 0; } +static int msm_ioctl_set_panel_feature(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct msm_drm_private *priv; + struct msm_kms *kms; + struct panel_param_info *param_info = data; + int ret; + + priv = dev->dev_private; + kms = priv->kms; + + if (unlikely(!param_info)) { + DRM_ERROR("ioctl_set_panel_feature invalid data\n"); + return -EINVAL; + } + + DRM_INFO("ioctl_set_panel_feature idx=%d, value=%d\n", + param_info->param_idx, param_info->value); + + if (kms && kms->funcs && kms->funcs->set_panel_feature) { + ret = kms->funcs->set_panel_feature(kms, *param_info); + if (ret) { + DRM_ERROR("kms set_panel_feature failed.\n"); + goto fail; + } + } + + return 0; +fail: + return ret; +} + static const struct drm_ioctl_desc msm_ioctls[] = { DRM_IOCTL_DEF_DRV(MSM_GEM_NEW, msm_ioctl_gem_new, DRM_AUTH|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_AUTH|DRM_RENDER_ALLOW), @@ -1761,6 +1793,8 @@ static const struct drm_ioctl_desc msm_ioctls[] = { DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(MSM_DISPLAY_HINT, msm_ioctl_display_hint_ops, DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(SET_PANEL_FEATURE, msm_ioctl_set_panel_feature, + DRM_UNLOCKED), }; static const struct vm_operations_struct vm_ops = { diff --git a/msm/msm_kms.h b/msm/msm_kms.h index 058f97cdf53a..c56c2f61f03d 100644 --- a/msm/msm_kms.h +++ b/msm/msm_kms.h @@ -133,6 +133,9 @@ struct msm_kms_funcs { /* topology dsc information */ int (*get_dsc_count)(const struct msm_kms *kms, u32 hdisplay, u32 *num_dsc); + /* set panel feature */ + int (*set_panel_feature)(const struct msm_kms *kms, + struct panel_param_info param_info); }; struct msm_kms { diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index ededce65fb3e..e750b82cf7dc 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -3657,6 +3657,27 @@ static int sde_kms_get_dsc_count(const struct msm_kms *kms, return 0; } +static int sde_kms_set_panel_feature(const struct msm_kms *kms, + struct panel_param_info param_info) +{ + struct sde_kms *sde_kms; + struct dsi_display *display; + struct msm_param_info param_info_msm; + + if (!kms) { + SDE_ERROR("invalid input args\n"); + return -EINVAL; + } + + sde_kms = to_sde_kms(kms); + param_info_msm.param_idx = (enum msm_param_id)param_info.param_idx; + param_info_msm.value = param_info.value; + display = (struct dsi_display *)sde_kms->dsi_displays[0]; + dsi_display_set_param(display, ¶m_info_msm); + + return 0; +} + static void _sde_kms_null_commit(struct drm_device *dev, struct drm_encoder *enc) { @@ -4085,6 +4106,7 @@ static const struct msm_kms_funcs kms_funcs = { .check_for_splash = sde_kms_check_for_splash, .get_mixer_count = sde_kms_get_mixer_count, .get_dsc_count = sde_kms_get_dsc_count, + .set_panel_feature = sde_kms_set_panel_feature, }; static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms)