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
msm_hdmi_power_on(struct drm_bridge * bridge)16 static 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
power_off(struct drm_bridge * bridge)37 static 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
msm_hdmi_config_avi_infoframe(struct hdmi * hdmi,const u8 * buffer,size_t len)57 static 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
msm_hdmi_config_audio_infoframe(struct hdmi * hdmi,const u8 * buffer,size_t len)96 static 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
msm_hdmi_config_spd_infoframe(struct hdmi * hdmi,const u8 * buffer,size_t len)129 static 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
msm_hdmi_config_hdmi_infoframe(struct hdmi * hdmi,const u8 * buffer,size_t len)162 static 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
msm_hdmi_bridge_clear_infoframe(struct drm_bridge * bridge,enum hdmi_infoframe_type type)197 static 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
msm_hdmi_bridge_write_infoframe(struct drm_bridge * bridge,enum hdmi_infoframe_type type,const u8 * buffer,size_t len)257 static 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
281 static void msm_hdmi_set_timings(struct hdmi *hdmi,
282 const struct drm_display_mode *mode);
283
msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge * bridge,struct drm_atomic_state * state)284 static 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
msm_hdmi_bridge_atomic_post_disable(struct drm_bridge * bridge,struct drm_atomic_state * state)326 static 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
msm_hdmi_set_timings(struct hdmi * hdmi,const struct drm_display_mode * mode)354 static 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
msm_hdmi_bridge_edid_read(struct drm_bridge * bridge,struct drm_connector * connector)405 static 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
msm_hdmi_bridge_tmds_char_rate_valid(const struct drm_bridge * bridge,const struct drm_display_mode * mode,unsigned long long tmds_rate)423 static 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
454 static 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
471 static void
msm_hdmi_hotplug_work(struct work_struct * work)472 msm_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 */
msm_hdmi_bridge_init(struct hdmi * hdmi)482 int 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 }
522