File Index
Files and directories
Sign in
FILE

hdmi_bridge.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2013 Red Hat
  4 * Author: Rob Clark <robdclark@gmail.com>
  5 */
  6
  7#include <linux/delay.h>
  8#include <drm/drm_bridge_connector.h>
  9#include <drm/drm_edid.h>
 10#include <drm/display/drm_hdmi_helper.h>
 11#include <drm/display/drm_hdmi_state_helper.h>
 12
 13#include "msm_kms.h"
 14#include "hdmi.h"
 15
 16static void msm_hdmi_power_on(struct drm_bridge *bridge)
 17{
 18	struct drm_device *dev = bridge->dev;
 19	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
 20	struct hdmi *hdmi = hdmi_bridge->hdmi;
 21	int ret;
 22
 23	pm_runtime_resume_and_get(&hdmi->pdev->dev);
 24
 25	if (hdmi->extp_clk) {
 26		DBG("pixclock: %lu", hdmi->pixclock);
 27		ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock);
 28		if (ret)
 29			DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: %d\n", ret);
 30
 31		ret = clk_prepare_enable(hdmi->extp_clk);
 32		if (ret)
 33			DRM_DEV_ERROR(dev->dev, "failed to enable extp clk: %d\n", ret);
 34	}
 35}
 36
 37static void power_off(struct drm_bridge *bridge)
 38{
 39	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
 40	struct hdmi *hdmi = hdmi_bridge->hdmi;
 41
 42	/* TODO do we need to wait for final vblank somewhere before
 43	 * cutting the clocks?
 44	 */
 45	mdelay(16 + 4);
 46
 47	if (hdmi->extp_clk)
 48		clk_disable_unprepare(hdmi->extp_clk);
 49
 50	pm_runtime_put(&hdmi->pdev->dev);
 51}
 52
 53#define AVI_IFRAME_LINE_NUMBER 1
 54#define SPD_IFRAME_LINE_NUMBER 1
 55#define VENSPEC_IFRAME_LINE_NUMBER 3
 56
 57static int msm_hdmi_config_avi_infoframe(struct hdmi *hdmi,
 58					 const u8 *buffer, size_t len)
 59{
 60	u32 buf[4] = {};
 61	u32 val;
 62	int i;
 63
 64	if (len != HDMI_INFOFRAME_SIZE(AVI) || len - 3 > sizeof(buf)) {
 65		DRM_DEV_ERROR(&hdmi->pdev->dev,
 66			"failed to configure avi infoframe\n");
 67		return -EINVAL;
 68	}
 69
 70	/*
 71	 * the AVI_INFOx registers don't map exactly to how the AVI infoframes
 72	 * are packed according to the spec. The checksum from the header is
 73	 * written to the LSB byte of AVI_INFO0 and the version is written to
 74	 * the third byte from the LSB of AVI_INFO3
 75	 */
 76	memcpy(buf, &buffer[3], len - 3);
 77
 78	buf[3] |= buffer[1] << 24;
 79
 80	for (i = 0; i < ARRAY_SIZE(buf); i++)
 81		hdmi_write(hdmi, REG_HDMI_AVI_INFO(i), buf[i]);
 82
 83	val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
 84	val |= HDMI_INFOFRAME_CTRL0_AVI_SEND |
 85		HDMI_INFOFRAME_CTRL0_AVI_CONT;
 86	hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
 87
 88	val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
 89	val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
 90	val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER);
 91	hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
 92
 93	return 0;
 94}
 95
 96static int msm_hdmi_config_audio_infoframe(struct hdmi *hdmi,
 97					   const u8 *buffer, size_t len)
 98{
 99	u32 val;
100
101	if (len != HDMI_INFOFRAME_SIZE(AUDIO)) {
102		DRM_DEV_ERROR(&hdmi->pdev->dev,
103			"failed to configure audio infoframe\n");
104		return -EINVAL;
105	}
106
107	hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0,
108		   buffer[3] |
109		   buffer[4] << 8 |
110		   buffer[5] << 16 |
111		   buffer[6] << 24);
112
113	hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1,
114		   buffer[7] |
115		   buffer[8] << 8 |
116		   buffer[9] << 16 |
117		   buffer[10] << 24);
118
119	val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
120	val |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
121		HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
122		HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
123		HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
124	hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
125
126	return 0;
127}
128
129static int msm_hdmi_config_spd_infoframe(struct hdmi *hdmi,
130					 const u8 *buffer, size_t len)
131{
132	u32 buf[7] = {};
133	u32 val;
134	int i;
135
136	if (len != HDMI_INFOFRAME_SIZE(SPD) || len - 3 > sizeof(buf)) {
137		DRM_DEV_ERROR(&hdmi->pdev->dev,
138			"failed to configure SPD infoframe\n");
139		return -EINVAL;
140	}
141
142	/* checksum gets written together with the body of the frame */
143	hdmi_write(hdmi, REG_HDMI_GENERIC1_HDR,
144		   buffer[0] |
145		   buffer[1] << 8 |
146		   buffer[2] << 16);
147
148	memcpy(buf, &buffer[3], len - 3);
149
150	for (i = 0; i < ARRAY_SIZE(buf); i++)
151		hdmi_write(hdmi, REG_HDMI_GENERIC1(i), buf[i]);
152
153	val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
154	val |= HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
155		 HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
156		 HDMI_GEN_PKT_CTRL_GENERIC1_LINE(SPD_IFRAME_LINE_NUMBER);
157	hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
158
159	return 0;
160}
161
162static int msm_hdmi_config_hdmi_infoframe(struct hdmi *hdmi,
163					  const u8 *buffer, size_t len)
164{
165	u32 buf[7] = {};
166	u32 val;
167	int i;
168
169	if (len < HDMI_INFOFRAME_HEADER_SIZE + HDMI_VENDOR_INFOFRAME_SIZE ||
170	    len - 3 > sizeof(buf)) {
171		DRM_DEV_ERROR(&hdmi->pdev->dev,
172			"failed to configure HDMI infoframe\n");
173		return -EINVAL;
174	}
175
176	/* checksum gets written together with the body of the frame */
177	hdmi_write(hdmi, REG_HDMI_GENERIC0_HDR,
178		   buffer[0] |
179		   buffer[1] << 8 |
180		   buffer[2] << 16);
181
182	memcpy(buf, &buffer[3], len - 3);
183
184	for (i = 0; i < ARRAY_SIZE(buf); i++)
185		hdmi_write(hdmi, REG_HDMI_GENERIC0(i), buf[i]);
186
187	val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
188	val |= HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
189		 HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
190		 HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
191		 HDMI_GEN_PKT_CTRL_GENERIC0_LINE(VENSPEC_IFRAME_LINE_NUMBER);
192	hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
193
194	return 0;
195}
196
197static int msm_hdmi_bridge_clear_infoframe(struct drm_bridge *bridge,
198					   enum hdmi_infoframe_type type)
199{
200	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
201	struct hdmi *hdmi = hdmi_bridge->hdmi;
202	u32 val;
203
204	switch (type) {
205	case HDMI_INFOFRAME_TYPE_AVI:
206		val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
207		val &= ~(HDMI_INFOFRAME_CTRL0_AVI_SEND |
208			 HDMI_INFOFRAME_CTRL0_AVI_CONT);
209		hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
210
211		val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
212		val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
213		hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
214
215		break;
216
217	case HDMI_INFOFRAME_TYPE_AUDIO:
218		val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
219		val &= ~(HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND |
220			 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT |
221			 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE |
222			 HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE);
223		hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, val);
224
225		val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
226		val &= ~HDMI_INFOFRAME_CTRL1_AUDIO_INFO_LINE__MASK;
227		hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
228
229		break;
230
231	case HDMI_INFOFRAME_TYPE_SPD:
232		val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
233		val &= ~(HDMI_GEN_PKT_CTRL_GENERIC1_SEND |
234			 HDMI_GEN_PKT_CTRL_GENERIC1_CONT |
235			 HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK);
236		hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
237
238		break;
239
240	case HDMI_INFOFRAME_TYPE_VENDOR:
241		val = hdmi_read(hdmi, REG_HDMI_GEN_PKT_CTRL);
242		val &= ~(HDMI_GEN_PKT_CTRL_GENERIC0_SEND |
243			 HDMI_GEN_PKT_CTRL_GENERIC0_CONT |
244			 HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE |
245			 HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK);
246		hdmi_write(hdmi, REG_HDMI_GEN_PKT_CTRL, val);
247
248		break;
249
250	default:
251		drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type);
252	}
253
254	return 0;
255}
256
257static int msm_hdmi_bridge_write_infoframe(struct drm_bridge *bridge,
258					   enum hdmi_infoframe_type type,
259					   const u8 *buffer, size_t len)
260{
261	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
262	struct hdmi *hdmi = hdmi_bridge->hdmi;
263
264	msm_hdmi_bridge_clear_infoframe(bridge, type);
265
266	switch (type) {
267	case HDMI_INFOFRAME_TYPE_AVI:
268		return msm_hdmi_config_avi_infoframe(hdmi, buffer, len);
269	case HDMI_INFOFRAME_TYPE_AUDIO:
270		return msm_hdmi_config_audio_infoframe(hdmi, buffer, len);
271	case HDMI_INFOFRAME_TYPE_SPD:
272		return msm_hdmi_config_spd_infoframe(hdmi, buffer, len);
273	case HDMI_INFOFRAME_TYPE_VENDOR:
274		return msm_hdmi_config_hdmi_infoframe(hdmi, buffer, len);
275	default:
276		drm_dbg_driver(hdmi_bridge->base.dev, "Unsupported infoframe type %x\n", type);
277		return 0;
278	}
279}
280
281static void msm_hdmi_set_timings(struct hdmi *hdmi,
282				 const struct drm_display_mode *mode);
283
284static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
285					      struct drm_atomic_state *state)
286{
287	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
288	struct hdmi *hdmi = hdmi_bridge->hdmi;
289	struct hdmi_phy *phy = hdmi->phy;
290	struct drm_encoder *encoder = bridge->encoder;
291	struct drm_connector *connector;
292	struct drm_connector_state *conn_state;
293	struct drm_crtc_state *crtc_state;
294
295	DBG("power up");
296
297	connector = drm_atomic_get_new_connector_for_encoder(state, encoder);
298	conn_state = drm_atomic_get_new_connector_state(state, connector);
299	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
300
301	hdmi->pixclock = conn_state->hdmi.tmds_char_rate;
302
303	msm_hdmi_set_timings(hdmi, &crtc_state->adjusted_mode);
304
305	mutex_lock(&hdmi->state_mutex);
306	if (!hdmi->power_on) {
307		msm_hdmi_phy_resource_enable(phy);
308		msm_hdmi_power_on(bridge);
309		hdmi->power_on = true;
310	}
311	mutex_unlock(&hdmi->state_mutex);
312
313	if (connector->display_info.is_hdmi)
314		msm_hdmi_audio_update(hdmi);
315
316	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
317
318	msm_hdmi_phy_powerup(phy, hdmi->pixclock);
319
320	msm_hdmi_set_mode(hdmi, true);
321
322	if (hdmi->hdcp_ctrl)
323		msm_hdmi_hdcp_on(hdmi->hdcp_ctrl);
324}
325
326static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
327						struct drm_atomic_state *state)
328{
329	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
330	struct hdmi *hdmi = hdmi_bridge->hdmi;
331	struct hdmi_phy *phy = hdmi->phy;
332
333	if (hdmi->hdcp_ctrl)
334		msm_hdmi_hdcp_off(hdmi->hdcp_ctrl);
335
336	DBG("power down");
337
338	/* Keep the HDMI enabled if the HPD is enabled */
339	mutex_lock(&hdmi->state_mutex);
340	msm_hdmi_set_mode(hdmi, hdmi->hpd_enabled);
341
342	msm_hdmi_phy_powerdown(phy);
343
344	if (hdmi->power_on) {
345		power_off(bridge);
346		hdmi->power_on = false;
347		if (hdmi->connector->display_info.is_hdmi)
348			msm_hdmi_audio_update(hdmi);
349		msm_hdmi_phy_resource_disable(phy);
350	}
351	mutex_unlock(&hdmi->state_mutex);
352}
353
354static void msm_hdmi_set_timings(struct hdmi *hdmi,
355				 const struct drm_display_mode *mode)
356{
357	int hstart, hend, vstart, vend;
358	uint32_t frame_ctrl;
359
360	hstart = mode->htotal - mode->hsync_start;
361	hend   = mode->htotal - mode->hsync_start + mode->hdisplay;
362
363	vstart = mode->vtotal - mode->vsync_start - 1;
364	vend   = mode->vtotal - mode->vsync_start + mode->vdisplay - 1;
365
366	DBG("htotal=%d, vtotal=%d, hstart=%d, hend=%d, vstart=%d, vend=%d",
367			mode->htotal, mode->vtotal, hstart, hend, vstart, vend);
368
369	hdmi_write(hdmi, REG_HDMI_TOTAL,
370			HDMI_TOTAL_H_TOTAL(mode->htotal - 1) |
371			HDMI_TOTAL_V_TOTAL(mode->vtotal - 1));
372
373	hdmi_write(hdmi, REG_HDMI_ACTIVE_HSYNC,
374			HDMI_ACTIVE_HSYNC_START(hstart) |
375			HDMI_ACTIVE_HSYNC_END(hend));
376	hdmi_write(hdmi, REG_HDMI_ACTIVE_VSYNC,
377			HDMI_ACTIVE_VSYNC_START(vstart) |
378			HDMI_ACTIVE_VSYNC_END(vend));
379
380	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
381		hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
382				HDMI_VSYNC_TOTAL_F2_V_TOTAL(mode->vtotal));
383		hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
384				HDMI_VSYNC_ACTIVE_F2_START(vstart + 1) |
385				HDMI_VSYNC_ACTIVE_F2_END(vend + 1));
386	} else {
387		hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
388				HDMI_VSYNC_TOTAL_F2_V_TOTAL(0));
389		hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
390				HDMI_VSYNC_ACTIVE_F2_START(0) |
391				HDMI_VSYNC_ACTIVE_F2_END(0));
392	}
393
394	frame_ctrl = 0;
395	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
396		frame_ctrl |= HDMI_FRAME_CTRL_HSYNC_LOW;
397	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
398		frame_ctrl |= HDMI_FRAME_CTRL_VSYNC_LOW;
399	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
400		frame_ctrl |= HDMI_FRAME_CTRL_INTERLACED_EN;
401	DBG("frame_ctrl=%08x", frame_ctrl);
402	hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl);
403}
404
405static const struct drm_edid *msm_hdmi_bridge_edid_read(struct drm_bridge *bridge,
406							struct drm_connector *connector)
407{
408	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
409	struct hdmi *hdmi = hdmi_bridge->hdmi;
410	const struct drm_edid *drm_edid;
411	uint32_t hdmi_ctrl;
412
413	hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
414	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
415
416	drm_edid = drm_edid_read_ddc(connector, hdmi->i2c);
417
418	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
419
420	return drm_edid;
421}
422
423static enum drm_mode_status msm_hdmi_bridge_tmds_char_rate_valid(const struct drm_bridge *bridge,
424								 const struct drm_display_mode *mode,
425								 unsigned long long tmds_rate)
426{
427	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
428	struct hdmi *hdmi = hdmi_bridge->hdmi;
429	struct msm_drm_private *priv = bridge->dev->dev_private;
430	struct msm_kms *kms = priv->kms;
431	long actual;
432
433	/* for mdp5/apq8074, we manage our own pixel clk (as opposed to
434	 * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder
435	 * instead):
436	 */
437	if (kms->funcs->round_pixclk)
438		actual = kms->funcs->round_pixclk(kms,
439						  tmds_rate,
440						  hdmi_bridge->hdmi->encoder);
441	else if (hdmi->extp_clk)
442		actual = clk_round_rate(hdmi->extp_clk, tmds_rate);
443	else
444		actual = tmds_rate;
445
446	DBG("requested=%lld, actual=%ld", tmds_rate, actual);
447
448	if (actual != tmds_rate)
449		return MODE_CLOCK_RANGE;
450
451	return 0;
452}
453
454static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
455	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
456	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
457	.atomic_reset = drm_atomic_helper_bridge_reset,
458	.atomic_pre_enable = msm_hdmi_bridge_atomic_pre_enable,
459	.atomic_post_disable = msm_hdmi_bridge_atomic_post_disable,
460	.edid_read = msm_hdmi_bridge_edid_read,
461	.detect = msm_hdmi_bridge_detect,
462	.hpd_enable = msm_hdmi_hpd_enable,
463	.hpd_disable = msm_hdmi_hpd_disable,
464	.hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid,
465	.hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe,
466	.hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe,
467	.hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare,
468	.hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown,
469};
470
471static void
472msm_hdmi_hotplug_work(struct work_struct *work)
473{
474	struct hdmi_bridge *hdmi_bridge =
475		container_of(work, struct hdmi_bridge, hpd_work);
476	struct drm_bridge *bridge = &hdmi_bridge->base;
477
478	drm_bridge_hpd_notify(bridge, drm_bridge_detect(bridge, hdmi_bridge->hdmi->connector));
479}
480
481/* initialize bridge */
482int msm_hdmi_bridge_init(struct hdmi *hdmi)
483{
484	struct drm_bridge *bridge = NULL;
485	struct hdmi_bridge *hdmi_bridge;
486	int ret;
487
488	hdmi_bridge = devm_drm_bridge_alloc(hdmi->dev->dev, struct hdmi_bridge, base,
489					    &msm_hdmi_bridge_funcs);
490	if (IS_ERR(hdmi_bridge))
491		return PTR_ERR(hdmi_bridge);
492
493	hdmi_bridge->hdmi = hdmi;
494	INIT_WORK(&hdmi_bridge->hpd_work, msm_hdmi_hotplug_work);
495
496	bridge = &hdmi_bridge->base;
497	bridge->ddc = hdmi->i2c;
498	bridge->type = DRM_MODE_CONNECTOR_HDMIA;
499	bridge->vendor = "Qualcomm";
500	bridge->product = "Snapdragon";
501	bridge->ops = DRM_BRIDGE_OP_HPD |
502		DRM_BRIDGE_OP_DETECT |
503		DRM_BRIDGE_OP_HDMI |
504		DRM_BRIDGE_OP_HDMI_AUDIO |
505		DRM_BRIDGE_OP_EDID;
506	bridge->hdmi_audio_max_i2s_playback_channels = 8;
507	bridge->hdmi_audio_dev = &hdmi->pdev->dev;
508	bridge->hdmi_audio_dai_port = -1;
509
510	ret = devm_drm_bridge_add(hdmi->dev->dev, bridge);
511	if (ret)
512		return ret;
513
514	ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
515	if (ret)
516		return ret;
517
518	hdmi->bridge = bridge;
519
520	return 0;
521}
~/ Read-only file preview.