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