Skip to contentSkip to conversation

drm/amd: Load DMCU IRAM

PATCH Superseded David Francis 2 participants 3 messages Nov 15, 2018 – Nov 16, 2018 2 messages not in the archive

Subsystems (3)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH v3 1/2 drm/amd: Load DMCU IRAM

DMCU IRAM must be loaded by the driver before DMCU can function.

Move the IRAM code out of the shadows and into a new file modules/power/power_helpers.c

The IRAM table contains the backlight curve and ABM parameters

Add this new file to the Makefiles

Call dmcu_load_iram in late init of DM

Move struct dmcu_version from dc.h to dmcu.h to allow dmcu to be included on its own

---
 drivers/gpu/drm/amd/display/Makefile          |   3 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  21 ++
 drivers/gpu/drm/amd/display/dc/dc.h           |   8 +-
 drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h  |   7 +
 .../drm/amd/display/modules/power/Makefile    |  31 ++
 .../amd/display/modules/power/power_helpers.c | 326 ++++++++++++++++++
 .../amd/display/modules/power/power_helpers.h |  47 +++
 7 files changed, 435 insertions(+), 8 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/modules/power/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/modules/power/power_helpers.c
 create mode 100644 drivers/gpu/drm/amd/display/modules/power/power_helpers.h
drivers/gpu/drm/amd/display/Makefile +2 -1
index c97dc9613325..cfde1568c79a 100644
@@ -32,11 +32,12 @@ subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/inc
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/freesync
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/color
 subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/info_packet
+subdir-ccflags-y += -I$(FULL_AMD_DISPLAY_PATH)/modules/power
 
 #TODO: remove when Timing Sync feature is complete
 subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
 
-DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet
+DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power
 
 AMD_DAL = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/,$(DAL_LIBS)))
 
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +21 -0
index 0c1a533eb531..f71febb4210d 100644
@@ -72,6 +72,7 @@
 #endif
 
 #include "modules/inc/mod_freesync.h"
+#include "modules/power/power_helpers.h"
 
 #define FIRMWARE_RAVEN_DMCU		"amdgpu/raven_dmcu.bin"
 MODULE_FIRMWARE(FIRMWARE_RAVEN_DMCU);
@@ -643,6 +644,26 @@ static int dm_late_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	struct dmcu_iram_parameters params;
+	unsigned int linear_lut[16];
+	int i;
+	struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu;
+	bool ret;
+
+	for (i = 0; i < 16; i++)
+		linear_lut[i] = 0xFFFF * i / 15;
+
+	params.set = 0;
+	params.backlight_ramping_start = 0xCCCC;
+	params.backlight_ramping_reduction = 0xCCCCCCCC;
+	params.backlight_lut_array_size = 16;
+	params.backlight_lut_array = linear_lut;
+
+	ret = dmcu_load_iram(dmcu, params);
+
+	if (!ret)
+		return -EINVAL;
+
 	return detect_mst_link_for_all_connectors(adev->ddev);
 }
 
drivers/gpu/drm/amd/display/dc/dc.h +1 -7
index 18865a76ea55..6b0988310138 100644
@@ -36,6 +36,7 @@
 
 #include "inc/hw_sequencer.h"
 #include "inc/compressor.h"
+#include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
 #define DC_VER "3.2.06"
@@ -47,13 +48,6 @@
 /*******************************************************************************
  * Display Core Interfaces
  ******************************************************************************/
