LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - radeon_dp_mst.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 386 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : #include <dev/pci/drm/drmP.h>
       3             : #include <dev/pci/drm/drm_dp_mst_helper.h>
       4             : #include <dev/pci/drm/drm_fb_helper.h>
       5             : 
       6             : #include "radeon.h"
       7             : #include "atom.h"
       8             : #include "ni_reg.h"
       9             : 
      10             : static struct radeon_encoder *radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector);
      11             : 
      12           0 : static int radeon_atom_set_enc_offset(int id)
      13             : {
      14             :         static const int offsets[] = { EVERGREEN_CRTC0_REGISTER_OFFSET,
      15             :                                        EVERGREEN_CRTC1_REGISTER_OFFSET,
      16             :                                        EVERGREEN_CRTC2_REGISTER_OFFSET,
      17             :                                        EVERGREEN_CRTC3_REGISTER_OFFSET,
      18             :                                        EVERGREEN_CRTC4_REGISTER_OFFSET,
      19             :                                        EVERGREEN_CRTC5_REGISTER_OFFSET,
      20             :                                        0x13830 - 0x7030 };
      21             : 
      22           0 :         return offsets[id];
      23             : }
      24             : 
      25           0 : static int radeon_dp_mst_set_be_cntl(struct radeon_encoder *primary,
      26             :                                      struct radeon_encoder_mst *mst_enc,
      27             :                                      enum radeon_hpd_id hpd, bool enable)
      28             : {
      29           0 :         struct drm_device *dev = primary->base.dev;
      30           0 :         struct radeon_device *rdev = dev->dev_private;
      31             :         uint32_t reg;
      32             :         int retries = 0;
      33             :         uint32_t temp;
      34             : 
      35           0 :         reg = RREG32(NI_DIG_BE_CNTL + primary->offset);
      36             : 
      37             :         /* set MST mode */
      38           0 :         reg &= ~NI_DIG_FE_DIG_MODE(7);
      39           0 :         reg |= NI_DIG_FE_DIG_MODE(NI_DIG_MODE_DP_MST);
      40             : 
      41           0 :         if (enable)
      42           0 :                 reg |= NI_DIG_FE_SOURCE_SELECT(1 << mst_enc->fe);
      43             :         else
      44           0 :                 reg &= ~NI_DIG_FE_SOURCE_SELECT(1 << mst_enc->fe);
      45             : 
      46           0 :         reg |= NI_DIG_HPD_SELECT(hpd);
      47             :         DRM_DEBUG_KMS("writing 0x%08x 0x%08x\n", NI_DIG_BE_CNTL + primary->offset, reg);
      48           0 :         WREG32(NI_DIG_BE_CNTL + primary->offset, reg);
      49             : 
      50           0 :         if (enable) {
      51           0 :                 uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe);
      52             : 
      53           0 :                 do {
      54           0 :                         temp = RREG32(NI_DIG_FE_CNTL + offset);
      55           0 :                 } while ((temp & NI_DIG_SYMCLK_FE_ON) && retries++ < 10000);
      56           0 :                 if (retries == 10000)
      57           0 :                         DRM_ERROR("timed out waiting for FE %d %d\n", primary->offset, mst_enc->fe);
      58           0 :         }
      59           0 :         return 0;
      60             : }
      61             : 
      62           0 : static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary,
      63             :                                            int stream_number,
      64             :                                            int fe,
      65             :                                            int slots)
      66             : {
      67           0 :         struct drm_device *dev = primary->base.dev;
      68           0 :         struct radeon_device *rdev = dev->dev_private;
      69             :         u32 temp, val;
      70             :         int retries  = 0;
      71             :         int satreg, satidx;
      72             : 
      73           0 :         satreg = stream_number >> 1;
      74           0 :         satidx = stream_number & 1;
      75             : 
      76           0 :         temp = RREG32(NI_DP_MSE_SAT0 + satreg + primary->offset);
      77             : 
      78           0 :         val = NI_DP_MSE_SAT_SLOT_COUNT0(slots) | NI_DP_MSE_SAT_SRC0(fe);
      79             : 
      80           0 :         val <<= (16 * satidx);
      81             : 
      82           0 :         temp &= ~(0xffff << (16 * satidx));
      83             : 
      84           0 :         temp |= val;
      85             : 
      86             :         DRM_DEBUG_KMS("writing 0x%08x 0x%08x\n", NI_DP_MSE_SAT0 + satreg + primary->offset, temp);
      87           0 :         WREG32(NI_DP_MSE_SAT0 + satreg + primary->offset, temp);
      88             : 
      89           0 :         WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1);
      90             : 
      91           0 :         do {
      92           0 :                 temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset);
      93           0 :         } while ((temp & 0x1) && retries++ < 10000);
      94             : 
      95           0 :         if (retries == 10000)
      96           0 :                 DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset);
      97             : 
      98             :         /* MTP 16 ? */
      99           0 :         return 0;
     100             : }
     101             : 
     102           0 : static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn,
     103             :                                                struct radeon_encoder *primary)
     104             : {
     105           0 :         struct drm_device *dev = mst_conn->base.dev;
     106           0 :         struct stream_attribs new_attribs[6];
     107             :         int i;
     108             :         int idx = 0;
     109             :         struct radeon_connector *radeon_connector;
     110             :         struct drm_connector *connector;
     111             : 
     112           0 :         memset(new_attribs, 0, sizeof(new_attribs));
     113           0 :         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
     114             :                 struct radeon_encoder *subenc;
     115             :                 struct radeon_encoder_mst *mst_enc;
     116             : 
     117           0 :                 radeon_connector = to_radeon_connector(connector);
     118           0 :                 if (!radeon_connector->is_mst_connector)
     119           0 :                         continue;
     120             : 
     121           0 :                 if (radeon_connector->mst_port != mst_conn)
     122           0 :                         continue;
     123             : 
     124           0 :                 subenc = radeon_connector->mst_encoder;
     125           0 :                 mst_enc = subenc->enc_priv;
     126             : 
     127           0 :                 if (!mst_enc->enc_active)
     128           0 :                         continue;
     129             : 
     130           0 :                 new_attribs[idx].fe = mst_enc->fe;
     131           0 :                 new_attribs[idx].slots = drm_dp_mst_get_vcpi_slots(&mst_conn->mst_mgr, mst_enc->port);
     132           0 :                 idx++;
     133           0 :         }
     134             : 
     135           0 :         for (i = 0; i < idx; i++) {
     136           0 :                 if (new_attribs[i].fe != mst_conn->cur_stream_attribs[i].fe ||
     137           0 :                     new_attribs[i].slots != mst_conn->cur_stream_attribs[i].slots) {
     138           0 :                         radeon_dp_mst_set_stream_attrib(primary, i, new_attribs[i].fe, new_attribs[i].slots);
     139           0 :                         mst_conn->cur_stream_attribs[i].fe = new_attribs[i].fe;
     140           0 :                         mst_conn->cur_stream_attribs[i].slots = new_attribs[i].slots;
     141           0 :                 }
     142             :         }
     143             : 
     144           0 :         for (i = idx; i < mst_conn->enabled_attribs; i++) {
     145           0 :                 radeon_dp_mst_set_stream_attrib(primary, i, 0, 0);
     146           0 :                 mst_conn->cur_stream_attribs[i].fe = 0;
     147           0 :                 mst_conn->cur_stream_attribs[i].slots = 0;
     148             :         }
     149           0 :         mst_conn->enabled_attribs = idx;
     150           0 :         return 0;
     151           0 : }
     152             : 
     153           0 : static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, uint32_t y)
     154             : {
     155           0 :         struct drm_device *dev = mst->base.dev;
     156           0 :         struct radeon_device *rdev = dev->dev_private;
     157           0 :         struct radeon_encoder_mst *mst_enc = mst->enc_priv;
     158             :         uint32_t val, temp;
     159           0 :         uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe);
     160             :         int retries = 0;
     161             : 
     162           0 :         val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y);
     163             : 
     164           0 :         WREG32(NI_DP_MSE_RATE_CNTL + offset, val);
     165             : 
     166           0 :         do {
     167           0 :                 temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset);
     168           0 :         } while ((temp & 0x1) && (retries++ < 10000));
     169             : 
     170           0 :         if (retries >= 10000)
     171           0 :                 DRM_ERROR("timed out wait for rate cntl %d\n", mst_enc->fe);
     172           0 :         return 0;
     173             : }
     174             : 
     175           0 : static int radeon_dp_mst_get_ddc_modes(struct drm_connector *connector)
     176             : {
     177           0 :         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
     178           0 :         struct radeon_connector *master = radeon_connector->mst_port;
     179             :         struct edid *edid;
     180             :         int ret = 0;
     181             : 
     182           0 :         edid = drm_dp_mst_get_edid(connector, &master->mst_mgr, radeon_connector->port);
     183           0 :         radeon_connector->edid = edid;
     184             :         DRM_DEBUG_KMS("edid retrieved %p\n", edid);
     185           0 :         if (radeon_connector->edid) {
     186           0 :                 drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
     187           0 :                 ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
     188           0 :                 drm_edid_to_eld(&radeon_connector->base, radeon_connector->edid);
     189           0 :                 return ret;
     190             :         }
     191           0 :         drm_mode_connector_update_edid_property(&radeon_connector->base, NULL);
     192             : 
     193           0 :         return ret;
     194           0 : }
     195             : 
     196           0 : static int radeon_dp_mst_get_modes(struct drm_connector *connector)
     197             : {
     198           0 :         return radeon_dp_mst_get_ddc_modes(connector);
     199             : }
     200             : 
     201             : static enum drm_mode_status
     202           0 : radeon_dp_mst_mode_valid(struct drm_connector *connector,
     203             :                         struct drm_display_mode *mode)
     204             : {
     205             :         /* TODO - validate mode against available PBN for link */
     206           0 :         if (mode->clock < 10000)
     207           0 :                 return MODE_CLOCK_LOW;
     208             : 
     209           0 :         if (mode->flags & DRM_MODE_FLAG_DBLCLK)
     210           0 :                 return MODE_H_ILLEGAL;
     211             : 
     212           0 :         return MODE_OK;
     213           0 : }
     214             : 
     215           0 : struct drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector)
     216             : {
     217           0 :         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
     218             : 
     219           0 :         return &radeon_connector->mst_encoder->base;
     220             : }
     221             : 
     222             : static const struct drm_connector_helper_funcs radeon_dp_mst_connector_helper_funcs = {
     223             :         .get_modes = radeon_dp_mst_get_modes,
     224             :         .mode_valid = radeon_dp_mst_mode_valid,
     225             :         .best_encoder = radeon_mst_best_encoder,
     226             : };
     227             : 
     228             : static enum drm_connector_status
     229           0 : radeon_dp_mst_detect(struct drm_connector *connector, bool force)
     230             : {
     231           0 :         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
     232           0 :         struct radeon_connector *master = radeon_connector->mst_port;
     233             : 
     234           0 :         return drm_dp_mst_detect_port(connector, &master->mst_mgr, radeon_connector->port);
     235             : }
     236             : 
     237             : static void
     238           0 : radeon_dp_mst_connector_destroy(struct drm_connector *connector)
     239             : {
     240           0 :         struct radeon_connector *radeon_connector = to_radeon_connector(connector);
     241           0 :         struct radeon_encoder *radeon_encoder = radeon_connector->mst_encoder;
     242             : 
     243           0 :         drm_encoder_cleanup(&radeon_encoder->base);
     244           0 :         kfree(radeon_encoder);
     245           0 :         drm_connector_cleanup(connector);
     246           0 :         kfree(radeon_connector);
     247           0 : }
     248             : 
     249           0 : static int radeon_connector_dpms(struct drm_connector *connector, int mode)
     250             : {
     251             :         DRM_DEBUG_KMS("\n");
     252           0 :         return 0;
     253             : }
     254             : 
     255             : static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = {
     256             :         .dpms = radeon_connector_dpms,
     257             :         .detect = radeon_dp_mst_detect,
     258             :         .fill_modes = drm_helper_probe_single_connector_modes,
     259             :         .destroy = radeon_dp_mst_connector_destroy,
     260             : };
     261             : 
     262           0 : static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
     263             :                                                          struct drm_dp_mst_port *port,
     264             :                                                          const char *pathprop)
     265             : {
     266           0 :         struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr);
     267           0 :         struct drm_device *dev = master->base.dev;
     268             :         struct radeon_connector *radeon_connector;
     269             :         struct drm_connector *connector;
     270             : 
     271           0 :         radeon_connector = kzalloc(sizeof(*radeon_connector), GFP_KERNEL);
     272           0 :         if (!radeon_connector)
     273           0 :                 return NULL;
     274             : 
     275           0 :         radeon_connector->is_mst_connector = true;
     276           0 :         connector = &radeon_connector->base;
     277           0 :         radeon_connector->port = port;
     278           0 :         radeon_connector->mst_port = master;
     279             :         DRM_DEBUG_KMS("\n");
     280             : 
     281           0 :         drm_connector_init(dev, connector, &radeon_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort);
     282           0 :         drm_connector_helper_add(connector, &radeon_dp_mst_connector_helper_funcs);
     283           0 :         radeon_connector->mst_encoder = radeon_dp_create_fake_mst_encoder(master);
     284             : 
     285           0 :         drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
     286           0 :         drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
     287           0 :         drm_mode_connector_set_path_property(connector, pathprop);
     288             : 
     289           0 :         return connector;
     290           0 : }
     291             : 
     292           0 : static void radeon_dp_register_mst_connector(struct drm_connector *connector)
     293             : {
     294           0 :         struct drm_device *dev = connector->dev;
     295           0 :         struct radeon_device *rdev = dev->dev_private;
     296             : 
     297           0 :         drm_modeset_lock_all(dev);
     298           0 :         radeon_fb_add_connector(rdev, connector);
     299           0 :         drm_modeset_unlock_all(dev);
     300             : 
     301           0 :         drm_connector_register(connector);
     302           0 : }
     303             : 
     304           0 : static void radeon_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
     305             :                                             struct drm_connector *connector)
     306             : {
     307           0 :         struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr);
     308           0 :         struct drm_device *dev = master->base.dev;
     309           0 :         struct radeon_device *rdev = dev->dev_private;
     310             : 
     311           0 :         drm_connector_unregister(connector);
     312             :         /* need to nuke the connector */
     313           0 :         drm_modeset_lock_all(dev);
     314             :         /* dpms off */
     315           0 :         radeon_fb_remove_connector(rdev, connector);
     316             : 
     317           0 :         drm_connector_cleanup(connector);
     318           0 :         drm_modeset_unlock_all(dev);
     319             : 
     320           0 :         kfree(connector);
     321             :         DRM_DEBUG_KMS("\n");
     322           0 : }
     323             : 
     324           0 : static void radeon_dp_mst_hotplug(struct drm_dp_mst_topology_mgr *mgr)
     325             : {
     326           0 :         struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr);
     327           0 :         struct drm_device *dev = master->base.dev;
     328             : 
     329           0 :         drm_kms_helper_hotplug_event(dev);
     330           0 : }
     331             : 
     332             : struct drm_dp_mst_topology_cbs mst_cbs = {
     333             :         .add_connector = radeon_dp_add_mst_connector,
     334             :         .register_connector = radeon_dp_register_mst_connector,
     335             :         .destroy_connector = radeon_dp_destroy_mst_connector,
     336             :         .hotplug = radeon_dp_mst_hotplug,
     337             : };
     338             : 
     339           0 : struct radeon_connector *radeon_mst_find_connector(struct drm_encoder *encoder)
     340             : {
     341           0 :         struct drm_device *dev = encoder->dev;
     342             :         struct drm_connector *connector;
     343             : 
     344           0 :         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
     345           0 :                 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
     346           0 :                 if (!connector->encoder)
     347           0 :                         continue;
     348           0 :                 if (!radeon_connector->is_mst_connector)
     349           0 :                         continue;
     350             : 
     351             :                 DRM_DEBUG_KMS("checking %p vs %p\n", connector->encoder, encoder);
     352           0 :                 if (connector->encoder == encoder)
     353           0 :                         return radeon_connector;
     354           0 :         }
     355           0 :         return NULL;
     356           0 : }
     357             : 
     358           0 : void radeon_dp_mst_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
     359             : {
     360           0 :         struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
     361           0 :         struct drm_device *dev = crtc->dev;
     362           0 :         struct radeon_device *rdev = dev->dev_private;
     363           0 :         struct radeon_encoder *radeon_encoder = to_radeon_encoder(radeon_crtc->encoder);
     364           0 :         struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv;
     365           0 :         struct radeon_connector *radeon_connector = radeon_mst_find_connector(&radeon_encoder->base);
     366             :         int dp_clock;
     367           0 :         struct radeon_connector_atom_dig *dig_connector = mst_enc->connector->con_priv;
     368             : 
     369           0 :         if (radeon_connector) {
     370           0 :                 radeon_connector->pixelclock_for_modeset = mode->clock;
     371           0 :                 if (radeon_connector->base.display_info.bpc)
     372           0 :                         radeon_crtc->bpc = radeon_connector->base.display_info.bpc;
     373             :                 else
     374           0 :                         radeon_crtc->bpc = 8;
     375             :         }
     376             : 
     377             :         DRM_DEBUG_KMS("dp_clock %p %d\n", dig_connector, dig_connector->dp_clock);
     378           0 :         dp_clock = dig_connector->dp_clock;
     379           0 :         radeon_crtc->ss_enabled =
     380           0 :                 radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
     381             :                                                  ASIC_INTERNAL_SS_ON_DP,
     382             :                                                  dp_clock);
     383           0 : }
     384             : 
     385             : static void
     386           0 : radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
     387             : {
     388           0 :         struct drm_device *dev = encoder->dev;
     389           0 :         struct radeon_device *rdev = dev->dev_private;
     390             :         struct radeon_encoder *radeon_encoder, *primary;
     391             :         struct radeon_encoder_mst *mst_enc;
     392             :         struct radeon_encoder_atom_dig *dig_enc;
     393             :         struct radeon_connector *radeon_connector;
     394             :         struct drm_crtc *crtc;
     395             :         struct radeon_crtc *radeon_crtc;
     396           0 :         int ret, slots;
     397             : 
     398           0 :         if (!ASIC_IS_DCE5(rdev)) {
     399           0 :                 DRM_ERROR("got mst dpms on non-DCE5\n");
     400           0 :                 return;
     401             :         }
     402             : 
     403           0 :         radeon_connector = radeon_mst_find_connector(encoder);
     404           0 :         if (!radeon_connector)
     405           0 :                 return;
     406             : 
     407           0 :         radeon_encoder = to_radeon_encoder(encoder);
     408             : 
     409           0 :         mst_enc = radeon_encoder->enc_priv;
     410             : 
     411           0 :         primary = mst_enc->primary;
     412             : 
     413           0 :         dig_enc = primary->enc_priv;
     414             : 
     415           0 :         crtc = encoder->crtc;
     416             :         DRM_DEBUG_KMS("got connector %d\n", dig_enc->active_mst_links);
     417             : 
     418           0 :         switch (mode) {
     419             :         case DRM_MODE_DPMS_ON:
     420           0 :                 dig_enc->active_mst_links++;
     421             : 
     422           0 :                 radeon_crtc = to_radeon_crtc(crtc);
     423             : 
     424           0 :                 if (dig_enc->active_mst_links == 1) {
     425           0 :                         mst_enc->fe = dig_enc->dig_encoder;
     426           0 :                         mst_enc->fe_from_be = true;
     427           0 :                         atombios_set_mst_encoder_crtc_source(encoder, mst_enc->fe);
     428             : 
     429           0 :                         atombios_dig_encoder_setup(&primary->base, ATOM_ENCODER_CMD_SETUP, 0);
     430           0 :                         atombios_dig_transmitter_setup2(&primary->base, ATOM_TRANSMITTER_ACTION_ENABLE,
     431           0 :                                                         0, 0, dig_enc->dig_encoder);
     432             : 
     433           0 :                         if (radeon_dp_needs_link_train(mst_enc->connector) ||
     434           0 :                             dig_enc->active_mst_links == 1) {
     435           0 :                                 radeon_dp_link_train(&primary->base, &mst_enc->connector->base);
     436           0 :                         }
     437             : 
     438             :                 } else {
     439           0 :                         mst_enc->fe = radeon_atom_pick_dig_encoder(encoder, radeon_crtc->crtc_id);
     440           0 :                         if (mst_enc->fe == -1)
     441           0 :                                 DRM_ERROR("failed to get frontend for dig encoder\n");
     442           0 :                         mst_enc->fe_from_be = false;
     443           0 :                         atombios_set_mst_encoder_crtc_source(encoder, mst_enc->fe);
     444             :                 }
     445             : 
     446             :                 DRM_DEBUG_KMS("dig encoder is %d %d %d\n", dig_enc->dig_encoder,
     447             :                               dig_enc->linkb, radeon_crtc->crtc_id);
     448             : 
     449           0 :                 ret = drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
     450           0 :                                                radeon_connector->port,
     451           0 :                                                mst_enc->pbn, &slots);
     452           0 :                 ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
     453             : 
     454           0 :                 radeon_dp_mst_set_be_cntl(primary, mst_enc,
     455           0 :                                           radeon_connector->mst_port->hpd.hpd, true);
     456             : 
     457           0 :                 mst_enc->enc_active = true;
     458           0 :                 radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary);
     459           0 :                 radeon_dp_mst_set_vcp_size(radeon_encoder, slots, 0);
     460             : 
     461           0 :                 atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0,
     462           0 :                                             mst_enc->fe);
     463           0 :                 ret = drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
     464             : 
     465           0 :                 ret = drm_dp_update_payload_part2(&radeon_connector->mst_port->mst_mgr);
     466             : 
     467           0 :                 break;
     468             :         case DRM_MODE_DPMS_STANDBY:
     469             :         case DRM_MODE_DPMS_SUSPEND:
     470             :         case DRM_MODE_DPMS_OFF:
     471           0 :                 DRM_ERROR("DPMS OFF %d\n", dig_enc->active_mst_links);
     472             : 
     473           0 :                 if (!mst_enc->enc_active)
     474           0 :                         return;
     475             : 
     476           0 :                 drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
     477           0 :                 ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr);
     478             : 
     479           0 :                 drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
     480             :                 /* and this can also fail */
     481           0 :                 drm_dp_update_payload_part2(&radeon_connector->mst_port->mst_mgr);
     482             : 
     483           0 :                 drm_dp_mst_deallocate_vcpi(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
     484             : 
     485           0 :                 mst_enc->enc_active = false;
     486           0 :                 radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary);
     487             : 
     488           0 :                 radeon_dp_mst_set_be_cntl(primary, mst_enc,
     489           0 :                                           radeon_connector->mst_port->hpd.hpd, false);
     490           0 :                 atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0,
     491           0 :                                             mst_enc->fe);
     492             : 
     493           0 :                 if (!mst_enc->fe_from_be)
     494           0 :                         radeon_atom_release_dig_encoder(rdev, mst_enc->fe);
     495             : 
     496           0 :                 mst_enc->fe_from_be = false;
     497           0 :                 dig_enc->active_mst_links--;
     498             :                 if (dig_enc->active_mst_links == 0) {
     499             :                         /* drop link */
     500             :                 }
     501             : 
     502           0 :                 break;
     503             :         }
     504             : 
     505           0 : }
     506             : 
     507           0 : static bool radeon_mst_mode_fixup(struct drm_encoder *encoder,
     508             :                                    const struct drm_display_mode *mode,
     509             :                                    struct drm_display_mode *adjusted_mode)
     510             : {
     511             :         struct radeon_encoder_mst *mst_enc;
     512           0 :         struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
     513             :         int bpp = 24;
     514             : 
     515           0 :         mst_enc = radeon_encoder->enc_priv;
     516             : 
     517           0 :         mst_enc->pbn = drm_dp_calc_pbn_mode(adjusted_mode->clock, bpp);
     518             : 
     519           0 :         mst_enc->primary->active_device = mst_enc->primary->devices & mst_enc->connector->devices;
     520             :         DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
     521             :                       mst_enc->primary->active_device, mst_enc->primary->devices,
     522             :                       mst_enc->connector->devices, mst_enc->primary->base.encoder_type);
     523             : 
     524             : 
     525           0 :         drm_mode_set_crtcinfo(adjusted_mode, 0);
     526             :         {
     527             :           struct radeon_connector_atom_dig *dig_connector;
     528           0 :           dig_connector = mst_enc->connector->con_priv;
     529           0 :           dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd);
     530           0 :           dig_connector->dp_clock = drm_dp_max_link_rate(dig_connector->dpcd);
     531             :           DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector,
     532             :                         dig_connector->dp_lane_count, dig_connector->dp_clock);
     533             :         }
     534           0 :         return true;
     535             : }
     536             : 
     537           0 : static void radeon_mst_encoder_prepare(struct drm_encoder *encoder)
     538             : {
     539             :         struct radeon_connector *radeon_connector;
     540             :         struct radeon_encoder *radeon_encoder, *primary;
     541             :         struct radeon_encoder_mst *mst_enc;
     542             :         struct radeon_encoder_atom_dig *dig_enc;
     543             : 
     544           0 :         radeon_connector = radeon_mst_find_connector(encoder);
     545           0 :         if (!radeon_connector) {
     546             :                 DRM_DEBUG_KMS("failed to find connector %p\n", encoder);
     547           0 :                 return;
     548             :         }
     549           0 :         radeon_encoder = to_radeon_encoder(encoder);
     550             : 
     551           0 :         radeon_mst_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
     552             : 
     553           0 :         mst_enc = radeon_encoder->enc_priv;
     554             : 
     555           0 :         primary = mst_enc->primary;
     556             : 
     557           0 :         dig_enc = primary->enc_priv;
     558             : 
     559           0 :         mst_enc->port = radeon_connector->port;
     560             : 
     561           0 :         if (dig_enc->dig_encoder == -1) {
     562           0 :                 dig_enc->dig_encoder = radeon_atom_pick_dig_encoder(&primary->base, -1);
     563           0 :                 primary->offset = radeon_atom_set_enc_offset(dig_enc->dig_encoder);
     564           0 :                 atombios_set_mst_encoder_crtc_source(encoder, dig_enc->dig_encoder);
     565             : 
     566             : 
     567           0 :         }
     568             :         DRM_DEBUG_KMS("%d %d\n", dig_enc->dig_encoder, primary->offset);
     569           0 : }
     570             : 
     571             : static void
     572           0 : radeon_mst_encoder_mode_set(struct drm_encoder *encoder,
     573             :                              struct drm_display_mode *mode,
     574             :                              struct drm_display_mode *adjusted_mode)
     575             : {
     576             :         DRM_DEBUG_KMS("\n");
     577           0 : }
     578             : 
     579           0 : static void radeon_mst_encoder_commit(struct drm_encoder *encoder)
     580             : {
     581           0 :         radeon_mst_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
     582             :         DRM_DEBUG_KMS("\n");
     583           0 : }
     584             : 
     585             : static const struct drm_encoder_helper_funcs radeon_mst_helper_funcs = {
     586             :         .dpms = radeon_mst_encoder_dpms,
     587             :         .mode_fixup = radeon_mst_mode_fixup,
     588             :         .prepare = radeon_mst_encoder_prepare,
     589             :         .mode_set = radeon_mst_encoder_mode_set,
     590             :         .commit = radeon_mst_encoder_commit,
     591             : };
     592             : 
     593           0 : void radeon_dp_mst_encoder_destroy(struct drm_encoder *encoder)
     594             : {
     595           0 :         drm_encoder_cleanup(encoder);
     596           0 :         kfree(encoder);
     597           0 : }
     598             : 
     599             : static const struct drm_encoder_funcs radeon_dp_mst_enc_funcs = {
     600             :         .destroy = radeon_dp_mst_encoder_destroy,
     601             : };
     602             : 
     603             : static struct radeon_encoder *
     604           0 : radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector)
     605             : {
     606           0 :         struct drm_device *dev = connector->base.dev;
     607           0 :         struct radeon_device *rdev = dev->dev_private;
     608             :         struct radeon_encoder *radeon_encoder;
     609             :         struct radeon_encoder_mst *mst_enc;
     610             :         struct drm_encoder *encoder;
     611           0 :         const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private;
     612           0 :         struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base);
     613             : 
     614             :         DRM_DEBUG_KMS("enc master is %p\n", enc_master);
     615           0 :         radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL);
     616           0 :         if (!radeon_encoder)
     617           0 :                 return NULL;
     618             : 
     619           0 :         radeon_encoder->enc_priv = kzalloc(sizeof(*mst_enc), GFP_KERNEL);
     620           0 :         if (!radeon_encoder->enc_priv) {
     621           0 :                 kfree(radeon_encoder);
     622           0 :                 return NULL;
     623             :         }
     624           0 :         encoder = &radeon_encoder->base;
     625           0 :         switch (rdev->num_crtc) {
     626             :         case 1:
     627           0 :                 encoder->possible_crtcs = 0x1;
     628           0 :                 break;
     629             :         case 2:
     630             :         default:
     631           0 :                 encoder->possible_crtcs = 0x3;
     632           0 :                 break;
     633             :         case 4:
     634           0 :                 encoder->possible_crtcs = 0xf;
     635           0 :                 break;
     636             :         case 6:
     637           0 :                 encoder->possible_crtcs = 0x3f;
     638           0 :                 break;
     639             :         }
     640             : 
     641           0 :         drm_encoder_init(dev, &radeon_encoder->base, &radeon_dp_mst_enc_funcs,
     642             :                          DRM_MODE_ENCODER_DPMST);
     643           0 :         drm_encoder_helper_add(encoder, &radeon_mst_helper_funcs);
     644             : 
     645           0 :         mst_enc = radeon_encoder->enc_priv;
     646           0 :         mst_enc->connector = connector;
     647           0 :         mst_enc->primary = to_radeon_encoder(enc_master);
     648           0 :         radeon_encoder->is_mst_encoder = true;
     649           0 :         return radeon_encoder;
     650           0 : }
     651             : 
     652             : int
     653           0 : radeon_dp_mst_init(struct radeon_connector *radeon_connector)
     654             : {
     655           0 :         struct drm_device *dev = radeon_connector->base.dev;
     656             : 
     657           0 :         if (!radeon_connector->ddc_bus->has_aux)
     658           0 :                 return 0;
     659             : 
     660           0 :         radeon_connector->mst_mgr.cbs = &mst_cbs;
     661           0 :         return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev->dev,
     662           0 :                                             &radeon_connector->ddc_bus->aux, 16, 6,
     663           0 :                                             radeon_connector->base.base.id);
     664           0 : }
     665             : 
     666             : int
     667           0 : radeon_dp_mst_probe(struct radeon_connector *radeon_connector)
     668             : {
     669           0 :         struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
     670           0 :         struct drm_device *dev = radeon_connector->base.dev;
     671           0 :         struct radeon_device *rdev = dev->dev_private;
     672             :         int ret;
     673           0 :         u8 msg[1];
     674             : 
     675           0 :         if (!radeon_mst)
     676           0 :                 return 0;
     677             : 
     678           0 :         if (!ASIC_IS_DCE5(rdev))
     679           0 :                 return 0;
     680             : 
     681           0 :         if (dig_connector->dpcd[DP_DPCD_REV] < 0x12)
     682           0 :                 return 0;
     683             : 
     684           0 :         ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_MSTM_CAP, msg,
     685             :                                1);
     686           0 :         if (ret) {
     687           0 :                 if (msg[0] & DP_MST_CAP) {
     688             :                         DRM_DEBUG_KMS("Sink is MST capable\n");
     689           0 :                         dig_connector->is_mst = true;
     690           0 :                 } else {
     691             :                         DRM_DEBUG_KMS("Sink is not MST capable\n");
     692           0 :                         dig_connector->is_mst = false;
     693             :                 }
     694             : 
     695             :         }
     696           0 :         drm_dp_mst_topology_mgr_set_mst(&radeon_connector->mst_mgr,
     697           0 :                                         dig_connector->is_mst);
     698           0 :         return dig_connector->is_mst;
     699           0 : }
     700             : 
     701             : int
     702           0 : radeon_dp_mst_check_status(struct radeon_connector *radeon_connector)
     703             : {
     704           0 :         struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
     705             :         int retry;
     706             : 
     707           0 :         if (dig_connector->is_mst) {
     708           0 :                 u8 esi[16] = { 0 };
     709             :                 int dret;
     710             :                 int ret = 0;
     711           0 :                 bool handled;
     712             : 
     713           0 :                 dret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux,
     714           0 :                                        DP_SINK_COUNT_ESI, esi, 8);
     715             : go_again:
     716           0 :                 if (dret == 8) {
     717             :                         DRM_DEBUG_KMS("got esi %02x %02x %02x\n", esi[0], esi[1], esi[2]);
     718           0 :                         ret = drm_dp_mst_hpd_irq(&radeon_connector->mst_mgr, esi, &handled);
     719             : 
     720           0 :                         if (handled) {
     721           0 :                                 for (retry = 0; retry < 3; retry++) {
     722             :                                         int wret;
     723           0 :                                         wret = drm_dp_dpcd_write(&radeon_connector->ddc_bus->aux,
     724           0 :                                                                  DP_SINK_COUNT_ESI + 1, &esi[1], 3);
     725           0 :                                         if (wret == 3)
     726           0 :                                                 break;
     727           0 :                                 }
     728             : 
     729           0 :                                 dret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux,
     730             :                                                         DP_SINK_COUNT_ESI, esi, 8);
     731           0 :                                 if (dret == 8) {
     732             :                                         DRM_DEBUG_KMS("got esi2 %02x %02x %02x\n", esi[0], esi[1], esi[2]);
     733           0 :                                         goto go_again;
     734             :                                 }
     735             :                         } else
     736             :                                 ret = 0;
     737             : 
     738           0 :                         return ret;
     739             :                 } else {
     740             :                         DRM_DEBUG_KMS("failed to get ESI - device may have failed %d\n", ret);
     741           0 :                         dig_connector->is_mst = false;
     742           0 :                         drm_dp_mst_topology_mgr_set_mst(&radeon_connector->mst_mgr,
     743             :                                                         dig_connector->is_mst);
     744             :                         /* send a hotplug event */
     745             :                 }
     746           0 :         }
     747           0 :         return -EINVAL;
     748           0 : }
     749             : 
     750             : #if defined(CONFIG_DEBUG_FS)
     751             : 
     752             : static int radeon_debugfs_mst_info(struct seq_file *m, void *data)
     753             : {
     754             :         struct drm_info_node *node = (struct drm_info_node *)m->private;
     755             :         struct drm_device *dev = node->minor->dev;
     756             :         struct drm_connector *connector;
     757             :         struct radeon_connector *radeon_connector;
     758             :         struct radeon_connector_atom_dig *dig_connector;
     759             :         int i;
     760             : 
     761             :         drm_modeset_lock_all(dev);
     762             :         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
     763             :                 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
     764             :                         continue;
     765             : 
     766             :                 radeon_connector = to_radeon_connector(connector);
     767             :                 dig_connector = radeon_connector->con_priv;
     768             :                 if (radeon_connector->is_mst_connector)
     769             :                         continue;
     770             :                 if (!dig_connector->is_mst)
     771             :                         continue;
     772             :                 drm_dp_mst_dump_topology(m, &radeon_connector->mst_mgr);
     773             : 
     774             :                 for (i = 0; i < radeon_connector->enabled_attribs; i++)
     775             :                         seq_printf(m, "attrib %d: %d %d\n", i,
     776             :                                    radeon_connector->cur_stream_attribs[i].fe,
     777             :                                    radeon_connector->cur_stream_attribs[i].slots);
     778             :         }
     779             :         drm_modeset_unlock_all(dev);
     780             :         return 0;
     781             : }
     782             : 
     783             : static struct drm_info_list radeon_debugfs_mst_list[] = {
     784             :         {"radeon_mst_info", &radeon_debugfs_mst_info, 0, NULL},
     785             : };
     786             : #endif
     787             : 
     788           0 : int radeon_mst_debugfs_init(struct radeon_device *rdev)
     789             : {
     790             : #if defined(CONFIG_DEBUG_FS)
     791             :         return radeon_debugfs_add_files(rdev, radeon_debugfs_mst_list, 1);
     792             : #endif
     793           0 :         return 0;
     794             : }

Generated by: LCOV version 1.13