Commit f01ee019 authored by Fangzhi Zuo's avatar Fangzhi Zuo Committed by Alex Deucher

drm/amd/display: Add DP 2.0 SST DC Support

1. Retrieve 128/132b link cap.
2. 128/132b link training and payload allocation.
3. UHBR10 link rate support.

[squash in warning fixes - Alex]
Signed-off-by: default avatarFangzhi Zuo <Jerry.Zuo@amd.com>
Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5a2730fc
......@@ -751,3 +751,11 @@ void dm_helpers_mst_enable_stream_features(const struct dc_stream_state *stream)
&new_downspread.raw,
sizeof(new_downspread));
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz)
{
// FPGA programming for this clock in diags framework that
// needs to go through dm layer, therefore leave dummy interace here
}
#endif
\ No newline at end of file
......@@ -255,6 +255,24 @@ static bool create_links(
goto failed_alloc;
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) &&
dc->caps.dp_hpo &&
link->dc->res_pool->res_cap->num_hpo_dp_link_encoder > 0) {
/* FPGA case - Allocate HPO DP link encoder */
if (i < link->dc->res_pool->res_cap->num_hpo_dp_link_encoder) {
link->hpo_dp_link_enc = link->dc->res_pool->hpo_dp_link_enc[i];
if (link->hpo_dp_link_enc == NULL) {
BREAK_TO_DEBUGGER();
goto failed_alloc;
}
link->hpo_dp_link_enc->hpd_source = link->link_enc->hpd_source;
link->hpo_dp_link_enc->transmitter = link->link_enc->transmitter;
}
}
#endif
link->link_status.dpcd_caps = &link->dpcd_caps;
enc_init.ctx = dc->ctx;
......
......@@ -41,6 +41,7 @@
#include "set_mode_types.h"
#include "virtual/virtual_stream_encoder.h"
#include "dpcd_defs.h"
#include "dc_link_dp.h"
#if defined(CONFIG_DRM_AMD_DC_SI)
#include "dce60/dce60_resource.h"
......@@ -346,6 +347,29 @@ bool resource_construct(
}
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
pool->hpo_dp_stream_enc_count = 0;
if (create_funcs->create_hpo_dp_stream_encoder) {
for (i = 0; i < caps->num_hpo_dp_stream_encoder; i++) {
pool->hpo_dp_stream_enc[i] = create_funcs->create_hpo_dp_stream_encoder(i+ENGINE_ID_HPO_DP_0, ctx);
if (pool->hpo_dp_stream_enc[i] == NULL)
DC_ERR("DC: failed to create HPO DP stream encoder!\n");
pool->hpo_dp_stream_enc_count++;
}
}
pool->hpo_dp_link_enc_count = 0;
if (create_funcs->create_hpo_dp_link_encoder) {
for (i = 0; i < caps->num_hpo_dp_link_encoder; i++) {
pool->hpo_dp_link_enc[i] = create_funcs->create_hpo_dp_link_encoder(i, ctx);
if (pool->hpo_dp_link_enc[i] == NULL)
DC_ERR("DC: failed to create HPO DP link encoder!\n");
pool->hpo_dp_link_enc_count++;
}
}
#endif
#if defined(CONFIG_DRM_AMD_DC_DCN)
for (i = 0; i < caps->num_mpc_3dlut; i++) {
pool->mpc_lut[i] = dc_create_3dlut_func();
......@@ -1665,6 +1689,22 @@ static void update_stream_engine_usage(
}
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
static void update_hpo_dp_stream_engine_usage(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct hpo_dp_stream_encoder *hpo_dp_stream_enc,
bool acquired)
{
int i;
for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) {
if (pool->hpo_dp_stream_enc[i] == hpo_dp_stream_enc)
res_ctx->is_hpo_dp_stream_enc_acquired[i] = acquired;
}
}
#endif
/* TODO: release audio object */
void update_audio_usage(
struct resource_context *res_ctx,
......@@ -1709,6 +1749,26 @@ static int acquire_first_free_pipe(
return -1;
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
static struct hpo_dp_stream_encoder *find_first_free_match_hpo_dp_stream_enc_for_link(
struct resource_context *res_ctx,
const struct resource_pool *pool,
struct dc_stream_state *stream)
{
int i;
for (i = 0; i < pool->hpo_dp_stream_enc_count; i++) {
if (!res_ctx->is_hpo_dp_stream_enc_acquired[i] &&
pool->hpo_dp_stream_enc[i]) {
return pool->hpo_dp_stream_enc[i];
}
}
return NULL;
}
#endif
static struct audio *find_first_free_audio(
struct resource_context *res_ctx,
const struct resource_pool *pool,
......@@ -1799,6 +1859,15 @@ enum dc_status dc_remove_stream_from_ctx(
if (dc->res_pool->funcs->link_enc_unassign)
dc->res_pool->funcs->link_enc_unassign(new_ctx, del_pipe->stream);
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(del_pipe)) {
update_hpo_dp_stream_engine_usage(
&new_ctx->res_ctx, dc->res_pool,
del_pipe->stream_res.hpo_dp_stream_enc,
false);
}
#endif
if (del_pipe->stream_res.audio)
update_audio_usage(
&new_ctx->res_ctx,
......@@ -2051,6 +2120,31 @@ enum dc_status resource_map_pool_resources(
pipe_ctx->stream_res.stream_enc,
true);
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* Allocate DP HPO Stream Encoder based on signal, hw capabilities
* and link settings
*/
if (dc_is_dp_signal(stream->signal) &&
dc->caps.dp_hpo) {
struct dc_link_settings link_settings = {0};
decide_link_settings(stream, &link_settings);
if (dp_get_link_encoding_format(&link_settings) == DP_128b_132b_ENCODING) {
pipe_ctx->stream_res.hpo_dp_stream_enc =
find_first_free_match_hpo_dp_stream_enc_for_link(
&context->res_ctx, pool, stream);
if (!pipe_ctx->stream_res.hpo_dp_stream_enc)
return DC_NO_STREAM_ENC_RESOURCE;
update_hpo_dp_stream_engine_usage(
&context->res_ctx, pool,
pipe_ctx->stream_res.hpo_dp_stream_enc,
true);
}
}
#endif
/* TODO: Add check if ASIC support and EDID audio */
if (!stream->converter_disable_audio &&
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
......@@ -2726,6 +2820,11 @@ bool pipe_need_reprogram(
if (pipe_ctx_old->stream_res.dsc != pipe_ctx->stream_res.dsc)
return true;
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (pipe_ctx_old->stream_res.hpo_dp_stream_enc != pipe_ctx->stream_res.hpo_dp_stream_enc)
return true;
#endif
/* DIG link encoder resource assignment for stream changed. */
if (pipe_ctx_old->stream->link_enc != pipe_ctx->stream->link_enc)
return true;
......@@ -2975,3 +3074,22 @@ void get_audio_check(struct audio_info *aud_modes,
}
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_link_encoder *resource_get_unused_hpo_dp_link_encoder(
const struct resource_pool *pool)
{
uint8_t i;
struct hpo_dp_link_encoder *enc = NULL;
ASSERT(pool->hpo_dp_link_enc_count <= MAX_HPO_DP2_LINK_ENCODERS);
for (i = 0; i < pool->hpo_dp_link_enc_count; i++) {
if (pool->hpo_dp_link_enc[i]->transmitter == TRANSMITTER_UNKNOWN) {
enc = pool->hpo_dp_link_enc[i];
break;
}
}
return enc;
}
#endif
......@@ -183,6 +183,9 @@ struct dc_caps {
unsigned int cursor_cache_size;
struct dc_plane_cap planes[MAX_PLANES];
struct dc_color_caps color;
#if defined(CONFIG_DRM_AMD_DC_DCN)
bool dp_hpo;
#endif
bool vbios_lttpr_aware;
bool vbios_lttpr_enable;
};
......@@ -289,7 +292,15 @@ struct dc_cap_funcs {
struct link_training_settings;
#if defined(CONFIG_DRM_AMD_DC_DCN)
union allow_lttpr_non_transparent_mode {
struct {
bool DP1_4A : 1;
bool DP2_0 : 1;
} bits;
unsigned char raw;
};
#endif
/* Structure to hold configuration flags set by dm at dc creation. */
struct dc_config {
bool gpu_vm_support;
......@@ -302,7 +313,11 @@ struct dc_config {
bool edp_no_power_sequencing;
bool force_enum_edp;
bool forced_clocks;
#if defined(CONFIG_DRM_AMD_DC_DCN)
union allow_lttpr_non_transparent_mode allow_lttpr_non_transparent_mode;
#else
bool allow_lttpr_non_transparent_mode;
#endif
bool multi_mon_pp_mclk_switch;
bool disable_dmcu;
bool enable_4to1MPC;
......@@ -614,6 +629,10 @@ struct dc_debug_options {
bool enable_dmcub_surface_flip;
bool usbc_combo_phy_reset_wa;
bool enable_dram_clock_change_one_display_vactive;
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* TODO - remove once tested */
bool legacy_dp2_lt;
#endif
union mem_low_power_enable_options enable_mem_low_power;
bool force_vblank_alignment;
......@@ -1146,6 +1165,12 @@ struct dpcd_caps {
struct dc_lttpr_caps lttpr_caps;
struct psr_caps psr_caps;
#if defined(CONFIG_DRM_AMD_DC_DCN)
union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
union dp_main_line_channel_coding_cap channel_coding_cap;
union dp_sink_video_fallback_formats fallback_formats;
union dp_fec_capability1 fec_cap1;
#endif
};
union dpcd_sink_ext_caps {
......
......@@ -53,7 +53,17 @@ enum dc_link_rate {
LINK_RATE_RBR2 = 0x0C, // Rate_5 (RBR2)- 3.24 Gbps/Lane
LINK_RATE_RATE_6 = 0x10, // Rate_6 - 4.32 Gbps/Lane
LINK_RATE_HIGH2 = 0x14, // Rate_7 (HBR2)- 5.40 Gbps/Lane
#if defined(CONFIG_DRM_AMD_DC_DCN)
LINK_RATE_HIGH3 = 0x1E, // Rate_8 (HBR3)- 8.10 Gbps/Lane
/* Starting from DP2.0 link rate enum directly represents actual
* link rate value in unit of 10 mbps
*/
LINK_RATE_UHBR10 = 1000, // UHBR10 - 10.0 Gbps/Lane
LINK_RATE_UHBR13_5 = 1350, // UHBR13.5 - 13.5 Gbps/Lane
LINK_RATE_UHBR20 = 2000, // UHBR10 - 20.0 Gbps/Lane
#else
LINK_RATE_HIGH3 = 0x1E // Rate_8 (HBR3)- 8.10 Gbps/Lane
#endif
};
enum dc_link_spread {
......@@ -90,17 +100,47 @@ enum dc_post_cursor2 {
POST_CURSOR2_MAX_LEVEL = POST_CURSOR2_LEVEL3,
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_dp_ffe_preset_level {
DP_FFE_PRESET_LEVEL0 = 0,
DP_FFE_PRESET_LEVEL1,
DP_FFE_PRESET_LEVEL2,
DP_FFE_PRESET_LEVEL3,
DP_FFE_PRESET_LEVEL4,
DP_FFE_PRESET_LEVEL5,
DP_FFE_PRESET_LEVEL6,
DP_FFE_PRESET_LEVEL7,
DP_FFE_PRESET_LEVEL8,
DP_FFE_PRESET_LEVEL9,
DP_FFE_PRESET_LEVEL10,
DP_FFE_PRESET_LEVEL11,
DP_FFE_PRESET_LEVEL12,
DP_FFE_PRESET_LEVEL13,
DP_FFE_PRESET_LEVEL14,
DP_FFE_PRESET_LEVEL15,
DP_FFE_PRESET_MAX_LEVEL = DP_FFE_PRESET_LEVEL15,
};
#endif
enum dc_dp_training_pattern {
DP_TRAINING_PATTERN_SEQUENCE_1 = 0,
DP_TRAINING_PATTERN_SEQUENCE_2,
DP_TRAINING_PATTERN_SEQUENCE_3,
DP_TRAINING_PATTERN_SEQUENCE_4,
DP_TRAINING_PATTERN_VIDEOIDLE,
#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_128b_132b_TPS1,
DP_128b_132b_TPS2,
DP_128b_132b_TPS2_CDS,
#endif
};
enum dp_link_encoding {
DP_UNKNOWN_ENCODING = 0,
DP_8b_10b_ENCODING = 1,
#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_128b_132b_ENCODING = 2,
#endif
};
struct dc_link_settings {
......@@ -112,10 +152,26 @@ struct dc_link_settings {
bool dpcd_source_device_specific_field_support;
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
union dc_dp_ffe_preset {
struct {
uint8_t level : 4;
uint8_t reserved : 1;
uint8_t no_preshoot : 1;
uint8_t no_deemphasis : 1;
uint8_t method2 : 1;
} settings;
uint8_t raw;
};
#endif
struct dc_lane_settings {
enum dc_voltage_swing VOLTAGE_SWING;
enum dc_pre_emphasis PRE_EMPHASIS;
enum dc_post_cursor2 POST_CURSOR2;
#if defined(CONFIG_DRM_AMD_DC_DCN)
union dc_dp_ffe_preset FFE_PRESET;
#endif
};
struct dc_link_training_settings {
......@@ -127,6 +183,9 @@ struct dc_link_training_overrides {
enum dc_voltage_swing *voltage_swing;
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
#if defined(CONFIG_DRM_AMD_DC_DCN)
union dc_dp_ffe_preset *ffe_preset;
#endif
uint16_t *cr_pattern_time;
uint16_t *eq_pattern_time;
......@@ -140,6 +199,16 @@ struct dc_link_training_overrides {
bool *fec_enable;
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
union payload_table_update_status {
struct {
uint8_t VC_PAYLOAD_TABLE_UPDATED:1;
uint8_t ACT_HANDLED:1;
} bits;
uint8_t raw;
};
#endif
union dpcd_rev {
struct {
uint8_t MINOR:4;
......@@ -227,7 +296,14 @@ union lane_align_status_updated {
struct {
uint8_t INTERLANE_ALIGN_DONE:1;
uint8_t POST_LT_ADJ_REQ_IN_PROGRESS:1;
#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t EQ_INTERLANE_ALIGN_DONE_128b_132b:1;
uint8_t CDS_INTERLANE_ALIGN_DONE_128b_132b:1;
uint8_t LT_FAILED_128b_132b:1;
uint8_t RESERVED:1;
#else
uint8_t RESERVED:4;
#endif
uint8_t DOWNSTREAM_PORT_STATUS_CHANGED:1;
uint8_t LINK_STATUS_UPDATED:1;
} bits;
......@@ -240,6 +316,12 @@ union lane_adjust {
uint8_t PRE_EMPHASIS_LANE:2;
uint8_t RESERVED:4;
} bits;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct {
uint8_t PRESET_VALUE :4;
uint8_t RESERVED :4;
} tx_ffe;
#endif
uint8_t raw;
};
......@@ -269,6 +351,12 @@ union dpcd_training_lane {
uint8_t MAX_PRE_EMPHASIS_REACHED:1;
uint8_t RESERVED:2;
} bits;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct {
uint8_t PRESET_VALUE :4;
uint8_t RESERVED :4;
} tx_ffe;
#endif
uint8_t raw;
};
......@@ -551,12 +639,18 @@ union test_response {
union phy_test_pattern {
struct {
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* This field is 7 bits for DP2.0 */
uint8_t PATTERN :7;
uint8_t RESERVED :1;
#else
/* DpcdPhyTestPatterns. This field is 2 bits for DP1.1
* and 3 bits for DP1.2.
*/
uint8_t PATTERN :3;
/* BY speci, bit7:2 is 0 for DP1.1. */
uint8_t RESERVED :5;
#endif
} bits;
uint8_t raw;
};
......@@ -634,7 +728,14 @@ union dpcd_fec_capability {
uint8_t UNCORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1;
uint8_t CORRECTED_BLOCK_ERROR_COUNT_CAPABLE:1;
uint8_t BIT_ERROR_COUNT_CAPABLE:1;
#if defined(CONFIG_DRM_AMD_DC_DCN)
uint8_t PARITY_BLOCK_ERROR_COUNT_CAPABLE:1;
uint8_t ARITY_BIT_ERROR_COUNT_CAPABLE:1;
uint8_t FEC_RUNNING_INDICATOR_SUPPORTED:1;
uint8_t FEC_ERROR_REPORTING_POLICY_SUPPORTED:1;
#else
uint8_t RESERVED:4;
#endif
} bits;
uint8_t raw;
};
......@@ -758,4 +859,125 @@ struct psr_caps {
bool psr_exit_link_training_required;
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
#define DP_MAIN_LINK_CHANNEL_CODING_CAP 0x006
#define DP_SINK_VIDEO_FALLBACK_FORMATS 0x020
#define DP_FEC_CAPABILITY_1 0x091
#define DP_DFP_CAPABILITY_EXTENSION_SUPPORT 0x0A3
#define DP_DSC_CONFIGURATION 0x161
#define DP_PHY_SQUARE_PATTERN 0x249
#define DP_128b_132b_SUPPORTED_LINK_RATES 0x2215
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL 0x2216
#define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0X2230
#define DP_TEST_264BIT_CUSTOM_PATTERN_263_256 0X2250
#define DP_DSC_SUPPORT_AND_DECODER_COUNT 0x2260
#define DP_DSC_MAX_SLICE_COUNT_AND_AGGREGATION_0 0x2270
# define DP_DSC_DECODER_0_MAXIMUM_SLICE_COUNT_MASK (1 << 0)
# define DP_DSC_DECODER_0_AGGREGATION_SUPPORT_MASK (0b111 << 1)
# define DP_DSC_DECODER_0_AGGREGATION_SUPPORT_SHIFT 1
# define DP_DSC_DECODER_COUNT_MASK (0b111 << 5)
# define DP_DSC_DECODER_COUNT_SHIFT 5
#define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108
#define DP_MAIN_LINK_CHANNEL_CODING_PHY_REPEATER 0xF0006
#define DP_PHY_REPEATER_128b_132b_RATES 0xF0007
#define DP_128b_132b_TRAINING_AUX_RD_INTERVAL_PHY_REPEATER1 0xF0022
#define DP_INTRA_HOP_AUX_REPLY_INDICATION (1 << 3)
/* TODO - Use DRM header to replace above once available */
union dp_main_line_channel_coding_cap {
struct {
uint8_t DP_8b_10b_SUPPORTED :1;
uint8_t DP_128b_132b_SUPPORTED :1;
uint8_t RESERVED :6;
} bits;
uint8_t raw;
};
union dp_main_link_channel_coding_lttpr_cap {
struct {
uint8_t DP_128b_132b_SUPPORTED :1;
uint8_t RESERVED :7;
} bits;
uint8_t raw;
};
union dp_128b_132b_supported_link_rates {
struct {
uint8_t UHBR10 :1;
uint8_t UHBR20 :1;
uint8_t UHBR13_5:1;
uint8_t RESERVED:5;
} bits;
uint8_t raw;
};
union dp_128b_132b_supported_lttpr_link_rates {
struct {
uint8_t UHBR10 :1;
uint8_t UHBR13_5:1;
uint8_t UHBR20 :1;
uint8_t RESERVED:5;
} bits;
uint8_t raw;
};
union dp_sink_video_fallback_formats {
struct {
uint8_t dp_1024x768_60Hz_24bpp_support :1;
uint8_t dp_1280x720_60Hz_24bpp_support :1;
uint8_t dp_1920x1080_60Hz_24bpp_support :1;
uint8_t RESERVED :5;
} bits;
uint8_t raw;
};
union dp_fec_capability1 {
struct {
uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE :1;
uint8_t RESERVED :7;
} bits;
uint8_t raw;
};
struct dp_color_depth_caps {
uint8_t support_6bpc :1;
uint8_t support_8bpc :1;
uint8_t support_10bpc :1;
uint8_t support_12bpc :1;
uint8_t support_16bpc :1;
uint8_t RESERVED :3;
};
struct dp_encoding_format_caps {
uint8_t support_rgb :1;
uint8_t support_ycbcr444:1;
uint8_t support_ycbcr422:1;
uint8_t support_ycbcr420:1;
uint8_t RESERVED :4;
};
union dp_dfp_cap_ext {
struct {
uint8_t supported;
uint8_t max_pixel_rate_in_mps[2];
uint8_t max_video_h_active_width[2];
uint8_t max_video_v_active_height[2];
struct dp_encoding_format_caps encoding_format_caps;
struct dp_color_depth_caps rgb_color_depth_caps;
struct dp_color_depth_caps ycbcr444_color_depth_caps;
struct dp_color_depth_caps ycbcr422_color_depth_caps;
struct dp_color_depth_caps ycbcr420_color_depth_caps;
} fields;
uint8_t raw[12];
};
union dp_128b_132b_training_aux_rd_interval {
struct {
uint8_t VALUE :7;
uint8_t UNIT :1;
} bits;
uint8_t raw;
};
#endif
#endif /* DC_DP_TYPES_H */
......@@ -154,6 +154,9 @@ struct dc_link {
struct panel_cntl *panel_cntl;
struct link_encoder *link_enc;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_link_encoder *hpo_dp_link_enc;
#endif
struct graphics_object_id link_id;
/* Endpoint type distinguishes display endpoints which do not have entries
* in the BIOS connector table from those that do. Helps when tracking link
......
......@@ -395,9 +395,27 @@ struct dc_lttpr_caps {
uint8_t max_link_rate;
uint8_t phy_repeater_cnt;
uint8_t max_ext_timeout;
#if defined(CONFIG_DRM_AMD_DC_DCN)
union dp_main_link_channel_coding_lttpr_cap main_link_channel_coding;
union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates;
#endif
uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1];
};
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_dongle_dfp_cap_ext {
bool supported;
uint16_t max_pixel_rate_in_mps;
uint16_t max_video_h_active_width;
uint16_t max_video_v_active_height;
struct dp_encoding_format_caps encoding_format_caps;
struct dp_color_depth_caps rgb_color_depth_caps;
struct dp_color_depth_caps ycbcr444_color_depth_caps;
struct dp_color_depth_caps ycbcr422_color_depth_caps;
struct dp_color_depth_caps ycbcr420_color_depth_caps;
};
#endif
struct dc_dongle_caps {
/* dongle type (DP converter, CV smart dongle) */
enum display_dongle_type dongle_type;
......@@ -411,6 +429,9 @@ struct dc_dongle_caps {
bool is_dp_hdmi_ycbcr420_converter;
uint32_t dp_hdmi_max_bpc;
uint32_t dp_hdmi_max_pixel_clk_in_khz;
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct dc_dongle_dfp_cap_ext dfp_cap_ext;
#endif
};
/* Scaling format */
enum scaling_transformation {
......
......@@ -1108,8 +1108,17 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx)
clk_mgr->funcs->enable_pme_wa(clk_mgr);
/* un-mute audio */
/* TODO: audio should be per stream rather than per link */
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.hpo_dp_stream_enc, false);
else
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, false);
#else
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, false);
#endif
if (pipe_ctx->stream_res.audio)
pipe_ctx->stream_res.audio->enabled = true;
}
......@@ -1129,14 +1138,32 @@ void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx)
if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false)
return;
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.hpo_dp_stream_enc, true);
else
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, true);
#else
pipe_ctx->stream_res.stream_enc->funcs->audio_mute_control(
pipe_ctx->stream_res.stream_enc, true);
#endif
if (pipe_ctx->stream_res.audio) {
pipe_ctx->stream_res.audio->enabled = false;
if (dc_is_dp_signal(pipe_ctx->stream->signal))
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_disable(
pipe_ctx->stream_res.hpo_dp_stream_enc);
else
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
pipe_ctx->stream_res.stream_enc);
#else
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_disable(
pipe_ctx->stream_res.stream_enc);
#endif
else
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_disable(
pipe_ctx->stream_res.stream_enc);
......@@ -1166,16 +1193,37 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
pipe_ctx->stream_res.stream_enc);
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets(
pipe_ctx->stream_res.hpo_dp_stream_enc);
} else if (dc_is_dp_signal(pipe_ctx->stream->signal))
#else
if (dc_is_dp_signal(pipe_ctx->stream->signal))
#endif
pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets(
pipe_ctx->stream_res.stream_enc);
dc->hwss.disable_audio_stream(pipe_ctx);
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->disable(
pipe_ctx->stream_res.hpo_dp_stream_enc);
setup_dp_hpo_stream(pipe_ctx, false);
/* TODO - DP2.0 HW: unmap stream from link encoder here */
} else {
link->link_enc->funcs->connect_dig_be_to_fe(
link->link_enc,
pipe_ctx->stream_res.stream_enc->id,
false);
}
#else
link->link_enc->funcs->connect_dig_be_to_fe(
link->link_enc,
pipe_ctx->stream_res.stream_enc->id,
false);
#endif
}
......@@ -1210,7 +1258,15 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx)
link->dc->hwss.set_abm_immediate_disable(pipe_ctx);
}
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx)) {
/* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank(
pipe_ctx->stream_res.hpo_dp_stream_enc);
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
#else
if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
#endif
pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc);
if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) {
......@@ -1451,10 +1507,23 @@ static enum dc_status apply_single_controller_ctx_to_hw(
build_audio_output(context, pipe_ctx, &audio_output);
if (dc_is_dp_signal(pipe_ctx->stream->signal))
#if defined(CONFIG_DRM_AMD_DC_DCN)
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_setup(
pipe_ctx->stream_res.hpo_dp_stream_enc,
pipe_ctx->stream_res.audio->inst,
&pipe_ctx->stream->audio_info);
else
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.audio->inst,
&pipe_ctx->stream->audio_info);
#else
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_setup(
pipe_ctx->stream_res.stream_enc,
pipe_ctx->stream_res.audio->inst,
&pipe_ctx->stream->audio_info);
#endif
else
pipe_ctx->stream_res.stream_enc->funcs->hdmi_audio_setup(
pipe_ctx->stream_res.stream_enc,
......@@ -1469,10 +1538,18 @@ static enum dc_status apply_single_controller_ctx_to_hw(
&pipe_ctx->stream->audio_info);
}
/* */
/* Do not touch stream timing on seamless boot optimization. */
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* DCN3.1 FPGA Workaround
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
* To do so, move calling function enable_stream_timing to only be done AFTER calling
* function core_link_enable_stream
*/
if (!(hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)))
#endif
/* */
/* Do not touch stream timing on seamless boot optimization. */
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
if (hws->funcs.setup_vupdate_interrupt)
hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx);
......@@ -1526,6 +1603,18 @@ static enum dc_status apply_single_controller_ctx_to_hw(
if (!stream->dpms_off)
core_link_enable_stream(context, pipe_ctx);
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* DCN3.1 FPGA Workaround
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
* To do so, move calling function enable_stream_timing to only be done AFTER calling
* function core_link_enable_stream
*/
if (hws->wa.dp_hpo_and_otg_sequence && is_dp_128b_132b_signal(pipe_ctx)) {
if (!pipe_ctx->stream->apply_seamless_boot_optimization)
hws->funcs.enable_stream_timing(pipe_ctx, context, dc);
}
#endif
pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false;
......
......@@ -1460,5 +1460,14 @@ void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc,
if (enc->features.flags.bits.IS_HBR3_CAPABLE)
max_link_cap.link_rate = LINK_RATE_HIGH3;
if (enc->features.flags.bits.IS_UHBR10_CAPABLE)
max_link_cap.link_rate = LINK_RATE_UHBR10;
if (enc->features.flags.bits.IS_UHBR13_5_CAPABLE)
max_link_cap.link_rate = LINK_RATE_UHBR13_5;
if (enc->features.flags.bits.IS_UHBR20_CAPABLE)
max_link_cap.link_rate = LINK_RATE_UHBR20;
*link_settings = max_link_cap;
}
......@@ -2135,7 +2135,12 @@ void dcn20_unblank_stream(struct pipe_ctx *pipe_ctx,
params.link_settings.link_rate = link_settings->link_rate;
if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
if (is_dp_128b_132b_signal(pipe_ctx)) {
/* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_unblank(
pipe_ctx->stream_res.hpo_dp_stream_enc,
pipe_ctx->stream_res.tg->inst);
} else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
if (optc2_is_two_pixels_per_containter(&stream->timing) || params.opp_cnt > 1)
params.timing.pix_clk_100hz /= 2;
pipe_ctx->stream_res.stream_enc->funcs->dp_set_odm_combine(
......@@ -2380,8 +2385,19 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
* disconnect them during disable_stream
* BY this, it is logic clean to separate stream and link
*/
link->link_enc->funcs->connect_dig_be_to_fe(link->link_enc,
pipe_ctx->stream_res.stream_enc->id, true);
if (is_dp_128b_132b_signal(pipe_ctx)) {
setup_dp_hpo_stream(pipe_ctx, true);
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->enable_stream(
pipe_ctx->stream_res.hpo_dp_stream_enc);
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->map_stream_to_link(
pipe_ctx->stream_res.hpo_dp_stream_enc,
pipe_ctx->stream_res.hpo_dp_stream_enc->inst,
link->hpo_dp_link_enc->inst);
}
if (!is_dp_128b_132b_signal(pipe_ctx))
link->link_enc->funcs->connect_dig_be_to_fe(
link->link_enc, pipe_ctx->stream_res.stream_enc->id, true);
if (pipe_ctx->plane_state && pipe_ctx->plane_state->flip_immediate != 1) {
if (link->dc->hwss.program_dmdata_engine)
......@@ -2406,7 +2422,9 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
/* enable audio only within mode set */
if (pipe_ctx->stream_res.audio != NULL) {
if (dc_is_dp_signal(pipe_ctx->stream->signal))
if (is_dp_128b_132b_signal(pipe_ctx))
pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.hpo_dp_stream_enc);
else if (dc_is_dp_signal(pipe_ctx->stream->signal))
pipe_ctx->stream_res.stream_enc->funcs->dp_audio_enable(pipe_ctx->stream_res.stream_enc);
}
}
......
......@@ -63,6 +63,7 @@
#include "dcn20_dccg.h"
#include "dcn20_vmid.h"
#include "dc_link_ddc.h"
#include "dc_link_dp.h"
#include "dce/dce_panel_cntl.h"
#include "navi10_ip_offset.h"
......@@ -1604,6 +1605,7 @@ static void get_pixel_clock_parameters(
pixel_clk_params->signal_type = pipe_ctx->stream->signal;
pixel_clk_params->controller_id = pipe_ctx->stream_res.tg->inst + 1;
/* TODO: un-hardcode*/
/* TODO - DP2.0 HW: calculate requested_sym_clk for UHBR rates */
pixel_clk_params->requested_sym_clk = LINK_RATE_LOW *
LINK_RATE_REF_FREQ_IN_KHZ;
pixel_clk_params->flags.ENABLE_SS = 0;
......@@ -3044,6 +3046,8 @@ static bool is_dtbclk_required(struct dc *dc, struct dc_state *context)
for (i = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
if (is_dp_128b_132b_signal(&context->res_ctx.pipe_ctx[i]))
return true;
}
return false;
}
......
......@@ -561,11 +561,6 @@ static const struct dcn10_link_enc_mask le_mask = {
DPCS_DCN31_MASK_SH_LIST(_MASK)
};
#define dpp_regs(id)\
[id] = {\
DPP_REG_LIST_DCN30(id),\
}
#define hpo_dp_stream_encoder_reg_list(id)\
[id] = {\
DCN3_1_HPO_DP_STREAM_ENC_REG_LIST(id)\
......@@ -609,6 +604,11 @@ static const struct dcn31_hpo_dp_link_encoder_mask hpo_dp_le_mask = {
DCN3_1_HPO_DP_LINK_ENC_MASK_SH_LIST(_MASK)
};
#define dpp_regs(id)\
[id] = {\
DPP_REG_LIST_DCN30(id),\
}
static const struct dcn3_dpp_registers dpp_regs[] = {
dpp_regs(0),
dpp_regs(1),
......@@ -1449,6 +1449,13 @@ static struct dce_hwseq *dcn31_hwseq_create(
hws->regs = &hwseq_reg;
hws->shifts = &hwseq_shift;
hws->masks = &hwseq_mask;
/* DCN3.1 FPGA Workaround
* Need to enable HPO DP Stream Encoder before setting OTG master enable.
* To do so, move calling function enable_stream_timing to only be done AFTER calling
* function core_link_enable_stream
*/
if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
hws->wa.dp_hpo_and_otg_sequence = true;
}
return hws;
}
......@@ -2102,6 +2109,7 @@ static bool dcn31_resource_construct(
dc->caps.max_slave_rgb_planes = 1;
dc->caps.post_blend_color_processing = true;
dc->caps.force_dp_tps4_for_cp2520 = true;
dc->caps.dp_hpo = true;
dc->caps.extended_aux_timeout_support = true;
dc->caps.dmcub_support = true;
dc->caps.is_apu = true;
......
......@@ -37,6 +37,7 @@ struct cp_psp_stream_config {
uint8_t phy_idx;
uint8_t assr_enabled;
uint8_t mst_enabled;
uint8_t dp2_enabled;
void *dm_stream_ctx;
bool dpms_off;
};
......
......@@ -160,6 +160,8 @@ void dm_set_dcn_clocks(
struct dc_context *ctx,
struct dc_clocks *clks);
void dm_set_phyd32clk(struct dc_context *ctx, int freq_khz);
bool dm_helpers_dmub_outbox_interrupt_control(struct dc_context *ctx, bool enable);
void dm_helpers_smu_timeout(struct dc_context *ctx, unsigned int msg_id, unsigned int param, unsigned int timeout_us);
......
......@@ -30,6 +30,7 @@
#define LINK_TRAINING_RETRY_DELAY 50 /* ms */
#define LINK_AUX_DEFAULT_LTTPR_TIMEOUT_PERIOD 3200 /*us*/
#define LINK_AUX_DEFAULT_TIMEOUT_PERIOD 552 /*us*/
#define MAX_MTP_SLOT_COUNT 64
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
#define TRAINING_AUX_RD_INTERVAL 100 //us
......@@ -189,5 +190,26 @@ enum dc_status dpcd_configure_lttpr_mode(
struct link_training_settings *lt_settings);
enum dp_link_encoding dp_get_link_encoding_format(const struct dc_link_settings *link_settings);
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);
enum dc_status dpcd_configure_channel_coding(
struct dc_link *link,
struct link_training_settings *lt_settings);
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 enable_dp_hpo_output(struct dc_link *link, const struct dc_link_settings *link_settings);
void disable_dp_hpo_output(struct dc_link *link, enum signal_type signal);
void setup_dp_hpo_stream(struct pipe_ctx *pipe_ctx, bool enable);
bool is_dp_128b_132b_signal(struct pipe_ctx *pipe_ctx);
void reset_dp_hpo_stream_encoders_for_link(struct dc_link *link);
bool dp_retrieve_lttpr_cap(struct dc_link *link);
#endif /* __DC_LINK_DP_H__ */
......@@ -41,6 +41,9 @@ struct dce_hwseq_wa {
bool DEGVIDCN10_254;
bool DEGVIDCN21;
bool disallow_self_refresh_during_multi_plane_transition;
#if defined(CONFIG_DRM_AMD_DC_DCN)
bool dp_hpo_and_otg_sequence;
#endif
};
struct hwseq_wa_state {
......
......@@ -200,4 +200,9 @@ int get_num_mpc_splits(struct pipe_ctx *pipe);
int get_num_odm_splits(struct pipe_ctx *pipe);
#if defined(CONFIG_DRM_AMD_DC_DCN)
struct hpo_dp_link_encoder *resource_get_unused_hpo_dp_link_encoder(
const struct resource_pool *pool);
#endif
#endif /* DRIVERS_GPU_DRM_AMD_DC_DEV_DC_INC_RESOURCE_H_ */
......@@ -80,6 +80,15 @@ enum dpcd_phy_test_patterns {
PHY_TEST_PATTERN_CP2520_1,
PHY_TEST_PATTERN_CP2520_2,
PHY_TEST_PATTERN_CP2520_3, /* same as TPS4 */
PHY_TEST_PATTERN_128b_132b_TPS1 = 0x8,
PHY_TEST_PATTERN_128b_132b_TPS2 = 0x10,
PHY_TEST_PATTERN_PRBS9 = 0x18,
PHY_TEST_PATTERN_PRBS11 = 0x20,
PHY_TEST_PATTERN_PRBS15 = 0x28,
PHY_TEST_PATTERN_PRBS23 = 0x30,
PHY_TEST_PATTERN_PRBS31 = 0x38,
PHY_TEST_PATTERN_264BIT_CUSTOM = 0x40,
PHY_TEST_PATTERN_SQUARE_PULSE = 0x48,
};
enum dpcd_test_dyn_range {
......@@ -135,7 +144,14 @@ enum dpcd_training_patterns {
DPCD_TRAINING_PATTERN_1,
DPCD_TRAINING_PATTERN_2,
DPCD_TRAINING_PATTERN_3,
#if defined(CONFIG_DRM_AMD_DC_DCN)
DPCD_TRAINING_PATTERN_4 = 7,
DPCD_128b_132b_TPS1 = 1,
DPCD_128b_132b_TPS2 = 2,
DPCD_128b_132b_TPS2_CDS = 3,
#else
DPCD_TRAINING_PATTERN_4 = 7
#endif
};
/* This enum is for use with PsrSinkPsrStatus.bits.sinkSelfRefreshStatus
......
......@@ -53,7 +53,11 @@ enum edp_revision {
};
enum {
LINK_RATE_REF_FREQ_IN_KHZ = 27000 /*27MHz*/
LINK_RATE_REF_FREQ_IN_KHZ = 27000, /*27MHz*/
BITS_PER_DP_BYTE = 10,
DATA_EFFICIENCY_8b_10b_x10000 = 8000, /* 80% data efficiency */
DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100 = 97, /* 97% data efficiency when FEC is enabled */
DATA_EFFICIENCY_128b_132b_x10000 = 9646, /* 96.71% data efficiency x 99.75% downspread factor */
};
enum link_training_result {
......@@ -70,6 +74,12 @@ enum link_training_result {
LINK_TRAINING_LINK_LOSS,
/* Abort link training (because sink unplugged) */
LINK_TRAINING_ABORT,
#if defined(CONFIG_DRM_AMD_DC_DCN)
DP_128b_132b_LT_FAILED,
DP_128b_132b_MAX_LOOP_COUNT_REACHED,
DP_128b_132b_CHANNEL_EQ_DONE_TIMEOUT,
DP_128b_132b_CDS_DONE_TIMEOUT,
#endif
};
enum lttpr_mode {
......@@ -86,11 +96,23 @@ struct link_training_settings {
enum dc_pre_emphasis *pre_emphasis;
enum dc_post_cursor2 *post_cursor2;
bool should_set_fec_ready;
#if defined(CONFIG_DRM_AMD_DC_DCN)
/* TODO - factor lane_settings out because it changes during LT */
union dc_dp_ffe_preset *ffe_preset;
#endif
uint16_t cr_pattern_time;
uint16_t eq_pattern_time;
uint16_t cds_pattern_time;
enum dc_dp_training_pattern pattern_for_cr;
enum dc_dp_training_pattern pattern_for_eq;
#if defined(CONFIG_DRM_AMD_DC_DCN)
enum dc_dp_training_pattern pattern_for_cds;
uint32_t eq_wait_time_limit;
uint8_t eq_loop_count_limit;
uint32_t cds_wait_time_limit;
#endif
bool enhanced_framing;
bool allow_invalid_msa_timing_param;
......
......@@ -72,6 +72,9 @@
#define DC_LOG_DSC(...) DRM_DEBUG_KMS(__VA_ARGS__)
#define DC_LOG_SMU(...) pr_debug("[SMU_MSG]:"__VA_ARGS__)
#define DC_LOG_DWB(...) DRM_DEBUG_KMS(__VA_ARGS__)
#if defined(CONFIG_DRM_AMD_DC_DCN)
#define DC_LOG_DP2(...) DRM_DEBUG_KMS(__VA_ARGS__)
#endif
struct dal_logger;
......@@ -123,6 +126,9 @@ enum dc_log_type {
LOG_MAX_HW_POINTS,
LOG_ALL_TF_CHANNELS,
LOG_SAMPLE_1DLUT,
#if defined(CONFIG_DRM_AMD_DC_DCN)
LOG_DP2,
#endif
LOG_SECTION_TOTAL_COUNT
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment