Skip to contentSkip to conversation

drm/amd: Load DMCU IRAM

PATCH In review David Francis 2 participants 3 messages Nov 20, 2018 – Nov 21, 2018 2 messages not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH v4 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): 20181120160017.16527-1-David.Francis-5C7GfCeVMHo@public.gmane.org

#2 lore raw

PATCH v4 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:
Store ABM level in crtc state to accommodate dc v4:
Fix ABM saving on dpms cycle

---
 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 | 36 ++++++++++++++++---
 .../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, 53 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 +32 -4
index f71febb4210d..95b1106e0662 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 =
@@ -4579,6 +4600,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 
 		dc_stream_attach->adjust = acrtc_state->adjust;
 		dc_stream_attach->vrr_infopacket = acrtc_state->vrr_infopacket;
+		dc_stream_attach->abm_level = acrtc_state->abm_level;
 
 		if (false == commit_planes_to_stream(dm->dc,
 							plane_states_constructed,
@@ -4759,7 +4781,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 +4797,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 +4818,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 +5156,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): 20181120160017.16527-2-David.Francis-5C7GfCeVMHo@public.gmane.org

Reviewed-by Harry Wentland
#4 lore raw

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

Quoted 19 lines · 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.

Quoted 8 lines

v2:
Fix commit message, only attach property if DMCU loaded v3:
Store ABM level in crtc state to accommodate dc v4:
Fix ABM saving on dpms cycle

Series is

Harry

Quoted 219 lines
---
 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 | 36 ++++++++++++++++---
 .../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, 53 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 +32 -4
index f71febb4210d..95b1106e0662 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 =
@@ -4579,6 +4600,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 
 		dc_stream_attach->adjust = acrtc_state->adjust;
 		dc_stream_attach->vrr_infopacket = acrtc_state->vrr_infopacket;
+		dc_stream_attach->abm_level = acrtc_state->abm_level;
 
 		if (false == commit_planes_to_stream(dm->dc,
 							plane_states_constructed,
@@ -4759,7 +4781,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 +4797,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 +4818,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 +5156,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