drm/amd: Load DMCU IRAM
Subsystems (3)
PATCH v2 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
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): 20181113194234.29022-1-David.Francis-5C7GfCeVMHo@public.gmane.org
PATCH v2 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.
--- 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 | 38 ++++++++++++++++--- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + drivers/gpu/drm/amd/display/dc/core/dc.c | 11 +++++- drivers/gpu/drm/amd/display/dc/dc.h | 1 + 6 files changed, 52 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +5 -0
@@ -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
@@ -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 +33 -5
@@ -3038,6 +3038,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 +3089,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 +3158,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 +3912,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,
@@ -4399,7 +4413,8 @@ static bool commit_planes_to_stream(uint8_t new_plane_count, struct dm_crtc_state *dm_new_crtc_state, struct dm_crtc_state *dm_old_crtc_state, - struct dc_state *state) + struct dc_state *state, + bool abm_level_changed) { /* no need to dynamically allocate this. it's pretty small */ struct dc_surface_update updates[MAX_SURFACES];
@@ -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 (abm_level_changed) { + abm_level = dm_new_crtc_state->stream->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 =
@@ -4585,7 +4606,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, planes_count, acrtc_state, dm_old_crtc_state, - dm_state->context)) + dm_state->context, + false))dm_error ("%s: Failed to attach plane!\n" , __func__); }else {/*TODO BUG Here should go disable planes on CRTC. */
@@ -4759,12 +4781,13 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) } } -/* Handle scaling and underscan changes*/ +/* Handle scaling, underscan, freesync, 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);struct amdgpu_crtc *acrtc =to_amdgpu_crtc (dm_new_con_state->base.crtc);struct dc_stream_status *status =NULL ; +bool abm_level_changed = dm_old_con_state->abm_level != dm_new_con_state->abm_level;if (acrtc) { new_crtc_state =drm_atomic_get_new_crtc_state (state, &acrtc->base);
@@ -4776,7 +4799,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)continue ;/* Skip anything that is not scaling or underscan changes */ -if (!is_scaling_state_different (dm_new_con_state, dm_old_con_state)) +if (!is_scaling_state_different (dm_new_con_state, dm_old_con_state) + && !abm_level_changed)continue ; dm_new_crtc_state =to_dm_crtc_state (new_crtc_state);
@@ -4794,6 +4818,9 @@ 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; +if (abm_level_changed) + dm_new_crtc_state->stream->abm_level = dm_new_con_state->abm_level; +/*TODO How it works with MPO ?*/ if (!commit_planes_to_stream( dm->dc,
@@ -4801,7 +4828,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) status->plane_count, dm_new_crtc_state, to_dm_crtc_state(old_crtc_state), - dm_state->context)) + dm_state->context, + abm_level_changed))dm_error ("%s: Failed to update stream scaling!\n" , __func__); }
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +1 -0
@@ -255,6 +255,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
@@ -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; -} +}
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_ */
Signature · 6 lines
2.17.1 _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx