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