Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2022 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 #include "link_hwss_dio.h"
0026 #include "core_types.h"
0027 #include "dc_link_dp.h"
0028 #include "link_enc_cfg.h"
0029 
0030 void set_dio_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
0031         struct fixed31_32 throttled_vcp_size)
0032 {
0033     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
0034 
0035     stream_encoder->funcs->set_throttled_vcp_size(
0036                 stream_encoder,
0037                 throttled_vcp_size);
0038 }
0039 
0040 void setup_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
0041 {
0042     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
0043     struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
0044 
0045     link_enc->funcs->connect_dig_be_to_fe(link_enc,
0046             pipe_ctx->stream_res.stream_enc->id, true);
0047     if (dc_is_dp_signal(pipe_ctx->stream->signal))
0048         dp_source_sequence_trace(pipe_ctx->stream->link,
0049                 DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_BE);
0050     if (stream_enc->funcs->enable_fifo)
0051         stream_enc->funcs->enable_fifo(stream_enc);
0052 }
0053 
0054 void reset_dio_stream_encoder(struct pipe_ctx *pipe_ctx)
0055 {
0056     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
0057     struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
0058 
0059     if (stream_enc && stream_enc->funcs->disable_fifo)
0060         stream_enc->funcs->disable_fifo(stream_enc);
0061 
0062     link_enc->funcs->connect_dig_be_to_fe(
0063             link_enc,
0064             pipe_ctx->stream_res.stream_enc->id,
0065             false);
0066     if (dc_is_dp_signal(pipe_ctx->stream->signal))
0067         dp_source_sequence_trace(pipe_ctx->stream->link,
0068                 DPCD_SOURCE_SEQ_AFTER_DISCONNECT_DIG_FE_BE);
0069 
0070 }
0071 
0072 void setup_dio_stream_attribute(struct pipe_ctx *pipe_ctx)
0073 {
0074     struct stream_encoder *stream_encoder = pipe_ctx->stream_res.stream_enc;
0075     struct dc_stream_state *stream = pipe_ctx->stream;
0076     struct dc_link *link = stream->link;
0077 
0078     if (!dc_is_virtual_signal(stream->signal))
0079         stream_encoder->funcs->setup_stereo_sync(
0080                 stream_encoder,
0081                 pipe_ctx->stream_res.tg->inst,
0082                 stream->timing.timing_3d_format != TIMING_3D_FORMAT_NONE);
0083 
0084     if (dc_is_dp_signal(stream->signal))
0085         stream_encoder->funcs->dp_set_stream_attribute(
0086                 stream_encoder,
0087                 &stream->timing,
0088                 stream->output_color_space,
0089                 stream->use_vsc_sdp_for_colorimetry,
0090                 link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
0091     else if (dc_is_hdmi_tmds_signal(stream->signal))
0092         stream_encoder->funcs->hdmi_set_stream_attribute(
0093                 stream_encoder,
0094                 &stream->timing,
0095                 stream->phy_pix_clk,
0096                 pipe_ctx->stream_res.audio != NULL);
0097     else if (dc_is_dvi_signal(stream->signal))
0098         stream_encoder->funcs->dvi_set_stream_attribute(
0099                 stream_encoder,
0100                 &stream->timing,
0101                 (stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) ?
0102                         true : false);
0103     else if (dc_is_lvds_signal(stream->signal))
0104         stream_encoder->funcs->lvds_set_stream_attribute(
0105                 stream_encoder,
0106                 &stream->timing);
0107 
0108     if (dc_is_dp_signal(stream->signal))
0109         dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DP_STREAM_ATTR);
0110 }
0111 
0112 void enable_dio_dp_link_output(struct dc_link *link,
0113         const struct link_resource *link_res,
0114         enum signal_type signal,
0115         enum clock_source_id clock_source,
0116         const struct dc_link_settings *link_settings)
0117 {
0118     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
0119 
0120     if (dc_is_dp_sst_signal(signal))
0121         link_enc->funcs->enable_dp_output(
0122                 link_enc,
0123                 link_settings,
0124                 clock_source);
0125     else
0126         link_enc->funcs->enable_dp_mst_output(
0127                 link_enc,
0128                 link_settings,
0129                 clock_source);
0130     dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY);
0131 }
0132 
0133 void disable_dio_dp_link_output(struct dc_link *link,
0134         const struct link_resource *link_res,
0135         enum signal_type signal)
0136 {
0137     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
0138 
0139     link_enc->funcs->disable_output(link_enc, signal);
0140     dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY);
0141 }
0142 
0143 void set_dio_dp_link_test_pattern(struct dc_link *link,
0144         const struct link_resource *link_res,
0145         struct encoder_set_dp_phy_pattern_param *tp_params)
0146 {
0147     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
0148 
0149     link_enc->funcs->dp_set_phy_pattern(link_enc, tp_params);
0150     dp_source_sequence_trace(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
0151 }
0152 
0153 void set_dio_dp_lane_settings(struct dc_link *link,
0154         const struct link_resource *link_res,
0155         const struct dc_link_settings *link_settings,
0156         const struct dc_lane_settings lane_settings[LANE_COUNT_DP_MAX])
0157 {
0158     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
0159 
0160     link_enc->funcs->dp_set_lane_settings(link_enc, link_settings, lane_settings);
0161 }
0162 
0163 static void update_dio_stream_allocation_table(struct dc_link *link,
0164         const struct link_resource *link_res,
0165         const struct link_mst_stream_allocation_table *table)
0166 {
0167     struct link_encoder *link_enc = link_enc_cfg_get_link_enc(link);
0168 
0169     ASSERT(link_enc);
0170     link_enc->funcs->update_mst_stream_allocation_table(link_enc, table);
0171 }
0172 
0173 static const struct link_hwss dio_link_hwss = {
0174     .setup_stream_encoder = setup_dio_stream_encoder,
0175     .reset_stream_encoder = reset_dio_stream_encoder,
0176     .setup_stream_attribute = setup_dio_stream_attribute,
0177     .ext = {
0178         .set_throttled_vcp_size = set_dio_throttled_vcp_size,
0179         .enable_dp_link_output = enable_dio_dp_link_output,
0180         .disable_dp_link_output = disable_dio_dp_link_output,
0181         .set_dp_link_test_pattern = set_dio_dp_link_test_pattern,
0182         .set_dp_lane_settings = set_dio_dp_lane_settings,
0183         .update_stream_allocation_table = update_dio_stream_allocation_table,
0184     },
0185 };
0186 
0187 bool can_use_dio_link_hwss(const struct dc_link *link,
0188         const struct link_resource *link_res)
0189 {
0190     return link->link_enc != NULL;
0191 }
0192 
0193 const struct link_hwss *get_dio_link_hwss(void)
0194 {
0195     return &dio_link_hwss;
0196 }