751 lines · c
1// SPDX-License-Identifier: MIT2 3#include <drm/drm_atomic.h>4#include <drm/drm_connector.h>5#include <drm/drm_edid.h>6#include <drm/drm_print.h>7 8#include <drm/display/drm_hdmi_helper.h>9#include <drm/display/drm_hdmi_state_helper.h>10 11/**12 * __drm_atomic_helper_connector_hdmi_reset() - Initializes all HDMI @drm_connector_state resources13 * @connector: DRM connector14 * @new_conn_state: connector state to reset15 *16 * Initializes all HDMI resources from a @drm_connector_state without17 * actually allocating it. This is useful for HDMI drivers, in18 * combination with __drm_atomic_helper_connector_reset() or19 * drm_atomic_helper_connector_reset().20 */21void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,22 struct drm_connector_state *new_conn_state)23{24 unsigned int max_bpc = connector->max_bpc;25 26 new_conn_state->max_bpc = max_bpc;27 new_conn_state->max_requested_bpc = max_bpc;28 new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_AUTO;29}30EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset);31 32static const struct drm_display_mode *33connector_state_get_mode(const struct drm_connector_state *conn_state)34{35 struct drm_atomic_state *state;36 struct drm_crtc_state *crtc_state;37 struct drm_crtc *crtc;38 39 state = conn_state->state;40 if (!state)41 return NULL;42 43 crtc = conn_state->crtc;44 if (!crtc)45 return NULL;46 47 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);48 if (!crtc_state)49 return NULL;50 51 return &crtc_state->mode;52}53 54static bool hdmi_is_limited_range(const struct drm_connector *connector,55 const struct drm_connector_state *conn_state)56{57 const struct drm_display_info *info = &connector->display_info;58 const struct drm_display_mode *mode =59 connector_state_get_mode(conn_state);60 61 /*62 * The Broadcast RGB property only applies to RGB format, and63 * i915 just assumes limited range for YCbCr output, so let's64 * just do the same.65 */66 if (conn_state->hdmi.output_format != HDMI_COLORSPACE_RGB)67 return true;68 69 if (conn_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_FULL)70 return false;71 72 if (conn_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)73 return true;74 75 if (!info->is_hdmi)76 return false;77 78 return drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_LIMITED;79}80 81static bool82sink_supports_format_bpc(const struct drm_connector *connector,83 const struct drm_display_info *info,84 const struct drm_display_mode *mode,85 unsigned int format, unsigned int bpc)86{87 struct drm_device *dev = connector->dev;88 u8 vic = drm_match_cea_mode(mode);89 90 /*91 * CTA-861-F, section 5.4 - Color Coding & Quantization states92 * that the bpc must be 8, 10, 12 or 16 except for the default93 * 640x480 VIC1 where the value must be 8.94 *95 * The definition of default here is ambiguous but the spec96 * refers to VIC1 being the default timing in several occasions97 * so our understanding is that for the default timing (ie,98 * VIC1), the bpc must be 8.99 */100 if (vic == 1 && bpc != 8) {101 drm_dbg_kms(dev, "VIC1 requires a bpc of 8, got %u\n", bpc);102 return false;103 }104 105 if (!info->is_hdmi &&106 (format != HDMI_COLORSPACE_RGB || bpc != 8)) {107 drm_dbg_kms(dev, "DVI Monitors require an RGB output at 8 bpc\n");108 return false;109 }110 111 if (!(connector->hdmi.supported_formats & BIT(format))) {112 drm_dbg_kms(dev, "%s format unsupported by the connector.\n",113 drm_hdmi_connector_get_output_format_name(format));114 return false;115 }116 117 switch (format) {118 case HDMI_COLORSPACE_RGB:119 drm_dbg_kms(dev, "RGB Format, checking the constraints.\n");120 121 /*122 * In some cases, like when the EDID readout fails, or123 * is not an HDMI compliant EDID for some reason, the124 * color_formats field will be blank and not report any125 * format supported. In such a case, assume that RGB is126 * supported so we can keep things going and light up127 * the display.128 */129 if (!(info->color_formats & DRM_COLOR_FORMAT_RGB444))130 drm_warn(dev, "HDMI Sink doesn't support RGB, something's wrong.\n");131 132 if (bpc == 10 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30)) {133 drm_dbg_kms(dev, "10 BPC but sink doesn't support Deep Color 30.\n");134 return false;135 }136 137 if (bpc == 12 && !(info->edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_36)) {138 drm_dbg_kms(dev, "12 BPC but sink doesn't support Deep Color 36.\n");139 return false;140 }141 142 drm_dbg_kms(dev, "RGB format supported in that configuration.\n");143 144 return true;145 146 case HDMI_COLORSPACE_YUV420:147 /* TODO: YUV420 is unsupported at the moment. */148 drm_dbg_kms(dev, "YUV420 format isn't supported yet.\n");149 return false;150 151 case HDMI_COLORSPACE_YUV422:152 drm_dbg_kms(dev, "YUV422 format, checking the constraints.\n");153 154 if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {155 drm_dbg_kms(dev, "Sink doesn't support YUV422.\n");156 return false;157 }158 159 if (bpc > 12) {160 drm_dbg_kms(dev, "YUV422 only supports 12 bpc or lower.\n");161 return false;162 }163 164 /*165 * HDMI Spec 1.3 - Section 6.5 Pixel Encodings and Color Depth166 * states that Deep Color is not relevant for YUV422 so we167 * don't need to check the Deep Color bits in the EDIDs here.168 */169 170 drm_dbg_kms(dev, "YUV422 format supported in that configuration.\n");171 172 return true;173 174 case HDMI_COLORSPACE_YUV444:175 drm_dbg_kms(dev, "YUV444 format, checking the constraints.\n");176 177 if (!(info->color_formats & DRM_COLOR_FORMAT_YCBCR444)) {178 drm_dbg_kms(dev, "Sink doesn't support YUV444.\n");179 return false;180 }181 182 if (bpc == 10 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_30)) {183 drm_dbg_kms(dev, "10 BPC but sink doesn't support Deep Color 30.\n");184 return false;185 }186 187 if (bpc == 12 && !(info->edid_hdmi_ycbcr444_dc_modes & DRM_EDID_HDMI_DC_36)) {188 drm_dbg_kms(dev, "12 BPC but sink doesn't support Deep Color 36.\n");189 return false;190 }191 192 drm_dbg_kms(dev, "YUV444 format supported in that configuration.\n");193 194 return true;195 }196 197 drm_dbg_kms(dev, "Unsupported pixel format.\n");198 return false;199}200 201static enum drm_mode_status202hdmi_clock_valid(const struct drm_connector *connector,203 const struct drm_display_mode *mode,204 unsigned long long clock)205{206 const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;207 const struct drm_display_info *info = &connector->display_info;208 209 if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000)210 return MODE_CLOCK_HIGH;211 212 if (funcs && funcs->tmds_char_rate_valid) {213 enum drm_mode_status status;214 215 status = funcs->tmds_char_rate_valid(connector, mode, clock);216 if (status != MODE_OK)217 return status;218 }219 220 return MODE_OK;221}222 223static int224hdmi_compute_clock(const struct drm_connector *connector,225 struct drm_connector_state *conn_state,226 const struct drm_display_mode *mode,227 unsigned int bpc, enum hdmi_colorspace fmt)228{229 enum drm_mode_status status;230 unsigned long long clock;231 232 clock = drm_hdmi_compute_mode_clock(mode, bpc, fmt);233 if (!clock)234 return -EINVAL;235 236 status = hdmi_clock_valid(connector, mode, clock);237 if (status != MODE_OK)238 return -EINVAL;239 240 conn_state->hdmi.tmds_char_rate = clock;241 242 return 0;243}244 245static bool246hdmi_try_format_bpc(const struct drm_connector *connector,247 struct drm_connector_state *conn_state,248 const struct drm_display_mode *mode,249 unsigned int bpc, enum hdmi_colorspace fmt)250{251 const struct drm_display_info *info = &connector->display_info;252 struct drm_device *dev = connector->dev;253 int ret;254 255 drm_dbg_kms(dev, "Trying %s output format\n",256 drm_hdmi_connector_get_output_format_name(fmt));257 258 if (!sink_supports_format_bpc(connector, info, mode, fmt, bpc)) {259 drm_dbg_kms(dev, "%s output format not supported with %u bpc\n",260 drm_hdmi_connector_get_output_format_name(fmt),261 bpc);262 return false;263 }264 265 ret = hdmi_compute_clock(connector, conn_state, mode, bpc, fmt);266 if (ret) {267 drm_dbg_kms(dev, "Couldn't compute clock for %s output format and %u bpc\n",268 drm_hdmi_connector_get_output_format_name(fmt),269 bpc);270 return false;271 }272 273 drm_dbg_kms(dev, "%s output format supported with %u (TMDS char rate: %llu Hz)\n",274 drm_hdmi_connector_get_output_format_name(fmt),275 bpc, conn_state->hdmi.tmds_char_rate);276 277 return true;278}279 280static int281hdmi_compute_format(const struct drm_connector *connector,282 struct drm_connector_state *conn_state,283 const struct drm_display_mode *mode,284 unsigned int bpc)285{286 struct drm_device *dev = connector->dev;287 288 /*289 * TODO: Add support for YCbCr420 output for HDMI 2.0 capable290 * devices, for modes that only support YCbCr420.291 */292 if (hdmi_try_format_bpc(connector, conn_state, mode, bpc, HDMI_COLORSPACE_RGB)) {293 conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB;294 return 0;295 }296 297 drm_dbg_kms(dev, "Failed. No Format Supported for that bpc count.\n");298 299 return -EINVAL;300}301 302static int303hdmi_compute_config(const struct drm_connector *connector,304 struct drm_connector_state *conn_state,305 const struct drm_display_mode *mode)306{307 struct drm_device *dev = connector->dev;308 unsigned int max_bpc = clamp_t(unsigned int,309 conn_state->max_bpc,310 8, connector->max_bpc);311 unsigned int bpc;312 int ret;313 314 for (bpc = max_bpc; bpc >= 8; bpc -= 2) {315 drm_dbg_kms(dev, "Trying with a %d bpc output\n", bpc);316 317 ret = hdmi_compute_format(connector, conn_state, mode, bpc);318 if (ret)319 continue;320 321 conn_state->hdmi.output_bpc = bpc;322 323 drm_dbg_kms(dev,324 "Mode %ux%u @ %uHz: Found configuration: bpc: %u, fmt: %s, clock: %llu\n",325 mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),326 conn_state->hdmi.output_bpc,327 drm_hdmi_connector_get_output_format_name(conn_state->hdmi.output_format),328 conn_state->hdmi.tmds_char_rate);329 330 return 0;331 }332 333 return -EINVAL;334}335 336static int hdmi_generate_avi_infoframe(const struct drm_connector *connector,337 struct drm_connector_state *conn_state)338{339 const struct drm_display_mode *mode =340 connector_state_get_mode(conn_state);341 struct drm_connector_hdmi_infoframe *infoframe =342 &conn_state->hdmi.infoframes.avi;343 struct hdmi_avi_infoframe *frame =344 &infoframe->data.avi;345 bool is_limited_range = conn_state->hdmi.is_limited_range;346 enum hdmi_quantization_range rgb_quant_range =347 is_limited_range ? HDMI_QUANTIZATION_RANGE_LIMITED : HDMI_QUANTIZATION_RANGE_FULL;348 int ret;349 350 ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, mode);351 if (ret)352 return ret;353 354 frame->colorspace = conn_state->hdmi.output_format;355 356 /*357 * FIXME: drm_hdmi_avi_infoframe_quant_range() doesn't handle358 * YUV formats at all at the moment, so if we ever support YUV359 * formats this needs to be revised.360 */361 drm_hdmi_avi_infoframe_quant_range(frame, connector, mode, rgb_quant_range);362 drm_hdmi_avi_infoframe_colorimetry(frame, conn_state);363 drm_hdmi_avi_infoframe_bars(frame, conn_state);364 365 infoframe->set = true;366 367 return 0;368}369 370static int hdmi_generate_spd_infoframe(const struct drm_connector *connector,371 struct drm_connector_state *conn_state)372{373 struct drm_connector_hdmi_infoframe *infoframe =374 &conn_state->hdmi.infoframes.spd;375 struct hdmi_spd_infoframe *frame =376 &infoframe->data.spd;377 int ret;378 379 ret = hdmi_spd_infoframe_init(frame,380 connector->hdmi.vendor,381 connector->hdmi.product);382 if (ret)383 return ret;384 385 frame->sdi = HDMI_SPD_SDI_PC;386 387 infoframe->set = true;388 389 return 0;390}391 392static int hdmi_generate_hdr_infoframe(const struct drm_connector *connector,393 struct drm_connector_state *conn_state)394{395 struct drm_connector_hdmi_infoframe *infoframe =396 &conn_state->hdmi.infoframes.hdr_drm;397 struct hdmi_drm_infoframe *frame =398 &infoframe->data.drm;399 int ret;400 401 if (connector->max_bpc < 10)402 return 0;403 404 if (!conn_state->hdr_output_metadata)405 return 0;406 407 ret = drm_hdmi_infoframe_set_hdr_metadata(frame, conn_state);408 if (ret)409 return ret;410 411 infoframe->set = true;412 413 return 0;414}415 416static int hdmi_generate_hdmi_vendor_infoframe(const struct drm_connector *connector,417 struct drm_connector_state *conn_state)418{419 const struct drm_display_info *info = &connector->display_info;420 const struct drm_display_mode *mode =421 connector_state_get_mode(conn_state);422 struct drm_connector_hdmi_infoframe *infoframe =423 &conn_state->hdmi.infoframes.hdmi;424 struct hdmi_vendor_infoframe *frame =425 &infoframe->data.vendor.hdmi;426 int ret;427 428 if (!info->has_hdmi_infoframe)429 return 0;430 431 ret = drm_hdmi_vendor_infoframe_from_display_mode(frame, connector, mode);432 if (ret)433 return ret;434 435 infoframe->set = true;436 437 return 0;438}439 440static int441hdmi_generate_infoframes(const struct drm_connector *connector,442 struct drm_connector_state *conn_state)443{444 const struct drm_display_info *info = &connector->display_info;445 int ret;446 447 if (!info->is_hdmi)448 return 0;449 450 ret = hdmi_generate_avi_infoframe(connector, conn_state);451 if (ret)452 return ret;453 454 ret = hdmi_generate_spd_infoframe(connector, conn_state);455 if (ret)456 return ret;457 458 /*459 * Audio Infoframes will be generated by ALSA, and updated by460 * drm_atomic_helper_connector_hdmi_update_audio_infoframe().461 */462 463 ret = hdmi_generate_hdr_infoframe(connector, conn_state);464 if (ret)465 return ret;466 467 ret = hdmi_generate_hdmi_vendor_infoframe(connector, conn_state);468 if (ret)469 return ret;470 471 return 0;472}473 474/**475 * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state476 * @connector: DRM Connector477 * @state: the DRM State object478 *479 * Provides a default connector state check handler for HDMI connectors.480 * Checks that a desired connector update is valid, and updates various481 * fields of derived state.482 *483 * RETURNS:484 * Zero on success, or an errno code otherwise.485 */486int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector,487 struct drm_atomic_state *state)488{489 struct drm_connector_state *old_conn_state =490 drm_atomic_get_old_connector_state(state, connector);491 struct drm_connector_state *new_conn_state =492 drm_atomic_get_new_connector_state(state, connector);493 const struct drm_display_mode *mode =494 connector_state_get_mode(new_conn_state);495 int ret;496 497 new_conn_state->hdmi.is_limited_range = hdmi_is_limited_range(connector, new_conn_state);498 499 ret = hdmi_compute_config(connector, new_conn_state, mode);500 if (ret)501 return ret;502 503 ret = hdmi_generate_infoframes(connector, new_conn_state);504 if (ret)505 return ret;506 507 if (old_conn_state->hdmi.broadcast_rgb != new_conn_state->hdmi.broadcast_rgb ||508 old_conn_state->hdmi.output_bpc != new_conn_state->hdmi.output_bpc ||509 old_conn_state->hdmi.output_format != new_conn_state->hdmi.output_format) {510 struct drm_crtc *crtc = new_conn_state->crtc;511 struct drm_crtc_state *crtc_state;512 513 crtc_state = drm_atomic_get_crtc_state(state, crtc);514 if (IS_ERR(crtc_state))515 return PTR_ERR(crtc_state);516 517 crtc_state->mode_changed = true;518 }519 520 return 0;521}522EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_check);523 524static int clear_device_infoframe(struct drm_connector *connector,525 enum hdmi_infoframe_type type)526{527 const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;528 struct drm_device *dev = connector->dev;529 int ret;530 531 drm_dbg_kms(dev, "Clearing infoframe type 0x%x\n", type);532 533 if (!funcs || !funcs->clear_infoframe) {534 drm_dbg_kms(dev, "Function not implemented, bailing.\n");535 return 0;536 }537 538 ret = funcs->clear_infoframe(connector, type);539 if (ret) {540 drm_dbg_kms(dev, "Call failed: %d\n", ret);541 return ret;542 }543 544 return 0;545}546 547static int clear_infoframe(struct drm_connector *connector,548 struct drm_connector_hdmi_infoframe *old_frame)549{550 int ret;551 552 ret = clear_device_infoframe(connector, old_frame->data.any.type);553 if (ret)554 return ret;555 556 return 0;557}558 559static int write_device_infoframe(struct drm_connector *connector,560 union hdmi_infoframe *frame)561{562 const struct drm_connector_hdmi_funcs *funcs = connector->hdmi.funcs;563 struct drm_device *dev = connector->dev;564 u8 buffer[HDMI_INFOFRAME_SIZE(MAX)];565 int ret;566 int len;567 568 drm_dbg_kms(dev, "Writing infoframe type %x\n", frame->any.type);569 570 if (!funcs || !funcs->write_infoframe) {571 drm_dbg_kms(dev, "Function not implemented, bailing.\n");572 return -EINVAL;573 }574 575 len = hdmi_infoframe_pack(frame, buffer, sizeof(buffer));576 if (len < 0)577 return len;578 579 ret = funcs->write_infoframe(connector, frame->any.type, buffer, len);580 if (ret) {581 drm_dbg_kms(dev, "Call failed: %d\n", ret);582 return ret;583 }584 585 return 0;586}587 588static int write_infoframe(struct drm_connector *connector,589 struct drm_connector_hdmi_infoframe *new_frame)590{591 int ret;592 593 ret = write_device_infoframe(connector, &new_frame->data);594 if (ret)595 return ret;596 597 return 0;598}599 600static int write_or_clear_infoframe(struct drm_connector *connector,601 struct drm_connector_hdmi_infoframe *old_frame,602 struct drm_connector_hdmi_infoframe *new_frame)603{604 if (new_frame->set)605 return write_infoframe(connector, new_frame);606 607 if (old_frame->set && !new_frame->set)608 return clear_infoframe(connector, old_frame);609 610 return 0;611}612 613/**614 * drm_atomic_helper_connector_hdmi_update_infoframes - Update the Infoframes615 * @connector: A pointer to the HDMI connector616 * @state: The HDMI connector state to generate the infoframe from617 *618 * This function is meant for HDMI connector drivers to write their619 * infoframes. It will typically be used in a620 * @drm_connector_helper_funcs.atomic_enable implementation.621 *622 * Returns:623 * Zero on success, error code on failure.624 */625int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,626 struct drm_atomic_state *state)627{628 struct drm_connector_state *old_conn_state =629 drm_atomic_get_old_connector_state(state, connector);630 struct drm_connector_state *new_conn_state =631 drm_atomic_get_new_connector_state(state, connector);632 struct drm_display_info *info = &connector->display_info;633 int ret;634 635 if (!info->is_hdmi)636 return 0;637 638 mutex_lock(&connector->hdmi.infoframes.lock);639 640 ret = write_or_clear_infoframe(connector,641 &old_conn_state->hdmi.infoframes.avi,642 &new_conn_state->hdmi.infoframes.avi);643 if (ret)644 goto out;645 646 if (connector->hdmi.infoframes.audio.set) {647 ret = write_infoframe(connector,648 &connector->hdmi.infoframes.audio);649 if (ret)650 goto out;651 }652 653 ret = write_or_clear_infoframe(connector,654 &old_conn_state->hdmi.infoframes.hdr_drm,655 &new_conn_state->hdmi.infoframes.hdr_drm);656 if (ret)657 goto out;658 659 ret = write_or_clear_infoframe(connector,660 &old_conn_state->hdmi.infoframes.spd,661 &new_conn_state->hdmi.infoframes.spd);662 if (ret)663 goto out;664 665 if (info->has_hdmi_infoframe) {666 ret = write_or_clear_infoframe(connector,667 &old_conn_state->hdmi.infoframes.hdmi,668 &new_conn_state->hdmi.infoframes.hdmi);669 if (ret)670 goto out;671 }672 673out:674 mutex_unlock(&connector->hdmi.infoframes.lock);675 return ret;676}677EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_infoframes);678 679/**680 * drm_atomic_helper_connector_hdmi_update_audio_infoframe - Update the Audio Infoframe681 * @connector: A pointer to the HDMI connector682 * @frame: A pointer to the audio infoframe to write683 *684 * This function is meant for HDMI connector drivers to update their685 * audio infoframe. It will typically be used in one of the ALSA hooks686 * (most likely prepare).687 *688 * Returns:689 * Zero on success, error code on failure.690 */691int692drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector *connector,693 struct hdmi_audio_infoframe *frame)694{695 struct drm_connector_hdmi_infoframe *infoframe =696 &connector->hdmi.infoframes.audio;697 struct drm_display_info *info = &connector->display_info;698 int ret;699 700 if (!info->is_hdmi)701 return 0;702 703 mutex_lock(&connector->hdmi.infoframes.lock);704 705 memcpy(&infoframe->data, frame, sizeof(infoframe->data));706 infoframe->set = true;707 708 ret = write_infoframe(connector, infoframe);709 710 mutex_unlock(&connector->hdmi.infoframes.lock);711 712 return ret;713}714EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_update_audio_infoframe);715 716/**717 * drm_atomic_helper_connector_hdmi_clear_audio_infoframe - Stop sending the Audio Infoframe718 * @connector: A pointer to the HDMI connector719 *720 * This function is meant for HDMI connector drivers to stop sending their721 * audio infoframe. It will typically be used in one of the ALSA hooks722 * (most likely shutdown).723 *724 * Returns:725 * Zero on success, error code on failure.726 */727int728drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector)729{730 struct drm_connector_hdmi_infoframe *infoframe =731 &connector->hdmi.infoframes.audio;732 struct drm_display_info *info = &connector->display_info;733 int ret;734 735 if (!info->is_hdmi)736 return 0;737 738 mutex_lock(&connector->hdmi.infoframes.lock);739 740 infoframe->set = false;741 742 ret = clear_infoframe(connector, infoframe);743 744 memset(&infoframe->data, 0, sizeof(infoframe->data));745 746 mutex_unlock(&connector->hdmi.infoframes.lock);747 748 return ret;749}750EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);751