-struct dmcu_version {
-	unsigned int date;
-	unsigned int month;
-	unsigned int year;
-	unsigned int interface_version;
-};
-
 struct dc_versions {
 	const char *dc_ver;
 	struct dmcu_version dmcu_version;
drivers/gpu/drm/amd/display/dc/inc/hw/dmcu.h +7 -0
index 4550747fb61c..cb85eaa9857f 100644
@@ -32,6 +32,13 @@ enum dmcu_state {
 	DMCU_RUNNING = 1
 };
 
+struct dmcu_version {
+	unsigned int date;
+	unsigned int month;
+	unsigned int year;
+	unsigned int interface_version;
+};
+
 struct dmcu {
 	struct dc_context *ctx;
 	const struct dmcu_funcs *funcs;
drivers/gpu/drm/amd/display/modules/power/Makefile new file +31 -0
new file mode 100644
index 000000000000..87851f892a52
@@ -0,0 +1,31 @@
+#
+# Copyright 2017 Advanced Micro Devices, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#
+# Makefile for the 'power' sub-module of DAL.
+#
+
+MOD_POWER = power_helpers.o
+
+AMD_DAL_MOD_POWER = $(addprefix $(AMDDALPATH)/modules/power/,$(MOD_POWER))
+#$(info ************  DAL POWER MODULE MAKEFILE ************)
+
+AMD_DISPLAY_FILES += $(AMD_DAL_MOD_POWER)
\ No newline at end of file
drivers/gpu/drm/amd/display/modules/power/power_helpers.c new file +326 -0

326 lines not on this page · raw message

drivers/gpu/drm/amd/display/modules/power/power_helpers.h new file +47 -0

47 lines not on this page · raw message

Signature · 6 lines
2.17.1

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

A message that is not in the archive (sent off-list or not yet received): 20181115152022.12191-1-David.Francis-5C7GfCeVMHo@public.gmane.org

#2 lore raw

PATCH v3 2/2 drm/amd: Add abm level drm property

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

---
 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(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +5 -0
index 7d6a36bca9dd..ced8cefa223b 100644
@@ -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;
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +2 -0
index 1627dd3413c7..2938635c0fc1 100644
@@ -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;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +31 -4
index f71febb4210d..090a602f3014 100644
@@ -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 &new_state->base;
 }
@@ -3904,6 +3913,12 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
 		drm_object_attach_property(&aconnector->base.base,
 				adev->mode_info.freesync_capable_property, 0);
 	}
+
+	if (connector_type == DRM_MODE_CONNECTOR_eDP &&
+	    dc_is_dmcu_initialized(adev->dm.dc)) {
+		drm_object_attach_property(&aconnector->base.base,
+				adev->mode_info.abm_level_property, 0);
+	}
 }
 
 static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap,
@@ -4410,6 +4425,7 @@ static bool commit_planes_to_stream(
 	struct dc_stream_state *dc_stream = dm_new_crtc_state->stream;
 	struct dc_stream_update *stream_update =
 			kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
+	unsigned int abm_level;
 
 	if (!stream_update) {
 		BREAK_TO_DEBUGGER();
@@ -4442,6 +4458,11 @@ static bool commit_planes_to_stream(
 		stream_update->adjust = &dc_stream->adjust;
 	}
 
+	if (dm_new_crtc_state->abm_level != dm_old_crtc_state->abm_level) {
+		abm_level = dm_new_crtc_state->abm_level;
+		stream_update->abm_level = &abm_level;
+	}
+
 	for (i = 0; i < new_plane_count; i++) {
 		updates[i].surface = plane_states[i];
 		updates[i].gamma =
@@ -4759,7 +4780,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 		}
 	}
 
-	/* Handle scaling and underscan changes*/
+	/* Handle scaling, underscan, and abm changes*/
 	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
 		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
 		struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
@@ -4775,11 +4796,14 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 		if (!acrtc || drm_atomic_crtc_needs_modeset(new_crtc_state))
 			continue;
 
-		/* Skip anything that is not scaling or underscan changes */
-		if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state))
-			continue;
 
 		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
+
+		/* Skip anything that is not scaling or underscan changes */
+		if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state) &&
+				(dm_new_crtc_state->abm_level == dm_old_crtc_state->abm_level))
+			continue;
 
 		update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode,
 				dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream);
@@ -4793,6 +4817,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 
 		dm_new_crtc_state->stream->adjust = dm_new_crtc_state->adjust;
 		dm_new_crtc_state->stream->vrr_infopacket = dm_new_crtc_state->vrr_infopacket;
