xref: /linux/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2021-2022 Rockchip Electronics Co., Ltd.
4  * Copyright (c) 2024 Collabora Ltd.
5  *
6  * Author: Algea Cao <algea.cao@rock-chips.com>
7  * Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
8  */
9 #include <linux/completion.h>
10 #include <linux/hdmi.h>
11 #include <linux/i2c.h>
12 #include <linux/irq.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/of.h>
16 #include <linux/workqueue.h>
17 
18 #include <drm/bridge/dw_hdmi_qp.h>
19 #include <drm/display/drm_hdmi_helper.h>
20 #include <drm/display/drm_hdmi_state_helper.h>
21 #include <drm/drm_atomic.h>
22 #include <drm/drm_atomic_helper.h>
23 #include <drm/drm_bridge.h>
24 #include <drm/drm_connector.h>
25 #include <drm/drm_edid.h>
26 #include <drm/drm_modes.h>
27 
28 #include <sound/hdmi-codec.h>
29 
30 #include "dw-hdmi-qp.h"
31 
32 #define DDC_CI_ADDR		0x37
33 #define DDC_SEGMENT_ADDR	0x30
34 
35 #define HDMI14_MAX_TMDSCLK	340000000
36 
37 #define SCRAMB_POLL_DELAY_MS	3000
38 
39 struct dw_hdmi_qp_i2c {
40 	struct i2c_adapter	adap;
41 
42 	struct mutex		lock;	/* used to serialize data transfers */
43 	struct completion	cmp;
44 	u8			stat;
45 
46 	u8			slave_reg;
47 	bool			is_regaddr;
48 	bool			is_segment;
49 };
50 
51 struct dw_hdmi_qp {
52 	struct drm_bridge bridge;
53 
54 	struct device *dev;
55 	struct dw_hdmi_qp_i2c *i2c;
56 
57 	struct {
58 		const struct dw_hdmi_qp_phy_ops *ops;
59 		void *data;
60 	} phy;
61 
62 	struct regmap *regm;
63 };
64 
65 static void dw_hdmi_qp_write(struct dw_hdmi_qp *hdmi, unsigned int val,
66 			     int offset)
67 {
68 	regmap_write(hdmi->regm, offset, val);
69 }
70 
71 static unsigned int dw_hdmi_qp_read(struct dw_hdmi_qp *hdmi, int offset)
72 {
73 	unsigned int val = 0;
74 
75 	regmap_read(hdmi->regm, offset, &val);
76 
77 	return val;
78 }
79 
80 static void dw_hdmi_qp_mod(struct dw_hdmi_qp *hdmi, unsigned int data,
81 			   unsigned int mask, unsigned int reg)
82 {
83 	regmap_update_bits(hdmi->regm, reg, mask, data);
84 }
85 
86 static int dw_hdmi_qp_i2c_read(struct dw_hdmi_qp *hdmi,
87 			       unsigned char *buf, unsigned int length)
88 {
89 	struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
90 	int stat;
91 
92 	if (!i2c->is_regaddr) {
93 		dev_dbg(hdmi->dev, "set read register address to 0\n");
94 		i2c->slave_reg = 0x00;
95 		i2c->is_regaddr = true;
96 	}
97 
98 	while (length--) {
99 		reinit_completion(&i2c->cmp);
100 
101 		dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR,
102 			       I2CM_INTERFACE_CONTROL0);
103 
104 		if (i2c->is_segment)
105 			dw_hdmi_qp_mod(hdmi, I2CM_EXT_READ, I2CM_WR_MASK,
106 				       I2CM_INTERFACE_CONTROL0);
107 		else
108 			dw_hdmi_qp_mod(hdmi, I2CM_FM_READ, I2CM_WR_MASK,
109 				       I2CM_INTERFACE_CONTROL0);
110 
111 		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
112 		if (!stat) {
113 			dev_err(hdmi->dev, "i2c read timed out\n");
114 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
115 			return -EAGAIN;
116 		}
117 
118 		/* Check for error condition on the bus */
119 		if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
120 			dev_err(hdmi->dev, "i2c read error\n");
121 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
122 			return -EIO;
123 		}
124 
125 		*buf++ = dw_hdmi_qp_read(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff;
126 		dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
127 	}
128 
129 	i2c->is_segment = false;
130 
131 	return 0;
132 }
133 
134 static int dw_hdmi_qp_i2c_write(struct dw_hdmi_qp *hdmi,
135 				unsigned char *buf, unsigned int length)
136 {
137 	struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
138 	int stat;
139 
140 	if (!i2c->is_regaddr) {
141 		/* Use the first write byte as register address */
142 		i2c->slave_reg = buf[0];
143 		length--;
144 		buf++;
145 		i2c->is_regaddr = true;
146 	}
147 
148 	while (length--) {
149 		reinit_completion(&i2c->cmp);
150 
151 		dw_hdmi_qp_write(hdmi, *buf++, I2CM_INTERFACE_WRDATA_0_3);
152 		dw_hdmi_qp_mod(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR,
153 			       I2CM_INTERFACE_CONTROL0);
154 		dw_hdmi_qp_mod(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK,
155 			       I2CM_INTERFACE_CONTROL0);
156 
157 		stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
158 		if (!stat) {
159 			dev_err(hdmi->dev, "i2c write time out!\n");
160 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
161 			return -EAGAIN;
162 		}
163 
164 		/* Check for error condition on the bus */
165 		if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
166 			dev_err(hdmi->dev, "i2c write nack!\n");
167 			dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
168 			return -EIO;
169 		}
170 
171 		dw_hdmi_qp_mod(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
172 	}
173 
174 	return 0;
175 }
176 
177 static int dw_hdmi_qp_i2c_xfer(struct i2c_adapter *adap,
178 			       struct i2c_msg *msgs, int num)
179 {
180 	struct dw_hdmi_qp *hdmi = i2c_get_adapdata(adap);
181 	struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
182 	u8 addr = msgs[0].addr;
183 	int i, ret = 0;
184 
185 	if (addr == DDC_CI_ADDR)
186 		/*
187 		 * The internal I2C controller does not support the multi-byte
188 		 * read and write operations needed for DDC/CI.
189 		 * FIXME: Blacklist the DDC/CI address until we filter out
190 		 * unsupported I2C operations.
191 		 */
192 		return -EOPNOTSUPP;
193 
194 	for (i = 0; i < num; i++) {
195 		if (msgs[i].len == 0) {
196 			dev_err(hdmi->dev,
197 				"unsupported transfer %d/%d, no data\n",
198 				i + 1, num);
199 			return -EOPNOTSUPP;
200 		}
201 	}
202 
203 	guard(mutex)(&i2c->lock);
204 
205 	/* Unmute DONE and ERROR interrupts */
206 	dw_hdmi_qp_mod(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
207 		       I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
208 		       MAINUNIT_1_INT_MASK_N);
209 
210 	/* Set slave device address taken from the first I2C message */
211 	if (addr == DDC_SEGMENT_ADDR && msgs[0].len == 1)
212 		addr = DDC_ADDR;
213 
214 	dw_hdmi_qp_mod(hdmi, addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0);
215 
216 	/* Set slave device register address on transfer */
217 	i2c->is_regaddr = false;
218 
219 	/* Set segment pointer for I2C extended read mode operation */
220 	i2c->is_segment = false;
221 
222 	for (i = 0; i < num; i++) {
223 		if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) {
224 			i2c->is_segment = true;
225 			dw_hdmi_qp_mod(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR,
226 				       I2CM_INTERFACE_CONTROL1);
227 			dw_hdmi_qp_mod(hdmi, *msgs[i].buf << 7, I2CM_SEG_PTR,
228 				       I2CM_INTERFACE_CONTROL1);
229 		} else {
230 			if (msgs[i].flags & I2C_M_RD)
231 				ret = dw_hdmi_qp_i2c_read(hdmi, msgs[i].buf,
232 							  msgs[i].len);
233 			else
234 				ret = dw_hdmi_qp_i2c_write(hdmi, msgs[i].buf,
235 							   msgs[i].len);
236 		}
237 		if (ret < 0)
238 			break;
239 	}
240 
241 	if (!ret)
242 		ret = num;
243 
244 	/* Mute DONE and ERROR interrupts */
245 	dw_hdmi_qp_mod(hdmi, 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N,
246 		       MAINUNIT_1_INT_MASK_N);
247 
248 	return ret;
249 }
250 
251 static u32 dw_hdmi_qp_i2c_func(struct i2c_adapter *adapter)
252 {
253 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
254 }
255 
256 static const struct i2c_algorithm dw_hdmi_qp_algorithm = {
257 	.master_xfer	= dw_hdmi_qp_i2c_xfer,
258 	.functionality	= dw_hdmi_qp_i2c_func,
259 };
260 
261 static struct i2c_adapter *dw_hdmi_qp_i2c_adapter(struct dw_hdmi_qp *hdmi)
262 {
263 	struct dw_hdmi_qp_i2c *i2c;
264 	struct i2c_adapter *adap;
265 	int ret;
266 
267 	i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
268 	if (!i2c)
269 		return ERR_PTR(-ENOMEM);
270 
271 	mutex_init(&i2c->lock);
272 	init_completion(&i2c->cmp);
273 
274 	adap = &i2c->adap;
275 	adap->owner = THIS_MODULE;
276 	adap->dev.parent = hdmi->dev;
277 	adap->algo = &dw_hdmi_qp_algorithm;
278 	strscpy(adap->name, "DesignWare HDMI QP", sizeof(adap->name));
279 
280 	i2c_set_adapdata(adap, hdmi);
281 
282 	ret = devm_i2c_add_adapter(hdmi->dev, adap);
283 	if (ret) {
284 		dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
285 		devm_kfree(hdmi->dev, i2c);
286 		return ERR_PTR(ret);
287 	}
288 
289 	hdmi->i2c = i2c;
290 	dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
291 
292 	return adap;
293 }
294 
295 static int dw_hdmi_qp_config_avi_infoframe(struct dw_hdmi_qp *hdmi,
296 					   const u8 *buffer, size_t len)
297 {
298 	u32 val, i, j;
299 
300 	if (len != HDMI_INFOFRAME_SIZE(AVI)) {
301 		dev_err(hdmi->dev, "failed to configure avi infoframe\n");
302 		return -EINVAL;
303 	}
304 
305 	/*
306 	 * DW HDMI QP IP uses a different byte format from standard AVI info
307 	 * frames, though generally the bits are in the correct bytes.
308 	 */
309 	val = buffer[1] << 8 | buffer[2] << 16;
310 	dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS0);
311 
312 	for (i = 0; i < 4; i++) {
313 		for (j = 0; j < 4; j++) {
314 			if (i * 4 + j >= 14)
315 				break;
316 			if (!j)
317 				val = buffer[i * 4 + j + 3];
318 			val |= buffer[i * 4 + j + 3] << (8 * j);
319 		}
320 
321 		dw_hdmi_qp_write(hdmi, val, PKT_AVI_CONTENTS1 + i * 4);
322 	}
323 
324 	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
325 
326 	dw_hdmi_qp_mod(hdmi, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
327 		       PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN);
328 
329 	return 0;
330 }
331 
332 static int dw_hdmi_qp_config_drm_infoframe(struct dw_hdmi_qp *hdmi,
333 					   const u8 *buffer, size_t len)
334 {
335 	u32 val, i;
336 
337 	if (len != HDMI_INFOFRAME_SIZE(DRM)) {
338 		dev_err(hdmi->dev, "failed to configure drm infoframe\n");
339 		return -EINVAL;
340 	}
341 
342 	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
343 
344 	val = buffer[1] << 8 | buffer[2] << 16;
345 	dw_hdmi_qp_write(hdmi, val, PKT_DRMI_CONTENTS0);
346 
347 	for (i = 0; i <= buffer[2]; i++) {
348 		if (i % 4 == 0)
349 			val = buffer[3 + i];
350 		val |= buffer[3 + i] << ((i % 4) * 8);
351 
352 		if ((i % 4 == 3) || i == buffer[2])
353 			dw_hdmi_qp_write(hdmi, val,
354 					 PKT_DRMI_CONTENTS1 + ((i / 4) * 4));
355 	}
356 
357 	dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
358 	dw_hdmi_qp_mod(hdmi, PKTSCHED_DRMI_TX_EN, PKTSCHED_DRMI_TX_EN,
359 		       PKTSCHED_PKT_EN);
360 
361 	return 0;
362 }
363 
364 static int dw_hdmi_qp_bridge_atomic_check(struct drm_bridge *bridge,
365 					  struct drm_bridge_state *bridge_state,
366 					  struct drm_crtc_state *crtc_state,
367 					  struct drm_connector_state *conn_state)
368 {
369 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
370 	int ret;
371 
372 	ret = drm_atomic_helper_connector_hdmi_check(conn_state->connector,
373 						     conn_state->state);
374 	if (ret)
375 		dev_dbg(hdmi->dev, "%s failed: %d\n", __func__, ret);
376 
377 	return ret;
378 }
379 
380 static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
381 					    struct drm_bridge_state *old_state)
382 {
383 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
384 	struct drm_atomic_state *state = old_state->base.state;
385 	struct drm_connector_state *conn_state;
386 	struct drm_connector *connector;
387 	unsigned int op_mode;
388 
389 	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
390 	if (WARN_ON(!connector))
391 		return;
392 
393 	conn_state = drm_atomic_get_new_connector_state(state, connector);
394 	if (WARN_ON(!conn_state))
395 		return;
396 
397 	if (connector->display_info.is_hdmi) {
398 		dev_dbg(hdmi->dev, "%s mode=HDMI rate=%llu\n",
399 			__func__, conn_state->hdmi.tmds_char_rate);
400 		op_mode = 0;
401 	} else {
402 		dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__);
403 		op_mode = OPMODE_DVI;
404 	}
405 
406 	hdmi->phy.ops->init(hdmi, hdmi->phy.data);
407 
408 	dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
409 	dw_hdmi_qp_mod(hdmi, op_mode, OPMODE_DVI, LINK_CONFIG0);
410 
411 	drm_atomic_helper_connector_hdmi_update_infoframes(connector, state);
412 }
413 
414 static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge,
415 					     struct drm_bridge_state *old_state)
416 {
417 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
418 
419 	hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
420 }
421 
422 static enum drm_connector_status
423 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge)
424 {
425 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
426 
427 	return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
428 }
429 
430 static const struct drm_edid *
431 dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge,
432 			    struct drm_connector *connector)
433 {
434 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
435 	const struct drm_edid *drm_edid;
436 
437 	drm_edid = drm_edid_read_ddc(connector, bridge->ddc);
438 	if (!drm_edid)
439 		dev_dbg(hdmi->dev, "failed to get edid\n");
440 
441 	return drm_edid;
442 }
443 
444 static enum drm_mode_status
445 dw_hdmi_qp_bridge_mode_valid(struct drm_bridge *bridge,
446 			     const struct drm_display_info *info,
447 			     const struct drm_display_mode *mode)
448 {
449 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
450 	unsigned long long rate;
451 
452 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
453 	if (rate > HDMI14_MAX_TMDSCLK) {
454 		dev_dbg(hdmi->dev, "Unsupported mode clock: %d\n", mode->clock);
455 		return MODE_CLOCK_HIGH;
456 	}
457 
458 	return MODE_OK;
459 }
460 
461 static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge,
462 					     enum hdmi_infoframe_type type)
463 {
464 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
465 
466 	switch (type) {
467 	case HDMI_INFOFRAME_TYPE_AVI:
468 		dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN,
469 			       PKTSCHED_PKT_EN);
470 		break;
471 
472 	case HDMI_INFOFRAME_TYPE_DRM:
473 		dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN);
474 		break;
475 
476 	default:
477 		dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type);
478 	}
479 
480 	return 0;
481 }
482 
483 static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge,
484 					     enum hdmi_infoframe_type type,
485 					     const u8 *buffer, size_t len)
486 {
487 	struct dw_hdmi_qp *hdmi = bridge->driver_private;
488 
489 	dw_hdmi_qp_bridge_clear_infoframe(bridge, type);
490 
491 	switch (type) {
492 	case HDMI_INFOFRAME_TYPE_AVI:
493 		return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len);
494 
495 	case HDMI_INFOFRAME_TYPE_DRM:
496 		return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len);
497 
498 	default:
499 		dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type);
500 		return 0;
501 	}
502 }
503 
504 static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = {
505 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
506 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
507 	.atomic_reset = drm_atomic_helper_bridge_reset,
508 	.atomic_check = dw_hdmi_qp_bridge_atomic_check,
509 	.atomic_enable = dw_hdmi_qp_bridge_atomic_enable,
510 	.atomic_disable = dw_hdmi_qp_bridge_atomic_disable,
511 	.detect = dw_hdmi_qp_bridge_detect,
512 	.edid_read = dw_hdmi_qp_bridge_edid_read,
513 	.mode_valid = dw_hdmi_qp_bridge_mode_valid,
514 	.hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe,
515 	.hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe,
516 };
517 
518 static irqreturn_t dw_hdmi_qp_main_hardirq(int irq, void *dev_id)
519 {
520 	struct dw_hdmi_qp *hdmi = dev_id;
521 	struct dw_hdmi_qp_i2c *i2c = hdmi->i2c;
522 	u32 stat;
523 
524 	stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS);
525 
526 	i2c->stat = stat & (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ |
527 			    I2CM_NACK_RCVD_IRQ);
528 
529 	if (i2c->stat) {
530 		dw_hdmi_qp_write(hdmi, i2c->stat, MAINUNIT_1_INT_CLEAR);
531 		complete(&i2c->cmp);
532 	}
533 
534 	if (stat)
535 		return IRQ_HANDLED;
536 
537 	return IRQ_NONE;
538 }
539 
540 static const struct regmap_config dw_hdmi_qp_regmap_config = {
541 	.reg_bits	= 32,
542 	.val_bits	= 32,
543 	.reg_stride	= 4,
544 	.max_register	= EARCRX_1_INT_FORCE,
545 };
546 
547 static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi)
548 {
549 	dw_hdmi_qp_write(hdmi, 0, MAINUNIT_0_INT_MASK_N);
550 	dw_hdmi_qp_write(hdmi, 0, MAINUNIT_1_INT_MASK_N);
551 	dw_hdmi_qp_write(hdmi, 428571429, TIMER_BASE_CONFIG0);
552 
553 	/* Software reset */
554 	dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0);
555 
556 	dw_hdmi_qp_write(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0);
557 
558 	dw_hdmi_qp_mod(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0);
559 
560 	/* Clear DONE and ERROR interrupts */
561 	dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR,
562 			 MAINUNIT_1_INT_CLEAR);
563 
564 	if (hdmi->phy.ops->setup_hpd)
565 		hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
566 }
567 
568 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
569 				   struct drm_encoder *encoder,
570 				   const struct dw_hdmi_qp_plat_data *plat_data)
571 {
572 	struct device *dev = &pdev->dev;
573 	struct dw_hdmi_qp *hdmi;
574 	void __iomem *regs;
575 	int ret;
576 
577 	if (!plat_data->phy_ops || !plat_data->phy_ops->init ||
578 	    !plat_data->phy_ops->disable || !plat_data->phy_ops->read_hpd) {
579 		dev_err(dev, "Missing platform PHY ops\n");
580 		return ERR_PTR(-ENODEV);
581 	}
582 
583 	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
584 	if (!hdmi)
585 		return ERR_PTR(-ENOMEM);
586 
587 	hdmi->dev = dev;
588 
589 	regs = devm_platform_ioremap_resource(pdev, 0);
590 	if (IS_ERR(regs))
591 		return ERR_CAST(regs);
592 
593 	hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config);
594 	if (IS_ERR(hdmi->regm)) {
595 		dev_err(dev, "Failed to configure regmap\n");
596 		return ERR_CAST(hdmi->regm);
597 	}
598 
599 	hdmi->phy.ops = plat_data->phy_ops;
600 	hdmi->phy.data = plat_data->phy_data;
601 
602 	dw_hdmi_qp_init_hw(hdmi);
603 
604 	ret = devm_request_threaded_irq(dev, plat_data->main_irq,
605 					dw_hdmi_qp_main_hardirq, NULL,
606 					IRQF_SHARED, dev_name(dev), hdmi);
607 	if (ret)
608 		return ERR_PTR(ret);
609 
610 	hdmi->bridge.driver_private = hdmi;
611 	hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs;
612 	hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT |
613 			   DRM_BRIDGE_OP_EDID |
614 			   DRM_BRIDGE_OP_HDMI |
615 			   DRM_BRIDGE_OP_HPD;
616 	hdmi->bridge.of_node = pdev->dev.of_node;
617 	hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
618 	hdmi->bridge.vendor = "Synopsys";
619 	hdmi->bridge.product = "DW HDMI QP TX";
620 
621 	hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi);
622 	if (IS_ERR(hdmi->bridge.ddc))
623 		return ERR_CAST(hdmi->bridge.ddc);
624 
625 	ret = devm_drm_bridge_add(dev, &hdmi->bridge);
626 	if (ret)
627 		return ERR_PTR(ret);
628 
629 	ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL,
630 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
631 	if (ret)
632 		return ERR_PTR(ret);
633 
634 	return hdmi;
635 }
636 EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind);
637 
638 void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi)
639 {
640 	dw_hdmi_qp_init_hw(hdmi);
641 }
642 EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume);
643 
644 MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>");
645 MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>");
646 MODULE_DESCRIPTION("DW HDMI QP transmitter library");
647 MODULE_LICENSE("GPL");
648