2 * Copyright 2015 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
26 #include <drm/drm_crtc.h>
27 #include <drm/drm_vblank.h>
30 #include "amdgpu_dm.h"
32 #include "amdgpu_securedisplay.h"
33 #include "amdgpu_dm_psr.h"
35 static const char *const pipe_crc_sources[] = {
44 static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
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;
57 return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID;
60 static bool dm_is_crc_source_crtc(enum amdgpu_dm_pipe_crc_source src)
62 return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) ||
63 (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER);
66 static bool dm_is_crc_source_dprx(enum amdgpu_dm_pipe_crc_source src)
68 return (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) ||
69 (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER);
72 static bool dm_need_crc_dither(enum amdgpu_dm_pipe_crc_source src)
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);
79 const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc,
82 *count = ARRAY_SIZE(pipe_crc_sources);
83 return pipe_crc_sources;
86 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
87 static void update_phy_id_mapping(struct amdgpu_device *adev)
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;
97 dm->secure_display_ctx.phy_mapping_updated = false;
99 mutex_lock(&ddev->mode_config.mutex);
100 drm_connector_list_iter_begin(ddev, &iter);
101 drm_for_each_connector_iter(connector, &iter) {
103 if (connector->status != connector_status_connected)
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);
112 aconnector = to_amdgpu_dm_connector(connector);
114 sort_connector[idx] = aconnector;
118 drm_connector_list_iter_end(&iter);
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]);
130 * Sort mst connectors by RAD. mst connectors with the same enc_hw_instance are already
131 * sorted together above.
133 for (idx = 0; idx < connector_cnt; /*Do nothing*/) {
134 if (sort_connector[idx]->mst_root) {
136 uint8_t mst_con_cnt = 1;
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)
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;
153 /* Sort by mst tree depth first. Then compare RAD if depth is the same*/
154 if (mstb_lct > next_mstb_lct) {
156 } else if (mstb_lct == next_mstb_lct) {
158 if (sort_connector[j]->mst_output_port->port_num > sort_connector[j + 1]->mst_output_port->port_num)
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;
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;
169 if (port_num > next_port_num) {
175 DRM_ERROR("MST LCT shouldn't be set as < 1");
176 mutex_unlock(&ddev->mode_config.mutex);
182 swap(sort_connector[j], sort_connector[j + 1]);
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];
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;
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));
209 mutex_unlock(&ddev->mode_config.mutex);
211 dm->secure_display_ctx.phy_id_mapping_cnt = connector_cnt;
212 dm->secure_display_ctx.phy_mapping_updated = true;
215 static bool get_phy_id(struct amdgpu_display_manager *dm,
216 struct amdgpu_dm_connector *aconnector, uint8_t *phy_id)
222 * Assume secure display start after all connectors are probed. The connection
223 * config is static as well
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__);
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);
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) {
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__);
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__);
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) {
258 } else if (aconnector->mst_output_port->parent->lct > 1) {
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;
265 if (port_num != port_num2)
269 if (idx_2 == aconnector->mst_output_port->parent->lct - 1) {
274 DRM_ERROR("lCT should be >= 1");
284 DRM_DEBUG_DRIVER("Associated secure display PHY ID as %d", idx);
287 DRM_WARN("Can't find associated phy ID");
294 static void amdgpu_dm_set_crc_window_default(struct drm_crtc *crtc, struct dc_stream_state *stream)
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;
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;
316 acrtc->dm_irq_params.crc_window_activated = false;
317 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
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;
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);
330 dc_stream_forward_crc_window(stream, NULL, phy_id, true);
332 DRM_DEBUG_DRIVER("%s Can't find matching phy id", __func__);
337 static void amdgpu_dm_crtc_notify_ta_to_read(struct work_struct *work)
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;
346 struct amdgpu_display_manager *dm;
347 struct crc_data crc_cpy[MAX_CRC_WINDOW_NUM];
353 crtc_ctx = container_of(work, struct secure_display_crtc_context, notify_ta_work);
354 crtc = crtc_ctx->crtc;
359 psp = &drm_to_adev(crtc->dev)->psp;
361 if (!psp->securedisplay_context.context.initialized) {
362 DRM_DEBUG_DRIVER("Secure Display fails to notify PSP TA\n");
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;
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);
378 mutex_unlock(&crtc->dev->mode_config.mutex);
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);
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.
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);
393 securedisplay_cmd->securedisplay_in_message.send_roi_crc_v2.phy_id = phy_inst;
395 for (i = 0; i < MAX_CRC_WINDOW_NUM; i++) {
396 if (crc_cpy[i].crc_ready)
399 securedisplay_cmd->securedisplay_in_message.send_roi_crc_v2.roi_idx = roi_idx;
401 ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC_V2);
403 psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
404 TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
406 securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_inst;
408 ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
412 if (securedisplay_cmd->status != TA_SECUREDISPLAY_STATUS__SUCCESS)
413 psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);
416 mutex_unlock(&psp->securedisplay_context.mutex);
420 amdgpu_dm_forward_crc_window(struct work_struct *work)
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];
431 crtc_ctx = container_of(work, struct secure_display_crtc_context, forward_roi_work);
432 crtc = crtc_ctx->crtc;
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;
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);
450 mutex_unlock(&crtc->dev->mode_config.mutex);
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);
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,
461 dc_stream_forward_crc_window(stream, &roi_cpy[0].rect,
463 mutex_unlock(&dm->dc_lock);
466 bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc)
468 struct drm_device *drm_dev = crtc->dev;
469 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
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);
481 amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name,
484 enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name);
487 DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n",
488 src_name, crtc->index);
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)
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);
505 /* Configuration will be deferred to stream enable. */
509 mutex_lock(&adev->dm.dc_lock);
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);
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)) {
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);
530 dc_stream_set_dither_option(stream_state,
531 DITHER_OPTION_DEFAULT);
532 dc_stream_set_dyn_expansion(stream_state->ctx->dc, stream_state,
537 mutex_unlock(&adev->dm.dc_lock);
542 int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
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;
553 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
554 struct drm_dp_aux *aux = NULL;
556 bool enabled = false;
560 DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n",
561 src_name, crtc->index);
565 ret = drm_modeset_lock(&crtc->mutex, NULL);
569 spin_lock(&crtc->commit_lock);
570 commit = list_first_entry_or_null(&crtc->commit_list,
571 struct drm_crtc_commit, commit_entry);
573 drm_crtc_commit_get(commit);
574 spin_unlock(&crtc->commit_lock);
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.
584 ret = wait_for_completion_interruptible_timeout(
585 &commit->hw_done, 10 * HZ);
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);
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
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;
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)
621 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
624 aconn = to_amdgpu_dm_connector(connector);
627 drm_connector_list_iter_end(&conn_iter);
630 DRM_DEBUG_DRIVER("No amd connector matching CRTC-%d\n", crtc->index);
635 aux = (aconn->mst_output_port) ? &aconn->mst_output_port->aux : &aconn->dm_dp_aux.aux;
638 DRM_DEBUG_DRIVER("No dp aux for amd connector\n");
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");
653 * Reading the CRC requires the vblank interrupt handler to be
654 * enabled. Keep a reference until CRC capture stops.
656 enabled = amdgpu_dm_is_valid_crc_source(cur_crc_src);
657 if (!enabled && enable) {
658 ret = drm_crtc_vblank_get(crtc);
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);
668 if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source)) {
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");
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");
692 spin_lock_irq(&drm_dev->event_lock);
693 acrtc->dm_irq_params.crc_src = source;
694 spin_unlock_irq(&drm_dev->event_lock);
696 /* Reset crc_skipped on dm state */
697 crtc_state->crc_skip_count = 0;
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);
708 drm_crtc_commit_put(commit);
710 drm_modeset_unlock(&crtc->mutex);
716 * amdgpu_dm_crtc_handle_crc_irq: Report to DRM the CRC on given CRTC.
717 * @crtc: DRM CRTC object.
719 * This function should be called at the end of a vblank, when the fb has been
720 * fully processed through the pipe.
722 void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
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;
735 crtc_state = to_dm_crtc_state(crtc->state);
736 stream_state = crtc_state->stream;
737 acrtc = to_amdgpu_crtc(crtc);
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);
744 /* Early return if CRC capture is not enabled. */
745 if (!amdgpu_dm_is_valid_crc_source(cur_crc_src))
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.
754 if (crtc_state->crc_skip_count < 2) {
755 crtc_state->crc_skip_count += 1;
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]))
764 drm_crtc_add_crc_entry(crtc, true,
765 drm_crtc_accurate_vblank_count(crtc), crcs);
769 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
770 void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
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;
791 acrtc = to_amdgpu_crtc(crtc);
792 adev = drm_to_adev(crtc->dev);
794 stream_state = to_dm_crtc_state(crtc->state)->stream;
796 spin_lock_irqsave(&drm_dev->event_lock, flags1);
797 cur_crc_src = acrtc->dm_irq_params.crc_src;
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);
806 if (!acrtc->dm_irq_params.crc_window_activated) {
807 spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
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.
816 crtc_ctx->crtc = crtc;
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,
831 crtc_ctx->roi[i].enable = acrtc->dm_irq_params.window_param[i].enable;
833 if (!acrtc->dm_irq_params.window_param[i].enable) {
834 crtc_ctx->crc_info.crc[i].crc_ready = false;
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;
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;
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);
860 reset_crc_frame_count[i] = true;
862 acrtc->dm_irq_params.window_param[i].update_win = false;
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.
869 acrtc->dm_irq_params.window_param[i].skip_frame_cnt = 1;
870 crtc_ctx->crc_info.crc[i].crc_ready = false;
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);
876 if (adev->dm.secure_display_ctx.op_mode == LEGACY_MODE)
877 /* forward task to psp to read ROI/CRC and output via I2C */
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);
884 /* crc ready for psp to read out */
885 crtc_ctx->crc_info.crc[i].crc_ready = true;
889 spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
891 if (forward_roi_change)
892 schedule_work(&crtc_ctx->forward_roi_work);
895 schedule_work(&crtc_ctx->notify_ta_work);
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];
903 if (!crtc_ctx->roi[i].enable) {
904 crtc_ctx->crc_info.crc[i].frame_count = 0;
908 if (!crtc_ctx->crc_info.crc[i].crc_ready)
909 all_crc_ready = false;
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.
915 crtc_ctx->crc_info.crc[i].frame_count = 0;
917 crtc_ctx->crc_info.crc[i].frame_count += 1;
919 spin_unlock_irqrestore(&crtc_ctx->crc_info.lock, flags1);
922 complete_all(&crtc_ctx->crc_info.completion);
925 void amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev)
927 struct secure_display_crtc_context *crtc_ctx = NULL;
930 crtc_ctx = kcalloc(adev->mode_info.num_crtc,
931 sizeof(struct secure_display_crtc_context),
935 adev->dm.secure_display_ctx.crtc_ctx = NULL;
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);
946 adev->dm.secure_display_ctx.crtc_ctx = crtc_ctx;
948 adev->dm.secure_display_ctx.op_mode = DISPLAY_CRC_MODE;