forked from rrcarlosr/Jetpack
109 lines
2.9 KiB
C
109 lines
2.9 KiB
C
/*
|
|
* drivers/video/tegra/dc/dp_t19x.c
|
|
*
|
|
* Copyright (c) 2017, NVIDIA CORPORATION, All rights reserved.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include "dc.h"
|
|
#include "dp.h"
|
|
#include "dp_lt.h"
|
|
#include "dp_t19x.h"
|
|
#include "sor.h"
|
|
#include "sor_t19x.h"
|
|
|
|
int tegra_dp_init_max_link_cfg_t19x(struct tegra_dc_dp_data *dp,
|
|
struct tegra_dc_dp_link_config *cfg)
|
|
{
|
|
u8 dpcd_data = 0;
|
|
int ret = 0;
|
|
|
|
cfg->max_lane_count = tegra_dc_dp_get_max_lane_count(dp, &dpcd_data);
|
|
if (cfg->max_lane_count == 0) {
|
|
dev_err(&dp->dc->ndev->dev,
|
|
"dp: Invalid max lane count: %u\n", cfg->max_lane_count);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (dpcd_data & NV_DPCD_MAX_LANE_COUNT_TPS3_SUPPORTED_YES)
|
|
cfg->tps = TEGRA_DC_DP_TRAINING_PATTERN_3;
|
|
else
|
|
cfg->tps = TEGRA_DC_DP_TRAINING_PATTERN_2;
|
|
|
|
cfg->support_enhanced_framing =
|
|
(dpcd_data & NV_DPCD_MAX_LANE_COUNT_ENHANCED_FRAMING_YES) ?
|
|
true : false;
|
|
|
|
if (dp->sink_cap_valid) {
|
|
dpcd_data = dp->sink_cap[NV_DPCD_MAX_DOWNSPREAD];
|
|
} else {
|
|
ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_MAX_DOWNSPREAD,
|
|
&dpcd_data);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* The check for TPS4 should be after the check for TPS3. That helps
|
|
* assign a higher priority to TPS4
|
|
*/
|
|
if (dpcd_data & NV_DPCD_MAX_DOWNSPREAD_TPS4_SUPPORTED_YES)
|
|
cfg->tps = TEGRA_DC_DP_TRAINING_PATTERN_4;
|
|
|
|
cfg->downspread =
|
|
(dpcd_data & NV_DPCD_MAX_DOWNSPREAD_VAL_0_5_PCT) ?
|
|
true : false;
|
|
cfg->support_fast_lt = (dpcd_data &
|
|
NV_DPCD_MAX_DOWNSPREAD_NO_AUX_HANDSHAKE_LT_T) ?
|
|
true : false;
|
|
|
|
ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_TRAINING_AUX_RD_INTERVAL,
|
|
&dpcd_data);
|
|
if (ret)
|
|
return ret;
|
|
|
|
cfg->aux_rd_interval = dpcd_data &
|
|
NV_DPCD_TRAINING_AUX_RD_INTERVAL_MASK;
|
|
|
|
cfg->max_link_bw = tegra_dc_dp_get_max_link_bw(dp);
|
|
if (cfg->max_link_bw == 0) {
|
|
dev_err(&dp->dc->ndev->dev,
|
|
"dp: Invalid max link bw: %u\n", cfg->max_link_bw);
|
|
return -EINVAL;
|
|
}
|
|
tegra_dp_set_max_link_bw(dp->sor, cfg);
|
|
|
|
ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_EDP_CONFIG_CAP, &dpcd_data);
|
|
if (ret)
|
|
return ret;
|
|
|
|
cfg->alt_scramber_reset_cap =
|
|
(dpcd_data & NV_DPCD_EDP_CONFIG_CAP_ASC_RESET_YES) ?
|
|
true : false;
|
|
cfg->only_enhanced_framing = (dpcd_data &
|
|
NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES) ?
|
|
true : false;
|
|
cfg->edp_cap = (dpcd_data &
|
|
NV_DPCD_EDP_CONFIG_CAP_DISPLAY_CONTROL_CAP_YES) ?
|
|
true : false;
|
|
|
|
ret = tegra_dc_dp_dpcd_read(dp, NV_DPCD_FEATURE_ENUM_LIST, &dpcd_data);
|
|
if (ret)
|
|
return ret;
|
|
|
|
cfg->support_vsc_ext_colorimetry = (dpcd_data &
|
|
NV_DPCD_FEATURE_ENUM_LIST_VSC_EXT_COLORIMETRY) ?
|
|
true : false;
|
|
|
|
return 0;
|
|
}
|