/*
* Copyright 2022 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.
*
* Authors: AMD
*
*/
/* FILE POLICY AND INTENDED USAGE:
* This file implements retrieval and configuration of eDP panel features such
* as PSR and ABM and it also manages specs defined eDP panel power sequences.
*/
#include "link_edp_panel_control.h"
#include "link_dpcd.h"
#include "link_dp_capability.h"
#include "dm_helpers.h"
#include "dal_asic_id.h"
#include "link_dp_phy.h"
#include "dce/dmub_psr.h"
#include "dc/dc_dmub_srv.h"
#include "dce/dmub_replay.h"
#include "abm.h"
#include "resource.h"
#define DC_LOGGER \
link->ctx->logger
#define DC_LOGGER_INIT(logger)
#define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B
/* Travis */
static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT";
/* Nutmeg */
static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA";
void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode)
{
union dpcd_edp_config edp_config_set;
bool panel_mode_edp = false;
enum dc_status result;
memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config));
switch (panel_mode) {
case DP_PANEL_MODE_EDP:
case DP_PANEL_MODE_SPECIAL:
panel_mode_edp = true;
break;
default:
break;
}
/*set edp panel mode in receiver*/
result = core_link_read_dpcd(
link,
DP_EDP_CONFIGURATION_SET,
&edp_config_set.raw,
sizeof(edp_config_set.raw));
if (result == DC_OK &&
edp_config_set.bits.PANEL_MODE_EDP
!= panel_mode_edp) {
edp_config_set.bits.PANEL_MODE_EDP =
panel_mode_edp;
result = core_link_write_dpcd(
link,
DP_EDP_CONFIGURATION_SET,
&edp_config_set.raw,
sizeof(edp_config_set.raw));
ASSERT(result == DC_OK);
}
link->panel_mode = panel_mode;
DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d "
"eDP panel mode enabled: %d \n",
link->link_index,
link->dpcd_caps.panel_mode_edp,
panel_mode_edp);
}
enum dp_panel_mode dp_get_panel_mode(struct dc_link *link)
{
/* We need to explicitly check that connector
* is not DP. Some Travis_VGA get reported
* by video bios as DP.
*/
if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) {
switch (link->dpcd_caps.branch_dev_id) {
case DP_BRANCH_DEVICE_ID_0022B9:
/* alternate scrambler reset is required for Travis
* for the case when external chip does not
* provide sink device id, alternate scrambler
* scheme will be overriden later by querying
* Encoder features
*/
if (strncmp(
link->dpcd_caps.branch_dev_name,
DP_VGA_LVDS_CONVERTER_ID_2,
sizeof(
link->dpcd_caps.
branch_dev_name)) == 0) {
return DP_PANEL_MODE_SPECIAL;
}
break;
case DP_BRANCH_DEVICE_ID_00001A:
/* alternate scrambler reset is required for Travis
* for the case when external chip does not provide
* sink device id, alternate scrambler scheme will
* be overriden later by querying Encoder feature
*/
if (strncmp(link->dpcd_caps.branch_dev_name,
DP_VGA_LVDS_CONVERTER_ID_3,
sizeof(
link->dpcd_caps.
branch_dev_name)) == 0) {
return DP_PANEL_MODE_SPECIAL;
}
break;
default:
break;
}
}
if (link->dpcd_caps.panel_mode_edp &&
(link->connector_signal == SIGNAL_TYPE_EDP ||
(link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
link->is_internal_display))) {
return DP_PANEL_MODE_EDP;
}
return DP_PANEL_MODE_DEFAULT;
}
bool edp_set_backlight_level_nits(struct dc_link *link,
bool isHDR,
uint32_t backlight_millinits,
uint32_t transition_time_in_ms