From: Iswara Nagulendran <iswara.nagulend...@amd.com>

[HOW&WHY]
Write DPCD 721 bit 7 to high, and
the appropriate luminance level
to DPCD 734-736 if bit 4 from DPCD register
734 is high, indicating that the panel
luminance control is enabled from the panel side.

Reviewed-by: Anthony Koo <anthony....@amd.com>
Acked-by: Qingqing Zhuo <qingqing.z...@amd.com>
Signed-off-by: Iswara Nagulendran <iswara.nagulend...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_dp_types.h  |  7 +++++
 .../dc/link/protocols/link_dp_capability.c    |  9 +++++-
 .../link/protocols/link_edp_panel_control.c   | 29 ++++++++++++++++---
 include/drm/display/drm_dp.h                  |  3 ++
 4 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h 
b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
index 49aab1924665..4a7f6497dc5a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h
@@ -566,6 +566,12 @@ struct dpcd_amd_device_id {
        uint8_t dal_version_byte2;
 };
 
+struct target_luminance_value {
+       uint8_t byte0;
+       uint8_t byte1;
+       uint8_t byte2;
+};
+
 struct dpcd_source_backlight_set {
        struct  {
                uint8_t byte0;
@@ -1225,6 +1231,7 @@ struct dpcd_caps {
        union dp_main_line_channel_coding_cap channel_coding_cap;
        union dp_sink_video_fallback_formats fallback_formats;
        union dp_fec_capability1 fec_cap1;
+       bool panel_luminance_control;
        union dp_cable_id cable_id;
        uint8_t edp_rev;
        union edp_alpm_caps alpm_caps;
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index eeaceed61bc4..50327a559a47 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -1449,7 +1449,8 @@ bool read_is_mst_supported(struct dc_link *link)
  */
 static bool dpcd_read_sink_ext_caps(struct dc_link *link)
 {
-       uint8_t dpcd_data;
+       uint8_t dpcd_data = 0;
+       uint8_t edp_general_cap2 = 0;
 
        if (!link)
                return false;
@@ -1458,6 +1459,12 @@ static bool dpcd_read_sink_ext_caps(struct dc_link *link)
                return false;
 
        link->dpcd_sink_ext_caps.raw = dpcd_data;
+
+       if (core_link_read_dpcd(link, DP_EDP_GENERAL_CAP_2, &edp_general_cap2, 
1) != DC_OK)
+               return false;
+
+       link->dpcd_caps.panel_luminance_control = (edp_general_cap2 & 
DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE) != 0;
+
        return true;
 }
 
diff --git 
a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c 
b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
index d895046787bc..5ab2de12ccf8 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
@@ -164,14 +164,35 @@ bool edp_set_backlight_level_nits(struct dc_link *link,
        *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = 
(uint16_t)transition_time_in_ms;
 
 
-       if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
+       if (!link->dpcd_caps.panel_luminance_control) {
+               if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
                        (uint8_t *)(&dpcd_backlight_set),
                        sizeof(dpcd_backlight_set)) != DC_OK)
-               return false;
+                       return false;
 
-       if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
+               if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL,
                        &backlight_control, 1) != DC_OK)
-               return false;
+                       return false;
+       } else {
+               const uint8_t backlight_enable = 
DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE;
+               struct target_luminance_value *target_luminance = NULL;
+
+               //if target luminance value is greater than 24 bits, clip the 
value to 24 bits
+               if (backlight_millinits > 0xFFFFFF)
+                       backlight_millinits = 0xFFFFFF;
+
+               target_luminance = (struct target_luminance_value 
*)&backlight_millinits;
+
+               if (core_link_write_dpcd(link, 
DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
+                       &backlight_enable,
+                       sizeof(backlight_enable)) != DC_OK)
+                       return false;
+
+               if (core_link_write_dpcd(link, 
DP_EDP_PANEL_TARGET_LUMINANCE_VALUE,
+                       (uint8_t *)(target_luminance),
+                       sizeof(struct target_luminance_value)) != DC_OK)
+                       return false;
+       }
 
        return true;
 }
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index ed10e6b6f99d..f1be179c5f1f 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -973,6 +973,7 @@
 
 #define DP_EDP_GENERAL_CAP_2               0x703
 # define DP_EDP_OVERDRIVE_ENGINE_ENABLED               (1 << 0)
+# define DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE (1 << 4)
 
 #define DP_EDP_GENERAL_CAP_3               0x704    /* eDP 1.4 */
 # define DP_EDP_X_REGION_CAP_MASK                      (0xf << 0)
@@ -998,6 +999,7 @@
 # define DP_EDP_DYNAMIC_BACKLIGHT_ENABLE               (1 << 4)
 # define DP_EDP_REGIONAL_BACKLIGHT_ENABLE              (1 << 5)
 # define DP_EDP_UPDATE_REGION_BRIGHTNESS               (1 << 6) /* eDP 1.4 */
+# define DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE  (1 << 7)
 
 #define DP_EDP_BACKLIGHT_BRIGHTNESS_MSB     0x722
 #define DP_EDP_BACKLIGHT_BRIGHTNESS_LSB     0x723
@@ -1022,6 +1024,7 @@
 
 #define DP_EDP_DBC_MINIMUM_BRIGHTNESS_SET   0x732
 #define DP_EDP_DBC_MAXIMUM_BRIGHTNESS_SET   0x733
+#define DP_EDP_PANEL_TARGET_LUMINANCE_VALUE 0x734
 
 #define DP_EDP_REGIONAL_BACKLIGHT_BASE      0x740    /* eDP 1.4 */
 #define DP_EDP_REGIONAL_BACKLIGHT_0        0x741    /* eDP 1.4 */
-- 
2.34.1

Reply via email to