mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 22:52:19 +02:00
drm/amd/display: merge dc_link_dp into dc_link
[why] Temporarly merge dc_link_dp functions into dc_link for the purpose of removing dc_link_dp files. This is a transitional change for later commits where we will further refactor dc_link file. Reviewed-by: George Shen <George.Shen@amd.com> Acked-by: Alan Liu <HaoPing.Liu@amd.com> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
de3fb39017
commit
6ca7415f11
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "dm_services_types.h"
|
||||
#include "dc.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link_enc_cfg.h"
|
||||
#include "dc/inc/core_types.h"
|
||||
#include "dal_asic_id.h"
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@
|
|||
#include "dmub/dmub_srv.h"
|
||||
#include "resource.h"
|
||||
#include "dsc.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dc_link.h"
|
||||
#include "link_hwss.h"
|
||||
#include "dc/dc_dmub_srv.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include "amdgpu_dm_mst_types.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dc/inc/core_types.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
||||
#include "dm_helpers.h"
|
||||
#include "ddc_service_types.h"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include "dc.h"
|
||||
#include "dm_helpers.h"
|
||||
|
||||
#include "dc_link_dp.h"
|
||||
#include "ddc_service_types.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
|
|||
include $(AMD_DC)
|
||||
|
||||
DISPLAY_CORE = dc.o dc_stat.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
|
||||
dc_surface.o dc_link_dp.o dc_debug.o dc_stream.o \
|
||||
dc_link_enc_cfg.o
|
||||
dc_surface.o dc_debug.o dc_stream.o dc_link_enc_cfg.o
|
||||
|
||||
DISPLAY_CORE += dc_vm_helper.o
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "dcn30/dcn30_clk_mgr.h"
|
||||
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "link.h"
|
||||
|
||||
#include "logger_types.h"
|
||||
#undef DC_LOGGER
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#include "dcn31/dcn31_clk_mgr.h"
|
||||
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "dcn314_smu.h"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@
|
|||
#define DC_LOGGER \
|
||||
clk_mgr->base.base.ctx->logger
|
||||
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
|
||||
#define TO_CLK_MGR_DCN315(clk_mgr)\
|
||||
container_of(clk_mgr, struct clk_mgr_dcn315, base)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include "dcn316_smu.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
|
||||
// DCN316 this is CLK1 instance
|
||||
#define MAX_INSTANCE 7
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
#include "reg_helper.h"
|
||||
#include "core_types.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
|
||||
#include "atomfirmware.h"
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@
|
|||
#include "dm_helpers.h"
|
||||
#include "mem_input.h"
|
||||
|
||||
#include "dc_link_dp.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
|
||||
#include "dsc.h"
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "grph_object_id.h"
|
||||
#include "gpio_service_interface.h"
|
||||
#include "core_status.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link/protocols/link_dp_dpia.h"
|
||||
#include "link/protocols/link_ddc.h"
|
||||
#include "link_hwss.h"
|
||||
|
|
@ -46,6 +45,8 @@
|
|||
#include "fixed31_32.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dmcu.h"
|
||||
#include "dsc.h"
|
||||
#include "opp.h"
|
||||
#include "hw/clk_mgr.h"
|
||||
#include "dce/dmub_psr.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
|
|
@ -4304,3 +4305,591 @@ void dc_restore_link_res_map(const struct dc *dc, uint32_t *map)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dp_validate_mode_timing(
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing)
|
||||
{
|
||||
uint32_t req_bw;
|
||||
uint32_t max_bw;
|
||||
|
||||
const struct dc_link_settings *link_setting;
|
||||
|
||||
/* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
|
||||
if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
|
||||
!link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
|
||||
dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
|
||||
return false;
|
||||
|
||||
/*always DP fail safe mode*/
|
||||
if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
|
||||
timing->h_addressable == (uint32_t) 640 &&
|
||||
timing->v_addressable == (uint32_t) 480)
|
||||
return true;
|
||||
|
||||
link_setting = dc_link_get_link_cap(link);
|
||||
|
||||
/* TODO: DYNAMIC_VALIDATION needs to be implemented */
|
||||
/*if (flags.DYNAMIC_VALIDATION == 1 &&
|
||||
link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
|
||||
link_setting = &link->verified_link_cap;
|
||||
*/
|
||||
|
||||
req_bw = dc_bandwidth_in_kbps_from_timing(timing);
|
||||
max_bw = dc_link_bandwidth_kbps(link, link_setting);
|
||||
|
||||
if (req_bw <= max_bw) {
|
||||
/* remember the biggest mode here, during
|
||||
* initial link training (to get
|
||||
* verified_link_cap), LS sends event about
|
||||
* cannot train at reported cap to upper
|
||||
* layer and upper layer will re-enumerate modes.
|
||||
* this is not necessary if the lower
|
||||
* verified_link_cap is enough to drive
|
||||
* all the modes */
|
||||
|
||||
/* TODO: DYNAMIC_VALIDATION needs to be implemented */
|
||||
/* if (flags.DYNAMIC_VALIDATION == 1)
|
||||
dpsst->max_req_bw_for_verified_linkcap = dal_max(
|
||||
dpsst->max_req_bw_for_verified_linkcap, req_bw); */
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
|
||||
{
|
||||
unsigned char mstmCntl;
|
||||
|
||||
core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
|
||||
if (enable)
|
||||
mstmCntl |= DP_MST_EN;
|
||||
else
|
||||
mstmCntl &= (~DP_MST_EN);
|
||||
|
||||
core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
|
||||
}
|
||||
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready)
|
||||
{
|
||||
/* FEC has to be "set ready" before the link training.
|
||||
* The policy is to always train with FEC
|
||||
* if the sink supports it and leave it enabled on link.
|
||||
* If FEC is not supported, disable it.
|
||||
*/
|
||||
struct link_encoder *link_enc = NULL;
|
||||
enum dc_status status = DC_OK;
|
||||
uint8_t fec_config = 0;
|
||||
|
||||
link_enc = link_enc_cfg_get_link_enc(link);
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_link_should_enable_fec(link))
|
||||
return status;
|
||||
|
||||
if (link_enc->funcs->fec_set_ready &&
|
||||
link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
|
||||
if (ready) {
|
||||
fec_config = 1;
|
||||
status = core_link_write_dpcd(link,
|
||||
DP_FEC_CONFIGURATION,
|
||||
&fec_config,
|
||||
sizeof(fec_config));
|
||||
if (status == DC_OK) {
|
||||
link_enc->funcs->fec_set_ready(link_enc, true);
|
||||
link->fec_state = dc_link_fec_ready;
|
||||
} else {
|
||||
link_enc->funcs->fec_set_ready(link_enc, false);
|
||||
link->fec_state = dc_link_fec_not_ready;
|
||||
dm_error("dpcd write failed to set fec_ready");
|
||||
}
|
||||
} else if (link->fec_state == dc_link_fec_ready) {
|
||||
fec_config = 0;
|
||||
status = core_link_write_dpcd(link,
|
||||
DP_FEC_CONFIGURATION,
|
||||
&fec_config,
|
||||
sizeof(fec_config));
|
||||
link_enc->funcs->fec_set_ready(link_enc, false);
|
||||
link->fec_state = dc_link_fec_not_ready;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable)
|
||||
{
|
||||
struct link_encoder *link_enc = NULL;
|
||||
|
||||
link_enc = link_enc_cfg_get_link_enc(link);
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_link_should_enable_fec(link))
|
||||
return;
|
||||
|
||||
if (link_enc->funcs->fec_set_enable &&
|
||||
link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
|
||||
if (link->fec_state == dc_link_fec_ready && enable) {
|
||||
/* Accord to DP spec, FEC enable sequence can first
|
||||
* be transmitted anytime after 1000 LL codes have
|
||||
* been transmitted on the link after link training
|
||||
* completion. Using 1 lane RBR should have the maximum
|
||||
* time for transmitting 1000 LL codes which is 6.173 us.
|
||||
* So use 7 microseconds delay instead.
|
||||
*/
|
||||
udelay(7);
|
||||
link_enc->funcs->fec_set_enable(link_enc, true);
|
||||
link->fec_state = dc_link_fec_enabled;
|
||||
} else if (link->fec_state == dc_link_fec_enabled && !enable) {
|
||||
link_enc->funcs->fec_set_enable(link_enc, false);
|
||||
link->fec_state = dc_link_fec_ready;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
|
||||
static void get_lane_status(
|
||||
struct dc_link *link,
|
||||
uint32_t lane_count,
|
||||
union lane_status *status,
|
||||
union lane_align_status_updated *status_updated)
|
||||
{
|
||||
unsigned int lane;
|
||||
uint8_t dpcd_buf[3] = {0};
|
||||
|
||||
if (status == NULL || status_updated == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_LANE0_1_STATUS,
|
||||
dpcd_buf,
|
||||
sizeof(dpcd_buf));
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
status[lane].raw = dp_get_nibble_at_index(&dpcd_buf[0], lane);
|
||||
}
|
||||
|
||||
status_updated->raw = dpcd_buf[2];
|
||||
}
|
||||
|
||||
bool dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
struct link_mst_stream_allocation_table *proposed_table,
|
||||
bool allocate)
|
||||
{
|
||||
const uint8_t vc_id = 1; /// VC ID always 1 for SST
|
||||
const uint8_t start_time_slot = 0; /// Always start at time slot 0 for SST
|
||||
bool result = false;
|
||||
uint8_t req_slot_count = 0;
|
||||
struct fixed31_32 avg_time_slots_per_mtp = { 0 };
|
||||
union payload_table_update_status update_status = { 0 };
|
||||
const uint32_t max_retries = 30;
|
||||
uint32_t retries = 0;
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
if (allocate) {
|
||||
avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
|
||||
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
|
||||
/// Validation should filter out modes that exceed link BW
|
||||
ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT);
|
||||
if (req_slot_count > MAX_MTP_SLOT_COUNT)
|
||||
return false;
|
||||
} else {
|
||||
/// Leave req_slot_count = 0 if allocate is false.
|
||||
}
|
||||
|
||||
proposed_table->stream_count = 1; /// Always 1 stream for SST
|
||||
proposed_table->stream_allocations[0].slot_count = req_slot_count;
|
||||
proposed_table->stream_allocations[0].vcp_id = vc_id;
|
||||
|
||||
if (link->aux_access_disabled)
|
||||
return true;
|
||||
|
||||
/// Write DPCD 2C0 = 1 to start updating
|
||||
update_status.bits.VC_PAYLOAD_TABLE_UPDATED = 1;
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_TABLE_UPDATE_STATUS,
|
||||
&update_status.raw,
|
||||
1);
|
||||
|
||||
/// Program the changes in DPCD 1C0 - 1C2
|
||||
ASSERT(vc_id == 1);
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_ALLOCATE_SET,
|
||||
&vc_id,
|
||||
1);
|
||||
|
||||
ASSERT(start_time_slot == 0);
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_ALLOCATE_START_TIME_SLOT,
|
||||
&start_time_slot,
|
||||
1);
|
||||
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT,
|
||||
&req_slot_count,
|
||||
1);
|
||||
|
||||
/// Poll till DPCD 2C0 read 1
|
||||
/// Try for at least 150ms (30 retries, with 5ms delay after each attempt)
|
||||
|
||||
while (retries < max_retries) {
|
||||
if (core_link_read_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_TABLE_UPDATE_STATUS,
|
||||
&update_status.raw,
|
||||
1) == DC_OK) {
|
||||
if (update_status.bits.VC_PAYLOAD_TABLE_UPDATED == 1) {
|
||||
DC_LOG_DP2("SST Update Payload: downstream payload table updated.");
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
union dpcd_rev dpcdRev;
|
||||
|
||||
if (core_link_read_dpcd(
|
||||
link,
|
||||
DP_DPCD_REV,
|
||||
&dpcdRev.raw,
|
||||
1) != DC_OK) {
|
||||
DC_LOG_ERROR("SST Update Payload: Unable to read DPCD revision "
|
||||
"of sink while polling payload table "
|
||||
"updated status bit.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
retries++;
|
||||
msleep(5);
|
||||
}
|
||||
|
||||
if (!result && retries == max_retries) {
|
||||
DC_LOG_ERROR("SST Update Payload: Payload table not updated after retries, "
|
||||
"continue on. Something is wrong with the branch.");
|
||||
// TODO - DP2.0 Payload: Read and log the payload table from downstream branch
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link)
|
||||
{
|
||||
/*
|
||||
* wait for ACT handled
|
||||
*/
|
||||
int i;
|
||||
const int act_retries = 30;
|
||||
enum act_return_status result = ACT_FAILED;
|
||||
union payload_table_update_status update_status = {0};
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
|
||||
union lane_align_status_updated lane_status_updated;
|
||||
DC_LOGGER_INIT(link->ctx->logger);
|
||||
|
||||
if (link->aux_access_disabled)
|
||||
return true;
|
||||
for (i = 0; i < act_retries; i++) {
|
||||
get_lane_status(link, link->cur_link_settings.lane_count, dpcd_lane_status, &lane_status_updated);
|
||||
|
||||
if (!dp_is_cr_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
|
||||
!dp_is_ch_eq_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
|
||||
!dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) ||
|
||||
!dp_is_interlane_aligned(lane_status_updated)) {
|
||||
DC_LOG_ERROR("SST Update Payload: Link loss occurred while "
|
||||
"polling for ACT handled.");
|
||||
result = ACT_LINK_LOST;
|
||||
break;
|
||||
}
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_TABLE_UPDATE_STATUS,
|
||||
&update_status.raw,
|
||||
1);
|
||||
|
||||
if (update_status.bits.ACT_HANDLED == 1) {
|
||||
DC_LOG_DP2("SST Update Payload: ACT handled by downstream.");
|
||||
result = ACT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(5);
|
||||
}
|
||||
|
||||
if (result == ACT_FAILED) {
|
||||
DC_LOG_ERROR("SST Update Payload: ACT still not handled after retries, "
|
||||
"continue on. Something is wrong with the branch.");
|
||||
}
|
||||
|
||||
return (result == ACT_SUCCESS);
|
||||
}
|
||||
|
||||
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_stream_state *stream,
|
||||
const struct dc_link *link)
|
||||
{
|
||||
struct fixed31_32 link_bw_effective =
|
||||
dc_fixpt_from_int(
|
||||
dc_link_bandwidth_kbps(link, &link->cur_link_settings));
|
||||
struct fixed31_32 timeslot_bw_effective =
|
||||
dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT);
|
||||
struct fixed31_32 timing_bw =
|
||||
dc_fixpt_from_int(
|
||||
dc_bandwidth_in_kbps_from_timing(&stream->timing));
|
||||
struct fixed31_32 avg_time_slots_per_mtp =
|
||||
dc_fixpt_div(timing_bw, timeslot_bw_effective);
|
||||
|
||||
return avg_time_slots_per_mtp;
|
||||
}
|
||||
|
||||
void dc_link_clear_dprx_states(struct dc_link *link)
|
||||
{
|
||||
memset(&link->dprx_states, 0, sizeof(link->dprx_states));
|
||||
}
|
||||
|
||||
void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
|
||||
{
|
||||
if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
|
||||
core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
|
||||
&dp_test_mode, sizeof(dp_test_mode));
|
||||
}
|
||||
|
||||
static void dsc_optc_config_log(struct display_stream_compressor *dsc,
|
||||
struct dsc_optc_config *config)
|
||||
{
|
||||
uint32_t precision = 1 << 28;
|
||||
uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
|
||||
uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
|
||||
uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
|
||||
DC_LOGGER_INIT(dsc->ctx->logger);
|
||||
|
||||
/* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
|
||||
* bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
|
||||
* 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
|
||||
*/
|
||||
ll_bytes_per_pix_fraq *= 10000000;
|
||||
ll_bytes_per_pix_fraq /= precision;
|
||||
|
||||
DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
|
||||
config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
|
||||
DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
|
||||
DC_LOG_DSC("\tslice_width %d", config->slice_width);
|
||||
}
|
||||
|
||||
bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
bool result = false;
|
||||
|
||||
if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
|
||||
result = true;
|
||||
else
|
||||
result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
|
||||
* i.e. after dp_enable_dsc_on_rx() had been called
|
||||
*/
|
||||
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int opp_cnt = 1;
|
||||
DC_LOGGER_INIT(dsc->ctx->logger);
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
opp_cnt++;
|
||||
|
||||
if (enable) {
|
||||
struct dsc_config dsc_cfg;
|
||||
struct dsc_optc_config dsc_optc_cfg;
|
||||
enum optc_dsc_mode optc_dsc_mode;
|
||||
|
||||
/* Enable DSC hw block */
|
||||
dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
|
||||
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
|
||||
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
|
||||
dsc_cfg.color_depth = stream->timing.display_color_depth;
|
||||
dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
|
||||
dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
|
||||
ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
|
||||
dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
|
||||
|
||||
dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
|
||||
dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
|
||||
|
||||
odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
|
||||
odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
|
||||
}
|
||||
dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
|
||||
dsc_cfg.pic_width *= opp_cnt;
|
||||
|
||||
optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
|
||||
|
||||
/* Enable DSC in encoder */
|
||||
if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
|
||||
&& !link_is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
|
||||
dsc_optc_config_log(dsc, &dsc_optc_cfg);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
|
||||
optc_dsc_mode,
|
||||
dsc_optc_cfg.bytes_per_pixel,
|
||||
dsc_optc_cfg.slice_width);
|
||||
|
||||
/* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
|
||||
}
|
||||
|
||||
/* Enable DSC in OPTC */
|
||||
DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
|
||||
dsc_optc_config_log(dsc, &dsc_optc_cfg);
|
||||
pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
|
||||
optc_dsc_mode,
|
||||
dsc_optc_cfg.bytes_per_pixel,
|
||||
dsc_optc_cfg.slice_width);
|
||||
} else {
|
||||
/* disable DSC in OPTC */
|
||||
pipe_ctx->stream_res.tg->funcs->set_dsc_config(
|
||||
pipe_ctx->stream_res.tg,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
|
||||
/* disable DSC in stream encoder */
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false,
|
||||
NULL,
|
||||
true);
|
||||
else if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* disable DSC block */
|
||||
pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
|
||||
}
|
||||
}
|
||||
|
||||
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
bool result = false;
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC)
|
||||
goto out;
|
||||
if (!dsc)
|
||||
goto out;
|
||||
|
||||
if (enable) {
|
||||
{
|
||||
dp_set_dsc_on_stream(pipe_ctx, true);
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
dp_set_dsc_on_rx(pipe_ctx, false);
|
||||
dp_set_dsc_on_stream(pipe_ctx, false);
|
||||
result = true;
|
||||
}
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
|
||||
* hence PPS info packet update need to use frame update instead of immediate update.
|
||||
* Added parameter immediate_update for this purpose.
|
||||
* The decision to use frame update is hard-coded in function dp_update_dsc_config(),
|
||||
* which is the only place where a "false" would be passed in for param immediate_update.
|
||||
*
|
||||
* immediate_update is only applicable when DSC is enabled.
|
||||
*/
|
||||
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
DC_LOGGER_INIT(dsc->ctx->logger);
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
|
||||
return false;
|
||||
|
||||
if (enable) {
|
||||
struct dsc_config dsc_cfg;
|
||||
uint8_t dsc_packed_pps[128];
|
||||
|
||||
memset(&dsc_cfg, 0, sizeof(dsc_cfg));
|
||||
memset(dsc_packed_pps, 0, 128);
|
||||
|
||||
/* Enable DSC hw block */
|
||||
dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
|
||||
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
|
||||
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
|
||||
dsc_cfg.color_depth = stream->timing.display_color_depth;
|
||||
dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
|
||||
dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
|
||||
|
||||
dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
|
||||
memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0],
|
||||
immediate_update);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0],
|
||||
immediate_update);
|
||||
}
|
||||
} else {
|
||||
/* disable DSC PPS in stream encoder */
|
||||
memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps));
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false,
|
||||
NULL,
|
||||
true);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC)
|
||||
return false;
|
||||
if (!dsc)
|
||||
return false;
|
||||
|
||||
dp_set_dsc_on_stream(pipe_ctx, true);
|
||||
dp_set_dsc_pps_sdp(pipe_ctx, true, false);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,644 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 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
|
||||
*/
|
||||
#include "dm_services.h"
|
||||
#include "dc.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dm_helpers.h"
|
||||
#include "opp.h"
|
||||
#include "dsc.h"
|
||||
#include "resource.h"
|
||||
|
||||
#include "inc/core_types.h"
|
||||
#include "link_hwss.h"
|
||||
#include "link/protocols/link_ddc.h"
|
||||
#include "core_status.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#include "dc_dmub_srv.h"
|
||||
#include "dce/dmub_hw_lock_mgr.h"
|
||||
#include "link/protocols/link_dp_dpia.h"
|
||||
#include "inc/link_enc_cfg.h"
|
||||
#include "clk_mgr.h"
|
||||
#include "link/accessories/link_dp_trace.h"
|
||||
#include "link/protocols/link_dp_training.h"
|
||||
#include "link/protocols/link_dp_training_fixed_vs_pe_retimer.h"
|
||||
#include "link/protocols/link_dp_training_dpia.h"
|
||||
#include "link/protocols/link_dp_training_auxless.h"
|
||||
#include "link/protocols/link_dp_phy.h"
|
||||
#include "link/protocols/link_dp_capability.h"
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
||||
#define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */
|
||||
#include "link/protocols/link_dpcd.h"
|
||||
|
||||
bool dp_validate_mode_timing(
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing)
|
||||
{
|
||||
uint32_t req_bw;
|
||||
uint32_t max_bw;
|
||||
|
||||
const struct dc_link_settings *link_setting;
|
||||
|
||||
/* According to spec, VSC SDP should be used if pixel format is YCbCr420 */
|
||||
if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 &&
|
||||
!link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
|
||||
dal_graphics_object_id_get_connector_id(link->link_id) != CONNECTOR_ID_VIRTUAL)
|
||||
return false;
|
||||
|
||||
/*always DP fail safe mode*/
|
||||
if ((timing->pix_clk_100hz / 10) == (uint32_t) 25175 &&
|
||||
timing->h_addressable == (uint32_t) 640 &&
|
||||
timing->v_addressable == (uint32_t) 480)
|
||||
return true;
|
||||
|
||||
link_setting = dc_link_get_link_cap(link);
|
||||
|
||||
/* TODO: DYNAMIC_VALIDATION needs to be implemented */
|
||||
/*if (flags.DYNAMIC_VALIDATION == 1 &&
|
||||
link->verified_link_cap.lane_count != LANE_COUNT_UNKNOWN)
|
||||
link_setting = &link->verified_link_cap;
|
||||
*/
|
||||
|
||||
req_bw = dc_bandwidth_in_kbps_from_timing(timing);
|
||||
max_bw = dc_link_bandwidth_kbps(link, link_setting);
|
||||
|
||||
if (req_bw <= max_bw) {
|
||||
/* remember the biggest mode here, during
|
||||
* initial link training (to get
|
||||
* verified_link_cap), LS sends event about
|
||||
* cannot train at reported cap to upper
|
||||
* layer and upper layer will re-enumerate modes.
|
||||
* this is not necessary if the lower
|
||||
* verified_link_cap is enough to drive
|
||||
* all the modes */
|
||||
|
||||
/* TODO: DYNAMIC_VALIDATION needs to be implemented */
|
||||
/* if (flags.DYNAMIC_VALIDATION == 1)
|
||||
dpsst->max_req_bw_for_verified_linkcap = dal_max(
|
||||
dpsst->max_req_bw_for_verified_linkcap, req_bw); */
|
||||
return true;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
void dp_enable_mst_on_sink(struct dc_link *link, bool enable)
|
||||
{
|
||||
unsigned char mstmCntl;
|
||||
|
||||
core_link_read_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
|
||||
if (enable)
|
||||
mstmCntl |= DP_MST_EN;
|
||||
else
|
||||
mstmCntl &= (~DP_MST_EN);
|
||||
|
||||
core_link_write_dpcd(link, DP_MSTM_CTRL, &mstmCntl, 1);
|
||||
}
|
||||
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready)
|
||||
{
|
||||
/* FEC has to be "set ready" before the link training.
|
||||
* The policy is to always train with FEC
|
||||
* if the sink supports it and leave it enabled on link.
|
||||
* If FEC is not supported, disable it.
|
||||
*/
|
||||
struct link_encoder *link_enc = NULL;
|
||||
enum dc_status status = DC_OK;
|
||||
uint8_t fec_config = 0;
|
||||
|
||||
link_enc = link_enc_cfg_get_link_enc(link);
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_link_should_enable_fec(link))
|
||||
return status;
|
||||
|
||||
if (link_enc->funcs->fec_set_ready &&
|
||||
link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
|
||||
if (ready) {
|
||||
fec_config = 1;
|
||||
status = core_link_write_dpcd(link,
|
||||
DP_FEC_CONFIGURATION,
|
||||
&fec_config,
|
||||
sizeof(fec_config));
|
||||
if (status == DC_OK) {
|
||||
link_enc->funcs->fec_set_ready(link_enc, true);
|
||||
link->fec_state = dc_link_fec_ready;
|
||||
} else {
|
||||
link_enc->funcs->fec_set_ready(link_enc, false);
|
||||
link->fec_state = dc_link_fec_not_ready;
|
||||
dm_error("dpcd write failed to set fec_ready");
|
||||
}
|
||||
} else if (link->fec_state == dc_link_fec_ready) {
|
||||
fec_config = 0;
|
||||
status = core_link_write_dpcd(link,
|
||||
DP_FEC_CONFIGURATION,
|
||||
&fec_config,
|
||||
sizeof(fec_config));
|
||||
link_enc->funcs->fec_set_ready(link_enc, false);
|
||||
link->fec_state = dc_link_fec_not_ready;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable)
|
||||
{
|
||||
struct link_encoder *link_enc = NULL;
|
||||
|
||||
link_enc = link_enc_cfg_get_link_enc(link);
|
||||
ASSERT(link_enc);
|
||||
|
||||
if (!dc_link_should_enable_fec(link))
|
||||
return;
|
||||
|
||||
if (link_enc->funcs->fec_set_enable &&
|
||||
link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
|
||||
if (link->fec_state == dc_link_fec_ready && enable) {
|
||||
/* Accord to DP spec, FEC enable sequence can first
|
||||
* be transmitted anytime after 1000 LL codes have
|
||||
* been transmitted on the link after link training
|
||||
* completion. Using 1 lane RBR should have the maximum
|
||||
* time for transmitting 1000 LL codes which is 6.173 us.
|
||||
* So use 7 microseconds delay instead.
|
||||
*/
|
||||
udelay(7);
|
||||
link_enc->funcs->fec_set_enable(link_enc, true);
|
||||
link->fec_state = dc_link_fec_enabled;
|
||||
} else if (link->fec_state == dc_link_fec_enabled && !enable) {
|
||||
link_enc->funcs->fec_set_enable(link_enc, false);
|
||||
link->fec_state = dc_link_fec_ready;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - DP2.0 Link: Fix get_lane_status to handle LTTPR offset (SST and MST)
|
||||
static void get_lane_status(
|
||||
struct dc_link *link,
|
||||
uint32_t lane_count,
|
||||
union lane_status *status,
|
||||
union lane_align_status_updated *status_updated)
|
||||
{
|
||||
unsigned int lane;
|
||||
uint8_t dpcd_buf[3] = {0};
|
||||
|
||||
if (status == NULL || status_updated == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_LANE0_1_STATUS,
|
||||
dpcd_buf,
|
||||
sizeof(dpcd_buf));
|
||||
|
||||
for (lane = 0; lane < lane_count; lane++) {
|
||||
status[lane].raw = dp_get_nibble_at_index(&dpcd_buf[0], lane);
|
||||
}
|
||||
|
||||
status_updated->raw = dpcd_buf[2];
|
||||
}
|
||||
|
||||
bool dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
struct link_mst_stream_allocation_table *proposed_table,
|
||||
bool allocate)
|
||||
{
|
||||
const uint8_t vc_id = 1; /// VC ID always 1 for SST
|
||||
const uint8_t start_time_slot = 0; /// Always start at time slot 0 for SST
|
||||
bool result = false;
|
||||
uint8_t req_slot_count = 0;
|
||||
struct fixed31_32 avg_time_slots_per_mtp = { 0 };
|
||||
union payload_table_update_status update_status = { 0 };
|
||||
const uint32_t max_retries = 30;
|
||||
uint32_t retries = 0;
|
||||
|
||||
if (allocate) {
|
||||
avg_time_slots_per_mtp = calculate_sst_avg_time_slots_per_mtp(stream, link);
|
||||
req_slot_count = dc_fixpt_ceil(avg_time_slots_per_mtp);
|
||||
/// Validation should filter out modes that exceed link BW
|
||||
ASSERT(req_slot_count <= MAX_MTP_SLOT_COUNT);
|
||||
if (req_slot_count > MAX_MTP_SLOT_COUNT)
|
||||
return false;
|
||||
} else {
|
||||
/// Leave req_slot_count = 0 if allocate is false.
|
||||
}
|
||||
|
||||
proposed_table->stream_count = 1; /// Always 1 stream for SST
|
||||
proposed_table->stream_allocations[0].slot_count = req_slot_count;
|
||||
proposed_table->stream_allocations[0].vcp_id = vc_id;
|
||||
|
||||
if (link->aux_access_disabled)
|
||||
return true;
|
||||
|
||||
/// Write DPCD 2C0 = 1 to start updating
|
||||
update_status.bits.VC_PAYLOAD_TABLE_UPDATED = 1;
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_TABLE_UPDATE_STATUS,
|
||||
&update_status.raw,
|
||||
1);
|
||||
|
||||
/// Program the changes in DPCD 1C0 - 1C2
|
||||
ASSERT(vc_id == 1);
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_ALLOCATE_SET,
|
||||
&vc_id,
|
||||
1);
|
||||
|
||||
ASSERT(start_time_slot == 0);
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_ALLOCATE_START_TIME_SLOT,
|
||||
&start_time_slot,
|
||||
1);
|
||||
|
||||
core_link_write_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT,
|
||||
&req_slot_count,
|
||||
1);
|
||||
|
||||
/// Poll till DPCD 2C0 read 1
|
||||
/// Try for at least 150ms (30 retries, with 5ms delay after each attempt)
|
||||
|
||||
while (retries < max_retries) {
|
||||
if (core_link_read_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_TABLE_UPDATE_STATUS,
|
||||
&update_status.raw,
|
||||
1) == DC_OK) {
|
||||
if (update_status.bits.VC_PAYLOAD_TABLE_UPDATED == 1) {
|
||||
DC_LOG_DP2("SST Update Payload: downstream payload table updated.");
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
union dpcd_rev dpcdRev;
|
||||
|
||||
if (core_link_read_dpcd(
|
||||
link,
|
||||
DP_DPCD_REV,
|
||||
&dpcdRev.raw,
|
||||
1) != DC_OK) {
|
||||
DC_LOG_ERROR("SST Update Payload: Unable to read DPCD revision "
|
||||
"of sink while polling payload table "
|
||||
"updated status bit.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
retries++;
|
||||
msleep(5);
|
||||
}
|
||||
|
||||
if (!result && retries == max_retries) {
|
||||
DC_LOG_ERROR("SST Update Payload: Payload table not updated after retries, "
|
||||
"continue on. Something is wrong with the branch.");
|
||||
// TODO - DP2.0 Payload: Read and log the payload table from downstream branch
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link)
|
||||
{
|
||||
/*
|
||||
* wait for ACT handled
|
||||
*/
|
||||
int i;
|
||||
const int act_retries = 30;
|
||||
enum act_return_status result = ACT_FAILED;
|
||||
union payload_table_update_status update_status = {0};
|
||||
union lane_status dpcd_lane_status[LANE_COUNT_DP_MAX];
|
||||
union lane_align_status_updated lane_status_updated;
|
||||
|
||||
if (link->aux_access_disabled)
|
||||
return true;
|
||||
for (i = 0; i < act_retries; i++) {
|
||||
get_lane_status(link, link->cur_link_settings.lane_count, dpcd_lane_status, &lane_status_updated);
|
||||
|
||||
if (!dp_is_cr_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
|
||||
!dp_is_ch_eq_done(link->cur_link_settings.lane_count, dpcd_lane_status) ||
|
||||
!dp_is_symbol_locked(link->cur_link_settings.lane_count, dpcd_lane_status) ||
|
||||
!dp_is_interlane_aligned(lane_status_updated)) {
|
||||
DC_LOG_ERROR("SST Update Payload: Link loss occurred while "
|
||||
"polling for ACT handled.");
|
||||
result = ACT_LINK_LOST;
|
||||
break;
|
||||
}
|
||||
core_link_read_dpcd(
|
||||
link,
|
||||
DP_PAYLOAD_TABLE_UPDATE_STATUS,
|
||||
&update_status.raw,
|
||||
1);
|
||||
|
||||
if (update_status.bits.ACT_HANDLED == 1) {
|
||||
DC_LOG_DP2("SST Update Payload: ACT handled by downstream.");
|
||||
result = ACT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(5);
|
||||
}
|
||||
|
||||
if (result == ACT_FAILED) {
|
||||
DC_LOG_ERROR("SST Update Payload: ACT still not handled after retries, "
|
||||
"continue on. Something is wrong with the branch.");
|
||||
}
|
||||
|
||||
return (result == ACT_SUCCESS);
|
||||
}
|
||||
|
||||
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_stream_state *stream,
|
||||
const struct dc_link *link)
|
||||
{
|
||||
struct fixed31_32 link_bw_effective =
|
||||
dc_fixpt_from_int(
|
||||
dc_link_bandwidth_kbps(link, &link->cur_link_settings));
|
||||
struct fixed31_32 timeslot_bw_effective =
|
||||
dc_fixpt_div_int(link_bw_effective, MAX_MTP_SLOT_COUNT);
|
||||
struct fixed31_32 timing_bw =
|
||||
dc_fixpt_from_int(
|
||||
dc_bandwidth_in_kbps_from_timing(&stream->timing));
|
||||
struct fixed31_32 avg_time_slots_per_mtp =
|
||||
dc_fixpt_div(timing_bw, timeslot_bw_effective);
|
||||
|
||||
return avg_time_slots_per_mtp;
|
||||
}
|
||||
|
||||
void dc_link_clear_dprx_states(struct dc_link *link)
|
||||
{
|
||||
memset(&link->dprx_states, 0, sizeof(link->dprx_states));
|
||||
}
|
||||
|
||||
void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode)
|
||||
{
|
||||
if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
|
||||
core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
|
||||
&dp_test_mode, sizeof(dp_test_mode));
|
||||
}
|
||||
|
||||
#undef DC_LOGGER
|
||||
#define DC_LOGGER \
|
||||
dsc->ctx->logger
|
||||
static void dsc_optc_config_log(struct display_stream_compressor *dsc,
|
||||
struct dsc_optc_config *config)
|
||||
{
|
||||
uint32_t precision = 1 << 28;
|
||||
uint32_t bytes_per_pixel_int = config->bytes_per_pixel / precision;
|
||||
uint32_t bytes_per_pixel_mod = config->bytes_per_pixel % precision;
|
||||
uint64_t ll_bytes_per_pix_fraq = bytes_per_pixel_mod;
|
||||
|
||||
/* 7 fractional digits decimal precision for bytes per pixel is enough because DSC
|
||||
* bits per pixel precision is 1/16th of a pixel, which means bytes per pixel precision is
|
||||
* 1/16/8 = 1/128 of a byte, or 0.0078125 decimal
|
||||
*/
|
||||
ll_bytes_per_pix_fraq *= 10000000;
|
||||
ll_bytes_per_pix_fraq /= precision;
|
||||
|
||||
DC_LOG_DSC("\tbytes_per_pixel 0x%08x (%d.%07d)",
|
||||
config->bytes_per_pixel, bytes_per_pixel_int, (uint32_t)ll_bytes_per_pix_fraq);
|
||||
DC_LOG_DSC("\tis_pixel_format_444 %d", config->is_pixel_format_444);
|
||||
DC_LOG_DSC("\tslice_width %d", config->slice_width);
|
||||
}
|
||||
|
||||
bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
bool result = false;
|
||||
|
||||
if (dc_is_virtual_signal(stream->signal) || IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment))
|
||||
result = true;
|
||||
else
|
||||
result = dm_helpers_dp_write_dsc_enable(dc->ctx, stream, enable);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* The stream with these settings can be sent (unblanked) only after DSC was enabled on RX first,
|
||||
* i.e. after dp_enable_dsc_on_rx() had been called
|
||||
*/
|
||||
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
struct dc *dc = pipe_ctx->stream->ctx->dc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct pipe_ctx *odm_pipe;
|
||||
int opp_cnt = 1;
|
||||
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
opp_cnt++;
|
||||
|
||||
if (enable) {
|
||||
struct dsc_config dsc_cfg;
|
||||
struct dsc_optc_config dsc_optc_cfg;
|
||||
enum optc_dsc_mode optc_dsc_mode;
|
||||
|
||||
/* Enable DSC hw block */
|
||||
dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
|
||||
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
|
||||
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
|
||||
dsc_cfg.color_depth = stream->timing.display_color_depth;
|
||||
dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
|
||||
dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
|
||||
ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
|
||||
dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
|
||||
|
||||
dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
|
||||
dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
|
||||
struct display_stream_compressor *odm_dsc = odm_pipe->stream_res.dsc;
|
||||
|
||||
odm_dsc->funcs->dsc_set_config(odm_dsc, &dsc_cfg, &dsc_optc_cfg);
|
||||
odm_dsc->funcs->dsc_enable(odm_dsc, odm_pipe->stream_res.opp->inst);
|
||||
}
|
||||
dsc_cfg.dc_dsc_cfg.num_slices_h *= opp_cnt;
|
||||
dsc_cfg.pic_width *= opp_cnt;
|
||||
|
||||
optc_dsc_mode = dsc_optc_cfg.is_pixel_format_444 ? OPTC_DSC_ENABLED_444 : OPTC_DSC_ENABLED_NATIVE_SUBSAMPLED;
|
||||
|
||||
/* Enable DSC in encoder */
|
||||
if (dc_is_dp_signal(stream->signal) && !IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)
|
||||
&& !link_is_dp_128b_132b_signal(pipe_ctx)) {
|
||||
DC_LOG_DSC("Setting stream encoder DSC config for engine %d:", (int)pipe_ctx->stream_res.stream_enc->id);
|
||||
dsc_optc_config_log(dsc, &dsc_optc_cfg);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(pipe_ctx->stream_res.stream_enc,
|
||||
optc_dsc_mode,
|
||||
dsc_optc_cfg.bytes_per_pixel,
|
||||
dsc_optc_cfg.slice_width);
|
||||
|
||||
/* PPS SDP is set elsewhere because it has to be done after DIG FE is connected to DIG BE */
|
||||
}
|
||||
|
||||
/* Enable DSC in OPTC */
|
||||
DC_LOG_DSC("Setting optc DSC config for tg instance %d:", pipe_ctx->stream_res.tg->inst);
|
||||
dsc_optc_config_log(dsc, &dsc_optc_cfg);
|
||||
pipe_ctx->stream_res.tg->funcs->set_dsc_config(pipe_ctx->stream_res.tg,
|
||||
optc_dsc_mode,
|
||||
dsc_optc_cfg.bytes_per_pixel,
|
||||
dsc_optc_cfg.slice_width);
|
||||
} else {
|
||||
/* disable DSC in OPTC */
|
||||
pipe_ctx->stream_res.tg->funcs->set_dsc_config(
|
||||
pipe_ctx->stream_res.tg,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
|
||||
/* disable DSC in stream encoder */
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false,
|
||||
NULL,
|
||||
true);
|
||||
else if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_config(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
OPTC_DSC_DISABLED, 0, 0);
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* disable DSC block */
|
||||
pipe_ctx->stream_res.dsc->funcs->dsc_disable(pipe_ctx->stream_res.dsc);
|
||||
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
|
||||
odm_pipe->stream_res.dsc->funcs->dsc_disable(odm_pipe->stream_res.dsc);
|
||||
}
|
||||
}
|
||||
|
||||
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
bool result = false;
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC)
|
||||
goto out;
|
||||
if (!dsc)
|
||||
goto out;
|
||||
|
||||
if (enable) {
|
||||
{
|
||||
dp_set_dsc_on_stream(pipe_ctx, true);
|
||||
result = true;
|
||||
}
|
||||
} else {
|
||||
dp_set_dsc_on_rx(pipe_ctx, false);
|
||||
dp_set_dsc_on_stream(pipe_ctx, false);
|
||||
result = true;
|
||||
}
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
|
||||
* hence PPS info packet update need to use frame update instead of immediate update.
|
||||
* Added parameter immediate_update for this purpose.
|
||||
* The decision to use frame update is hard-coded in function dp_update_dsc_config(),
|
||||
* which is the only place where a "false" would be passed in for param immediate_update.
|
||||
*
|
||||
* immediate_update is only applicable when DSC is enabled.
|
||||
*/
|
||||
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC || !dsc)
|
||||
return false;
|
||||
|
||||
if (enable) {
|
||||
struct dsc_config dsc_cfg;
|
||||
uint8_t dsc_packed_pps[128];
|
||||
|
||||
memset(&dsc_cfg, 0, sizeof(dsc_cfg));
|
||||
memset(dsc_packed_pps, 0, 128);
|
||||
|
||||
/* Enable DSC hw block */
|
||||
dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
|
||||
dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
|
||||
dsc_cfg.pixel_encoding = stream->timing.pixel_encoding;
|
||||
dsc_cfg.color_depth = stream->timing.display_color_depth;
|
||||
dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
|
||||
dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
|
||||
|
||||
dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
|
||||
memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
DC_LOG_DSC("Setting stream encoder DSC PPS SDP for engine %d\n", (int)pipe_ctx->stream_res.stream_enc->id);
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0],
|
||||
immediate_update);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc,
|
||||
true,
|
||||
&dsc_packed_pps[0],
|
||||
immediate_update);
|
||||
}
|
||||
} else {
|
||||
/* disable DSC PPS in stream encoder */
|
||||
memset(&stream->dsc_packed_pps[0], 0, sizeof(stream->dsc_packed_pps));
|
||||
if (dc_is_dp_signal(stream->signal)) {
|
||||
if (link_is_dp_128b_132b_signal(pipe_ctx))
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.hpo_dp_stream_enc,
|
||||
false,
|
||||
NULL,
|
||||
true);
|
||||
else
|
||||
pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
|
||||
pipe_ctx->stream_res.stream_enc, false, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
|
||||
|
||||
if (!pipe_ctx->stream->timing.flags.DSC)
|
||||
return false;
|
||||
if (!dsc)
|
||||
return false;
|
||||
|
||||
dp_set_dsc_on_stream(pipe_ctx, true);
|
||||
dp_set_dsc_pps_sdp(pipe_ctx, true, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef DC_LOGGER
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include "link_enc_cfg.h"
|
||||
#include "resource.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
|
||||
#define DC_LOGGER dc->ctx->logger
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#include "virtual/virtual_stream_encoder.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "link_enc_cfg.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "virtual/virtual_link_hwss.h"
|
||||
#include "link/hwss/link_hwss_dio.h"
|
||||
|
|
|
|||
|
|
@ -577,4 +577,54 @@ bool dc_link_decide_edp_link_settings(struct dc_link *link,
|
|||
uint32_t req_bw);
|
||||
void dc_link_edp_panel_backlight_power_on(struct dc_link *link,
|
||||
bool wait_for_hpd);
|
||||
|
||||
#define LINK_TRAINING_ATTEMPTS 4
|
||||
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */
|
||||
#define MAX_MTP_SLOT_COUNT 64
|
||||
#define TRAINING_AUX_RD_INTERVAL 100 //us
|
||||
#define LINK_AUX_WAKE_TIMEOUT_MS 1500 // Timeout when trying to wake unresponsive DPRX.
|
||||
|
||||
struct dc_link;
|
||||
struct dc_stream_state;
|
||||
struct dc_link_settings;
|
||||
|
||||
enum {
|
||||
/*
|
||||
* Some receivers fail to train on first try and are good
|
||||
* on subsequent tries. 2 retries should be plenty. If we
|
||||
* don't have a successful training then we don't expect to
|
||||
* ever get one.
|
||||
*/
|
||||
LINK_TRAINING_MAX_VERIFY_RETRY = 2,
|
||||
PEAK_FACTOR_X1000 = 1006,
|
||||
};
|
||||
|
||||
bool dp_validate_mode_timing(
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
void dp_enable_mst_on_sink(struct dc_link *link, bool enable);
|
||||
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready);
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable);
|
||||
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update);
|
||||
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
|
||||
bool dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
struct link_mst_stream_allocation_table *proposed_table,
|
||||
bool allocate);
|
||||
|
||||
bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link);
|
||||
|
||||
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_stream_state *stream,
|
||||
const struct dc_link *link);
|
||||
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
|
||||
|
||||
#endif /* DC_LINK_H_ */
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include "link_enc_cfg.h"
|
||||
#include "link_hwss.h"
|
||||
#include "link.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dccg.h"
|
||||
#include "clock_source.h"
|
||||
#include "clk_mgr.h"
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
#include "dcn10_hubp.h"
|
||||
#include "dcn10_hubbub.h"
|
||||
#include "dcn10_cm_common.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dccg.h"
|
||||
#include "clk_mgr.h"
|
||||
#include "link_hwss.h"
|
||||
|
|
@ -56,7 +55,6 @@
|
|||
#include "dce/dmub_hw_lock_mgr.h"
|
||||
#include "dc_trace.h"
|
||||
#include "dce/dmub_outbox.h"
|
||||
#include "inc/dc_link_dp.h"
|
||||
#include "link.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "dcn10_stream_encoder.h"
|
||||
#include "reg_helper.h"
|
||||
#include "hw_shared.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dcn30/dcn30_afmt.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
#include "dchubbub.h"
|
||||
#include "reg_helper.h"
|
||||
#include "dcn10/dcn10_cm_common.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "vm_helper.h"
|
||||
#include "dccg.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include "dcn20_stream_encoder.h"
|
||||
#include "reg_helper.h"
|
||||
#include "hw_shared.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
#include "dpcd_defs.h"
|
||||
#include "../dcn20/dcn20_hwseq.h"
|
||||
#include "dcn30_resource.h"
|
||||
#include "inc/dc_link_dp.h"
|
||||
#include "link.h"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
#include "link_hwss.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dce/dmub_outbox.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "dcn10/dcn10_hw_sequencer.h"
|
||||
#include "inc/link_enc_cfg.h"
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "dcn314_dio_stream_encoder.h"
|
||||
#include "reg_helper.h"
|
||||
#include "hw_shared.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@
|
|||
#include "link_hwss.h"
|
||||
#include "dpcd_defs.h"
|
||||
#include "dce/dmub_outbox.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "inc/dc_link_dp.h"
|
||||
#include "dcn10/dcn10_hw_sequencer.h"
|
||||
#include "inc/link_enc_cfg.h"
|
||||
#include "dcn30/dcn30_vpg.h"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include "dcn32_dio_stream_encoder.h"
|
||||
#include "reg_helper.h"
|
||||
#include "hw_shared.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
#include "dce/dmub_hw_lock_mgr.h"
|
||||
#include "dcn32_resource.h"
|
||||
#include "link.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dmub/inc/dmub_subvp_state.h"
|
||||
|
||||
#define DC_LOGGER_INIT(logger)
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
|
||||
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
|
||||
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dcn31/dcn31_apg.h"
|
||||
#include "dcn31/dcn31_dio_link_encoder.h"
|
||||
#include "dcn32/dcn32_dio_link_encoder.h"
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@
|
|||
#include "dcn31/dcn31_hpo_dp_stream_encoder.h"
|
||||
#include "dcn31/dcn31_hpo_dp_link_encoder.h"
|
||||
#include "dcn32/dcn32_hpo_dp_link_encoder.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dcn31/dcn31_apg.h"
|
||||
#include "dcn31/dcn31_dio_link_encoder.h"
|
||||
#include "dcn32/dcn32_dio_link_encoder.h"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "resource.h"
|
||||
#include "clk_mgr.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dchubbub.h"
|
||||
#include "dcn20/dcn20_resource.h"
|
||||
#include "dcn21/dcn21_resource.h"
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
*
|
||||
*/
|
||||
#include "dcn32_fpu.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dcn32/dcn32_resource.h"
|
||||
#include "dcn20/dcn20_resource.h"
|
||||
#include "display_mode_vba_util_32.h"
|
||||
|
|
|
|||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright 2015 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_LINK_DP_H__
|
||||
#define __DC_LINK_DP_H__
|
||||
|
||||
#define LINK_TRAINING_ATTEMPTS 4
|
||||
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */
|
||||
#define MAX_MTP_SLOT_COUNT 64
|
||||
#define TRAINING_AUX_RD_INTERVAL 100 //us
|
||||
#define LINK_AUX_WAKE_TIMEOUT_MS 1500 // Timeout when trying to wake unresponsive DPRX.
|
||||
|
||||
struct dc_link;
|
||||
struct dc_stream_state;
|
||||
struct dc_link_settings;
|
||||
|
||||
enum {
|
||||
/*
|
||||
* Some receivers fail to train on first try and are good
|
||||
* on subsequent tries. 2 retries should be plenty. If we
|
||||
* don't have a successful training then we don't expect to
|
||||
* ever get one.
|
||||
*/
|
||||
LINK_TRAINING_MAX_VERIFY_RETRY = 2,
|
||||
PEAK_FACTOR_X1000 = 1006,
|
||||
};
|
||||
|
||||
bool dp_validate_mode_timing(
|
||||
struct dc_link *link,
|
||||
const struct dc_crtc_timing *timing);
|
||||
|
||||
void dp_enable_mst_on_sink(struct dc_link *link, bool enable);
|
||||
|
||||
enum dc_status dp_set_fec_ready(struct dc_link *link, const struct link_resource *link_res, bool ready);
|
||||
void dp_set_fec_enable(struct dc_link *link, bool enable);
|
||||
bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update);
|
||||
void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx);
|
||||
bool dp_set_dsc_on_rx(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
|
||||
bool dpcd_write_128b_132b_sst_payload_allocation_table(
|
||||
const struct dc_stream_state *stream,
|
||||
struct dc_link *link,
|
||||
struct link_mst_stream_allocation_table *proposed_table,
|
||||
bool allocate);
|
||||
|
||||
bool dpcd_poll_for_allocation_change_trigger(struct dc_link *link);
|
||||
|
||||
struct fixed31_32 calculate_sst_avg_time_slots_per_mtp(
|
||||
const struct dc_stream_state *stream,
|
||||
const struct dc_link *link);
|
||||
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
|
||||
void dp_source_sequence_trace(struct dc_link *link, uint8_t dp_test_mode);
|
||||
|
||||
|
||||
#endif /* __DC_LINK_DP_H__ */
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
#include "link_hwss_dio.h"
|
||||
#include "core_types.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "link_enc_cfg.h"
|
||||
|
||||
void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#define __LINK_HWSS_DIO_H__
|
||||
|
||||
#include "link_hwss.h"
|
||||
#include "link.h"
|
||||
|
||||
const struct link_hwss *get_dio_link_hwss(void);
|
||||
bool can_use_dio_link_hwss(const struct dc_link *link,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "dm_helpers.h"
|
||||
#include "core_types.h"
|
||||
#include "dccg.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "clk_mgr.h"
|
||||
|
||||
static enum phyd32clk_clock_source get_phyd32clk_src(struct dc_link *link)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#define __LINK_HWSS_HPO_DP_H__
|
||||
|
||||
#include "link_hwss.h"
|
||||
#include "link.h"
|
||||
|
||||
bool can_use_hpo_dp_link_hwss(const struct dc_link *link,
|
||||
const struct link_resource *link_res);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
#include "atomfirmware.h"
|
||||
#include "resource.h"
|
||||
#include "link_enc_cfg.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dc_dmub_srv.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "dc.h"
|
||||
#include "inc/core_status.h"
|
||||
#include "dc_link.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#include "link_dp_dpia.h"
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#include "link_dp_capability.h"
|
||||
#include "clk_mgr.h"
|
||||
#include "resource.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#include "link_dp_phy.h"
|
||||
#include "link_dp_capability.h"
|
||||
#include "link_edp_panel_control.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "atomfirmware.h"
|
||||
#include "link_enc_cfg.h"
|
||||
#include "resource.h"
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "link_dpcd.h"
|
||||
#include "link_dp_phy.h"
|
||||
#include "link_dp_capability.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include "link_dpcd.h"
|
||||
#include "link_dp_phy.h"
|
||||
#include "link_dp_capability.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
*/
|
||||
#include "link_dp_training_auxless.h"
|
||||
#include "link_dp_phy.h"
|
||||
#include "dc_link_dp.h"
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
bool dc_link_dp_perform_link_training_skip_aux(
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "dc.h"
|
||||
#include "inc/core_status.h"
|
||||
#include "dc_link.h"
|
||||
#include "dc_link_dp.h"
|
||||
#include "dpcd_defs.h"
|
||||
|
||||
#include "link_dp_dpia.h"
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#include "link_dpcd.h"
|
||||
#include "link_dp_phy.h"
|
||||
#include "link_dp_capability.h"
|
||||
#include "dc_link_dp.h"
|
||||
|
||||
#define DC_LOGGER \
|
||||
link->ctx->logger
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user