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 void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge, 365 struct drm_atomic_state *state) 366 { 367 struct dw_hdmi_qp *hdmi = bridge->driver_private; 368 struct drm_connector_state *conn_state; 369 struct drm_connector *connector; 370 unsigned int op_mode; 371 372 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); 373 if (WARN_ON(!connector)) 374 return; 375 376 conn_state = drm_atomic_get_new_connector_state(state, connector); 377 if (WARN_ON(!conn_state)) 378 return; 379 380 if (connector->display_info.is_hdmi) { 381 dev_dbg(hdmi->dev, "%s mode=HDMI rate=%llu\n", 382 __func__, conn_state->hdmi.tmds_char_rate); 383 op_mode = 0; 384 } else { 385 dev_dbg(hdmi->dev, "%s mode=DVI\n", __func__); 386 op_mode = OPMODE_DVI; 387 } 388 389 hdmi->phy.ops->init(hdmi, hdmi->phy.data); 390 391 dw_hdmi_qp_mod(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0); 392 dw_hdmi_qp_mod(hdmi, op_mode, OPMODE_DVI, LINK_CONFIG0); 393 394 drm_atomic_helper_connector_hdmi_update_infoframes(connector, state); 395 } 396 397 static void dw_hdmi_qp_bridge_atomic_disable(struct drm_bridge *bridge, 398 struct drm_atomic_state *state) 399 { 400 struct dw_hdmi_qp *hdmi = bridge->driver_private; 401 402 hdmi->phy.ops->disable(hdmi, hdmi->phy.data); 403 } 404 405 static enum drm_connector_status 406 dw_hdmi_qp_bridge_detect(struct drm_bridge *bridge) 407 { 408 struct dw_hdmi_qp *hdmi = bridge->driver_private; 409 410 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); 411 } 412 413 static const struct drm_edid * 414 dw_hdmi_qp_bridge_edid_read(struct drm_bridge *bridge, 415 struct drm_connector *connector) 416 { 417 struct dw_hdmi_qp *hdmi = bridge->driver_private; 418 const struct drm_edid *drm_edid; 419 420 drm_edid = drm_edid_read_ddc(connector, bridge->ddc); 421 if (!drm_edid) 422 dev_dbg(hdmi->dev, "failed to get edid\n"); 423 424 return drm_edid; 425 } 426 427 static enum drm_mode_status 428 dw_hdmi_qp_bridge_tmds_char_rate_valid(const struct drm_bridge *bridge, 429 const struct drm_display_mode *mode, 430 unsigned long long rate) 431 { 432 struct dw_hdmi_qp *hdmi = bridge->driver_private; 433 434 if (rate > HDMI14_MAX_TMDSCLK) { 435 dev_dbg(hdmi->dev, "Unsupported TMDS char rate: %lld\n", rate); 436 return MODE_CLOCK_HIGH; 437 } 438 439 return MODE_OK; 440 } 441 442 static int dw_hdmi_qp_bridge_clear_infoframe(struct drm_bridge *bridge, 443 enum hdmi_infoframe_type type) 444 { 445 struct dw_hdmi_qp *hdmi = bridge->driver_private; 446 447 switch (type) { 448 case HDMI_INFOFRAME_TYPE_AVI: 449 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_AVI_TX_EN | PKTSCHED_GCP_TX_EN, 450 PKTSCHED_PKT_EN); 451 break; 452 453 case HDMI_INFOFRAME_TYPE_DRM: 454 dw_hdmi_qp_mod(hdmi, 0, PKTSCHED_DRMI_TX_EN, PKTSCHED_PKT_EN); 455 break; 456 457 default: 458 dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); 459 } 460 461 return 0; 462 } 463 464 static int dw_hdmi_qp_bridge_write_infoframe(struct drm_bridge *bridge, 465 enum hdmi_infoframe_type type, 466 const u8 *buffer, size_t len) 467 { 468 struct dw_hdmi_qp *hdmi = bridge->driver_private; 469 470 dw_hdmi_qp_bridge_clear_infoframe(bridge, type); 471 472 switch (type) { 473 case HDMI_INFOFRAME_TYPE_AVI: 474 return dw_hdmi_qp_config_avi_infoframe(hdmi, buffer, len); 475 476 case HDMI_INFOFRAME_TYPE_DRM: 477 return dw_hdmi_qp_config_drm_infoframe(hdmi, buffer, len); 478 479 default: 480 dev_dbg(hdmi->dev, "Unsupported infoframe type %x\n", type); 481 return 0; 482 } 483 } 484 485 static const struct drm_bridge_funcs dw_hdmi_qp_bridge_funcs = { 486 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 487 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 488 .atomic_reset = drm_atomic_helper_bridge_reset, 489 .atomic_enable = dw_hdmi_qp_bridge_atomic_enable, 490 .atomic_disable = dw_hdmi_qp_bridge_atomic_disable, 491 .detect = dw_hdmi_qp_bridge_detect, 492 .edid_read = dw_hdmi_qp_bridge_edid_read, 493 .hdmi_tmds_char_rate_valid = dw_hdmi_qp_bridge_tmds_char_rate_valid, 494 .hdmi_clear_infoframe = dw_hdmi_qp_bridge_clear_infoframe, 495 .hdmi_write_infoframe = dw_hdmi_qp_bridge_write_infoframe, 496 }; 497 498 static irqreturn_t dw_hdmi_qp_main_hardirq(int irq, void *dev_id) 499 { 500 struct dw_hdmi_qp *hdmi = dev_id; 501 struct dw_hdmi_qp_i2c *i2c = hdmi->i2c; 502 u32 stat; 503 504 stat = dw_hdmi_qp_read(hdmi, MAINUNIT_1_INT_STATUS); 505 506 i2c->stat = stat & (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ | 507 I2CM_NACK_RCVD_IRQ); 508 509 if (i2c->stat) { 510 dw_hdmi_qp_write(hdmi, i2c->stat, MAINUNIT_1_INT_CLEAR); 511 complete(&i2c->cmp); 512 } 513 514 if (stat) 515 return IRQ_HANDLED; 516 517 return IRQ_NONE; 518 } 519 520 static const struct regmap_config dw_hdmi_qp_regmap_config = { 521 .reg_bits = 32, 522 .val_bits = 32, 523 .reg_stride = 4, 524 .max_register = EARCRX_1_INT_FORCE, 525 }; 526 527 static void dw_hdmi_qp_init_hw(struct dw_hdmi_qp *hdmi) 528 { 529 dw_hdmi_qp_write(hdmi, 0, MAINUNIT_0_INT_MASK_N); 530 dw_hdmi_qp_write(hdmi, 0, MAINUNIT_1_INT_MASK_N); 531 dw_hdmi_qp_write(hdmi, 428571429, TIMER_BASE_CONFIG0); 532 533 /* Software reset */ 534 dw_hdmi_qp_write(hdmi, 0x01, I2CM_CONTROL0); 535 536 dw_hdmi_qp_write(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0); 537 538 dw_hdmi_qp_mod(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0); 539 540 /* Clear DONE and ERROR interrupts */ 541 dw_hdmi_qp_write(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR, 542 MAINUNIT_1_INT_CLEAR); 543 544 if (hdmi->phy.ops->setup_hpd) 545 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data); 546 } 547 548 struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev, 549 struct drm_encoder *encoder, 550 const struct dw_hdmi_qp_plat_data *plat_data) 551 { 552 struct device *dev = &pdev->dev; 553 struct dw_hdmi_qp *hdmi; 554 void __iomem *regs; 555 int ret; 556 557 if (!plat_data->phy_ops || !plat_data->phy_ops->init || 558 !plat_data->phy_ops->disable || !plat_data->phy_ops->read_hpd) { 559 dev_err(dev, "Missing platform PHY ops\n"); 560 return ERR_PTR(-ENODEV); 561 } 562 563 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); 564 if (!hdmi) 565 return ERR_PTR(-ENOMEM); 566 567 hdmi->dev = dev; 568 569 regs = devm_platform_ioremap_resource(pdev, 0); 570 if (IS_ERR(regs)) 571 return ERR_CAST(regs); 572 573 hdmi->regm = devm_regmap_init_mmio(dev, regs, &dw_hdmi_qp_regmap_config); 574 if (IS_ERR(hdmi->regm)) { 575 dev_err(dev, "Failed to configure regmap\n"); 576 return ERR_CAST(hdmi->regm); 577 } 578 579 hdmi->phy.ops = plat_data->phy_ops; 580 hdmi->phy.data = plat_data->phy_data; 581 582 dw_hdmi_qp_init_hw(hdmi); 583 584 ret = devm_request_threaded_irq(dev, plat_data->main_irq, 585 dw_hdmi_qp_main_hardirq, NULL, 586 IRQF_SHARED, dev_name(dev), hdmi); 587 if (ret) 588 return ERR_PTR(ret); 589 590 hdmi->bridge.driver_private = hdmi; 591 hdmi->bridge.funcs = &dw_hdmi_qp_bridge_funcs; 592 hdmi->bridge.ops = DRM_BRIDGE_OP_DETECT | 593 DRM_BRIDGE_OP_EDID | 594 DRM_BRIDGE_OP_HDMI | 595 DRM_BRIDGE_OP_HPD; 596 hdmi->bridge.of_node = pdev->dev.of_node; 597 hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 598 hdmi->bridge.vendor = "Synopsys"; 599 hdmi->bridge.product = "DW HDMI QP TX"; 600 601 hdmi->bridge.ddc = dw_hdmi_qp_i2c_adapter(hdmi); 602 if (IS_ERR(hdmi->bridge.ddc)) 603 return ERR_CAST(hdmi->bridge.ddc); 604 605 ret = devm_drm_bridge_add(dev, &hdmi->bridge); 606 if (ret) 607 return ERR_PTR(ret); 608 609 ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL, 610 DRM_BRIDGE_ATTACH_NO_CONNECTOR); 611 if (ret) 612 return ERR_PTR(ret); 613 614 return hdmi; 615 } 616 EXPORT_SYMBOL_GPL(dw_hdmi_qp_bind); 617 618 void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi) 619 { 620 dw_hdmi_qp_init_hw(hdmi); 621 } 622 EXPORT_SYMBOL_GPL(dw_hdmi_qp_resume); 623 624 MODULE_AUTHOR("Algea Cao <algea.cao@rock-chips.com>"); 625 MODULE_AUTHOR("Cristian Ciocaltea <cristian.ciocaltea@collabora.com>"); 626 MODULE_DESCRIPTION("DW HDMI QP transmitter library"); 627 MODULE_LICENSE("GPL"); 628