+		dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level;
 
 		/*TODO How it works with MPO ?*/
 		if (!commit_planes_to_stream(
@@ -5130,6 +5155,8 @@ static int dm_update_crtcs_state(struct amdgpu_display_manager *dm,
 			set_freesync_on_stream(dm, dm_new_crtc_state,
 					       dm_new_conn_state, new_stream);
 
+			dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level;
+
 			if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
 			    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
 				new_crtc_state->mode_changed = false;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +3 -0
index d6960644d714..3c2fbfac938f 100644
@@ -234,6 +234,8 @@ struct dm_crtc_state {
 	bool freesync_enabled;
 	struct dc_crtc_timing_adjust adjust;
 	struct dc_info_packet vrr_infopacket;
+
+	int abm_level;
 };
 
 #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
@@ -255,6 +257,7 @@ struct dm_connector_state {
 	bool underscan_enable;
 	bool freesync_enable;
 	bool freesync_capable;
+	uint8_t abm_level;
 };
 
 #define to_dm_connector_state(x)\
drivers/gpu/drm/amd/display/dc/core/dc.c +10 -1
index 1d8bd554869b..dba6b57830c7 100644
@@ -1686,6 +1686,15 @@ void dc_resume(struct dc *dc)
 		core_link_resume(dc->links[i]);
 }
 
+bool dc_is_dmcu_initialized(struct dc *dc)
+{
+	struct dmcu *dmcu = dc->res_pool->dmcu;
+
+	if (dmcu)
+		return dmcu->funcs->is_dmcu_initialized(dmcu);
+	return false;
+}
+
 bool dc_submit_i2c(
 		struct dc *dc,
 		uint32_t link_index,
@@ -1810,4 +1819,4 @@ void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx
 	info->dcfClockDeepSleep			= (unsigned int)state->bw.dcn.clk.dcfclk_deep_sleep_khz;
 	info->fClock					= (unsigned int)state->bw.dcn.clk.fclk_khz;
 	info->phyClock					= (unsigned int)state->bw.dcn.clk.phyclk_khz;
-}
\ No newline at end of file
+}
drivers/gpu/drm/amd/display/dc/dc.h +1 -0
index 6b0988310138..dea8bc39c688 100644
@@ -742,5 +742,6 @@ void dc_set_power_state(
 		struct dc *dc,
 		enum dc_acpi_cm_power_state power_state);
 void dc_resume(struct dc *dc);
+bool dc_is_dmcu_initialized(struct dc *dc);
 
 #endif /* DC_INTERFACE_H_ */
Signature · 6 lines
2.17.1

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

A message that is not in the archive (sent off-list or not yet received): 20181115152022.12191-2-David.Francis-5C7GfCeVMHo@public.gmane.org

#4 lore raw

Re: [PATCH v3 2/2] drm/amd: Add abm level drm property

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.

Quoted 235 lines · David.Francis at amd.com (David Francis)

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 <David.Francis at amd.com>
---
  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(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +5 -0
index 7d6a36bca9dd..ced8cefa223b 100644
@@ -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;
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +2 -0
index 1627dd3413c7..2938635c0fc1 100644
@@ -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;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +31 -4
index f71febb4210d..090a602f3014 100644
@@ -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 &new_state->base;
  }
@@ -3904,6 +3913,12 @@ void amdgpu_dm_connector_init_helper(struct amdgpu_display_manager *dm,
  		drm_object_attach_property(&aconnector->base.base,
  				adev->mode_info.freesync_capable_property, 0);
  	}
+
+	if (connector_type == DRM_MODE_CONNECTOR_eDP &&
+	    dc_is_dmcu_initialized(adev->dm.dc)) {
+		drm_object_attach_property(&aconnector->base.base,
+				adev->mode_info.abm_level_property, 0);
+	}
  }
 
  static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap,
@@ -4410,6 +4425,7 @@ static bool commit_planes_to_stream(
  	struct dc_stream_state *dc_stream = dm_new_crtc_state->stream;
  	struct dc_stream_update *stream_update =
  			kzalloc(sizeof(struct dc_stream_update), GFP_KERNEL);
+	unsigned int abm_level;
 
  	if (!stream_update) {
  		BREAK_TO_DEBUGGER();
@@ -4442,6 +4458,11 @@ static bool commit_planes_to_stream(
  		stream_update->adjust = &dc_stream->adjust;
  	}
 
+	if (dm_new_crtc_state->abm_level != dm_old_crtc_state->abm_level) {
+		abm_level = dm_new_crtc_state->abm_level;
+		stream_update->abm_level = &abm_level;
+	}
+
  	for (i = 0; i < new_plane_count; i++) {
  		updates[i].surface = plane_states[i];
  		updates[i].gamma =
@@ -4759,7 +4780,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
  		}
  	}
 
-	/* Handle scaling and underscan changes*/
+	/* Handle scaling, underscan, and abm changes*/
  	for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) {
  		struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state);
  		struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state);
