brintos

brintos / linux-shallow public Read only

0
0
Text · 20.4 KiB · feb7a3a Raw
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