1 /* 2 * Copyright 2015 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/string.h> 27 #include <linux/acpi.h> 28 #include <linux/version.h> 29 #include <linux/i2c.h> 30 31 #include <drm/drmP.h> 32 #include <drm/drm_crtc_helper.h> 33 #include <drm/amdgpu_drm.h> 34 #include <drm/drm_edid.h> 35 36 #include "dm_services.h" 37 #include "amdgpu.h" 38 #include "dc.h" 39 #include "amdgpu_dm.h" 40 #include "amdgpu_dm_irq.h" 41 42 #include "dm_helpers.h" 43 44 /* dm_helpers_parse_edid_caps 45 * 46 * Parse edid caps 47 * 48 * @edid: [in] pointer to edid 49 * edid_caps: [in] pointer to edid caps 50 * @return 51 * void 52 * */ 53 enum dc_edid_status dm_helpers_parse_edid_caps( 54 struct dc_context *ctx, 55 const struct dc_edid *edid, 56 struct dc_edid_caps *edid_caps) 57 { 58 struct edid *edid_buf = (struct edid *) edid->raw_edid; 59 struct cea_sad *sads; 60 int sad_count = -1; 61 int sadb_count = -1; 62 int i = 0; 63 int j = 0; 64 uint8_t *sadb = NULL; 65 66 enum dc_edid_status result = EDID_OK; 67 68 if (!edid_caps || !edid) 69 return EDID_BAD_INPUT; 70 71 if (!drm_edid_is_valid(edid_buf)) 72 result = EDID_BAD_CHECKSUM; 73 74 edid_caps->manufacturer_id = (uint16_t) edid_buf->mfg_id[0] | 75 ((uint16_t) edid_buf->mfg_id[1])<<8; 76 edid_caps->product_id = (uint16_t) edid_buf->prod_code[0] | 77 ((uint16_t) edid_buf->prod_code[1])<<8; 78 edid_caps->serial_number = edid_buf->serial; 79 edid_caps->manufacture_week = edid_buf->mfg_week; 80 edid_caps->manufacture_year = edid_buf->mfg_year; 81 82 /* One of the four detailed_timings stores the monitor name. It's 83 * stored in an array of length 13. */ 84 for (i = 0; i < 4; i++) { 85 if (edid_buf->detailed_timings[i].data.other_data.type == 0xfc) { 86 while (j < 13 && edid_buf->detailed_timings[i].data.other_data.data.str.str[j]) { 87 if (edid_buf->detailed_timings[i].data.other_data.data.str.str[j] == '\n') 88 break; 89 90 edid_caps->display_name[j] = 91 edid_buf->detailed_timings[i].data.other_data.data.str.str[j]; 92 j++; 93 } 94 } 95 } 96 97 edid_caps->edid_hdmi = drm_detect_hdmi_monitor( 98 (struct edid *) edid->raw_edid); 99 100 sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); 101 if (sad_count <= 0) { 102 DRM_INFO("SADs count is: %d, don't need to read it\n", 103 sad_count); 104 return result; 105 } 106 107 edid_caps->audio_mode_count = sad_count < DC_MAX_AUDIO_DESC_COUNT ? sad_count : DC_MAX_AUDIO_DESC_COUNT; 108 for (i = 0; i < edid_caps->audio_mode_count; ++i) { 109 struct cea_sad *sad = &sads[i]; 110 111 edid_caps->audio_modes[i].format_code = sad->format; 112 edid_caps->audio_modes[i].channel_count = sad->channels; 113 edid_caps->audio_modes[i].sample_rate = sad->freq; 114 edid_caps->audio_modes[i].sample_size = sad->byte2; 115 } 116 117 sadb_count = drm_edid_to_speaker_allocation((struct edid *) edid->raw_edid, &sadb); 118 119 if (sadb_count < 0) { 120 DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sadb_count); 121 sadb_count = 0; 122 } 123 124 if (sadb_count) 125 edid_caps->speaker_flags = sadb[0]; 126 else 127 edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION; 128 129 kfree(sads); 130 kfree(sadb); 131 132 return result; 133 } 134 135 static void get_payload_table( 136 struct amdgpu_dm_connector *aconnector, 137 struct dp_mst_stream_allocation_table *proposed_table) 138 { 139 int i; 140 struct drm_dp_mst_topology_mgr *mst_mgr = 141 &aconnector->mst_port->mst_mgr; 142 143 mutex_lock(&mst_mgr->payload_lock); 144 145 proposed_table->stream_count = 0; 146 147 /* number of active streams */ 148 for (i = 0; i < mst_mgr->max_payloads; i++) { 149 if (mst_mgr->payloads[i].num_slots == 0) 150 break; /* end of vcp_id table */ 151 152 ASSERT(mst_mgr->payloads[i].payload_state != 153 DP_PAYLOAD_DELETE_LOCAL); 154 155 if (mst_mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL || 156 mst_mgr->payloads[i].payload_state == 157 DP_PAYLOAD_REMOTE) { 158 159 struct dp_mst_stream_allocation *sa = 160 &proposed_table->stream_allocations[ 161 proposed_table->stream_count]; 162 163 sa->slot_count = mst_mgr->payloads[i].num_slots; 164 sa->vcp_id = mst_mgr->proposed_vcpis[i]->vcpi; 165 proposed_table->stream_count++; 166 } 167 } 168 169 mutex_unlock(&mst_mgr->payload_lock); 170 } 171 172 /* 173 * Writes payload allocation table in immediate downstream device. 174 */ 175 bool dm_helpers_dp_mst_write_payload_allocation_table( 176 struct dc_context *ctx, 177 const struct dc_stream_state *stream, 178 struct dp_mst_stream_allocation_table *proposed_table, 179 bool enable) 180 { 181 struct amdgpu_dm_connector *aconnector; 182 struct drm_dp_mst_topology_mgr *mst_mgr; 183 struct drm_dp_mst_port *mst_port; 184 int slots = 0; 185 bool ret; 186 int clock; 187 int bpp = 0; 188 int pbn = 0; 189 190 aconnector = stream->sink->priv; 191 192 if (!aconnector || !aconnector->mst_port) 193 return false; 194 195 mst_mgr = &aconnector->mst_port->mst_mgr; 196 197 if (!mst_mgr->mst_state) 198 return false; 199 200 mst_port = aconnector->port; 201 202 if (enable) { 203 clock = stream->timing.pix_clk_khz; 204 205 switch (stream->timing.display_color_depth) { 206 207 case COLOR_DEPTH_666: 208 bpp = 6; 209 break; 210 case COLOR_DEPTH_888: 211 bpp = 8; 212 break; 213 case COLOR_DEPTH_101010: 214 bpp = 10; 215 break; 216 case COLOR_DEPTH_121212: 217 bpp = 12; 218 break; 219 case COLOR_DEPTH_141414: 220 bpp = 14; 221 break; 222 case COLOR_DEPTH_161616: 223 bpp = 16; 224 break; 225 default: 226 ASSERT(bpp != 0); 227 break; 228 } 229 230 bpp = bpp * 3; 231 232 /* TODO need to know link rate */ 233 234 pbn = drm_dp_calc_pbn_mode(clock, bpp); 235 236 slots = drm_dp_find_vcpi_slots(mst_mgr, pbn); 237 ret = drm_dp_mst_allocate_vcpi(mst_mgr, mst_port, pbn, slots); 238 239 if (!ret) 240 return false; 241 242 } else { 243 drm_dp_mst_reset_vcpi_slots(mst_mgr, mst_port); 244 } 245 246 ret = drm_dp_update_payload_part1(mst_mgr); 247 248 /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or 249 * AUX message. The sequence is slot 1-63 allocated sequence for each 250 * stream. AMD ASIC stream slot allocation should follow the same 251 * sequence. copy DRM MST allocation to dc */ 252 253 get_payload_table(aconnector, proposed_table); 254 255 if (ret) 256 return false; 257 258 return true; 259 } 260 261 /* 262 * Polls for ACT (allocation change trigger) handled and sends 263 * ALLOCATE_PAYLOAD message. 264 */ 265 bool dm_helpers_dp_mst_poll_for_allocation_change_trigger( 266 struct dc_context *ctx, 267 const struct dc_stream_state *stream) 268 { 269 struct amdgpu_dm_connector *aconnector; 270 struct drm_dp_mst_topology_mgr *mst_mgr; 271 int ret; 272 273 aconnector = stream->sink->priv; 274 275 if (!aconnector || !aconnector->mst_port) 276 return false; 277 278 mst_mgr = &aconnector->mst_port->mst_mgr; 279 280 if (!mst_mgr->mst_state) 281 return false; 282 283 ret = drm_dp_check_act_status(mst_mgr); 284 285 if (ret) 286 return false; 287 288 return true; 289 } 290 291 bool dm_helpers_dp_mst_send_payload_allocation( 292 struct dc_context *ctx, 293 const struct dc_stream_state *stream, 294 bool enable) 295 { 296 struct amdgpu_dm_connector *aconnector; 297 struct drm_dp_mst_topology_mgr *mst_mgr; 298 struct drm_dp_mst_port *mst_port; 299 int ret; 300 301 aconnector = stream->sink->priv; 302 303 if (!aconnector || !aconnector->mst_port) 304 return false; 305 306 mst_port = aconnector->port; 307 308 mst_mgr = &aconnector->mst_port->mst_mgr; 309 310 if (!mst_mgr->mst_state) 311 return false; 312 313 ret = drm_dp_update_payload_part2(mst_mgr); 314 315 if (ret) 316 return false; 317 318 if (!enable) 319 drm_dp_mst_deallocate_vcpi(mst_mgr, mst_port); 320 321 return true; 322 } 323 324 bool dm_helpers_dc_conn_log(struct dc_context *ctx, struct log_entry *entry, enum dc_log_type event) 325 { 326 return true; 327 } 328 329 void dm_dtn_log_begin(struct dc_context *ctx) 330 {} 331 332 void dm_dtn_log_append_v(struct dc_context *ctx, 333 const char *pMsg, ...) 334 {} 335 336 void dm_dtn_log_end(struct dc_context *ctx) 337 {} 338 339 bool dm_helpers_dp_mst_start_top_mgr( 340 struct dc_context *ctx, 341 const struct dc_link *link, 342 bool boot) 343 { 344 struct amdgpu_dm_connector *aconnector = link->priv; 345 346 if (!aconnector) { 347 DRM_ERROR("Failed to found connector for link!"); 348 return false; 349 } 350 351 if (boot) { 352 DRM_INFO("DM_MST: Differing MST start on aconnector: %p [id: %d]\n", 353 aconnector, aconnector->base.base.id); 354 return true; 355 } 356 357 DRM_INFO("DM_MST: starting TM on aconnector: %p [id: %d]\n", 358 aconnector, aconnector->base.base.id); 359 360 return (drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, true) == 0); 361 } 362 363 void dm_helpers_dp_mst_stop_top_mgr( 364 struct dc_context *ctx, 365 const struct dc_link *link) 366 { 367 struct amdgpu_dm_connector *aconnector = link->priv; 368 369 if (!aconnector) { 370 DRM_ERROR("Failed to found connector for link!"); 371 return; 372 } 373 374 DRM_INFO("DM_MST: stopping TM on aconnector: %p [id: %d]\n", 375 aconnector, aconnector->base.base.id); 376 377 if (aconnector->mst_mgr.mst_state == true) 378 drm_dp_mst_topology_mgr_set_mst(&aconnector->mst_mgr, false); 379 } 380 381 bool dm_helpers_dp_read_dpcd( 382 struct dc_context *ctx, 383 const struct dc_link *link, 384 uint32_t address, 385 uint8_t *data, 386 uint32_t size) 387 { 388 389 struct amdgpu_dm_connector *aconnector = link->priv; 390 391 if (!aconnector) { 392 DRM_ERROR("Failed to found connector for link!"); 393 return false; 394 } 395 396 return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address, 397 data, size) > 0; 398 } 399 400 bool dm_helpers_dp_write_dpcd( 401 struct dc_context *ctx, 402 const struct dc_link *link, 403 uint32_t address, 404 const uint8_t *data, 405 uint32_t size) 406 { 407 struct amdgpu_dm_connector *aconnector = link->priv; 408 409 if (!aconnector) { 410 DRM_ERROR("Failed to found connector for link!"); 411 return false; 412 } 413 414 return drm_dp_dpcd_write(&aconnector->dm_dp_aux.aux, 415 address, (uint8_t *)data, size) > 0; 416 } 417 418 bool dm_helpers_submit_i2c( 419 struct dc_context *ctx, 420 const struct dc_link *link, 421 struct i2c_command *cmd) 422 { 423 struct amdgpu_dm_connector *aconnector = link->priv; 424 struct i2c_msg *msgs; 425 int i = 0; 426 int num = cmd->number_of_payloads; 427 bool result; 428 429 if (!aconnector) { 430 DRM_ERROR("Failed to found connector for link!"); 431 return false; 432 } 433 434 msgs = kzalloc(num * sizeof(struct i2c_msg), GFP_KERNEL); 435 436 if (!msgs) 437 return false; 438 439 for (i = 0; i < num; i++) { 440 msgs[i].flags = cmd->payloads[i].write ? 0 : I2C_M_RD; 441 msgs[i].addr = cmd->payloads[i].address; 442 msgs[i].len = cmd->payloads[i].length; 443 msgs[i].buf = cmd->payloads[i].data; 444 } 445 446 result = i2c_transfer(&aconnector->i2c->base, msgs, num) == num; 447 448 kfree(msgs); 449 450 return result; 451 } 452 453 enum dc_edid_status dm_helpers_read_local_edid( 454 struct dc_context *ctx, 455 struct dc_link *link, 456 struct dc_sink *sink) 457 { 458 struct amdgpu_dm_connector *aconnector = link->priv; 459 struct i2c_adapter *ddc; 460 int retry = 3; 461 enum dc_edid_status edid_status; 462 struct edid *edid; 463 464 if (link->aux_mode) 465 ddc = &aconnector->dm_dp_aux.aux.ddc; 466 else 467 ddc = &aconnector->i2c->base; 468 469 /* some dongles read edid incorrectly the first time, 470 * do check sum and retry to make sure read correct edid. 471 */ 472 do { 473 474 edid = drm_get_edid(&aconnector->base, ddc); 475 476 if (!edid) 477 return EDID_NO_RESPONSE; 478 479 sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1); 480 memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length); 481 482 /* We don't need the original edid anymore */ 483 kfree(edid); 484 485 edid_status = dm_helpers_parse_edid_caps( 486 ctx, 487 &sink->dc_edid, 488 &sink->edid_caps); 489 490 } while (edid_status == EDID_BAD_CHECKSUM && --retry > 0); 491 492 if (edid_status != EDID_OK) 493 DRM_ERROR("EDID err: %d, on connector: %s", 494 edid_status, 495 aconnector->base.name); 496 497 return edid_status; 498 } 499