David,
Your patch works great. If you are not aware, the ABM does not work
anymore after the display turns off and back on again. Setting ABM level
to 0 and back to 4 makes it start working again though. This happens
when my display turns off automatically, but you can replicate this by
running `xset dpms force off`.
On 15-11-18 07:20, David.Francis at amd.com (David Francis) wrote:
Adaptive Backlight Management (ABM) is a feature
that reduces backlight level to save power, while
increasing pixel contrast and pixel luminance
to maintain readability and image quality.
ABM will adjust in response to the
pixel luminance of the displayed content.
ABM is made available as a drm property on eDP
monitors called "abm level", which ranges from 0 to 4.
When this property is set to 0, ABM is off. Levels 1
to 4 represent different ranges of backlight reduction.
At higher levels both the backlight reduction and pixel
adjustment will be greater.
ABM requires DMCU firmware, which is currently available for
Raven ASICs only. If the feature does not work, please
ensure your firmware is up to date.
v2:
Fix commit message, only attach property if DMCU loaded
v3:
Storre ABM level in crtc state to accommodate dc
Signed-off-by: David Francis
---
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 5 +++
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 2 ++
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 35 ---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 ++
drivers/gpu/drm/amd/display/dc/core/dc.c | 11 +-
drivers/gpu/drm/amd/display/dc/dc.h | 1 +
6 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 7d6a36bca9dd..ced8cefa223b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -637,6 +637,11 @@ int amdgpu_display_modeset_create_props(struct
amdgpu_device *adev)
"freesync_capable");
if (!adev->mode_info.freesync_capable_property)
return -ENOMEM;
+ adev->mode_info.abm_level_property =
+ drm_property_create_range(adev->ddev, 0,
+ "abm level", 0, 4);
+ if (!adev->mode_info.abm_level_property)
+ return -ENOMEM;
}
return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1627dd3413c7..2938635c0fc1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -342,6 +342,8 @@ struct amdgpu_mode_info {
struct drm_property *freesync_property;
/* it is used to know about display capability of freesync mode */
struct drm_property *freesync_capable_property;
+ /* Adaptive Backlight Modulation (power feature) */
+ struct drm_property *abm_level_property;
/* hardcoded DFP edid from BIOS */
struct edid *bios_hardcoded_edid;
int bios_hardcoded_edid_size;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index f71febb4210d..090a602f3014 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2920,6 +2920,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
state->adjust = cur->adjust;
state->vrr_infopacket = cur->vrr_infopacket;
state->freesync_enabled = cur->freesync_enabled;
+ state->abm_level = cur->abm_level;
/* TODO Duplicate dc_stream after objects are stream object is flattened */
@@ -3038,6 +3039,9 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector,
} else if (property == adev->mode_info.freesync_capable_property) {
dm_new_state->freesync_capable = val;
ret = 0;
+ } else if (property == adev->mode_info.abm_level_property) {
+ dm_new_state->abm_level = val;
+ ret = 0;
}
return ret;
@@ -3086,7 +3090,11 @@ int amdgpu_dm_connector_atomic_get_property(struct
drm_connector *connector,
} else if (property == adev->mode_info.freesync_capable_property) {
*val = dm_state->freesync_capable;
ret = 0;
+ } else if (property == adev->mode_info.abm_level_property) {
+ *val = dm_state->abm_level;
+ ret = 0;
}
+
return ret;
}
@@ -3151,6 +3159,7 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
new_state->freesync_capable = state->freesync_capable;
new_state->freesync_enable = state->freesync_enable;
+ new_state->abm_level = state->abm_level;
return _state->base;
}
@@ -3904,6 +3913,12 @@ void