mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 05:04:02 +02:00
drm/amd/display: Enable CACP on Linux
[Why] Enable OLED panels to save more power on the Linux platform by enabling CACP support on Linux. [How] Update abm_feature_support() to return ABM_CACP_SUPPORT for OLED panels. Enable ABM property for all eDP panels including OLED to support CACP via set_abm_level. Reviewed-by: Sun peng (Leo) Li <sunpeng.li@amd.com> Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
5b69770e94
commit
7b0cc30852
|
|
@ -559,7 +559,6 @@ EXPORT_IF_KUNIT(amdgpu_dm_update_connector_ext_caps);
|
|||
void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct amdgpu_dm_backlight_caps *caps;
|
||||
struct dc_link *link = aconnector->dc_link;
|
||||
int bl_idx = dm->num_of_edps;
|
||||
|
||||
|
|
@ -579,10 +578,12 @@ void amdgpu_dm_setup_backlight_device(struct amdgpu_display_manager *dm,
|
|||
dm->num_of_edps++;
|
||||
|
||||
amdgpu_dm_update_connector_ext_caps(aconnector);
|
||||
caps = &dm->backlight_caps[aconnector->bl_idx];
|
||||
|
||||
/* Only offer ABM property when non-OLED and user didn't turn off by module parameter */
|
||||
if (caps->ext_caps && !caps->ext_caps->bits.oled && amdgpu_dm_abm_level < 0)
|
||||
/* Offer ABM property when user didn't turn off by module parameter.
|
||||
* OLED panels are included to support CACP (Content Adaptive
|
||||
* Contrast and Power) feature via set_abm_level.
|
||||
*/
|
||||
if (amdgpu_dm_abm_level < 0)
|
||||
drm_object_attach_property(&aconnector->base.base,
|
||||
dm->adev->mode_info.abm_level_property,
|
||||
ABM_SYSFS_CONTROL);
|
||||
|
|
@ -666,22 +667,16 @@ const struct attribute_group amdgpu_group = {
|
|||
bool
|
||||
amdgpu_dm_should_create_sysfs(struct amdgpu_dm_connector *amdgpu_dm_connector)
|
||||
{
|
||||
struct dc_link *link = amdgpu_dm_connector->dc_link;
|
||||
|
||||
if (amdgpu_dm_abm_level >= 0)
|
||||
return false;
|
||||
|
||||
if (amdgpu_dm_connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
|
||||
return false;
|
||||
|
||||
/* check for OLED panels */
|
||||
if (amdgpu_dm_connector->bl_idx >= 0) {
|
||||
struct drm_device *drm = amdgpu_dm_connector->base.dev;
|
||||
struct amdgpu_display_manager *dm = &drm_to_adev(drm)->dm;
|
||||
struct amdgpu_dm_backlight_caps *caps;
|
||||
|
||||
caps = &dm->backlight_caps[amdgpu_dm_connector->bl_idx];
|
||||
if (caps->aux_support)
|
||||
return false;
|
||||
}
|
||||
if (link->panel_type != PANEL_TYPE_LCD && !link->panel_config.cacp.cacp_supported)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,32 +392,31 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_commit *state,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void dm_set_panel_type(struct amdgpu_dm_connector *aconnector)
|
||||
static void amdgpu_dm_set_panel_type(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct drm_connector *connector = &aconnector->base;
|
||||
struct drm_display_info *display_info = &connector->display_info;
|
||||
struct dc_link *link = aconnector->dc_link;
|
||||
struct amdgpu_device *adev;
|
||||
enum dc_panel_type panel_type = PANEL_TYPE_NONE;
|
||||
|
||||
adev = drm_to_adev(connector->dev);
|
||||
|
||||
link->panel_type = PANEL_TYPE_NONE;
|
||||
|
||||
switch (display_info->amd_vsdb.panel_type) {
|
||||
case AMD_VSDB_PANEL_TYPE_OLED:
|
||||
link->panel_type = PANEL_TYPE_OLED;
|
||||
panel_type = PANEL_TYPE_OLED;
|
||||
break;
|
||||
case AMD_VSDB_PANEL_TYPE_MINILED:
|
||||
link->panel_type = PANEL_TYPE_MINILED;
|
||||
panel_type = PANEL_TYPE_MINILED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If VSDB didn't determine panel type, check DPCD ext caps */
|
||||
if (link->panel_type == PANEL_TYPE_NONE) {
|
||||
if (panel_type == PANEL_TYPE_NONE) {
|
||||
if (link->dpcd_sink_ext_caps.bits.miniled == 1)
|
||||
link->panel_type = PANEL_TYPE_MINILED;
|
||||
panel_type = PANEL_TYPE_MINILED;
|
||||
if (link->dpcd_sink_ext_caps.bits.oled == 1)
|
||||
link->panel_type = PANEL_TYPE_OLED;
|
||||
panel_type = PANEL_TYPE_OLED;
|
||||
}
|
||||
|
||||
/* If VSDB and DPCD didn't determine panel type, check DID */
|
||||
|
|
@ -428,7 +427,7 @@ static void dm_set_panel_type(struct amdgpu_dm_connector *aconnector)
|
|||
link->panel_type = PANEL_TYPE_OLED;
|
||||
}
|
||||
|
||||
if (link->panel_type == PANEL_TYPE_NONE) {
|
||||
if (panel_type == PANEL_TYPE_NONE) {
|
||||
struct drm_amd_vsdb_info *vsdb = &display_info->amd_vsdb;
|
||||
u32 lum1_max = vsdb->luminance_range1.max_luminance;
|
||||
u32 lum2_max = vsdb->luminance_range2.max_luminance;
|
||||
|
|
@ -437,9 +436,14 @@ static void dm_set_panel_type(struct amdgpu_dm_connector *aconnector)
|
|||
link->local_sink->edid_caps.manufacturer_id ==
|
||||
DDC_MANUFACTURERNAME_SAMSUNG &&
|
||||
lum1_max >= ((lum2_max * 3) / 2))
|
||||
link->panel_type = PANEL_TYPE_MINILED;
|
||||
panel_type = PANEL_TYPE_MINILED;
|
||||
}
|
||||
|
||||
if (panel_type != PANEL_TYPE_NONE)
|
||||
link->panel_type = panel_type;
|
||||
else
|
||||
link->panel_type = PANEL_TYPE_LCD;
|
||||
|
||||
if (link->panel_type == PANEL_TYPE_OLED)
|
||||
drm_object_property_set_value(&connector->base,
|
||||
adev_to_drm(adev)->mode_config.panel_type_property,
|
||||
|
|
@ -456,6 +460,32 @@ static void dm_set_panel_type(struct amdgpu_dm_connector *aconnector)
|
|||
drm_dbg_kms(aconnector->base.dev, "Panel type: %d\n", link->panel_type);
|
||||
}
|
||||
|
||||
static void amdgpu_dm_update_cacp_caps(struct amdgpu_dm_connector *aconnector)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(aconnector->base.dev);
|
||||
struct dc_link *link = aconnector->dc_link;
|
||||
|
||||
link->panel_config.cacp.cacp_supported = true;
|
||||
|
||||
if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(3, 1, 4) ||
|
||||
amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(3, 1, 6)) {
|
||||
link->panel_config.cacp.cacp_supported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (link->connector_signal != SIGNAL_TYPE_EDP &&
|
||||
link->connector_signal != SIGNAL_TYPE_LVDS) {
|
||||
link->panel_config.cacp.cacp_supported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (link->panel_type == PANEL_TYPE_LCD)
|
||||
link->panel_config.cacp.cacp_supported = false;
|
||||
|
||||
drm_dbg_kms(aconnector->base.dev, "cacp_supported: %d\n",
|
||||
link->panel_config.cacp.cacp_supported);
|
||||
}
|
||||
|
||||
DEFINE_FREE(sink_release, struct dc_sink *, if (_T) dc_sink_release(_T))
|
||||
|
||||
void amdgpu_dm_update_connector_after_detect(
|
||||
|
|
@ -581,7 +611,8 @@ void amdgpu_dm_update_connector_after_detect(
|
|||
|
||||
amdgpu_dm_update_freesync_caps(connector, aconnector->drm_edid, true);
|
||||
amdgpu_dm_update_connector_ext_caps(aconnector);
|
||||
dm_set_panel_type(aconnector);
|
||||
amdgpu_dm_set_panel_type(aconnector);
|
||||
amdgpu_dm_update_cacp_caps(aconnector);
|
||||
|
||||
if (aconnector->hdmi_comp_auto) {
|
||||
if (sink->sink_signal != SIGNAL_TYPE_HDMI_FRL)
|
||||
|
|
|
|||
|
|
@ -632,6 +632,7 @@ enum visual_confirm {
|
|||
VISUAL_CONFIRM_SMARTMUX_DGPU = 10,
|
||||
VISUAL_CONFIRM_REPLAY = 12,
|
||||
VISUAL_CONFIRM_SUBVP = 14,
|
||||
VISUAL_CONFIRM_ABM = 15,
|
||||
VISUAL_CONFIRM_MCLK_SWITCH = 16,
|
||||
VISUAL_CONFIRM_FAMS2 = 19,
|
||||
VISUAL_CONFIRM_HW_CURSOR = 20,
|
||||
|
|
|
|||
|
|
@ -1347,6 +1347,14 @@ struct dc_panel_config {
|
|||
struct ilr {
|
||||
bool optimize_edp_link_rate; /* eDP ILR */
|
||||
} ilr;
|
||||
/* CACP*/
|
||||
struct cacp {
|
||||
unsigned int cacp_supported;
|
||||
unsigned int cacp_control_mode;
|
||||
unsigned int strscl_valid;
|
||||
unsigned int strscl_sdr[4];
|
||||
unsigned int strscl_hdr[4];
|
||||
} cacp;
|
||||
/* Adaptive VariBright*/
|
||||
struct adaptive_vb {
|
||||
bool disable_adaptive_vb;
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@
|
|||
# Makefile for common 'dce' logic
|
||||
# HW object file under this folder follow similar pattern for HW programming
|
||||
# - register offset and/or shift + mask stored in the dec_hw struct
|
||||
# - register programming through common macros that look up register
|
||||
# - register programming through common macros that look up register
|
||||
# offset/shift/mask stored in dce_hw struct
|
||||
|
||||
DCE = dce_audio.o dce_stream_encoder.o dce_link_encoder.o \
|
||||
dce_mem_input.o dce_clock_source.o dce_scl_filters.o dce_transform.o \
|
||||
dce_opp.o dce_dmcu.o dce_abm.o dce_ipp.o dce_aux.o \
|
||||
dce_i2c.o dce_i2c_hw.o dce_i2c_sw.o dmub_psr.o dmub_abm.o dmub_abm_lcd.o dce_panel_cntl.o \
|
||||
dmub_hw_lock_mgr.o dmub_outbox.o dmub_replay.o
|
||||
dmub_hw_lock_mgr.o dmub_outbox.o dmub_replay.o dmub_abm_cacp.o
|
||||
|
||||
AMD_DAL_DCE = $(addprefix $(AMDDALPATH)/dc/dce/,$(DCE))
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "dmub_abm.h"
|
||||
#include "dmub_abm_lcd.h"
|
||||
#include "dmub_abm_cacp.h"
|
||||
#include "dc.h"
|
||||
#include "core_types.h"
|
||||
#include "dmub_cmd.h"
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
|
||||
#define ABM_FEATURE_NO_SUPPORT 0
|
||||
#define ABM_LCD_SUPPORT 1
|
||||
#define ABM_CACP_SUPPORT 2
|
||||
|
||||
static unsigned int abm_feature_support(struct abm *abm, unsigned int panel_inst)
|
||||
{
|
||||
|
|
@ -52,15 +54,48 @@ static unsigned int abm_feature_support(struct abm *abm, unsigned int panel_inst
|
|||
}
|
||||
|
||||
if (i < edp_num) {
|
||||
ret = ABM_LCD_SUPPORT;
|
||||
if (edp_links[panel_inst]->panel_config.cacp.cacp_supported)
|
||||
ret = ABM_CACP_SUPPORT;
|
||||
else if ((edp_links[panel_inst]->panel_type == PANEL_TYPE_LCD) ||
|
||||
(edp_links[panel_inst]->panel_type == PANEL_TYPE_MINILED))
|
||||
ret = ABM_LCD_SUPPORT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum dc_panel_type abm_get_paneltype(struct abm *abm, unsigned int panel_inst)
|
||||
{
|
||||
struct dc_context *dc = abm->ctx;
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
unsigned int i, edp_num;
|
||||
enum dc_panel_type ret = PANEL_TYPE_NONE;
|
||||
|
||||
dc_get_edp_links(dc->dc, edp_links, &edp_num);
|
||||
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (edp_links[i]->link_status.link_active
|
||||
&& panel_inst == i)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < edp_num)
|
||||
ret = edp_links[panel_inst]->panel_type;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dmub_abm_init_ex(struct abm *abm, uint32_t backlight, uint32_t user_level)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
uint8_t panel_mask = 0;
|
||||
|
||||
dmub_abm_init(abm, backlight, user_level);
|
||||
for (i = 0; i < MAX_NUM_EDP; i++)
|
||||
panel_mask |= (0x01 << i);
|
||||
|
||||
if (panel_mask)
|
||||
dmub_cacp_enable_fractional_pwm(abm, panel_mask);
|
||||
}
|
||||
|
||||
static unsigned int dmub_abm_get_current_backlight_ex(struct abm *abm)
|
||||
|
|
@ -82,17 +117,23 @@ static bool dmub_abm_set_level_ex(struct abm *abm, uint32_t level)
|
|||
bool ret = false;
|
||||
unsigned int feature_support, i;
|
||||
uint8_t panel_mask0 = 0;
|
||||
uint8_t panel_mask1 = 0;
|
||||
|
||||
for (i = 0; i < MAX_NUM_EDP; i++) {
|
||||
feature_support = abm_feature_support(abm, i);
|
||||
|
||||
if (feature_support == ABM_LCD_SUPPORT)
|
||||
panel_mask0 |= (0x01 << i);
|
||||
else if (feature_support == ABM_CACP_SUPPORT)
|
||||
panel_mask1 |= (0x01 << i);
|
||||
}
|
||||
|
||||
if (panel_mask0)
|
||||
ret = dmub_abm_set_level(abm, level, panel_mask0);
|
||||
|
||||
if (panel_mask1)
|
||||
ret = dmub_cacp_set_level(abm, level, panel_mask1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +148,8 @@ static bool dmub_abm_init_config_ex(struct abm *abm,
|
|||
|
||||
if (feature_support == ABM_LCD_SUPPORT)
|
||||
dmub_abm_init_config(abm, src, bytes, inst);
|
||||
else if (feature_support == ABM_CACP_SUPPORT)
|
||||
dmub_cacp_init(abm, src, bytes, inst);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -120,6 +163,8 @@ static bool dmub_abm_set_pause_ex(struct abm *abm, bool pause, unsigned int pane
|
|||
|
||||
if (feature_support == ABM_LCD_SUPPORT)
|
||||
ret = dmub_abm_set_pause(abm, pause, panel_inst, stream_inst);
|
||||
else if (feature_support == ABM_CACP_SUPPORT)
|
||||
ret = dmub_cacp_set_pause(abm, pause, panel_inst, stream_inst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -163,6 +208,25 @@ static bool dmub_abm_set_pipe_ex(struct abm *abm,
|
|||
|
||||
if (feature_support == ABM_LCD_SUPPORT)
|
||||
ret = dmub_abm_set_pipe(abm, otg_inst, option, panel_inst, pwrseq_inst);
|
||||
else if (feature_support == ABM_CACP_SUPPORT)
|
||||
ret = dmub_cacp_set_pipe(abm, otg_inst, option, panel_inst, pwrseq_inst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool dmub_abm_set_event_ex(struct abm *abm, unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable, unsigned int scaling_strength_map,
|
||||
unsigned int panel_inst)
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned int feature_support;
|
||||
|
||||
feature_support = abm_feature_support(abm, panel_inst);
|
||||
|
||||
if (feature_support == ABM_LCD_SUPPORT)
|
||||
ret = dmub_abm_set_event(abm, scaling_enable, scaling_strength_map, panel_inst);
|
||||
else if (feature_support == ABM_CACP_SUPPORT)
|
||||
ret = dmub_cacp_set_event(abm, full_screen, trans_info, hdr_mode, scaling_enable, panel_inst);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -176,11 +240,17 @@ static bool dmub_abm_set_backlight_level_pwm_ex(struct abm *abm,
|
|||
(void)controller_id;
|
||||
bool ret = false;
|
||||
unsigned int feature_support;
|
||||
enum dc_panel_type panel_type = PANEL_TYPE_NONE;
|
||||
|
||||
feature_support = abm_feature_support(abm, panel_inst);
|
||||
|
||||
if (feature_support == ABM_LCD_SUPPORT)
|
||||
ret = dmub_abm_set_backlight_level(abm, backlight_pwm_u16_16, frame_ramp, panel_inst);
|
||||
else if (feature_support == ABM_CACP_SUPPORT) {
|
||||
panel_type = abm_get_paneltype(abm, panel_inst);
|
||||
if (panel_type == PANEL_TYPE_MINILED)
|
||||
ret = dmub_cacp_set_backlight_level(abm, backlight_pwm_u16_16, frame_ramp, panel_inst);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -194,6 +264,7 @@ static const struct abm_funcs abm_funcs = {
|
|||
.set_abm_pause = dmub_abm_set_pause_ex,
|
||||
.save_restore = dmub_abm_save_restore_ex,
|
||||
.set_pipe_ex = dmub_abm_set_pipe_ex,
|
||||
.set_abm_event = dmub_abm_set_event_ex,
|
||||
.set_backlight_level_pwm = dmub_abm_set_backlight_level_pwm_ex,
|
||||
};
|
||||
|
||||
|
|
|
|||
213
drivers/gpu/drm/amd/display/dc/dce/dmub_abm_cacp.c
Normal file
213
drivers/gpu/drm/amd/display/dc/dce/dmub_abm_cacp.c
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/* Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved. */
|
||||
|
||||
#include "dmub_abm.h"
|
||||
#include "dmub_abm_cacp.h"
|
||||
#include "dce_abm.h"
|
||||
#include "dc.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
#include "core_types.h"
|
||||
|
||||
#define CACP_LEVEL_NUM 4
|
||||
|
||||
void dmub_cacp_init(struct abm *abm, const char *src, unsigned int bytes, unsigned int panel_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
uint8_t panel_mask = 0x01 << panel_inst;
|
||||
struct dc_link *edp_links[MAX_NUM_EDP];
|
||||
unsigned int i, edp_num;
|
||||
|
||||
// TODO: Optimize by only reading back final 4 bytes
|
||||
dmub_srv_flush_buffer_mem(dc->dmub_srv->dmub, &dc->dmub_srv->dmub->scratch_mem_fb);
|
||||
|
||||
// Copy iramtable into cw7
|
||||
memcpy(dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, (void *)src, bytes);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
// Fw will copy from cw7 to fw_state
|
||||
cmd.cacp_init_config.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_init_config.header.sub_type = DMUB_CMD__CACP_INIT_CONFIG;
|
||||
cmd.cacp_init_config.cacp_init_config_data.src.quad_part = dc->dmub_srv->dmub->scratch_mem_fb.gpu_addr;
|
||||
cmd.cacp_init_config.cacp_init_config_data.bytes = (uint16_t)bytes;
|
||||
cmd.cacp_init_config.cacp_init_config_data.panel_mask = panel_mask;
|
||||
cmd.cacp_init_config.cacp_init_config_data.visual_confirm =
|
||||
(dc->dc->debug.visual_confirm == VISUAL_CONFIRM_ABM) ? true : false;
|
||||
|
||||
cmd.cacp_init_config.header.payload_bytes = sizeof(struct dmub_cmd_cacp_init_config_data);
|
||||
|
||||
dc_get_edp_links(dc->dc, edp_links, &edp_num);
|
||||
for (i = 0; i < edp_num; i++) {
|
||||
if (panel_inst == i)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < edp_num) {
|
||||
cmd.cacp_init_config.cacp_init_config_data.strscl_valid =
|
||||
(uint8_t)edp_links[panel_inst]->panel_config.cacp.strscl_valid;
|
||||
cmd.cacp_init_config.cacp_init_config_data.mode =
|
||||
edp_links[panel_inst]->panel_config.cacp.cacp_control_mode ?
|
||||
DMUB_CMD_CACP_CONTROL_MODE_1 : DMUB_CMD_CACP_CONTROL_MODE_0;
|
||||
for (int j = 0; j < CACP_LEVEL_NUM; j++) {
|
||||
cmd.cacp_init_config.cacp_init_config_data.strscl_sdr[j] =
|
||||
(uint8_t)edp_links[panel_inst]->panel_config.cacp.strscl_sdr[j];
|
||||
cmd.cacp_init_config.cacp_init_config_data.strscl_hdr[j] =
|
||||
(uint8_t)edp_links[panel_inst]->panel_config.cacp.strscl_hdr[j];
|
||||
}
|
||||
}
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
}
|
||||
|
||||
bool dmub_cacp_set_level(struct abm *abm, unsigned int abm_level, unsigned char panel_mask)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_set_level.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_set_level.header.sub_type = DMUB_CMD__CACP_SET_LEVEL;
|
||||
|
||||
cmd.cacp_set_level.cacp_set_level_data.level = abm_level;
|
||||
cmd.cacp_set_level.cacp_set_level_data.version = DMUB_CMD_CACP_CONTROL_VERSION_1;
|
||||
cmd.cacp_set_level.cacp_set_level_data.panel_mask = panel_mask;
|
||||
|
||||
cmd.cacp_set_level.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_level_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dmub_cacp_set_pipe(struct abm *abm, unsigned int otg_inst,
|
||||
unsigned int pipe_option, unsigned int panel_inst, unsigned int pwrseq_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_set_pipe.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_set_pipe.header.sub_type = DMUB_CMD__CACP_SET_PIPE;
|
||||
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.otg_inst = (uint8_t)otg_inst;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.panel_inst = (uint8_t)panel_inst;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.set_pipe_option = (uint8_t)pipe_option;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.pwrseq_inst = (uint8_t)pwrseq_inst;
|
||||
cmd.cacp_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_pipe_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dmub_cacp_set_event(struct abm *abm, unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable, unsigned int panel_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_set_event.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_set_event.header.sub_type = DMUB_CMD__CACP_SET_EVENT;
|
||||
|
||||
//TODO:
|
||||
cmd.cacp_set_event.cacp_set_event_data.full_screen_mode = (uint8_t)full_screen;
|
||||
cmd.cacp_set_event.cacp_set_event_data.trans_info = trans_info;
|
||||
cmd.cacp_set_event.cacp_set_event_data.hdr_mode = (uint8_t)hdr_mode;
|
||||
cmd.cacp_set_event.cacp_set_event_data.vb_scaling_enable = (uint8_t)scaling_enable;
|
||||
cmd.cacp_set_event.cacp_set_event_data.panel_mask = (1<<panel_inst);
|
||||
|
||||
cmd.cacp_set_event.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_event_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dmub_cacp_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int otg_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_pause.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_pause.header.sub_type = DMUB_CMD__CACP_PAUSE;
|
||||
|
||||
cmd.cacp_pause.cacp_pause_data.panel_mask = (1<<panel_inst);
|
||||
cmd.cacp_pause.cacp_pause_data.otg_inst = (uint8_t)otg_inst;
|
||||
cmd.cacp_pause.cacp_pause_data.enable = pause;
|
||||
|
||||
cmd.cacp_pause.header.payload_bytes = sizeof(struct dmub_cmd_cacp_pause_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dmub_cacp_set_backlight_level(struct abm *abm,
|
||||
unsigned int backlight_pwm_u16_16,
|
||||
unsigned int frame_ramp,
|
||||
unsigned int panel_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_set_backlight.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_set_backlight.header.sub_type = DMUB_CMD__CACP_SET_BACKLIGHT;
|
||||
cmd.cacp_set_backlight.cacp_set_backlight_data.frame_ramp = frame_ramp;
|
||||
cmd.cacp_set_backlight.cacp_set_backlight_data.backlight_user_level = backlight_pwm_u16_16;
|
||||
cmd.cacp_set_backlight.cacp_set_backlight_data.version = DMUB_CMD_CACP_CONTROL_VERSION_1;
|
||||
cmd.cacp_set_backlight.cacp_set_backlight_data.panel_mask = (0x01 << panel_inst);
|
||||
cmd.cacp_set_backlight.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_backlight_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dmub_cacp_enable_fractional_pwm(struct abm *abm, uint8_t panel_mask)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
uint32_t fractional_pwm = (dc->dc->config.disable_fractional_pwm == false) ? 1 : 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_set_pwm_frac.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_set_pwm_frac.header.sub_type = DMUB_CMD__CACP_SET_PWM_FRAC;
|
||||
cmd.cacp_set_pwm_frac.cacp_set_pwm_frac_data.fractional_pwm = fractional_pwm;
|
||||
cmd.cacp_set_pwm_frac.cacp_set_pwm_frac_data.version = DMUB_CMD_CACP_CONTROL_VERSION_1;
|
||||
cmd.cacp_set_pwm_frac.cacp_set_pwm_frac_data.panel_mask = panel_mask;
|
||||
cmd.cacp_set_pwm_frac.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_pwm_frac_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
}
|
||||
|
||||
bool dmub_cacp_get_histogram(
|
||||
struct dc_context *dc,
|
||||
unsigned int panel_inst,
|
||||
unsigned int *histogram,
|
||||
enum dmub_abm_histogram_type histogram_type,
|
||||
unsigned int size)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
|
||||
dmub_srv_flush_buffer_mem(dc->dmub_srv->dmub, &dc->dmub_srv->dmub->scratch_mem_fb);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_get_histogram.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_get_histogram.header.sub_type = DMUB_CMD__CACP_GET_HISTOGRAM;
|
||||
|
||||
cmd.cacp_get_histogram.dest.quad_part = dc->dmub_srv->dmub->scratch_mem_fb.gpu_addr;
|
||||
cmd.cacp_get_histogram.bytes = (uint16_t)size;
|
||||
cmd.cacp_get_histogram.panel_inst = (uint8_t)panel_inst;
|
||||
cmd.cacp_get_histogram.histogram_type = histogram_type;
|
||||
cmd.cacp_get_histogram.header.payload_bytes = sizeof(struct dmub_rb_cmd_cacp_get_histogram);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
memcpy((void *)histogram, dc->dmub_srv->dmub->scratch_mem_fb.cpu_addr, size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
20
drivers/gpu/drm/amd/display/dc/dce/dmub_abm_cacp.h
Normal file
20
drivers/gpu/drm/amd/display/dc/dce/dmub_abm_cacp.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved. */
|
||||
|
||||
#include "dmub_cmd.h"
|
||||
|
||||
#ifndef __DMUB_ABM_CACP_H__
|
||||
#define __DMUB_ABM_CACP_H__
|
||||
|
||||
void dmub_cacp_init(struct abm *abm, const char *src, unsigned int bytes, unsigned int panel_inst);
|
||||
bool dmub_cacp_set_level(struct abm *abm, unsigned int cacp_level, unsigned char panel_mask);
|
||||
bool dmub_cacp_set_pipe(struct abm *abm, unsigned int otg_inst, unsigned int pipe_option,
|
||||
unsigned int panel_inst, unsigned int pwrseq_inst);
|
||||
bool dmub_cacp_set_event(struct abm *abm, unsigned int full_screen, unsigned int trans_info, unsigned int hdr_mode,
|
||||
unsigned int scaling_enable, unsigned int panel_inst);
|
||||
bool dmub_cacp_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int otg_inst);
|
||||
bool dmub_cacp_set_backlight_level(struct abm *abm, unsigned int backlight_pwm_u16_16, unsigned int frame_ramp,
|
||||
unsigned int panel_inst);
|
||||
void dmub_cacp_enable_fractional_pwm(struct abm *abm, uint8_t panel_mask);
|
||||
bool dmub_cacp_get_histogram(struct dc_context *dc, unsigned int panel_inst, unsigned int *histogram,
|
||||
enum dmub_abm_histogram_type histogram_type, unsigned int size);
|
||||
#endif
|
||||
|
|
@ -136,6 +136,26 @@ void dcn21_PLAT_58856_wa(struct dc_state *context, struct pipe_ctx *pipe_ctx)
|
|||
pipe_ctx->stream->dpms_off = true;
|
||||
}
|
||||
|
||||
bool dcn21_dmub_cacp_set_pipe(struct abm *abm, uint32_t otg_inst,
|
||||
uint32_t option, uint32_t panel_inst, uint32_t pwrseq_inst)
|
||||
{
|
||||
union dmub_rb_cmd cmd;
|
||||
struct dc_context *dc = abm->ctx;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cacp_set_pipe.header.type = DMUB_CMD__CACP;
|
||||
cmd.cacp_set_pipe.header.sub_type = DMUB_CMD__CACP_SET_PIPE;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.otg_inst = (uint8_t)otg_inst;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.pwrseq_inst = (uint8_t)pwrseq_inst;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.set_pipe_option = (uint8_t)option;
|
||||
cmd.cacp_set_pipe.cacp_set_pipe_data.panel_inst = (uint8_t)panel_inst;
|
||||
cmd.cacp_set_pipe.header.payload_bytes = sizeof(struct dmub_cmd_cacp_set_pipe_data);
|
||||
|
||||
dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dcn21_dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst,
|
||||
uint32_t option, uint32_t panel_inst, uint32_t pwrseq_inst)
|
||||
{
|
||||
|
|
@ -181,10 +201,12 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
|
|||
uint32_t otg_inst = pipe_ctx->stream_res.tg->inst;
|
||||
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
|
||||
struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
|
||||
// make a short term w/a for an issue that backlight ramping unexpectedly paused in the middle,
|
||||
// will decouple backlight from ABM and redefine DMUB interface, then this w/a could be removed
|
||||
if (pipe_ctx->stream->abm_level == 0 || pipe_ctx->stream->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) {
|
||||
if ((pipe_ctx->stream->abm_level == 0 || pipe_ctx->stream->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE)
|
||||
&& (link && !link->panel_config.cacp.cacp_supported)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -197,6 +219,9 @@ void dcn21_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx)
|
|||
if (abm->funcs && abm->funcs->set_pipe_ex) {
|
||||
abm->funcs->set_pipe_ex(abm, otg_inst, SET_ABM_PIPE_IMMEDIATELY_DISABLE,
|
||||
panel_cntl->inst, panel_cntl->pwrseq_inst);
|
||||
} else if (link && link->panel_config.cacp.cacp_supported) {
|
||||
dcn21_dmub_cacp_set_pipe(abm, otg_inst, SET_CACP_PIPE_IMMEDIATELY_DISABLE,
|
||||
panel_cntl->inst, panel_cntl->pwrseq_inst);
|
||||
} else {
|
||||
dcn21_dmub_abm_set_pipe(abm,
|
||||
otg_inst,
|
||||
|
|
@ -214,6 +239,7 @@ void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
|
|||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
|
||||
struct dmcu *dmcu = pipe_ctx->stream->ctx->dc->res_pool->dmcu;
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
uint32_t otg_inst;
|
||||
|
||||
if (!abm || !tg || !panel_cntl)
|
||||
|
|
@ -233,6 +259,11 @@ void dcn21_set_pipe(struct pipe_ctx *pipe_ctx)
|
|||
panel_cntl->inst,
|
||||
panel_cntl->pwrseq_inst);
|
||||
} else {
|
||||
|
||||
if (link && link->panel_config.cacp.cacp_supported)
|
||||
dcn21_dmub_cacp_set_pipe(abm, otg_inst, SET_CACP_PIPE_NORMAL,
|
||||
panel_cntl->inst, panel_cntl->pwrseq_inst);
|
||||
else
|
||||
dcn21_dmub_abm_set_pipe(abm, otg_inst,
|
||||
SET_ABM_PIPE_NORMAL,
|
||||
panel_cntl->inst,
|
||||
|
|
@ -250,6 +281,7 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
|||
uint32_t otg_inst;
|
||||
uint32_t backlight_pwm_u16_16 = backlight_level_params->backlight_pwm_u16_16;
|
||||
uint32_t frame_ramp = backlight_level_params->frame_ramp;
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
|
||||
if (!abm || !tg || !panel_cntl)
|
||||
return false;
|
||||
|
|
@ -268,6 +300,12 @@ bool dcn21_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
|||
panel_cntl->inst,
|
||||
panel_cntl->pwrseq_inst);
|
||||
} else {
|
||||
if (link && link->panel_config.cacp.cacp_supported)
|
||||
dcn21_dmub_cacp_set_pipe(abm, otg_inst,
|
||||
SET_CACP_PIPE_NORMAL,
|
||||
panel_cntl->inst,
|
||||
panel_cntl->pwrseq_inst);
|
||||
else
|
||||
dcn21_dmub_abm_set_pipe(abm,
|
||||
otg_inst,
|
||||
SET_ABM_PIPE_NORMAL,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ void dcn21_optimize_pwr_state(
|
|||
void dcn21_PLAT_58856_wa(struct dc_state *context,
|
||||
struct pipe_ctx *pipe_ctx);
|
||||
|
||||
bool dcn21_dmub_cacp_set_pipe(struct abm *abm, uint32_t otg_inst,
|
||||
uint32_t option, uint32_t panel_inst, uint32_t pwrseq_inst);
|
||||
bool dcn21_dmub_abm_set_pipe(struct abm *abm, uint32_t otg_inst,
|
||||
uint32_t option, uint32_t panel_inst, uint32_t pwrseq_inst);
|
||||
void dcn21_set_pipe(struct pipe_ctx *pipe_ctx);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "dce/dce_i2c_hw.h"
|
||||
#include "dce/dmub_abm_lcd.h"
|
||||
#include "dio/dcn10/dcn10_dio.h"
|
||||
#include "dce/dmub_abm_cacp.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
||||
|
|
@ -726,12 +727,19 @@ bool dcn31_set_backlight_level(struct pipe_ctx *pipe_ctx,
|
|||
struct timing_generator *tg = pipe_ctx->stream_res.tg;
|
||||
struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl;
|
||||
uint32_t otg_inst;
|
||||
struct dc_link *link = pipe_ctx->stream->link;
|
||||
|
||||
if (!abm || !tg || !panel_cntl)
|
||||
return false;
|
||||
|
||||
otg_inst = tg->inst;
|
||||
|
||||
if (link && link->panel_config.cacp.cacp_supported)
|
||||
dcn21_dmub_cacp_set_pipe(abm, otg_inst,
|
||||
SET_CACP_PIPE_NORMAL,
|
||||
panel_cntl->inst,
|
||||
panel_cntl->pwrseq_inst);
|
||||
else
|
||||
dcn21_dmub_abm_set_pipe(abm,
|
||||
otg_inst,
|
||||
SET_ABM_PIPE_NORMAL,
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ struct abm_funcs {
|
|||
unsigned int option,
|
||||
unsigned int panel_inst,
|
||||
unsigned int pwrseq_inst);
|
||||
bool (*set_abm_event)(struct abm *abm, unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable, unsigned int scaling_strength_map,
|
||||
unsigned int panel_inst);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -328,6 +328,17 @@ bool mod_power_is_abm_active(struct mod_power *mod_power,
|
|||
const struct dc_link *link,
|
||||
unsigned int inst);
|
||||
|
||||
bool mod_power_is_abm_supported(struct mod_power *mod_power,
|
||||
unsigned int inst);
|
||||
|
||||
bool mod_power_abm_set_event(struct mod_power *mod_power,
|
||||
unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable,
|
||||
unsigned int scaling_strength_map, unsigned int inst);
|
||||
|
||||
bool mod_power_abm_set_strength(struct mod_power *mod_power,
|
||||
unsigned int strength,
|
||||
unsigned int inst);
|
||||
|
||||
bool mod_power_set_psr_event(struct mod_power *mod_power,
|
||||
struct dc_stream_state *stream, bool set_event,
|
||||
|
|
|
|||
|
|
@ -1453,6 +1453,76 @@ bool mod_power_is_abm_active(struct mod_power *mod_power,
|
|||
return is_active;
|
||||
}
|
||||
|
||||
bool mod_power_is_abm_supported(struct mod_power *mod_power,
|
||||
unsigned int inst)
|
||||
{
|
||||
struct core_power *core_power = NULL;
|
||||
struct dc *dc = NULL;
|
||||
|
||||
if (mod_power == NULL)
|
||||
return false;
|
||||
|
||||
core_power = MOD_POWER_TO_CORE(mod_power);
|
||||
dc = core_power->dc;
|
||||
|
||||
// It's only implemented on dmcub.
|
||||
if (dc->ctx->dmub_srv) {
|
||||
if (!dmub_is_abm_supported(dc->res_pool, inst))
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mod_power_abm_set_event(struct mod_power *mod_power,
|
||||
unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable,
|
||||
unsigned int scaling_strength_map, unsigned int inst)
|
||||
{
|
||||
struct core_power *core_power = NULL;
|
||||
struct dc *dc = NULL;
|
||||
|
||||
if (mod_power == NULL)
|
||||
return false;
|
||||
|
||||
core_power = MOD_POWER_TO_CORE(mod_power);
|
||||
dc = core_power->dc;
|
||||
|
||||
// It's only implemented on dmcub.
|
||||
if (dc->ctx->dmub_srv) {
|
||||
if (!dmub_set_abm_event(dc->res_pool, full_screen, trans_info,
|
||||
hdr_mode, scaling_enable, scaling_strength_map, inst))
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mod_power_abm_set_strength(struct mod_power *mod_power,
|
||||
unsigned int strength,
|
||||
unsigned int inst)
|
||||
{
|
||||
struct core_power *core_power = NULL;
|
||||
struct dc *dc = NULL;
|
||||
|
||||
if (mod_power == NULL)
|
||||
return false;
|
||||
|
||||
core_power = MOD_POWER_TO_CORE(mod_power);
|
||||
dc = core_power->dc;
|
||||
|
||||
// It's only implemented on dmcub.
|
||||
if (dc->ctx->dmub_srv) {
|
||||
if (!dmub_set_abm_strength(dc->res_pool, strength, inst))
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void fill_backlight_transform_table(struct dmcu_iram_parameters params,
|
||||
struct iram_table_v_2 *table)
|
||||
{
|
||||
|
|
@ -1990,6 +2060,62 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
|
|||
return result;
|
||||
}
|
||||
|
||||
bool dmub_is_abm_supported(struct resource_pool *res_pool, unsigned int inst)
|
||||
{
|
||||
|
||||
if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dmub_set_abm_event(struct resource_pool *res_pool,
|
||||
unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable, unsigned int scaling_strength_map,
|
||||
unsigned int inst)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
|
||||
return false;
|
||||
|
||||
if (res_pool->multiple_abms[inst]) {
|
||||
if (res_pool->multiple_abms[inst]->funcs->set_abm_event)
|
||||
result = res_pool->multiple_abms[inst]->funcs->set_abm_event(
|
||||
res_pool->multiple_abms[inst], full_screen, trans_info,
|
||||
hdr_mode, scaling_enable, scaling_strength_map, inst);
|
||||
} else {
|
||||
if (res_pool->abm->funcs->set_abm_event)
|
||||
result = res_pool->abm->funcs->set_abm_event(
|
||||
res_pool->abm, full_screen, trans_info,
|
||||
hdr_mode, scaling_enable, scaling_strength_map, inst);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmub_set_abm_strength(struct resource_pool *res_pool,
|
||||
unsigned int strength,
|
||||
unsigned int inst)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (res_pool->abm == NULL && res_pool->multiple_abms[inst] == NULL)
|
||||
return false;
|
||||
|
||||
if (res_pool->multiple_abms[inst]) {
|
||||
if (res_pool->multiple_abms[inst]->funcs->set_abm_level)
|
||||
result = res_pool->multiple_abms[inst]->funcs->set_abm_level(
|
||||
res_pool->multiple_abms[inst], strength);
|
||||
} else {
|
||||
if (res_pool->abm->funcs->set_abm_level)
|
||||
result = res_pool->abm->funcs->set_abm_level(
|
||||
res_pool->abm, strength);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dmcu_load_iram(struct dmcu *dmcu,
|
||||
struct dmcu_iram_parameters params)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -146,6 +146,16 @@ bool dmub_init_abm_config(struct resource_pool *res_pool,
|
|||
struct dmcu_iram_parameters params,
|
||||
unsigned int inst);
|
||||
|
||||
bool dmub_is_abm_supported(struct resource_pool *res_pool,
|
||||
unsigned int inst);
|
||||
bool dmub_set_abm_event(struct resource_pool *res_pool,
|
||||
unsigned int full_screen, unsigned int trans_info,
|
||||
unsigned int hdr_mode, unsigned int scaling_enable,
|
||||
unsigned int scaling_strength_map, unsigned int inst);
|
||||
bool dmub_set_abm_strength(struct resource_pool *res_pool,
|
||||
unsigned int strength,
|
||||
unsigned int inst);
|
||||
|
||||
void init_replay_config(struct dc_link *link, struct replay_config *pr_config);
|
||||
void set_replay_coasting_vtotal(struct dc_link *link,
|
||||
enum replay_coasting_vtotal_type type,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user