LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/display - intel_dp_mst.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 386 0.0 %
Date: 2022-04-01 14:35:51 Functions: 0 28 0.0 %
Branches: 0 198 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2008 Intel Corporation
       3                 :            :  *             2014 Red Hat Inc.
       4                 :            :  *
       5                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a
       6                 :            :  * copy of this software and associated documentation files (the "Software"),
       7                 :            :  * to deal in the Software without restriction, including without limitation
       8                 :            :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       9                 :            :  * and/or sell copies of the Software, and to permit persons to whom the
      10                 :            :  * Software is furnished to do so, subject to the following conditions:
      11                 :            :  *
      12                 :            :  * The above copyright notice and this permission notice (including the next
      13                 :            :  * paragraph) shall be included in all copies or substantial portions of the
      14                 :            :  * Software.
      15                 :            :  *
      16                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      17                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      18                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      19                 :            :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      20                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      21                 :            :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
      22                 :            :  * IN THE SOFTWARE.
      23                 :            :  *
      24                 :            :  */
      25                 :            : 
      26                 :            : #include <drm/drm_atomic_helper.h>
      27                 :            : #include <drm/drm_edid.h>
      28                 :            : #include <drm/drm_probe_helper.h>
      29                 :            : 
      30                 :            : #include "i915_drv.h"
      31                 :            : #include "intel_atomic.h"
      32                 :            : #include "intel_audio.h"
      33                 :            : #include "intel_connector.h"
      34                 :            : #include "intel_ddi.h"
      35                 :            : #include "intel_display_types.h"
      36                 :            : #include "intel_dp.h"
      37                 :            : #include "intel_dp_mst.h"
      38                 :            : #include "intel_dpio_phy.h"
      39                 :            : 
      40                 :            : static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
      41                 :            :                                             struct intel_crtc_state *crtc_state,
      42                 :            :                                             struct drm_connector_state *conn_state,
      43                 :            :                                             struct link_config_limits *limits)
      44                 :            : {
      45                 :            :         struct drm_atomic_state *state = crtc_state->uapi.state;
      46                 :            :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
      47                 :            :         struct intel_dp *intel_dp = &intel_mst->primary->dp;
      48                 :            :         struct intel_connector *connector =
      49                 :            :                 to_intel_connector(conn_state->connector);
      50                 :            :         const struct drm_display_mode *adjusted_mode =
      51                 :            :                 &crtc_state->hw.adjusted_mode;
      52                 :            :         void *port = connector->port;
      53                 :            :         bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
      54                 :            :                                            DP_DPCD_QUIRK_CONSTANT_N);
      55                 :            :         int bpp, slots = -EINVAL;
      56                 :            : 
      57                 :            :         crtc_state->lane_count = limits->max_lane_count;
      58                 :            :         crtc_state->port_clock = limits->max_clock;
      59                 :            : 
      60                 :            :         for (bpp = limits->max_bpp; bpp >= limits->min_bpp; bpp -= 2 * 3) {
      61                 :            :                 crtc_state->pipe_bpp = bpp;
      62                 :            : 
      63                 :            :                 crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock,
      64                 :            :                                                        crtc_state->pipe_bpp,
      65                 :            :                                                        false);
      66                 :            : 
      67                 :            :                 slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
      68                 :            :                                                       port, crtc_state->pbn, 0);
      69                 :            :                 if (slots == -EDEADLK)
      70                 :            :                         return slots;
      71                 :            :                 if (slots >= 0)
      72                 :            :                         break;
      73                 :            :         }
      74                 :            : 
      75                 :            :         if (slots < 0) {
      76                 :            :                 DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
      77                 :            :                 return slots;
      78                 :            :         }
      79                 :            : 
      80                 :            :         intel_link_compute_m_n(crtc_state->pipe_bpp,
      81                 :            :                                crtc_state->lane_count,
      82                 :            :                                adjusted_mode->crtc_clock,
      83                 :            :                                crtc_state->port_clock,
      84                 :            :                                &crtc_state->dp_m_n,
      85                 :            :                                constant_n, crtc_state->fec_enable);
      86                 :            :         crtc_state->dp_m_n.tu = slots;
      87                 :            : 
      88                 :            :         return 0;
      89                 :            : }
      90                 :            : 
      91                 :            : /*
      92                 :            :  * Iterate over all connectors and return the smallest transcoder in the MST
      93                 :            :  * stream
      94                 :            :  */
      95                 :            : static enum transcoder
      96                 :          0 : intel_dp_mst_master_trans_compute(struct intel_atomic_state *state,
      97                 :            :                                   struct intel_dp *mst_port)
      98                 :            : {
      99         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
     100                 :          0 :         struct intel_digital_connector_state *conn_state;
     101                 :          0 :         struct intel_connector *connector;
     102                 :          0 :         enum pipe ret = I915_MAX_PIPES;
     103                 :          0 :         int i;
     104                 :            : 
     105         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) < 12)
     106                 :            :                 return INVALID_TRANSCODER;
     107                 :            : 
     108   [ #  #  #  # ]:          0 :         for_each_new_intel_connector_in_state(state, connector, conn_state, i) {
     109                 :          0 :                 struct intel_crtc_state *crtc_state;
     110                 :          0 :                 struct intel_crtc *crtc;
     111                 :            : 
     112   [ #  #  #  # ]:          0 :                 if (connector->mst_port != mst_port || !conn_state->base.crtc)
     113                 :          0 :                         continue;
     114                 :            : 
     115                 :          0 :                 crtc = to_intel_crtc(conn_state->base.crtc);
     116         [ #  # ]:          0 :                 crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
     117         [ #  # ]:          0 :                 if (!crtc_state->uapi.active)
     118                 :          0 :                         continue;
     119                 :            : 
     120                 :            :                 /*
     121                 :            :                  * Using crtc->pipe because crtc_state->cpu_transcoder is
     122                 :            :                  * computed, so others CRTCs could have non-computed
     123                 :            :                  * cpu_transcoder
     124                 :            :                  */
     125                 :          0 :                 if (crtc->pipe < ret)
     126                 :            :                         ret = crtc->pipe;
     127                 :            :         }
     128                 :            : 
     129         [ #  # ]:          0 :         if (ret == I915_MAX_PIPES)
     130                 :          0 :                 return INVALID_TRANSCODER;
     131                 :            : 
     132                 :            :         /* Simple cast works because TGL don't have a eDP transcoder */
     133                 :            :         return (enum transcoder)ret;
     134                 :            : }
     135                 :            : 
     136                 :          0 : static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
     137                 :            :                                        struct intel_crtc_state *pipe_config,
     138                 :            :                                        struct drm_connector_state *conn_state)
     139                 :            : {
     140                 :          0 :         struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state);
     141         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     142         [ #  # ]:          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     143                 :          0 :         struct intel_dp *intel_dp = &intel_mst->primary->dp;
     144                 :          0 :         struct intel_connector *connector =
     145                 :          0 :                 to_intel_connector(conn_state->connector);
     146                 :          0 :         struct intel_digital_connector_state *intel_conn_state =
     147                 :          0 :                 to_intel_digital_connector_state(conn_state);
     148                 :          0 :         const struct drm_display_mode *adjusted_mode =
     149                 :            :                 &pipe_config->hw.adjusted_mode;
     150                 :          0 :         void *port = connector->port;
     151                 :          0 :         struct link_config_limits limits;
     152                 :          0 :         int ret;
     153                 :            : 
     154         [ #  # ]:          0 :         if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
     155                 :            :                 return -EINVAL;
     156                 :            : 
     157                 :          0 :         pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
     158                 :          0 :         pipe_config->has_pch_encoder = false;
     159                 :            : 
     160         [ #  # ]:          0 :         if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
     161                 :          0 :                 pipe_config->has_audio =
     162                 :          0 :                         drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port);
     163                 :            :         else
     164                 :          0 :                 pipe_config->has_audio =
     165                 :          0 :                         intel_conn_state->force_audio == HDMI_AUDIO_ON;
     166                 :            : 
     167                 :            :         /*
     168                 :            :          * for MST we always configure max link bw - the spec doesn't
     169                 :            :          * seem to suggest we should do otherwise.
     170                 :            :          */
     171                 :          0 :         limits.min_clock =
     172                 :          0 :         limits.max_clock = intel_dp_max_link_rate(intel_dp);
     173                 :            : 
     174                 :          0 :         limits.min_lane_count =
     175                 :          0 :         limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
     176                 :            : 
     177                 :          0 :         limits.min_bpp = intel_dp_min_bpp(pipe_config);
     178                 :            :         /*
     179                 :            :          * FIXME: If all the streams can't fit into the link with
     180                 :            :          * their current pipe_bpp we should reduce pipe_bpp across
     181                 :            :          * the board until things start to fit. Until then we
     182                 :            :          * limit to <= 8bpc since that's what was hardcoded for all
     183                 :            :          * MST streams previously. This hack should be removed once
     184                 :            :          * we have the proper retry logic in place.
     185                 :            :          */
     186                 :          0 :         limits.max_bpp = min(pipe_config->pipe_bpp, 24);
     187                 :            : 
     188                 :          0 :         intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
     189                 :            : 
     190                 :          0 :         ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
     191                 :            :                                                conn_state, &limits);
     192         [ #  # ]:          0 :         if (ret)
     193                 :            :                 return ret;
     194                 :            : 
     195                 :          0 :         pipe_config->limited_color_range =
     196                 :          0 :                 intel_dp_limited_color_range(pipe_config, conn_state);
     197                 :            : 
     198   [ #  #  #  # ]:          0 :         if (IS_GEN9_LP(dev_priv))
     199                 :          0 :                 pipe_config->lane_lat_optim_mask =
     200                 :          0 :                         bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
     201                 :            : 
     202                 :          0 :         intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
     203                 :            : 
     204                 :          0 :         pipe_config->mst_master_transcoder = intel_dp_mst_master_trans_compute(state, intel_dp);
     205                 :            : 
     206                 :          0 :         return 0;
     207                 :            : }
     208                 :            : 
     209                 :            : /*
     210                 :            :  * If one of the connectors in a MST stream needs a modeset, mark all CRTCs
     211                 :            :  * that shares the same MST stream as mode changed,
     212                 :            :  * intel_modeset_pipe_config()+intel_crtc_check_fastset() will take care to do
     213                 :            :  * a fastset when possible.
     214                 :            :  */
     215                 :            : static int
     216                 :          0 : intel_dp_mst_atomic_master_trans_check(struct intel_connector *connector,
     217                 :            :                                        struct intel_atomic_state *state)
     218                 :            : {
     219         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(state->base.dev);
     220                 :          0 :         struct drm_connector_list_iter connector_list_iter;
     221                 :          0 :         struct intel_connector *connector_iter;
     222                 :            : 
     223         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) < 12)
     224                 :            :                 return  0;
     225                 :            : 
     226         [ #  # ]:          0 :         if (!intel_connector_needs_modeset(state, &connector->base))
     227                 :            :                 return 0;
     228                 :            : 
     229                 :          0 :         drm_connector_list_iter_begin(&dev_priv->drm, &connector_list_iter);
     230         [ #  # ]:          0 :         for_each_intel_connector_iter(connector_iter, &connector_list_iter) {
     231                 :          0 :                 struct intel_digital_connector_state *conn_iter_state;
     232                 :          0 :                 struct intel_crtc_state *crtc_state;
     233                 :          0 :                 struct intel_crtc *crtc;
     234                 :          0 :                 int ret;
     235                 :            : 
     236   [ #  #  #  # ]:          0 :                 if (connector_iter->mst_port != connector->mst_port ||
     237                 :            :                     connector_iter == connector)
     238                 :          0 :                         continue;
     239                 :            : 
     240                 :          0 :                 conn_iter_state = intel_atomic_get_digital_connector_state(state,
     241                 :            :                                                                            connector_iter);
     242         [ #  # ]:          0 :                 if (IS_ERR(conn_iter_state)) {
     243                 :          0 :                         drm_connector_list_iter_end(&connector_list_iter);
     244                 :          0 :                         return PTR_ERR(conn_iter_state);
     245                 :            :                 }
     246                 :            : 
     247         [ #  # ]:          0 :                 if (!conn_iter_state->base.crtc)
     248                 :          0 :                         continue;
     249                 :            : 
     250                 :          0 :                 crtc = to_intel_crtc(conn_iter_state->base.crtc);
     251                 :          0 :                 crtc_state = intel_atomic_get_crtc_state(&state->base, crtc);
     252         [ #  # ]:          0 :                 if (IS_ERR(crtc_state)) {
     253                 :          0 :                         drm_connector_list_iter_end(&connector_list_iter);
     254                 :          0 :                         return PTR_ERR(crtc_state);
     255                 :            :                 }
     256                 :            : 
     257                 :          0 :                 ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
     258         [ #  # ]:          0 :                 if (ret) {
     259                 :          0 :                         drm_connector_list_iter_end(&connector_list_iter);
     260                 :          0 :                         return ret;
     261                 :            :                 }
     262                 :          0 :                 crtc_state->uapi.mode_changed = true;
     263                 :            :         }
     264                 :          0 :         drm_connector_list_iter_end(&connector_list_iter);
     265                 :            : 
     266                 :          0 :         return 0;
     267                 :            : }
     268                 :            : 
     269                 :            : static int
     270                 :          0 : intel_dp_mst_atomic_check(struct drm_connector *connector,
     271                 :            :                           struct drm_atomic_state *_state)
     272                 :            : {
     273                 :          0 :         struct intel_atomic_state *state = to_intel_atomic_state(_state);
     274                 :          0 :         struct drm_connector_state *new_conn_state =
     275         [ #  # ]:          0 :                 drm_atomic_get_new_connector_state(&state->base, connector);
     276         [ #  # ]:          0 :         struct drm_connector_state *old_conn_state =
     277                 :            :                 drm_atomic_get_old_connector_state(&state->base, connector);
     278                 :          0 :         struct intel_connector *intel_connector =
     279                 :          0 :                 to_intel_connector(connector);
     280                 :          0 :         struct drm_crtc *new_crtc = new_conn_state->crtc;
     281                 :          0 :         struct drm_dp_mst_topology_mgr *mgr;
     282                 :          0 :         int ret;
     283                 :            : 
     284                 :          0 :         ret = intel_digital_connector_atomic_check(connector, &state->base);
     285         [ #  # ]:          0 :         if (ret)
     286                 :            :                 return ret;
     287                 :            : 
     288                 :          0 :         ret = intel_dp_mst_atomic_master_trans_check(intel_connector, state);
     289         [ #  # ]:          0 :         if (ret)
     290                 :            :                 return ret;
     291                 :            : 
     292         [ #  # ]:          0 :         if (!old_conn_state->crtc)
     293                 :            :                 return 0;
     294                 :            : 
     295                 :            :         /* We only want to free VCPI if this state disables the CRTC on this
     296                 :            :          * connector
     297                 :            :          */
     298         [ #  # ]:          0 :         if (new_crtc) {
     299                 :          0 :                 struct intel_crtc *intel_crtc = to_intel_crtc(new_crtc);
     300         [ #  # ]:          0 :                 struct intel_crtc_state *crtc_state =
     301                 :            :                         intel_atomic_get_new_crtc_state(state, intel_crtc);
     302                 :            : 
     303   [ #  #  #  # ]:          0 :                 if (!crtc_state ||
     304                 :          0 :                     !drm_atomic_crtc_needs_modeset(&crtc_state->uapi) ||
     305         [ #  # ]:          0 :                     crtc_state->uapi.enable)
     306                 :            :                         return 0;
     307                 :            :         }
     308                 :            : 
     309                 :          0 :         mgr = &enc_to_mst(to_intel_encoder(old_conn_state->best_encoder))->primary->dp.mst_mgr;
     310                 :          0 :         ret = drm_dp_atomic_release_vcpi_slots(&state->base, mgr,
     311                 :          0 :                                                intel_connector->port);
     312                 :            : 
     313                 :          0 :         return ret;
     314                 :            : }
     315                 :            : 
     316                 :          0 : static void intel_mst_disable_dp(struct intel_encoder *encoder,
     317                 :            :                                  const struct intel_crtc_state *old_crtc_state,
     318                 :            :                                  const struct drm_connector_state *old_conn_state)
     319                 :            : {
     320                 :          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     321                 :          0 :         struct intel_digital_port *intel_dig_port = intel_mst->primary;
     322                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     323                 :          0 :         struct intel_connector *connector =
     324                 :          0 :                 to_intel_connector(old_conn_state->connector);
     325                 :          0 :         int ret;
     326                 :            : 
     327                 :          0 :         DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
     328                 :            : 
     329                 :          0 :         drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, connector->port);
     330                 :            : 
     331                 :          0 :         ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
     332         [ #  # ]:          0 :         if (ret) {
     333                 :          0 :                 DRM_DEBUG_KMS("failed to update payload %d\n", ret);
     334                 :            :         }
     335         [ #  # ]:          0 :         if (old_crtc_state->has_audio)
     336                 :          0 :                 intel_audio_codec_disable(encoder,
     337                 :            :                                           old_crtc_state, old_conn_state);
     338                 :          0 : }
     339                 :            : 
     340                 :          0 : static void intel_mst_post_disable_dp(struct intel_encoder *encoder,
     341                 :            :                                       const struct intel_crtc_state *old_crtc_state,
     342                 :            :                                       const struct drm_connector_state *old_conn_state)
     343                 :            : {
     344         [ #  # ]:          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     345                 :          0 :         struct intel_digital_port *intel_dig_port = intel_mst->primary;
     346                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     347                 :          0 :         struct intel_connector *connector =
     348                 :          0 :                 to_intel_connector(old_conn_state->connector);
     349         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
     350                 :          0 :         bool last_mst_stream;
     351                 :          0 :         u32 val;
     352                 :            : 
     353                 :          0 :         intel_dp->active_mst_links--;
     354                 :          0 :         last_mst_stream = intel_dp->active_mst_links == 0;
     355   [ #  #  #  #  :          0 :         WARN_ON(INTEL_GEN(dev_priv) >= 12 && last_mst_stream &&
                   #  # ]
     356                 :            :                 !intel_dp_mst_is_master_trans(old_crtc_state));
     357                 :            : 
     358                 :          0 :         intel_crtc_vblank_off(old_crtc_state);
     359                 :            : 
     360                 :          0 :         intel_disable_pipe(old_crtc_state);
     361                 :            : 
     362                 :          0 :         drm_dp_update_payload_part2(&intel_dp->mst_mgr);
     363                 :            : 
     364                 :          0 :         val = I915_READ(TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder));
     365                 :          0 :         val &= ~TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
     366                 :          0 :         I915_WRITE(TRANS_DDI_FUNC_CTL(old_crtc_state->cpu_transcoder), val);
     367                 :            : 
     368         [ #  # ]:          0 :         if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
     369                 :            :                                   DP_TP_STATUS_ACT_SENT, 1))
     370                 :          0 :                 DRM_ERROR("Timed out waiting for ACT sent when disabling\n");
     371                 :          0 :         drm_dp_check_act_status(&intel_dp->mst_mgr);
     372                 :            : 
     373                 :          0 :         drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, connector->port);
     374                 :            : 
     375                 :          0 :         intel_ddi_disable_transcoder_func(old_crtc_state);
     376                 :            : 
     377         [ #  # ]:          0 :         if (INTEL_GEN(dev_priv) >= 9)
     378                 :          0 :                 skl_scaler_disable(old_crtc_state);
     379                 :            :         else
     380                 :          0 :                 ilk_pfit_disable(old_crtc_state);
     381                 :            : 
     382                 :            :         /*
     383                 :            :          * Power down mst path before disabling the port, otherwise we end
     384                 :            :          * up getting interrupts from the sink upon detecting link loss.
     385                 :            :          */
     386                 :          0 :         drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
     387                 :            :                                      false);
     388                 :            :         /*
     389                 :            :          * From TGL spec: "If multi-stream slave transcoder: Configure
     390                 :            :          * Transcoder Clock Select to direct no clock to the transcoder"
     391                 :            :          *
     392                 :            :          * From older GENs spec: "Configure Transcoder Clock Select to direct
     393                 :            :          * no clock to the transcoder"
     394                 :            :          */
     395   [ #  #  #  # ]:          0 :         if (INTEL_GEN(dev_priv) < 12 || !last_mst_stream)
     396                 :          0 :                 intel_ddi_disable_pipe_clock(old_crtc_state);
     397                 :            : 
     398                 :            : 
     399                 :          0 :         intel_mst->connector = NULL;
     400         [ #  # ]:          0 :         if (last_mst_stream)
     401                 :          0 :                 intel_dig_port->base.post_disable(&intel_dig_port->base,
     402                 :            :                                                   old_crtc_state, NULL);
     403                 :            : 
     404                 :          0 :         DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
     405                 :          0 : }
     406                 :            : 
     407                 :          0 : static void intel_mst_pre_pll_enable_dp(struct intel_encoder *encoder,
     408                 :            :                                         const struct intel_crtc_state *pipe_config,
     409                 :            :                                         const struct drm_connector_state *conn_state)
     410                 :            : {
     411         [ #  # ]:          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     412                 :          0 :         struct intel_digital_port *intel_dig_port = intel_mst->primary;
     413                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     414                 :            : 
     415         [ #  # ]:          0 :         if (intel_dp->active_mst_links == 0)
     416                 :          0 :                 intel_dig_port->base.pre_pll_enable(&intel_dig_port->base,
     417                 :            :                                                     pipe_config, NULL);
     418                 :          0 : }
     419                 :            : 
     420                 :          0 : static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
     421                 :            :                                     const struct intel_crtc_state *pipe_config,
     422                 :            :                                     const struct drm_connector_state *conn_state)
     423                 :            : {
     424         [ #  # ]:          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     425                 :          0 :         struct intel_digital_port *intel_dig_port = intel_mst->primary;
     426                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     427         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     428                 :          0 :         struct intel_connector *connector =
     429                 :          0 :                 to_intel_connector(conn_state->connector);
     430                 :          0 :         int ret;
     431                 :          0 :         u32 temp;
     432                 :          0 :         bool first_mst_stream;
     433                 :            : 
     434                 :            :         /* MST encoders are bound to a crtc, not to a connector,
     435                 :            :          * force the mapping here for get_hw_state.
     436                 :            :          */
     437                 :          0 :         connector->encoder = encoder;
     438                 :          0 :         intel_mst->connector = connector;
     439                 :          0 :         first_mst_stream = intel_dp->active_mst_links == 0;
     440   [ #  #  #  #  :          0 :         WARN_ON(INTEL_GEN(dev_priv) >= 12 && first_mst_stream &&
                   #  # ]
     441                 :            :                 !intel_dp_mst_is_master_trans(pipe_config));
     442                 :            : 
     443                 :          0 :         DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
     444                 :            : 
     445         [ #  # ]:          0 :         if (first_mst_stream)
     446                 :          0 :                 intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
     447                 :            : 
     448                 :          0 :         drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
     449                 :            : 
     450         [ #  # ]:          0 :         if (first_mst_stream)
     451                 :          0 :                 intel_dig_port->base.pre_enable(&intel_dig_port->base,
     452                 :            :                                                 pipe_config, NULL);
     453                 :            : 
     454                 :          0 :         ret = drm_dp_mst_allocate_vcpi(&intel_dp->mst_mgr,
     455                 :          0 :                                        connector->port,
     456                 :            :                                        pipe_config->pbn,
     457                 :          0 :                                        pipe_config->dp_m_n.tu);
     458         [ #  # ]:          0 :         if (!ret)
     459                 :          0 :                 DRM_ERROR("failed to allocate vcpi\n");
     460                 :            : 
     461                 :          0 :         intel_dp->active_mst_links++;
     462                 :          0 :         temp = I915_READ(intel_dp->regs.dp_tp_status);
     463                 :          0 :         I915_WRITE(intel_dp->regs.dp_tp_status, temp);
     464                 :            : 
     465                 :          0 :         ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
     466                 :            : 
     467                 :            :         /*
     468                 :            :          * Before Gen 12 this is not done as part of
     469                 :            :          * intel_dig_port->base.pre_enable() and should be done here. For
     470                 :            :          * Gen 12+ the step in which this should be done is different for the
     471                 :            :          * first MST stream, so it's done on the DDI for the first stream and
     472                 :            :          * here for the following ones.
     473                 :            :          */
     474   [ #  #  #  # ]:          0 :         if (INTEL_GEN(dev_priv) < 12 || !first_mst_stream)
     475                 :          0 :                 intel_ddi_enable_pipe_clock(pipe_config);
     476                 :            : 
     477                 :          0 :         intel_ddi_set_dp_msa(pipe_config, conn_state);
     478                 :          0 : }
     479                 :            : 
     480                 :          0 : static void intel_mst_enable_dp(struct intel_encoder *encoder,
     481                 :            :                                 const struct intel_crtc_state *pipe_config,
     482                 :            :                                 const struct drm_connector_state *conn_state)
     483                 :            : {
     484                 :          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     485                 :          0 :         struct intel_digital_port *intel_dig_port = intel_mst->primary;
     486                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     487                 :          0 :         struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
     488                 :            : 
     489                 :          0 :         DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
     490                 :            : 
     491         [ #  # ]:          0 :         if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
     492                 :            :                                   DP_TP_STATUS_ACT_SENT, 1))
     493                 :          0 :                 DRM_ERROR("Timed out waiting for ACT sent\n");
     494                 :            : 
     495                 :          0 :         drm_dp_check_act_status(&intel_dp->mst_mgr);
     496                 :            : 
     497                 :          0 :         drm_dp_update_payload_part2(&intel_dp->mst_mgr);
     498         [ #  # ]:          0 :         if (pipe_config->has_audio)
     499                 :          0 :                 intel_audio_codec_enable(encoder, pipe_config, conn_state);
     500                 :          0 : }
     501                 :            : 
     502                 :          0 : static bool intel_dp_mst_enc_get_hw_state(struct intel_encoder *encoder,
     503                 :            :                                       enum pipe *pipe)
     504                 :            : {
     505         [ #  # ]:          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     506                 :          0 :         *pipe = intel_mst->pipe;
     507         [ #  # ]:          0 :         if (intel_mst->connector)
     508                 :          0 :                 return true;
     509                 :            :         return false;
     510                 :            : }
     511                 :            : 
     512                 :          0 : static void intel_dp_mst_enc_get_config(struct intel_encoder *encoder,
     513                 :            :                                         struct intel_crtc_state *pipe_config)
     514                 :            : {
     515                 :          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
     516                 :          0 :         struct intel_digital_port *intel_dig_port = intel_mst->primary;
     517                 :            : 
     518                 :          0 :         intel_ddi_get_config(&intel_dig_port->base, pipe_config);
     519                 :          0 : }
     520                 :            : 
     521                 :          0 : static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
     522                 :            : {
     523                 :          0 :         struct intel_connector *intel_connector = to_intel_connector(connector);
     524                 :          0 :         struct intel_dp *intel_dp = intel_connector->mst_port;
     525                 :          0 :         struct edid *edid;
     526                 :          0 :         int ret;
     527                 :            : 
     528         [ #  # ]:          0 :         if (drm_connector_is_unregistered(connector))
     529                 :          0 :                 return intel_connector_update_modes(connector, NULL);
     530                 :            : 
     531                 :          0 :         edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
     532                 :          0 :         ret = intel_connector_update_modes(connector, edid);
     533                 :          0 :         kfree(edid);
     534                 :            : 
     535                 :          0 :         return ret;
     536                 :            : }
     537                 :            : 
     538                 :            : static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
     539                 :            :         .fill_modes = drm_helper_probe_single_connector_modes,
     540                 :            :         .atomic_get_property = intel_digital_connector_atomic_get_property,
     541                 :            :         .atomic_set_property = intel_digital_connector_atomic_set_property,
     542                 :            :         .late_register = intel_connector_register,
     543                 :            :         .early_unregister = intel_connector_unregister,
     544                 :            :         .destroy = intel_connector_destroy,
     545                 :            :         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
     546                 :            :         .atomic_duplicate_state = intel_digital_connector_duplicate_state,
     547                 :            : };
     548                 :            : 
     549                 :          0 : static int intel_dp_mst_get_modes(struct drm_connector *connector)
     550                 :            : {
     551                 :          0 :         return intel_dp_mst_get_ddc_modes(connector);
     552                 :            : }
     553                 :            : 
     554                 :            : static enum drm_mode_status
     555                 :          0 : intel_dp_mst_mode_valid(struct drm_connector *connector,
     556                 :            :                         struct drm_display_mode *mode)
     557                 :            : {
     558         [ #  # ]:          0 :         struct drm_i915_private *dev_priv = to_i915(connector->dev);
     559                 :          0 :         struct intel_connector *intel_connector = to_intel_connector(connector);
     560                 :          0 :         struct intel_dp *intel_dp = intel_connector->mst_port;
     561                 :          0 :         int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
     562                 :          0 :         int max_rate, mode_rate, max_lanes, max_link_clock;
     563                 :            : 
     564         [ #  # ]:          0 :         if (drm_connector_is_unregistered(connector))
     565                 :            :                 return MODE_ERROR;
     566                 :            : 
     567         [ #  # ]:          0 :         if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
     568                 :            :                 return MODE_NO_DBLESCAN;
     569                 :            : 
     570                 :          0 :         max_link_clock = intel_dp_max_link_rate(intel_dp);
     571                 :          0 :         max_lanes = intel_dp_max_lane_count(intel_dp);
     572                 :            : 
     573                 :          0 :         max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
     574                 :          0 :         mode_rate = intel_dp_link_required(mode->clock, 18);
     575                 :            : 
     576                 :            :         /* TODO - validate mode against available PBN for link */
     577         [ #  # ]:          0 :         if (mode->clock < 10000)
     578                 :            :                 return MODE_CLOCK_LOW;
     579                 :            : 
     580         [ #  # ]:          0 :         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
     581                 :            :                 return MODE_H_ILLEGAL;
     582                 :            : 
     583   [ #  #  #  # ]:          0 :         if (mode_rate > max_rate || mode->clock > max_dotclk)
     584                 :            :                 return MODE_CLOCK_HIGH;
     585                 :            : 
     586                 :          0 :         return intel_mode_valid_max_plane_size(dev_priv, mode);
     587                 :            : }
     588                 :            : 
     589                 :          0 : static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector,
     590                 :            :                                                          struct drm_connector_state *state)
     591                 :            : {
     592                 :          0 :         struct intel_connector *intel_connector = to_intel_connector(connector);
     593                 :          0 :         struct intel_dp *intel_dp = intel_connector->mst_port;
     594                 :          0 :         struct intel_crtc *crtc = to_intel_crtc(state->crtc);
     595                 :            : 
     596                 :          0 :         return &intel_dp->mst_encoders[crtc->pipe]->base.base;
     597                 :            : }
     598                 :            : 
     599                 :            : static int
     600                 :          0 : intel_dp_mst_detect(struct drm_connector *connector,
     601                 :            :                     struct drm_modeset_acquire_ctx *ctx, bool force)
     602                 :            : {
     603                 :          0 :         struct intel_connector *intel_connector = to_intel_connector(connector);
     604                 :          0 :         struct intel_dp *intel_dp = intel_connector->mst_port;
     605                 :            : 
     606         [ #  # ]:          0 :         if (drm_connector_is_unregistered(connector))
     607                 :            :                 return connector_status_disconnected;
     608                 :            : 
     609                 :          0 :         return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr,
     610                 :          0 :                                       intel_connector->port);
     611                 :            : }
     612                 :            : 
     613                 :            : static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = {
     614                 :            :         .get_modes = intel_dp_mst_get_modes,
     615                 :            :         .mode_valid = intel_dp_mst_mode_valid,
     616                 :            :         .atomic_best_encoder = intel_mst_atomic_best_encoder,
     617                 :            :         .atomic_check = intel_dp_mst_atomic_check,
     618                 :            :         .detect_ctx = intel_dp_mst_detect,
     619                 :            : };
     620                 :            : 
     621                 :          0 : static void intel_dp_mst_encoder_destroy(struct drm_encoder *encoder)
     622                 :            : {
     623                 :          0 :         struct intel_dp_mst_encoder *intel_mst = enc_to_mst(to_intel_encoder(encoder));
     624                 :            : 
     625                 :          0 :         drm_encoder_cleanup(encoder);
     626                 :          0 :         kfree(intel_mst);
     627                 :          0 : }
     628                 :            : 
     629                 :            : static const struct drm_encoder_funcs intel_dp_mst_enc_funcs = {
     630                 :            :         .destroy = intel_dp_mst_encoder_destroy,
     631                 :            : };
     632                 :            : 
     633                 :          0 : static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
     634                 :            : {
     635   [ #  #  #  # ]:          0 :         if (connector->encoder && connector->base.state->crtc) {
     636                 :          0 :                 enum pipe pipe;
     637         [ #  # ]:          0 :                 if (!connector->encoder->get_hw_state(connector->encoder, &pipe))
     638                 :            :                         return false;
     639                 :          0 :                 return true;
     640                 :            :         }
     641                 :            :         return false;
     642                 :            : }
     643                 :            : 
     644                 :          0 : static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
     645                 :            : {
     646                 :          0 :         struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
     647                 :          0 :         struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
     648                 :          0 :         struct drm_device *dev = intel_dig_port->base.base.dev;
     649                 :          0 :         struct drm_i915_private *dev_priv = to_i915(dev);
     650                 :          0 :         struct intel_connector *intel_connector;
     651                 :          0 :         struct drm_connector *connector;
     652                 :          0 :         enum pipe pipe;
     653                 :          0 :         int ret;
     654                 :            : 
     655                 :          0 :         intel_connector = intel_connector_alloc();
     656         [ #  # ]:          0 :         if (!intel_connector)
     657                 :            :                 return NULL;
     658                 :            : 
     659                 :          0 :         intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
     660                 :          0 :         intel_connector->mst_port = intel_dp;
     661                 :          0 :         intel_connector->port = port;
     662                 :          0 :         drm_dp_mst_get_port_malloc(port);
     663                 :            : 
     664                 :          0 :         connector = &intel_connector->base;
     665                 :          0 :         ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs,
     666                 :            :                                  DRM_MODE_CONNECTOR_DisplayPort);
     667         [ #  # ]:          0 :         if (ret) {
     668                 :          0 :                 intel_connector_free(intel_connector);
     669                 :          0 :                 return NULL;
     670                 :            :         }
     671                 :            : 
     672                 :          0 :         drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs);
     673                 :            : 
     674   [ #  #  #  # ]:          0 :         for_each_pipe(dev_priv, pipe) {
     675                 :          0 :                 struct drm_encoder *enc =
     676                 :          0 :                         &intel_dp->mst_encoders[pipe]->base.base;
     677                 :            : 
     678                 :          0 :                 ret = drm_connector_attach_encoder(&intel_connector->base, enc);
     679         [ #  # ]:          0 :                 if (ret)
     680                 :          0 :                         goto err;
     681                 :            :         }
     682                 :            : 
     683                 :          0 :         drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
     684                 :          0 :         drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
     685                 :            : 
     686                 :          0 :         ret = drm_connector_set_path_property(connector, pathprop);
     687         [ #  # ]:          0 :         if (ret)
     688                 :          0 :                 goto err;
     689                 :            : 
     690                 :          0 :         intel_attach_force_audio_property(connector);
     691                 :          0 :         intel_attach_broadcast_rgb_property(connector);
     692                 :            : 
     693                 :            :         /*
     694                 :            :          * Reuse the prop from the SST connector because we're
     695                 :            :          * not allowed to create new props after device registration.
     696                 :            :          */
     697                 :          0 :         connector->max_bpc_property =
     698                 :          0 :                 intel_dp->attached_connector->base.max_bpc_property;
     699         [ #  # ]:          0 :         if (connector->max_bpc_property)
     700                 :          0 :                 drm_connector_attach_max_bpc_property(connector, 6, 12);
     701                 :            : 
     702                 :            :         return connector;
     703                 :            : 
     704                 :          0 : err:
     705                 :          0 :         drm_connector_cleanup(connector);
     706                 :          0 :         return NULL;
     707                 :            : }
     708                 :            : 
     709                 :          0 : static void intel_dp_register_mst_connector(struct drm_connector *connector)
     710                 :            : {
     711                 :          0 :         struct drm_i915_private *dev_priv = to_i915(connector->dev);
     712                 :            : 
     713                 :          0 :         if (dev_priv->fbdev)
     714                 :            :                 drm_fb_helper_add_one_connector(&dev_priv->fbdev->helper,
     715                 :            :                                                 connector);
     716                 :            : 
     717                 :          0 :         drm_connector_register(connector);
     718                 :          0 : }
     719                 :            : 
     720                 :          0 : static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
     721                 :            :                                            struct drm_connector *connector)
     722                 :            : {
     723                 :          0 :         struct drm_i915_private *dev_priv = to_i915(connector->dev);
     724                 :            : 
     725                 :          0 :         DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name);
     726                 :          0 :         drm_connector_unregister(connector);
     727                 :            : 
     728                 :          0 :         if (dev_priv->fbdev)
     729                 :            :                 drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
     730                 :            :                                                    connector);
     731                 :            : 
     732                 :          0 :         drm_connector_put(connector);
     733                 :          0 : }
     734                 :            : 
     735                 :            : static const struct drm_dp_mst_topology_cbs mst_cbs = {
     736                 :            :         .add_connector = intel_dp_add_mst_connector,
     737                 :            :         .register_connector = intel_dp_register_mst_connector,
     738                 :            :         .destroy_connector = intel_dp_destroy_mst_connector,
     739                 :            : };
     740                 :            : 
     741                 :            : static struct intel_dp_mst_encoder *
     742                 :          0 : intel_dp_create_fake_mst_encoder(struct intel_digital_port *intel_dig_port, enum pipe pipe)
     743                 :            : {
     744                 :          0 :         struct intel_dp_mst_encoder *intel_mst;
     745                 :          0 :         struct intel_encoder *intel_encoder;
     746                 :          0 :         struct drm_device *dev = intel_dig_port->base.base.dev;
     747                 :            : 
     748                 :          0 :         intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL);
     749                 :            : 
     750         [ #  # ]:          0 :         if (!intel_mst)
     751                 :            :                 return NULL;
     752                 :            : 
     753                 :          0 :         intel_mst->pipe = pipe;
     754                 :          0 :         intel_encoder = &intel_mst->base;
     755                 :          0 :         intel_mst->primary = intel_dig_port;
     756                 :            : 
     757                 :          0 :         drm_encoder_init(dev, &intel_encoder->base, &intel_dp_mst_enc_funcs,
     758                 :            :                          DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe));
     759                 :            : 
     760                 :          0 :         intel_encoder->type = INTEL_OUTPUT_DP_MST;
     761                 :          0 :         intel_encoder->power_domain = intel_dig_port->base.power_domain;
     762                 :          0 :         intel_encoder->port = intel_dig_port->base.port;
     763                 :          0 :         intel_encoder->cloneable = 0;
     764                 :            :         /*
     765                 :            :          * This is wrong, but broken userspace uses the intersection
     766                 :            :          * of possible_crtcs of all the encoders of a given connector
     767                 :            :          * to figure out which crtcs can drive said connector. What
     768                 :            :          * should be used instead is the union of possible_crtcs.
     769                 :            :          * To keep such userspace functioning we must misconfigure
     770                 :            :          * this to make sure the intersection is not empty :(
     771                 :            :          */
     772                 :          0 :         intel_encoder->pipe_mask = ~0;
     773                 :            : 
     774                 :          0 :         intel_encoder->compute_config = intel_dp_mst_compute_config;
     775                 :          0 :         intel_encoder->disable = intel_mst_disable_dp;
     776                 :          0 :         intel_encoder->post_disable = intel_mst_post_disable_dp;
     777                 :          0 :         intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp;
     778                 :          0 :         intel_encoder->pre_enable = intel_mst_pre_enable_dp;
     779                 :          0 :         intel_encoder->enable = intel_mst_enable_dp;
     780                 :          0 :         intel_encoder->get_hw_state = intel_dp_mst_enc_get_hw_state;
     781                 :          0 :         intel_encoder->get_config = intel_dp_mst_enc_get_config;
     782                 :            : 
     783                 :          0 :         return intel_mst;
     784                 :            : 
     785                 :            : }
     786                 :            : 
     787                 :            : static bool
     788                 :          0 : intel_dp_create_fake_mst_encoders(struct intel_digital_port *intel_dig_port)
     789                 :            : {
     790                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     791                 :          0 :         struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
     792                 :          0 :         enum pipe pipe;
     793                 :            : 
     794   [ #  #  #  # ]:          0 :         for_each_pipe(dev_priv, pipe)
     795                 :          0 :                 intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(intel_dig_port, pipe);
     796                 :          0 :         return true;
     797                 :            : }
     798                 :            : 
     799                 :            : int
     800                 :          0 : intel_dp_mst_encoder_active_links(struct intel_digital_port *intel_dig_port)
     801                 :            : {
     802                 :          0 :         return intel_dig_port->dp.active_mst_links;
     803                 :            : }
     804                 :            : 
     805                 :            : int
     806                 :          0 : intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_base_id)
     807                 :            : {
     808         [ #  # ]:          0 :         struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev);
     809                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     810                 :          0 :         enum port port = intel_dig_port->base.port;
     811                 :          0 :         int ret;
     812                 :            : 
     813   [ #  #  #  # ]:          0 :         if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp))
     814                 :          0 :                 return 0;
     815                 :            : 
     816   [ #  #  #  # ]:          0 :         if (INTEL_GEN(i915) < 12 && port == PORT_A)
     817                 :            :                 return 0;
     818                 :            : 
     819   [ #  #  #  # ]:          0 :         if (INTEL_GEN(i915) < 11 && port == PORT_E)
     820                 :            :                 return 0;
     821                 :            : 
     822                 :          0 :         intel_dp->mst_mgr.cbs = &mst_cbs;
     823                 :            : 
     824                 :            :         /* create encoders */
     825                 :          0 :         intel_dp_create_fake_mst_encoders(intel_dig_port);
     826                 :          0 :         ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
     827                 :            :                                            &intel_dp->aux, 16, 3, conn_base_id);
     828         [ #  # ]:          0 :         if (ret)
     829                 :            :                 return ret;
     830                 :            : 
     831                 :          0 :         intel_dp->can_mst = true;
     832                 :            : 
     833                 :          0 :         return 0;
     834                 :            : }
     835                 :            : 
     836                 :            : void
     837                 :          0 : intel_dp_mst_encoder_cleanup(struct intel_digital_port *intel_dig_port)
     838                 :            : {
     839                 :          0 :         struct intel_dp *intel_dp = &intel_dig_port->dp;
     840                 :            : 
     841         [ #  # ]:          0 :         if (!intel_dp->can_mst)
     842                 :            :                 return;
     843                 :            : 
     844                 :          0 :         drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
     845                 :            :         /* encoders will get killed by normal cleanup */
     846                 :            : }
     847                 :            : 
     848                 :          0 : bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state)
     849                 :            : {
     850   [ #  #  #  # ]:          0 :         return crtc_state->mst_master_transcoder == crtc_state->cpu_transcoder;
     851                 :            : }
     852                 :            : 
     853                 :          0 : bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state)
     854                 :            : {
     855         [ #  # ]:          0 :         return crtc_state->mst_master_transcoder != INVALID_TRANSCODER &&
     856         [ #  # ]:          0 :                crtc_state->mst_master_transcoder != crtc_state->cpu_transcoder;
     857                 :            : }

Generated by: LCOV version 1.14