1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include <linux/version.h> 27 #include <drm/drm_atomic_helper.h> 28 #include "dm_services.h" 29 #include "amdgpu.h" 30 #include "amdgpu_dm.h" 31 #include "amdgpu_dm_mst_types.h" 32 33 #include "dc.h" 34 #include "dm_helpers.h" 35 36 #include "dc_link_ddc.h" 37 38 #include "i2caux_interface.h" 39 #if defined(CONFIG_DEBUG_FS) 40 #include "amdgpu_dm_debugfs.h" 41 #endif 42 /* #define TRACE_DPCD */ 43 44 #ifdef TRACE_DPCD 45 #define SIDE_BAND_MSG(address) (address >= DP_SIDEBAND_MSG_DOWN_REQ_BASE && address < DP_SINK_COUNT_ESI) 46 47 static inline char *side_band_msg_type_to_str(uint32_t address) 48 { 49 static char str[10] = {0}; 50 51 if (address < DP_SIDEBAND_MSG_UP_REP_BASE) 52 strcpy(str, "DOWN_REQ"); 53 else if (address < DP_SIDEBAND_MSG_DOWN_REP_BASE) 54 strcpy(str, "UP_REP"); 55 else if (address < DP_SIDEBAND_MSG_UP_REQ_BASE) 56 strcpy(str, "DOWN_REP"); 57 else 58 strcpy(str, "UP_REQ"); 59 60 return str; 61 } 62 63 static void log_dpcd(uint8_t type, 64 uint32_t address, 65 uint8_t *data, 66 uint32_t size, 67 bool res) 68 { 69 DRM_DEBUG_KMS("Op: %s, addr: %04x, SideBand Msg: %s, Op res: %s\n", 70 (type == DP_AUX_NATIVE_READ) || 71 (type == DP_AUX_I2C_READ) ? 72 "Read" : "Write", 73 address, 74 SIDE_BAND_MSG(address) ? 75 side_band_msg_type_to_str(address) : "Nop", 76 res ? "OK" : "Fail"); 77 78 if (res) { 79 print_hex_dump(KERN_INFO, "Body: ", DUMP_PREFIX_NONE, 16, 1, data, size, false); 80 } 81 } 82 #endif 83 84 static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, 85 struct drm_dp_aux_msg *msg) 86 { 87 ssize_t result = 0; 88 struct aux_payload payload; 89 enum aux_channel_operation_result operation_result; 90 91 if (WARN_ON(msg->size > 16)) 92 return -E2BIG; 93 94 payload.address = msg->address; 95 payload.data = msg->buffer; 96 payload.length = msg->size; 97 payload.reply = &msg->reply; 98 payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0; 99 payload.write = (msg->request & DP_AUX_I2C_READ) == 0; 100 payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0; 101 payload.defer_delay = 0; 102 103 result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, 104 &operation_result); 105 106 if (payload.write) 107 result = msg->size; 108 109 if (result < 0) 110 switch (operation_result) { 111 case AUX_CHANNEL_OPERATION_SUCCEEDED: 112 break; 113 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 114 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: 115 result = -EIO; 116 break; 117 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: 118 case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE: 119 result = -EBUSY; 120 break; 121 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: 122 result = -ETIMEDOUT; 123 break; 124 } 125 126 return result; 127 } 128 129 static void 130 dm_dp_mst_connector_destroy(struct drm_connector *connector) 131 { 132 struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); 133 struct amdgpu_encoder *amdgpu_encoder = amdgpu_dm_connector->mst_encoder; 134 135 kfree(amdgpu_dm_connector->edid); 136 amdgpu_dm_connector->edid = NULL; 137 138 drm_encoder_cleanup(&amdgpu_encoder->base); 139 kfree(amdgpu_encoder); 140 drm_connector_cleanup(connector); 141 drm_dp_mst_put_port_malloc(amdgpu_dm_connector->port); 142 kfree(amdgpu_dm_connector); 143 } 144 145 static int 146 amdgpu_dm_mst_connector_late_register(struct drm_connector *connector) 147 { 148 struct amdgpu_dm_connector *amdgpu_dm_connector = 149 to_amdgpu_dm_connector(connector); 150 struct drm_dp_mst_port *port = amdgpu_dm_connector->port; 151 152 #if defined(CONFIG_DEBUG_FS) 153 connector_debugfs_init(amdgpu_dm_connector); 154 amdgpu_dm_connector->debugfs_dpcd_address = 0; 155 amdgpu_dm_connector->debugfs_dpcd_size = 0; 156 #endif 157 158 return drm_dp_mst_connector_late_register(connector, port); 159 } 160 161 static void 162 amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector) 163 { 164 struct amdgpu_dm_connector *amdgpu_dm_connector = 165 to_amdgpu_dm_connector(connector); 166 struct drm_dp_mst_port *port = amdgpu_dm_connector->port; 167 168 drm_dp_mst_connector_early_unregister(connector, port); 169 } 170 171 static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { 172 .fill_modes = drm_helper_probe_single_connector_modes, 173 .destroy = dm_dp_mst_connector_destroy, 174 .reset = amdgpu_dm_connector_funcs_reset, 175 .atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state, 176 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 177 .atomic_set_property = amdgpu_dm_connector_atomic_set_property, 178 .atomic_get_property = amdgpu_dm_connector_atomic_get_property, 179 .late_register = amdgpu_dm_mst_connector_late_register, 180 .early_unregister = amdgpu_dm_mst_connector_early_unregister, 181 }; 182 183 static int dm_dp_mst_get_modes(struct drm_connector *connector) 184 { 185 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 186 int ret = 0; 187 188 if (!aconnector) 189 return drm_add_edid_modes(connector, NULL); 190 191 if (!aconnector->edid) { 192 struct edid *edid; 193 edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); 194 195 if (!edid) { 196 drm_connector_update_edid_property( 197 &aconnector->base, 198 NULL); 199 return ret; 200 } 201 202 aconnector->edid = edid; 203 } 204 205 if (aconnector->dc_sink && aconnector->dc_sink->sink_signal == SIGNAL_TYPE_VIRTUAL) { 206 dc_sink_release(aconnector->dc_sink); 207 aconnector->dc_sink = NULL; 208 } 209 210 if (!aconnector->dc_sink) { 211 struct dc_sink *dc_sink; 212 struct dc_sink_init_data init_params = { 213 .link = aconnector->dc_link, 214 .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; 215 dc_sink = dc_link_add_remote_sink( 216 aconnector->dc_link, 217 (uint8_t *)aconnector->edid, 218 (aconnector->edid->extensions + 1) * EDID_LENGTH, 219 &init_params); 220 221 dc_sink->priv = aconnector; 222 /* dc_link_add_remote_sink returns a new reference */ 223 aconnector->dc_sink = dc_sink; 224 225 if (aconnector->dc_sink) 226 amdgpu_dm_update_freesync_caps( 227 connector, aconnector->edid); 228 229 } 230 231 drm_connector_update_edid_property( 232 &aconnector->base, aconnector->edid); 233 234 ret = drm_add_edid_modes(connector, aconnector->edid); 235 236 return ret; 237 } 238 239 static struct drm_encoder * 240 dm_mst_atomic_best_encoder(struct drm_connector *connector, 241 struct drm_connector_state *connector_state) 242 { 243 return &to_amdgpu_dm_connector(connector)->mst_encoder->base; 244 } 245 246 static int 247 dm_dp_mst_detect(struct drm_connector *connector, 248 struct drm_modeset_acquire_ctx *ctx, bool force) 249 { 250 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 251 struct amdgpu_dm_connector *master = aconnector->mst_port; 252 253 return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr, 254 aconnector->port); 255 } 256 257 static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs = { 258 .get_modes = dm_dp_mst_get_modes, 259 .mode_valid = amdgpu_dm_connector_mode_valid, 260 .atomic_best_encoder = dm_mst_atomic_best_encoder, 261 .detect_ctx = dm_dp_mst_detect, 262 }; 263 264 static void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder) 265 { 266 drm_encoder_cleanup(encoder); 267 kfree(encoder); 268 } 269 270 static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { 271 .destroy = amdgpu_dm_encoder_destroy, 272 }; 273 274 static struct amdgpu_encoder * 275 dm_dp_create_fake_mst_encoder(struct amdgpu_dm_connector *connector) 276 { 277 struct drm_device *dev = connector->base.dev; 278 struct amdgpu_device *adev = dev->dev_private; 279 struct amdgpu_encoder *amdgpu_encoder; 280 struct drm_encoder *encoder; 281 282 amdgpu_encoder = kzalloc(sizeof(*amdgpu_encoder), GFP_KERNEL); 283 if (!amdgpu_encoder) 284 return NULL; 285 286 encoder = &amdgpu_encoder->base; 287 encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev); 288 289 drm_encoder_init( 290 dev, 291 &amdgpu_encoder->base, 292 &amdgpu_dm_encoder_funcs, 293 DRM_MODE_ENCODER_DPMST, 294 NULL); 295 296 drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs); 297 298 return amdgpu_encoder; 299 } 300 301 static struct drm_connector * 302 dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, 303 struct drm_dp_mst_port *port, 304 const char *pathprop) 305 { 306 struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); 307 struct drm_device *dev = master->base.dev; 308 struct amdgpu_device *adev = dev->dev_private; 309 struct amdgpu_dm_connector *aconnector; 310 struct drm_connector *connector; 311 312 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); 313 if (!aconnector) 314 return NULL; 315 316 connector = &aconnector->base; 317 aconnector->port = port; 318 aconnector->mst_port = master; 319 320 if (drm_connector_init( 321 dev, 322 connector, 323 &dm_dp_mst_connector_funcs, 324 DRM_MODE_CONNECTOR_DisplayPort)) { 325 kfree(aconnector); 326 return NULL; 327 } 328 drm_connector_helper_add(connector, &dm_dp_mst_connector_helper_funcs); 329 330 amdgpu_dm_connector_init_helper( 331 &adev->dm, 332 aconnector, 333 DRM_MODE_CONNECTOR_DisplayPort, 334 master->dc_link, 335 master->connector_id); 336 337 aconnector->mst_encoder = dm_dp_create_fake_mst_encoder(master); 338 drm_connector_attach_encoder(&aconnector->base, 339 &aconnector->mst_encoder->base); 340 341 drm_object_attach_property( 342 &connector->base, 343 dev->mode_config.path_property, 344 0); 345 drm_object_attach_property( 346 &connector->base, 347 dev->mode_config.tile_property, 348 0); 349 350 drm_connector_set_path_property(connector, pathprop); 351 352 /* 353 * Initialize connector state before adding the connectror to drm and 354 * framebuffer lists 355 */ 356 amdgpu_dm_connector_funcs_reset(connector); 357 358 DRM_INFO("DM_MST: added connector: %p [id: %d] [master: %p]\n", 359 aconnector, connector->base.id, aconnector->mst_port); 360 361 drm_dp_mst_get_port_malloc(port); 362 363 DRM_DEBUG_KMS(":%d\n", connector->base.id); 364 365 return connector; 366 } 367 368 static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, 369 struct drm_connector *connector) 370 { 371 struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); 372 struct drm_device *dev = master->base.dev; 373 struct amdgpu_device *adev = dev->dev_private; 374 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 375 376 DRM_INFO("DM_MST: Disabling connector: %p [id: %d] [master: %p]\n", 377 aconnector, connector->base.id, aconnector->mst_port); 378 379 if (aconnector->dc_sink) { 380 amdgpu_dm_update_freesync_caps(connector, NULL); 381 dc_link_remove_remote_sink(aconnector->dc_link, 382 aconnector->dc_sink); 383 dc_sink_release(aconnector->dc_sink); 384 aconnector->dc_sink = NULL; 385 } 386 387 drm_connector_unregister(connector); 388 if (adev->mode_info.rfbdev) 389 drm_fb_helper_remove_one_connector(&adev->mode_info.rfbdev->helper, connector); 390 drm_connector_put(connector); 391 } 392 393 static void dm_dp_mst_register_connector(struct drm_connector *connector) 394 { 395 struct drm_device *dev = connector->dev; 396 struct amdgpu_device *adev = dev->dev_private; 397 398 if (adev->mode_info.rfbdev) 399 drm_fb_helper_add_one_connector(&adev->mode_info.rfbdev->helper, connector); 400 else 401 DRM_ERROR("adev->mode_info.rfbdev is NULL\n"); 402 403 drm_connector_register(connector); 404 } 405 406 static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { 407 .add_connector = dm_dp_add_mst_connector, 408 .destroy_connector = dm_dp_destroy_mst_connector, 409 .register_connector = dm_dp_mst_register_connector 410 }; 411 412 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, 413 struct amdgpu_dm_connector *aconnector) 414 { 415 aconnector->dm_dp_aux.aux.name = "dmdc"; 416 aconnector->dm_dp_aux.aux.dev = aconnector->base.kdev; 417 aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer; 418 aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc; 419 420 drm_dp_aux_register(&aconnector->dm_dp_aux.aux); 421 drm_dp_cec_register_connector(&aconnector->dm_dp_aux.aux, 422 &aconnector->base); 423 424 if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) 425 return; 426 427 aconnector->mst_mgr.cbs = &dm_mst_cbs; 428 drm_dp_mst_topology_mgr_init( 429 &aconnector->mst_mgr, 430 dm->adev->ddev, 431 &aconnector->dm_dp_aux.aux, 432 16, 433 4, 434 aconnector->connector_id); 435 } 436 437