@@ -4775,11 +4796,14 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
  		if (!acrtc || drm_atomic_crtc_needs_modeset(new_crtc_state))
  			continue;
 
-		/* Skip anything that is not scaling or underscan changes */
-		if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state))
-			continue;
 
  		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
+
+		/* Skip anything that is not scaling or underscan changes */
+		if (!is_scaling_state_different(dm_new_con_state, dm_old_con_state) &&
+				(dm_new_crtc_state->abm_level == dm_old_crtc_state->abm_level))
+			continue;
 
  		update_stream_scaling_settings(&dm_new_con_state->base.crtc->mode,
  				dm_new_con_state, (struct dc_stream_state *)dm_new_crtc_state->stream);
@@ -4793,6 +4817,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 
  		dm_new_crtc_state->stream->adjust = dm_new_crtc_state->adjust;
  		dm_new_crtc_state->stream->vrr_infopacket = dm_new_crtc_state->vrr_infopacket;
+		dm_new_crtc_state->stream->abm_level = dm_new_crtc_state->abm_level;
 
  		/*TODO How it works with MPO ?*/
  		if (!commit_planes_to_stream(
@@ -5130,6 +5155,8 @@ static int dm_update_crtcs_state(struct amdgpu_display_manager *dm,
  			set_freesync_on_stream(dm, dm_new_crtc_state,
  					       dm_new_conn_state, new_stream);
 
+			dm_new_crtc_state->abm_level = dm_new_conn_state->abm_level;
+
  			if (dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) &&
  			    dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream)) {
  				new_crtc_state->mode_changed = false;
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +3 -0
index d6960644d714..3c2fbfac938f 100644
@@ -234,6 +234,8 @@ struct dm_crtc_state {
  	bool freesync_enabled;
  	struct dc_crtc_timing_adjust adjust;
  	struct dc_info_packet vrr_infopacket;
+
+	int abm_level;
  };
 
  #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
@@ -255,6 +257,7 @@ struct dm_connector_state {
  	bool underscan_enable;
  	bool freesync_enable;
  	bool freesync_capable;
+	uint8_t abm_level;
  };
 
  #define to_dm_connector_state(x)\
drivers/gpu/drm/amd/display/dc/core/dc.c +10 -1
index 1d8bd554869b..dba6b57830c7 100644
@@ -1686,6 +1686,15 @@ void dc_resume(struct dc *dc)
  		core_link_resume(dc->links[i]);
  }
 
+bool dc_is_dmcu_initialized(struct dc *dc)
+{
+	struct dmcu *dmcu = dc->res_pool->dmcu;
+
+	if (dmcu)
+		return dmcu->funcs->is_dmcu_initialized(dmcu);
+	return false;
+}
+
  bool dc_submit_i2c(
  		struct dc *dc,
  		uint32_t link_index,
@@ -1810,4 +1819,4 @@ void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx
  	info->dcfClockDeepSleep			= (unsigned int)state->bw.dcn.clk.dcfclk_deep_sleep_khz;
  	info->fClock					= (unsigned int)state->bw.dcn.clk.fclk_khz;
  	info->phyClock					= (unsigned int)state->bw.dcn.clk.phyclk_khz;
-}
\ No newline at end of file
+}
drivers/gpu/drm/amd/display/dc/dc.h +0 -0
index 6b0988310138..dea8bc39c688 100644

drivers/gpu/drm/amd/display/dc/dc.h void dc_set_power_state( · line 747

Quoted 6 lines
drivers/gpu/drm/amd/display/dc/dc.h +1 -0
@@ -742,5 +742,6 @@ void dc_set_power_state(
  		struct dc *dc,
  		enum dc_acpi_cm_power_state power_state);
  void dc_resume(struct dc *dc);
+bool dc_is_dmcu_initialized(struct dc *dc);
 
  #endif /* DC_INTERFACE_H_ */

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx