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 <drm/drm_crtc.h> 27 #include <drm/drm_vblank.h> 28 29 #include "amdgpu.h" 30 #include "amdgpu_dm.h" 31 #include "dc.h" 32 #include "amdgpu_securedisplay.h" 33 #include "amdgpu_dm_psr.h" 34 35 static const char *const pipe_crc_sources[] = { 36 "none", 37 "crtc", 38 "crtc dither", 39 "dprx", 40 "dprx dither", 41 "auto", 42 }; 43 44 static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source) 45 { 46 if (!source || !strcmp(source, "none")) 47 return AMDGPU_DM_PIPE_CRC_SOURCE_NONE; 48 if (!strcmp(source, "auto") || !strcmp(source, "crtc")) 49 return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC; 50 if (!strcmp(source, "dprx")) 51 return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX; 52 if (!strcmp(source, "crtc dither")) 53 return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER; 54 if (!strcmp(source, "dprx dither")) 55 return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER; 56 57 return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID; 58 } 59 60 static bool dm_is_crc_source_crtc(enum amdgpu_dm_pipe_crc_source src) 61 { 62 return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) || 63 (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER); 64 } 65 66 static bool dm_is_crc_source_dprx(enum amdgpu_dm_pipe_crc_source src) 67 { 68 return (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) || 69 (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER); 70 } 71 72 static bool dm_need_crc_dither(enum amdgpu_dm_pipe_crc_source src) 73 { 74 return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER) || 75 (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER) || 76 (src == AMDGPU_DM_PIPE_CRC_SOURCE_NONE); 77 } 78 79 const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc, 80 size_t *count) 81 { 82 *count = ARRAY_SIZE(pipe_crc_sources); 83 return pipe_crc_sources; 84 } 85 86 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY 87 static void update_phy_id_mapping(struct amdgpu_device *adev) 88 { 89 struct drm_device *ddev = adev_to_drm(adev); 90 struct amdgpu_display_manager *dm = &adev->dm; 91 struct drm_connector *connector; 92 struct amdgpu_dm_connector *aconnector; 93 struct amdgpu_dm_connector *sort_connector[AMDGPU_DM_MAX_CRTC] = {NULL}; 94 struct drm_connector_list_iter iter; 95 uint8_t idx = 0, idx_2 = 0, connector_cnt = 0; 96 97 dm->secure_display_ctx.phy_mapping_updated = false; 98 99 mutex_lock(&ddev->mode_config.mutex); 100 drm_connector_list_iter_begin(ddev, &iter); 101 drm_for_each_connector_iter(connector, &iter) { 102 103 if (connector->status != connector_status_connected) 104 continue; 105 106 if (idx >= AMDGPU_DM_MAX_CRTC) { 107 DRM_WARN("%s connected connectors exceed max crtc\n", __func__); 108 mutex_unlock(&ddev->mode_config.mutex); 109 return; 110 } 111 112 aconnector = to_amdgpu_dm_connector(connector); 113 114 sort_connector[idx] = aconnector; 115 idx++; 116 connector_cnt++; 117 } 118 drm_connector_list_iter_end(&iter); 119 120 /* sort connectors by link_enc_hw_instance first */ 121 for (idx = connector_cnt; idx > 1 ; idx--) { 122 for (idx_2 = 0; idx_2 < (idx - 1); idx_2++) { 123 if (sort_connector[idx_2]->dc_link->link_enc_hw_inst > 124 sort_connector[idx_2 + 1]->dc_link->link_enc_hw_inst) 125 swap(sort_connector[idx_2], sort_connector[idx_2 + 1]); 126 } 127 } 128 129 /* 130 * Sort mst connectors by RAD. mst connectors with the same enc_hw_instance are already 131 * sorted together above. 132 */ 133 for (idx = 0; idx < connector_cnt; /*Do nothing*/) { 134 if (sort_connector[idx]->mst_root) { 135 uint8_t i, j, k; 136 uint8_t mst_con_cnt = 1; 137 138 for (idx_2 = (idx + 1); idx_2 < connector_cnt; idx_2++) { 139 if (sort_connector[idx_2]->mst_root == sort_connector[idx]->mst_root) 140 mst_con_cnt++; 141 else 142 break; 143 } 144 145 for (i = mst_con_cnt; i > 1; i--) { 146 for (j = idx; j < (idx + i - 2); j++) { 147 int mstb_lct = sort_connector[j]->mst_output_port->parent->lct; 148 int next_mstb_lct = sort_connector[j + 1]->mst_output_port->parent->lct; 149 u8 *rad; 150 u8 *next_rad; 151 bool swap = false; 152 153 /* Sort by mst tree depth first. Then compare RAD if depth is the same*/ 154 if (mstb_lct > next_mstb_lct) { 155 swap = true; 156 } else if (mstb_lct == next_mstb_lct) { 157 if (mstb_lct == 1) { 158 if (sort_connector[j]->mst_output_port->port_num > sort_connector[j + 1]->mst_output_port->port_num) 159 swap = true; 160 } else if (mstb_lct > 1) { 161 rad = sort_connector[j]->mst_output_port->parent->rad; 162 next_rad = sort_connector[j + 1]->mst_output_port->parent->rad; 163 164 for (k = 0; k < mstb_lct - 1; k++) { 165 int shift = (k % 2) ? 0 : 4; 166 int port_num = (rad[k / 2] >> shift) & 0xf; 167 int next_port_num = (next_rad[k / 2] >> shift) & 0xf; 168 169 if (port_num > next_port_num) { 170 swap = true; 171 break; 172 } 173 } 174 } else { 175 DRM_ERROR("MST LCT shouldn't be set as < 1"); 176 mutex_unlock(&ddev->mode_config.mutex); 177 return; 178 } 179 } 180 181 if (swap) 182 swap(sort_connector[j], sort_connector[j + 1]); 183 } 184 } 185 186 idx += mst_con_cnt; 187 } else { 188 idx++; 189 } 190 } 191 192 /* Complete sorting. Assign relavant result to dm->secure_display_ctx.phy_id_mapping[]*/ 193 memset(dm->secure_display_ctx.phy_id_mapping, 0, sizeof(dm->secure_display_ctx.phy_id_mapping)); 194 for (idx = 0; idx < connector_cnt; idx++) { 195 aconnector = sort_connector[idx]; 196 197 dm->secure_display_ctx.phy_id_mapping[idx].assigned = true; 198 dm->secure_display_ctx.phy_id_mapping[idx].is_mst = false; 199 dm->secure_display_ctx.phy_id_mapping[idx].enc_hw_inst = aconnector->dc_link->link_enc_hw_inst; 200 201 if (sort_connector[idx]->mst_root) { 202 dm->secure_display_ctx.phy_id_mapping[idx].is_mst = true; 203 dm->secure_display_ctx.phy_id_mapping[idx].lct = aconnector->mst_output_port->parent->lct; 204 dm->secure_display_ctx.phy_id_mapping[idx].port_num = aconnector->mst_output_port->port_num; 205 memcpy(dm->secure_display_ctx.phy_id_mapping[idx].rad, 206 aconnector->mst_output_port->parent->rad, sizeof(aconnector->mst_output_port->parent->rad)); 207 } 208 } 209 mutex_unlock(&ddev->mode_config.mutex); 210 211 dm->secure_display_ctx.phy_id_mapping_cnt = connector_cnt; 212 dm->secure_display_ctx.phy_mapping_updated = true; 213 } 214 215 static bool get_phy_id(struct amdgpu_display_manager *dm, 216 struct amdgpu_dm_connector *aconnector, uint8_t *phy_id) 217 { 218 int idx, idx_2; 219 bool found = false; 220 221 /* 222 * Assume secure display start after all connectors are probed. The connection 223 * config is static as well 224 */ 225 if (!dm->secure_display_ctx.phy_mapping_updated) { 226 DRM_WARN("%s Should update the phy id table before get it's value", __func__); 227 return false; 228 } 229 230 for (idx = 0; idx < dm->secure_display_ctx.phy_id_mapping_cnt; idx++) { 231 if (!dm->secure_display_ctx.phy_id_mapping[idx].assigned) { 232 DRM_ERROR("phy_id_mapping[%d] should be assigned", idx); 233 return false; 234 } 235 236 if (aconnector->dc_link->link_enc_hw_inst == 237 dm->secure_display_ctx.phy_id_mapping[idx].enc_hw_inst) { 238 if (!dm->secure_display_ctx.phy_id_mapping[idx].is_mst) { 239 found = true; 240 goto out; 241 } else { 242 /* Could caused by wrongly pass mst root connector */ 243 if (!aconnector->mst_output_port) { 244 DRM_ERROR("%s Check mst case but connector without a port assigned", __func__); 245 return false; 246 } 247 248 if (aconnector->mst_root && 249 aconnector->mst_root->mst_mgr.mst_primary == NULL) { 250 DRM_WARN("%s pass in a stale mst connector", __func__); 251 } 252 253 if (aconnector->mst_output_port->parent->lct == dm->secure_display_ctx.phy_id_mapping[idx].lct && 254 aconnector->mst_output_port->port_num == dm->secure_display_ctx.phy_id_mapping[idx].port_num) { 255 if (aconnector->mst_output_port->parent->lct == 1) { 256 found = true; 257 goto out; 258 } else if (aconnector->mst_output_port->parent->lct > 1) { 259 /* Check RAD */ 260 for (idx_2 = 0; idx_2 < aconnector->mst_output_port->parent->lct - 1; idx_2++) { 261 int shift = (idx_2 % 2) ? 0 : 4; 262 int port_num = (aconnector->mst_output_port->parent->rad[idx_2 / 2] >> shift) & 0xf; 263 int port_num2 = (dm->secure_display_ctx.phy_id_mapping[idx].rad[idx_2 / 2] >> shift) & 0xf; 264 265 if (port_num != port_num2) 266 break; 267 } 268 269 if (idx_2 == aconnector->mst_output_port->parent->lct - 1) { 270 found = true; 271 goto out; 272 } 273 } else { 274 DRM_ERROR("lCT should be >= 1"); 275 return false; 276 } 277 } 278 } 279 } 280 } 281 282 out: 283 if (found) { 284 DRM_DEBUG_DRIVER("Associated secure display PHY ID as %d", idx); 285 *phy_id = idx; 286 } else { 287 DRM_WARN("Can't find associated phy ID"); 288 return false; 289 } 290 291 return true; 292 } 293 294 static void amdgpu_dm_set_crc_window_default(struct drm_crtc *crtc, struct dc_stream_state *stream) 295 { 296 struct drm_device *drm_dev = crtc->dev; 297 struct amdgpu_display_manager *dm = &drm_to_adev(drm_dev)->dm; 298 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 299 struct amdgpu_dm_connector *aconnector; 300 bool was_activated; 301 uint8_t phy_id; 302 unsigned long flags; 303 int i; 304 305 spin_lock_irqsave(&drm_dev->event_lock, flags); 306 was_activated = acrtc->dm_irq_params.crc_window_activated; 307 for (i = 0; i < MAX_CRC_WINDOW_NUM; i++) { 308 acrtc->dm_irq_params.window_param[i].x_start = 0; 309 acrtc->dm_irq_params.window_param[i].y_start = 0; 310 acrtc->dm_irq_params.window_param[i].x_end = 0; 311 acrtc->dm_irq_params.window_param[i].y_end = 0; 312 acrtc->dm_irq_params.window_param[i].enable = false; 313 acrtc->dm_irq_params.window_param[i].update_win = false; 314 acrtc->dm_irq_params.window_param[i].skip_frame_cnt = 0; 315 } 316 acrtc->dm_irq_params.crc_window_activated = false; 317 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 318 319 /* Disable secure_display if it was enabled */ 320 if (was_activated && dm->secure_display_ctx.op_mode == LEGACY_MODE) { 321 /* stop ROI update on this crtc */ 322 flush_work(&dm->secure_display_ctx.crtc_ctx[crtc->index].notify_ta_work); 323 flush_work(&dm->secure_display_ctx.crtc_ctx[crtc->index].forward_roi_work); 324 aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; 325 326 if (aconnector && get_phy_id(dm, aconnector, &phy_id)) { 327 if (dm->secure_display_ctx.support_mul_roi) 328 dc_stream_forward_multiple_crc_window(stream, NULL, phy_id, true); 329 else 330 dc_stream_forward_crc_window(stream, NULL, phy_id, true); 331 } else { 332 DRM_DEBUG_DRIVER("%s Can't find matching phy id", __func__); 333 } 334 } 335 } 336 337 static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work) 338 { 339 struct secure_display_crtc_context *crtc_ctx; 340 struct psp_context *psp; 341 struct ta_securedisplay_cmd *securedisplay_cmd; 342 struct drm_crtc *crtc; 343 struct dc_stream_state *stream; 344 struct amdgpu_dm_connector *aconnector; 345 uint8_t phy_inst; 346 struct amdgpu_display_manager *dm; 347 struct crc_data crc_cpy[MAX_CRC_WINDOW_NUM]; 348 unsigned long flags; 349 uint8_t roi_idx = 0; 350 int ret; 351 int i; 352 353 crtc_ctx = container_of(work, struct secure_display_crtc_context, notify_ta_work); 354 crtc = crtc_ctx->crtc; 355 356 if (!crtc) 357 return; 358 359 psp = &drm_to_adev(crtc->dev)->psp; 360 361 if (!psp->securedisplay_context.context.initialized) { 362 DRM_DEBUG_DRIVER("Secure Display fails to notify PSP TA\n"); 363 return; 364 } 365 366 dm = &drm_to_adev(crtc->dev)->dm; 367 stream = to_amdgpu_crtc(crtc)->dm_irq_params.stream; 368 aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; 369 if (!aconnector) 370 return; 371 372 mutex_lock(&crtc->dev->mode_config.mutex); 373 if (!get_phy_id(dm, aconnector, &phy_inst)) { 374 DRM_WARN("%s Can't find mapping phy id!", __func__); 375 mutex_unlock(&crtc->dev->mode_config.mutex); 376 return; 377 } 378 mutex_unlock(&crtc->dev->mode_config.mutex); 379 380 spin_lock_irqsave(&crtc->dev->event_lock, flags); 381 memcpy(crc_cpy, crtc_ctx->crc_info.crc, sizeof(struct crc_data) * MAX_CRC_WINDOW_NUM); 382 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 383 384 /* need lock for multiple crtcs to use the command buffer */ 385 mutex_lock(&psp->securedisplay_context.mutex); 386 /* PSP TA is expected to finish data transmission over I2C within current frame, 387 * even there are up to 4 crtcs request to send in this frame. 388 */ 389 if (dm->secure_display_ctx.support_mul_roi) { 390 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, 391 TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC_V2); 392 393 securedisplay_cmd->securedisplay_in_message.send_roi_crc_v2.phy_id = phy_inst; 394 395 for (i = 0; i < MAX_CRC_WINDOW_NUM; i++) { 396 if (crc_cpy[i].crc_ready) 397 roi_idx |= 1 << i; 398 } 399 securedisplay_cmd->securedisplay_in_message.send_roi_crc_v2.roi_idx = roi_idx; 400 401 ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC_V2); 402 } else { 403 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd, 404 TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); 405 406 securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_inst; 407 408 ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC); 409 } 410 411 if (!ret) { 412 if (securedisplay_cmd->status != TA_SECUREDISPLAY_STATUS__SUCCESS) 413 psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status); 414 } 415 416 mutex_unlock(&psp->securedisplay_context.mutex); 417 } 418 419 static void 420 amdgpu_dm_forward_crc_window(struct work_struct *work) 421 { 422 struct secure_display_crtc_context *crtc_ctx; 423 struct amdgpu_display_manager *dm; 424 struct drm_crtc *crtc; 425 struct dc_stream_state *stream; 426 struct amdgpu_dm_connector *aconnector; 427 struct crc_window roi_cpy[MAX_CRC_WINDOW_NUM]; 428 unsigned long flags; 429 uint8_t phy_id; 430 431 crtc_ctx = container_of(work, struct secure_display_crtc_context, forward_roi_work); 432 crtc = crtc_ctx->crtc; 433 434 if (!crtc) 435 return; 436 437 dm = &drm_to_adev(crtc->dev)->dm; 438 stream = to_amdgpu_crtc(crtc)->dm_irq_params.stream; 439 aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; 440 441 if (!aconnector) 442 return; 443 444 mutex_lock(&crtc->dev->mode_config.mutex); 445 if (!get_phy_id(dm, aconnector, &phy_id)) { 446 DRM_WARN("%s Can't find mapping phy id!", __func__); 447 mutex_unlock(&crtc->dev->mode_config.mutex); 448 return; 449 } 450 mutex_unlock(&crtc->dev->mode_config.mutex); 451 452 spin_lock_irqsave(&crtc->dev->event_lock, flags); 453 memcpy(roi_cpy, crtc_ctx->roi, sizeof(struct crc_window) * MAX_CRC_WINDOW_NUM); 454 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 455 456 mutex_lock(&dm->dc_lock); 457 if (dm->secure_display_ctx.support_mul_roi) 458 dc_stream_forward_multiple_crc_window(stream, roi_cpy, 459 phy_id, false); 460 else 461 dc_stream_forward_crc_window(stream, &roi_cpy[0].rect, 462 phy_id, false); 463 mutex_unlock(&dm->dc_lock); 464 } 465 466 bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc) 467 { 468 struct drm_device *drm_dev = crtc->dev; 469 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 470 bool ret = false; 471 472 spin_lock_irq(&drm_dev->event_lock); 473 ret = acrtc->dm_irq_params.crc_window_activated; 474 spin_unlock_irq(&drm_dev->event_lock); 475 476 return ret; 477 } 478 #endif 479 480 int 481 amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name, 482 size_t *values_cnt) 483 { 484 enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name); 485 486 if (source < 0) { 487 DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n", 488 src_name, crtc->index); 489 return -EINVAL; 490 } 491 492 *values_cnt = 3; 493 return 0; 494 } 495 496 int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, 497 struct dm_crtc_state *dm_crtc_state, 498 enum amdgpu_dm_pipe_crc_source source) 499 { 500 struct amdgpu_device *adev = drm_to_adev(crtc->dev); 501 struct dc_stream_state *stream_state = dm_crtc_state->stream; 502 bool enable = amdgpu_dm_is_valid_crc_source(source); 503 int ret = 0; 504 505 /* Configuration will be deferred to stream enable. */ 506 if (!stream_state) 507 return -EINVAL; 508 509 mutex_lock(&adev->dm.dc_lock); 510 511 /* For PSR1, check that the panel has exited PSR */ 512 if (stream_state->link->psr_settings.psr_version < DC_PSR_VERSION_SU_1) 513 amdgpu_dm_psr_wait_disable(stream_state); 514 515 /* Enable or disable CRTC CRC generation */ 516 if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { 517 if (!dc_stream_configure_crc(stream_state->ctx->dc, 518 stream_state, NULL, enable, enable, 0, true)) { 519 ret = -EINVAL; 520 goto unlock; 521 } 522 } 523 524 /* Configure dithering */ 525 if (!dm_need_crc_dither(source)) { 526 dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8); 527 dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state, 528 DYN_EXPANSION_DISABLE); 529 } else { 530 dc_stream_set_dither_option(stream_state, 531 DITHER_OPTION_DEFAULT); 532 dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state, 533 DYN_EXPANSION_AUTO); 534 } 535 536 unlock: 537 mutex_unlock(&adev->dm.dc_lock); 538 539 return ret; 540 } 541 542 int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name) 543 { 544 enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name); 545 enum amdgpu_dm_pipe_crc_source cur_crc_src; 546 struct drm_crtc_commit *commit; 547 struct dm_crtc_state *crtc_state; 548 struct drm_device *drm_dev = crtc->dev; 549 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) 550 struct amdgpu_device *adev = drm_to_adev(drm_dev); 551 struct amdgpu_display_manager *dm = &adev->dm; 552 #endif 553 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); 554 struct drm_dp_aux *aux = NULL; 555 bool enable = false; 556 bool enabled = false; 557 int ret = 0; 558 559 if (source < 0) { 560 DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n", 561 src_name, crtc->index); 562 return -EINVAL; 563 } 564 565 ret = drm_modeset_lock(&crtc->mutex, NULL); 566 if (ret) 567 return ret; 568 569 spin_lock(&crtc->commit_lock); 570 commit = list_first_entry_or_null(&crtc->commit_list, 571 struct drm_crtc_commit, commit_entry); 572 if (commit) 573 drm_crtc_commit_get(commit); 574 spin_unlock(&crtc->commit_lock); 575 576 if (commit) { 577 /* 578 * Need to wait for all outstanding programming to complete 579 * in commit tail since it can modify CRC related fields and 580 * hardware state. Since we're holding the CRTC lock we're 581 * guaranteed that no other commit work can be queued off 582 * before we modify the state below. 583 */ 584 ret = wait_for_completion_interruptible_timeout( 585 &commit->hw_done, 10 * HZ); 586 if (ret) 587 goto cleanup; 588 } 589 590 enable = amdgpu_dm_is_valid_crc_source(source); 591 crtc_state = to_dm_crtc_state(crtc->state); 592 spin_lock_irq(&drm_dev->event_lock); 593 cur_crc_src = acrtc->dm_irq_params.crc_src; 594 spin_unlock_irq(&drm_dev->event_lock); 595 596 /* 597 * USER REQ SRC | CURRENT SRC | BEHAVIOR 598 * ----------------------------- 599 * None | None | Do nothing 600 * None | CRTC | Disable CRTC CRC, set default to dither 601 * None | DPRX | Disable DPRX CRC, need 'aux', set default to dither 602 * None | CRTC DITHER | Disable CRTC CRC 603 * None | DPRX DITHER | Disable DPRX CRC, need 'aux' 604 * CRTC | XXXX | Enable CRTC CRC, no dither 605 * DPRX | XXXX | Enable DPRX CRC, need 'aux', no dither 606 * CRTC DITHER | XXXX | Enable CRTC CRC, set dither 607 * DPRX DITHER | XXXX | Enable DPRX CRC, need 'aux', set dither 608 */ 609 if (dm_is_crc_source_dprx(source) || 610 (source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE && 611 dm_is_crc_source_dprx(cur_crc_src))) { 612 struct amdgpu_dm_connector *aconn = NULL; 613 struct drm_connector *connector; 614 struct drm_connector_list_iter conn_iter; 615 616 drm_connector_list_iter_begin(crtc->dev, &conn_iter); 617 drm_for_each_connector_iter(connector, &conn_iter) { 618 if (!connector->state || connector->state->crtc != crtc) 619 continue; 620 621 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) 622 continue; 623 624 aconn = to_amdgpu_dm_connector(connector); 625 break; 626 } 627 drm_connector_list_iter_end(&conn_iter); 628 629 if (!aconn) { 630 DRM_DEBUG_DRIVER("No amd connector matching CRTC-%d\n", crtc->index); 631 ret = -EINVAL; 632 goto cleanup; 633 } 634 635 aux = (aconn->mst_output_port) ? &aconn->mst_output_port->aux : &aconn->dm_dp_aux.aux; 636 637 if (!aux) { 638 DRM_DEBUG_DRIVER("No dp aux for amd connector\n"); 639 ret = -EINVAL; 640 goto cleanup; 641 } 642 643 if ((aconn->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) && 644 (aconn->base.connector_type != DRM_MODE_CONNECTOR_eDP)) { 645 DRM_DEBUG_DRIVER("No DP connector available for CRC source\n"); 646 ret = -EINVAL; 647 goto cleanup; 648 } 649 650 } 651 652 /* 653 * Reading the CRC requires the vblank interrupt handler to be 654 * enabled. Keep a reference until CRC capture stops. 655 */ 656 enabled = amdgpu_dm_is_valid_crc_source(cur_crc_src); 657 if (!enabled && enable) { 658 ret = drm_crtc_vblank_get(crtc); 659 if (ret) 660 goto cleanup; 661 } 662 663 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) 664 /* Reset secure_display when we change crc source from debugfs */ 665 amdgpu_dm_set_crc_window_default(crtc, crtc_state->stream); 666 #endif 667 668 if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source)) { 669 ret = -EINVAL; 670 goto cleanup; 671 } 672 673 if (!enabled && enable) { 674 if (dm_is_crc_source_dprx(source)) { 675 if (drm_dp_start_crc(aux, crtc)) { 676 DRM_DEBUG_DRIVER("dp start crc failed\n"); 677 ret = -EINVAL; 678 goto cleanup; 679 } 680 } 681 } else if (enabled && !enable) { 682 drm_crtc_vblank_put(crtc); 683 if (dm_is_crc_source_dprx(source)) { 684 if (drm_dp_stop_crc(aux)) { 685 DRM_DEBUG_DRIVER("dp stop crc failed\n"); 686 ret = -EINVAL; 687 goto cleanup; 688 } 689 } 690 } 691 692 spin_lock_irq(&drm_dev->event_lock); 693 acrtc->dm_irq_params.crc_src = source; 694 spin_unlock_irq(&drm_dev->event_lock); 695 696 /* Reset crc_skipped on dm state */ 697 crtc_state->crc_skip_count = 0; 698 699 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) 700 /* Initialize phy id mapping table for secure display*/ 701 if (dm->secure_display_ctx.op_mode == LEGACY_MODE && 702 !dm->secure_display_ctx.phy_mapping_updated) 703 update_phy_id_mapping(adev); 704 #endif 705 706 cleanup: 707 if (commit) 708 drm_crtc_commit_put(commit); 709 710 drm_modeset_unlock(&crtc->mutex); 711 712 return ret; 713 } 714 715 /** 716 * amdgpu_dm_crtc_handle_crc_irq: Report to DRM the CRC on given CRTC. 717 * @crtc: DRM CRTC object. 718 * 719 * This function should be called at the end of a vblank, when the fb has been 720 * fully processed through the pipe. 721 */ 722 void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc) 723 { 724 struct dm_crtc_state *crtc_state; 725 struct dc_stream_state *stream_state; 726 struct drm_device *drm_dev = NULL; 727 enum amdgpu_dm_pipe_crc_source cur_crc_src; 728 struct amdgpu_crtc *acrtc = NULL; 729 uint32_t crcs[3]; 730 unsigned long flags; 731 732 if (crtc == NULL) 733 return; 734 735 crtc_state = to_dm_crtc_state(crtc->state); 736 stream_state = crtc_state->stream; 737 acrtc = to_amdgpu_crtc(crtc); 738 drm_dev = crtc->dev; 739 740 spin_lock_irqsave(&drm_dev->event_lock, flags); 741 cur_crc_src = acrtc->dm_irq_params.crc_src; 742 spin_unlock_irqrestore(&drm_dev->event_lock, flags); 743 744 /* Early return if CRC capture is not enabled. */ 745 if (!amdgpu_dm_is_valid_crc_source(cur_crc_src)) 746 return; 747 748 /* 749 * Since flipping and crc enablement happen asynchronously, we - more 750 * often than not - will be returning an 'uncooked' crc on first frame. 751 * Probably because hw isn't ready yet. For added security, skip the 752 * first two CRC values. 753 */ 754 if (crtc_state->crc_skip_count < 2) { 755 crtc_state->crc_skip_count += 1; 756 return; 757 } 758 759 if (dm_is_crc_source_crtc(cur_crc_src)) { 760 if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state, 0, 761 &crcs[0], &crcs[1], &crcs[2])) 762 return; 763 764 drm_crtc_add_crc_entry(crtc, true, 765 drm_crtc_accurate_vblank_count(crtc), crcs); 766 } 767 } 768 769 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) 770 void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) 771 { 772 struct drm_device *drm_dev = NULL; 773 enum amdgpu_dm_pipe_crc_source cur_crc_src; 774 struct amdgpu_crtc *acrtc = NULL; 775 struct amdgpu_device *adev = NULL; 776 struct secure_display_crtc_context *crtc_ctx = NULL; 777 bool reset_crc_frame_count[MAX_CRC_WINDOW_NUM] = {false}; 778 uint32_t crc_r[MAX_CRC_WINDOW_NUM] = {0}; 779 uint32_t crc_g[MAX_CRC_WINDOW_NUM] = {0}; 780 uint32_t crc_b[MAX_CRC_WINDOW_NUM] = {0}; 781 unsigned long flags1; 782 bool forward_roi_change = false; 783 bool notify_ta = false; 784 bool all_crc_ready = true; 785 struct dc_stream_state *stream_state; 786 int i; 787 788 if (crtc == NULL) 789 return; 790 791 acrtc = to_amdgpu_crtc(crtc); 792 adev = drm_to_adev(crtc->dev); 793 drm_dev = crtc->dev; 794 stream_state = to_dm_crtc_state(crtc->state)->stream; 795 796 spin_lock_irqsave(&drm_dev->event_lock, flags1); 797 cur_crc_src = acrtc->dm_irq_params.crc_src; 798 799 /* Early return if CRC capture is not enabled. */ 800 if (!amdgpu_dm_is_valid_crc_source(cur_crc_src) || 801 !dm_is_crc_source_crtc(cur_crc_src)) { 802 spin_unlock_irqrestore(&drm_dev->event_lock, flags1); 803 return; 804 } 805 806 if (!acrtc->dm_irq_params.crc_window_activated) { 807 spin_unlock_irqrestore(&drm_dev->event_lock, flags1); 808 return; 809 } 810 811 crtc_ctx = &adev->dm.secure_display_ctx.crtc_ctx[acrtc->crtc_id]; 812 if (WARN_ON(crtc_ctx->crtc != crtc)) { 813 /* We have set the crtc when creating secure_display_crtc_context, 814 * don't expect it to be changed here. 815 */ 816 crtc_ctx->crtc = crtc; 817 } 818 819 for (i = 0; i < MAX_CRC_WINDOW_NUM; i++) { 820 struct crc_params crc_window = { 821 .windowa_x_start = acrtc->dm_irq_params.window_param[i].x_start, 822 .windowa_y_start = acrtc->dm_irq_params.window_param[i].y_start, 823 .windowa_x_end = acrtc->dm_irq_params.window_param[i].x_end, 824 .windowa_y_end = acrtc->dm_irq_params.window_param[i].y_end, 825 .windowb_x_start = acrtc->dm_irq_params.window_param[i].x_start, 826 .windowb_y_start = acrtc->dm_irq_params.window_param[i].y_start, 827 .windowb_x_end = acrtc->dm_irq_params.window_param[i].x_end, 828 .windowb_y_end = acrtc->dm_irq_params.window_param[i].y_end, 829 }; 830 831 crtc_ctx->roi[i].enable = acrtc->dm_irq_params.window_param[i].enable; 832 833 if (!acrtc->dm_irq_params.window_param[i].enable) { 834 crtc_ctx->crc_info.crc[i].crc_ready = false; 835 continue; 836 } 837 838 if (acrtc->dm_irq_params.window_param[i].skip_frame_cnt) { 839 acrtc->dm_irq_params.window_param[i].skip_frame_cnt -= 1; 840 crtc_ctx->crc_info.crc[i].crc_ready = false; 841 continue; 842 } 843 844 if (acrtc->dm_irq_params.window_param[i].update_win) { 845 crtc_ctx->roi[i].rect.x = crc_window.windowa_x_start; 846 crtc_ctx->roi[i].rect.y = crc_window.windowa_y_start; 847 crtc_ctx->roi[i].rect.width = crc_window.windowa_x_end - 848 crc_window.windowa_x_start; 849 crtc_ctx->roi[i].rect.height = crc_window.windowa_y_end - 850 crc_window.windowa_y_start; 851 852 if (adev->dm.secure_display_ctx.op_mode == LEGACY_MODE) 853 /* forward task to dmub to update ROI */ 854 forward_roi_change = true; 855 else if (adev->dm.secure_display_ctx.op_mode == DISPLAY_CRC_MODE) 856 /* update ROI via dm*/ 857 dc_stream_configure_crc(stream_state->ctx->dc, stream_state, 858 &crc_window, true, true, i, false); 859 860 reset_crc_frame_count[i] = true; 861 862 acrtc->dm_irq_params.window_param[i].update_win = false; 863 864 /* Statically skip 1 frame, because we may need to wait below things 865 * before sending ROI to dmub: 866 * 1. We defer the work by using system workqueue. 867 * 2. We may need to wait for dc_lock before accessing dmub. 868 */ 869 acrtc->dm_irq_params.window_param[i].skip_frame_cnt = 1; 870 crtc_ctx->crc_info.crc[i].crc_ready = false; 871 } else { 872 if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state, i, 873 &crc_r[i], &crc_g[i], &crc_b[i])) 874 DRM_ERROR("Secure Display: fail to get crc from engine %d\n", i); 875 876 if (adev->dm.secure_display_ctx.op_mode == LEGACY_MODE) 877 /* forward task to psp to read ROI/CRC and output via I2C */ 878 notify_ta = true; 879 else if (adev->dm.secure_display_ctx.op_mode == DISPLAY_CRC_MODE) 880 /* Avoid ROI window get changed, keep overwriting. */ 881 dc_stream_configure_crc(stream_state->ctx->dc, stream_state, 882 &crc_window, true, true, i, false); 883 884 /* crc ready for psp to read out */ 885 crtc_ctx->crc_info.crc[i].crc_ready = true; 886 } 887 } 888 889 spin_unlock_irqrestore(&drm_dev->event_lock, flags1); 890 891 if (forward_roi_change) 892 schedule_work(&crtc_ctx->forward_roi_work); 893 894 if (notify_ta) 895 schedule_work(&crtc_ctx->notify_ta_work); 896 897 spin_lock_irqsave(&crtc_ctx->crc_info.lock, flags1); 898 for (i = 0; i < MAX_CRC_WINDOW_NUM; i++) { 899 crtc_ctx->crc_info.crc[i].crc_R = crc_r[i]; 900 crtc_ctx->crc_info.crc[i].crc_G = crc_g[i]; 901 crtc_ctx->crc_info.crc[i].crc_B = crc_b[i]; 902 903 if (!crtc_ctx->roi[i].enable) { 904 crtc_ctx->crc_info.crc[i].frame_count = 0; 905 continue; 906 } 907 908 if (!crtc_ctx->crc_info.crc[i].crc_ready) 909 all_crc_ready = false; 910 911 if (reset_crc_frame_count[i] || crtc_ctx->crc_info.crc[i].frame_count == UINT_MAX) 912 /* Reset the reference frame count after user update the ROI 913 * or it reaches the maximum value. 914 */ 915 crtc_ctx->crc_info.crc[i].frame_count = 0; 916 else 917 crtc_ctx->crc_info.crc[i].frame_count += 1; 918 } 919 spin_unlock_irqrestore(&crtc_ctx->crc_info.lock, flags1); 920 921 if (all_crc_ready) 922 complete_all(&crtc_ctx->crc_info.completion); 923 } 924 925 void amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev) 926 { 927 struct secure_display_crtc_context *crtc_ctx = NULL; 928 int i; 929 930 crtc_ctx = kcalloc(adev->mode_info.num_crtc, 931 sizeof(struct secure_display_crtc_context), 932 GFP_KERNEL); 933 934 if (!crtc_ctx) { 935 adev->dm.secure_display_ctx.crtc_ctx = NULL; 936 return; 937 } 938 939 for (i = 0; i < adev->mode_info.num_crtc; i++) { 940 INIT_WORK(&crtc_ctx[i].forward_roi_work, amdgpu_dm_forward_crc_window); 941 INIT_WORK(&crtc_ctx[i].notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read); 942 crtc_ctx[i].crtc = &adev->mode_info.crtcs[i]->base; 943 spin_lock_init(&crtc_ctx[i].crc_info.lock); 944 } 945 946 adev->dm.secure_display_ctx.crtc_ctx = crtc_ctx; 947 948 adev->dm.secure_display_ctx.op_mode = DISPLAY_CRC_MODE; 949 } 950 #endif 951