1 /* 2 * HDMI driver for OMAP5 3 * 4 * Copyright (C) 2014 Texas Instruments Incorporated 5 * 6 * Authors: 7 * Yong Zhi 8 * Mythri pk 9 * Archit Taneja <archit@ti.com> 10 * Tomi Valkeinen <tomi.valkeinen@ti.com> 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License version 2 as published by 14 * the Free Software Foundation. 15 * 16 * This program is distributed in the hope that it will be useful, but WITHOUT 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 19 * more details. 20 * 21 * You should have received a copy of the GNU General Public License along with 22 * this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 25 #define DSS_SUBSYS_NAME "HDMI" 26 27 #include <linux/kernel.h> 28 #include <linux/module.h> 29 #include <linux/err.h> 30 #include <linux/io.h> 31 #include <linux/interrupt.h> 32 #include <linux/mutex.h> 33 #include <linux/delay.h> 34 #include <linux/string.h> 35 #include <linux/platform_device.h> 36 #include <linux/pm_runtime.h> 37 #include <linux/clk.h> 38 #include <linux/gpio.h> 39 #include <linux/regulator/consumer.h> 40 #include <linux/component.h> 41 #include <video/omapdss.h> 42 #include <sound/omap-hdmi-audio.h> 43 44 #include "hdmi5_core.h" 45 #include "dss.h" 46 #include "dss_features.h" 47 48 static struct omap_hdmi hdmi; 49 50 static int hdmi_runtime_get(void) 51 { 52 int r; 53 54 DSSDBG("hdmi_runtime_get\n"); 55 56 r = pm_runtime_get_sync(&hdmi.pdev->dev); 57 WARN_ON(r < 0); 58 if (r < 0) 59 return r; 60 61 return 0; 62 } 63 64 static void hdmi_runtime_put(void) 65 { 66 int r; 67 68 DSSDBG("hdmi_runtime_put\n"); 69 70 r = pm_runtime_put_sync(&hdmi.pdev->dev); 71 WARN_ON(r < 0 && r != -ENOSYS); 72 } 73 74 static irqreturn_t hdmi_irq_handler(int irq, void *data) 75 { 76 struct hdmi_wp_data *wp = data; 77 u32 irqstatus; 78 79 irqstatus = hdmi_wp_get_irqstatus(wp); 80 hdmi_wp_set_irqstatus(wp, irqstatus); 81 82 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && 83 irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 84 u32 v; 85 /* 86 * If we get both connect and disconnect interrupts at the same 87 * time, turn off the PHY, clear interrupts, and restart, which 88 * raises connect interrupt if a cable is connected, or nothing 89 * if cable is not connected. 90 */ 91 92 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); 93 94 /* 95 * We always get bogus CONNECT & DISCONNECT interrupts when 96 * setting the PHY to LDOON. To ignore those, we force the RXDET 97 * line to 0 until the PHY power state has been changed. 98 */ 99 v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); 100 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ 101 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ 102 hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); 103 104 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | 105 HDMI_IRQ_LINK_DISCONNECT); 106 107 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 108 109 REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); 110 111 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { 112 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); 113 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 114 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 115 } 116 117 return IRQ_HANDLED; 118 } 119 120 static int hdmi_init_regulator(void) 121 { 122 int r; 123 struct regulator *reg; 124 125 if (hdmi.vdda_reg != NULL) 126 return 0; 127 128 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 129 if (IS_ERR(reg)) { 130 DSSERR("can't get VDDA regulator\n"); 131 return PTR_ERR(reg); 132 } 133 134 if (regulator_can_change_voltage(reg)) { 135 r = regulator_set_voltage(reg, 1800000, 1800000); 136 if (r) { 137 devm_regulator_put(reg); 138 DSSWARN("can't set the regulator voltage\n"); 139 return r; 140 } 141 } 142 143 hdmi.vdda_reg = reg; 144 145 return 0; 146 } 147 148 static int hdmi_power_on_core(struct omap_dss_device *dssdev) 149 { 150 int r; 151 152 r = regulator_enable(hdmi.vdda_reg); 153 if (r) 154 return r; 155 156 r = hdmi_runtime_get(); 157 if (r) 158 goto err_runtime_get; 159 160 /* Make selection of HDMI in DSS */ 161 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 162 163 hdmi.core_enabled = true; 164 165 return 0; 166 167 err_runtime_get: 168 regulator_disable(hdmi.vdda_reg); 169 170 return r; 171 } 172 173 static void hdmi_power_off_core(struct omap_dss_device *dssdev) 174 { 175 hdmi.core_enabled = false; 176 177 hdmi_runtime_put(); 178 regulator_disable(hdmi.vdda_reg); 179 } 180 181 static int hdmi_power_on_full(struct omap_dss_device *dssdev) 182 { 183 int r; 184 struct omap_video_timings *p; 185 enum omap_channel channel = dssdev->dispc_channel; 186 struct dss_pll_clock_info hdmi_cinfo = { 0 }; 187 unsigned pc; 188 189 r = hdmi_power_on_core(dssdev); 190 if (r) 191 return r; 192 193 p = &hdmi.cfg.timings; 194 195 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 196 197 pc = p->pixelclock; 198 if (p->double_pixel) 199 pc *= 2; 200 201 hdmi_pll_compute(&hdmi.pll, pc, &hdmi_cinfo); 202 203 /* disable and clear irqs */ 204 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 205 hdmi_wp_set_irqstatus(&hdmi.wp, 206 hdmi_wp_get_irqstatus(&hdmi.wp)); 207 208 r = dss_pll_enable(&hdmi.pll.pll); 209 if (r) { 210 DSSERR("Failed to enable PLL\n"); 211 goto err_pll_enable; 212 } 213 214 r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); 215 if (r) { 216 DSSERR("Failed to configure PLL\n"); 217 goto err_pll_cfg; 218 } 219 220 r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, 221 hdmi_cinfo.clkout[0]); 222 if (r) { 223 DSSDBG("Failed to start PHY\n"); 224 goto err_phy_cfg; 225 } 226 227 r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); 228 if (r) 229 goto err_phy_pwr; 230 231 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 232 233 /* bypass TV gamma table */ 234 dispc_enable_gamma_table(0); 235 236 /* tv size */ 237 dss_mgr_set_timings(channel, p); 238 239 r = dss_mgr_enable(channel); 240 if (r) 241 goto err_mgr_enable; 242 243 r = hdmi_wp_video_start(&hdmi.wp); 244 if (r) 245 goto err_vid_enable; 246 247 hdmi_wp_set_irqenable(&hdmi.wp, 248 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); 249 250 return 0; 251 252 err_vid_enable: 253 dss_mgr_disable(channel); 254 err_mgr_enable: 255 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 256 err_phy_pwr: 257 err_phy_cfg: 258 err_pll_cfg: 259 dss_pll_disable(&hdmi.pll.pll); 260 err_pll_enable: 261 hdmi_power_off_core(dssdev); 262 return -EIO; 263 } 264 265 static void hdmi_power_off_full(struct omap_dss_device *dssdev) 266 { 267 enum omap_channel channel = dssdev->dispc_channel; 268 269 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 270 271 hdmi_wp_video_stop(&hdmi.wp); 272 273 dss_mgr_disable(channel); 274 275 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 276 277 dss_pll_disable(&hdmi.pll.pll); 278 279 hdmi_power_off_core(dssdev); 280 } 281 282 static int hdmi_display_check_timing(struct omap_dss_device *dssdev, 283 struct omap_video_timings *timings) 284 { 285 if (!dispc_mgr_timings_ok(dssdev->dispc_channel, timings)) 286 return -EINVAL; 287 288 return 0; 289 } 290 291 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 292 struct omap_video_timings *timings) 293 { 294 mutex_lock(&hdmi.lock); 295 296 hdmi.cfg.timings = *timings; 297 298 dispc_set_tv_pclk(timings->pixelclock); 299 300 mutex_unlock(&hdmi.lock); 301 } 302 303 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 304 struct omap_video_timings *timings) 305 { 306 *timings = hdmi.cfg.timings; 307 } 308 309 static void hdmi_dump_regs(struct seq_file *s) 310 { 311 mutex_lock(&hdmi.lock); 312 313 if (hdmi_runtime_get()) { 314 mutex_unlock(&hdmi.lock); 315 return; 316 } 317 318 hdmi_wp_dump(&hdmi.wp, s); 319 hdmi_pll_dump(&hdmi.pll, s); 320 hdmi_phy_dump(&hdmi.phy, s); 321 hdmi5_core_dump(&hdmi.core, s); 322 323 hdmi_runtime_put(); 324 mutex_unlock(&hdmi.lock); 325 } 326 327 static int read_edid(u8 *buf, int len) 328 { 329 int r; 330 int idlemode; 331 332 mutex_lock(&hdmi.lock); 333 334 r = hdmi_runtime_get(); 335 BUG_ON(r); 336 337 idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); 338 /* No-idle mode */ 339 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); 340 341 r = hdmi5_read_edid(&hdmi.core, buf, len); 342 343 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); 344 345 hdmi_runtime_put(); 346 mutex_unlock(&hdmi.lock); 347 348 return r; 349 } 350 351 static void hdmi_start_audio_stream(struct omap_hdmi *hd) 352 { 353 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); 354 hdmi_wp_audio_enable(&hd->wp, true); 355 hdmi_wp_audio_core_req_enable(&hd->wp, true); 356 } 357 358 static void hdmi_stop_audio_stream(struct omap_hdmi *hd) 359 { 360 hdmi_wp_audio_core_req_enable(&hd->wp, false); 361 hdmi_wp_audio_enable(&hd->wp, false); 362 REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2); 363 } 364 365 static int hdmi_display_enable(struct omap_dss_device *dssdev) 366 { 367 struct omap_dss_device *out = &hdmi.output; 368 unsigned long flags; 369 int r = 0; 370 371 DSSDBG("ENTER hdmi_display_enable\n"); 372 373 mutex_lock(&hdmi.lock); 374 375 if (!out->dispc_channel_connected) { 376 DSSERR("failed to enable display: no output/manager\n"); 377 r = -ENODEV; 378 goto err0; 379 } 380 381 r = hdmi_power_on_full(dssdev); 382 if (r) { 383 DSSERR("failed to power on device\n"); 384 goto err0; 385 } 386 387 if (hdmi.audio_configured) { 388 r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, &hdmi.audio_config, 389 hdmi.cfg.timings.pixelclock); 390 if (r) { 391 DSSERR("Error restoring audio configuration: %d", r); 392 hdmi.audio_abort_cb(&hdmi.pdev->dev); 393 hdmi.audio_configured = false; 394 } 395 } 396 397 spin_lock_irqsave(&hdmi.audio_playing_lock, flags); 398 if (hdmi.audio_configured && hdmi.audio_playing) 399 hdmi_start_audio_stream(&hdmi); 400 hdmi.display_enabled = true; 401 spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); 402 403 mutex_unlock(&hdmi.lock); 404 return 0; 405 406 err0: 407 mutex_unlock(&hdmi.lock); 408 return r; 409 } 410 411 static void hdmi_display_disable(struct omap_dss_device *dssdev) 412 { 413 unsigned long flags; 414 415 DSSDBG("Enter hdmi_display_disable\n"); 416 417 mutex_lock(&hdmi.lock); 418 419 spin_lock_irqsave(&hdmi.audio_playing_lock, flags); 420 hdmi_stop_audio_stream(&hdmi); 421 hdmi.display_enabled = false; 422 spin_unlock_irqrestore(&hdmi.audio_playing_lock, flags); 423 424 hdmi_power_off_full(dssdev); 425 426 mutex_unlock(&hdmi.lock); 427 } 428 429 static int hdmi_core_enable(struct omap_dss_device *dssdev) 430 { 431 int r = 0; 432 433 DSSDBG("ENTER omapdss_hdmi_core_enable\n"); 434 435 mutex_lock(&hdmi.lock); 436 437 r = hdmi_power_on_core(dssdev); 438 if (r) { 439 DSSERR("failed to power on device\n"); 440 goto err0; 441 } 442 443 mutex_unlock(&hdmi.lock); 444 return 0; 445 446 err0: 447 mutex_unlock(&hdmi.lock); 448 return r; 449 } 450 451 static void hdmi_core_disable(struct omap_dss_device *dssdev) 452 { 453 DSSDBG("Enter omapdss_hdmi_core_disable\n"); 454 455 mutex_lock(&hdmi.lock); 456 457 hdmi_power_off_core(dssdev); 458 459 mutex_unlock(&hdmi.lock); 460 } 461 462 static int hdmi_connect(struct omap_dss_device *dssdev, 463 struct omap_dss_device *dst) 464 { 465 enum omap_channel channel = dssdev->dispc_channel; 466 int r; 467 468 r = hdmi_init_regulator(); 469 if (r) 470 return r; 471 472 r = dss_mgr_connect(channel, dssdev); 473 if (r) 474 return r; 475 476 r = omapdss_output_set_device(dssdev, dst); 477 if (r) { 478 DSSERR("failed to connect output to new device: %s\n", 479 dst->name); 480 dss_mgr_disconnect(channel, dssdev); 481 return r; 482 } 483 484 return 0; 485 } 486 487 static void hdmi_disconnect(struct omap_dss_device *dssdev, 488 struct omap_dss_device *dst) 489 { 490 enum omap_channel channel = dssdev->dispc_channel; 491 492 WARN_ON(dst != dssdev->dst); 493 494 if (dst != dssdev->dst) 495 return; 496 497 omapdss_output_unset_device(dssdev); 498 499 dss_mgr_disconnect(channel, dssdev); 500 } 501 502 static int hdmi_read_edid(struct omap_dss_device *dssdev, 503 u8 *edid, int len) 504 { 505 bool need_enable; 506 int r; 507 508 need_enable = hdmi.core_enabled == false; 509 510 if (need_enable) { 511 r = hdmi_core_enable(dssdev); 512 if (r) 513 return r; 514 } 515 516 r = read_edid(edid, len); 517 518 if (need_enable) 519 hdmi_core_disable(dssdev); 520 521 return r; 522 } 523 524 static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 525 const struct hdmi_avi_infoframe *avi) 526 { 527 hdmi.cfg.infoframe = *avi; 528 return 0; 529 } 530 531 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 532 bool hdmi_mode) 533 { 534 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 535 return 0; 536 } 537 538 static const struct omapdss_hdmi_ops hdmi_ops = { 539 .connect = hdmi_connect, 540 .disconnect = hdmi_disconnect, 541 542 .enable = hdmi_display_enable, 543 .disable = hdmi_display_disable, 544 545 .check_timings = hdmi_display_check_timing, 546 .set_timings = hdmi_display_set_timing, 547 .get_timings = hdmi_display_get_timings, 548 549 .read_edid = hdmi_read_edid, 550 .set_infoframe = hdmi_set_infoframe, 551 .set_hdmi_mode = hdmi_set_hdmi_mode, 552 }; 553 554 static void hdmi_init_output(struct platform_device *pdev) 555 { 556 struct omap_dss_device *out = &hdmi.output; 557 558 out->dev = &pdev->dev; 559 out->id = OMAP_DSS_OUTPUT_HDMI; 560 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 561 out->name = "hdmi.0"; 562 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 563 out->ops.hdmi = &hdmi_ops; 564 out->owner = THIS_MODULE; 565 566 omapdss_register_output(out); 567 } 568 569 static void hdmi_uninit_output(struct platform_device *pdev) 570 { 571 struct omap_dss_device *out = &hdmi.output; 572 573 omapdss_unregister_output(out); 574 } 575 576 static int hdmi_probe_of(struct platform_device *pdev) 577 { 578 struct device_node *node = pdev->dev.of_node; 579 struct device_node *ep; 580 int r; 581 582 ep = omapdss_of_get_first_endpoint(node); 583 if (!ep) 584 return 0; 585 586 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); 587 if (r) 588 goto err; 589 590 of_node_put(ep); 591 return 0; 592 593 err: 594 of_node_put(ep); 595 return r; 596 } 597 598 /* Audio callbacks */ 599 static int hdmi_audio_startup(struct device *dev, 600 void (*abort_cb)(struct device *dev)) 601 { 602 struct omap_hdmi *hd = dev_get_drvdata(dev); 603 int ret = 0; 604 605 mutex_lock(&hd->lock); 606 607 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 608 ret = -EPERM; 609 goto out; 610 } 611 612 hd->audio_abort_cb = abort_cb; 613 614 out: 615 mutex_unlock(&hd->lock); 616 617 return ret; 618 } 619 620 static int hdmi_audio_shutdown(struct device *dev) 621 { 622 struct omap_hdmi *hd = dev_get_drvdata(dev); 623 624 mutex_lock(&hd->lock); 625 hd->audio_abort_cb = NULL; 626 hd->audio_configured = false; 627 hd->audio_playing = false; 628 mutex_unlock(&hd->lock); 629 630 return 0; 631 } 632 633 static int hdmi_audio_start(struct device *dev) 634 { 635 struct omap_hdmi *hd = dev_get_drvdata(dev); 636 unsigned long flags; 637 638 WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); 639 640 spin_lock_irqsave(&hd->audio_playing_lock, flags); 641 642 if (hd->display_enabled) 643 hdmi_start_audio_stream(hd); 644 hd->audio_playing = true; 645 646 spin_unlock_irqrestore(&hd->audio_playing_lock, flags); 647 return 0; 648 } 649 650 static void hdmi_audio_stop(struct device *dev) 651 { 652 struct omap_hdmi *hd = dev_get_drvdata(dev); 653 unsigned long flags; 654 655 WARN_ON(!hdmi_mode_has_audio(&hd->cfg)); 656 657 spin_lock_irqsave(&hd->audio_playing_lock, flags); 658 659 if (hd->display_enabled) 660 hdmi_stop_audio_stream(hd); 661 hd->audio_playing = false; 662 663 spin_unlock_irqrestore(&hd->audio_playing_lock, flags); 664 } 665 666 static int hdmi_audio_config(struct device *dev, 667 struct omap_dss_audio *dss_audio) 668 { 669 struct omap_hdmi *hd = dev_get_drvdata(dev); 670 int ret; 671 672 mutex_lock(&hd->lock); 673 674 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 675 ret = -EPERM; 676 goto out; 677 } 678 679 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio, 680 hd->cfg.timings.pixelclock); 681 682 if (!ret) { 683 hd->audio_configured = true; 684 hd->audio_config = *dss_audio; 685 } 686 out: 687 mutex_unlock(&hd->lock); 688 689 return ret; 690 } 691 692 static const struct omap_hdmi_audio_ops hdmi_audio_ops = { 693 .audio_startup = hdmi_audio_startup, 694 .audio_shutdown = hdmi_audio_shutdown, 695 .audio_start = hdmi_audio_start, 696 .audio_stop = hdmi_audio_stop, 697 .audio_config = hdmi_audio_config, 698 }; 699 700 static int hdmi_audio_register(struct device *dev) 701 { 702 struct omap_hdmi_audio_pdata pdata = { 703 .dev = dev, 704 .dss_version = omapdss_get_version(), 705 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), 706 .ops = &hdmi_audio_ops, 707 }; 708 709 hdmi.audio_pdev = platform_device_register_data( 710 dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO, 711 &pdata, sizeof(pdata)); 712 713 if (IS_ERR(hdmi.audio_pdev)) 714 return PTR_ERR(hdmi.audio_pdev); 715 716 hdmi_runtime_get(); 717 hdmi.wp_idlemode = 718 REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); 719 hdmi_runtime_put(); 720 721 return 0; 722 } 723 724 /* HDMI HW IP initialisation */ 725 static int hdmi5_bind(struct device *dev, struct device *master, void *data) 726 { 727 struct platform_device *pdev = to_platform_device(dev); 728 int r; 729 int irq; 730 731 hdmi.pdev = pdev; 732 dev_set_drvdata(&pdev->dev, &hdmi); 733 734 mutex_init(&hdmi.lock); 735 spin_lock_init(&hdmi.audio_playing_lock); 736 737 if (pdev->dev.of_node) { 738 r = hdmi_probe_of(pdev); 739 if (r) 740 return r; 741 } 742 743 r = hdmi_wp_init(pdev, &hdmi.wp); 744 if (r) 745 return r; 746 747 r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp); 748 if (r) 749 return r; 750 751 r = hdmi_phy_init(pdev, &hdmi.phy); 752 if (r) 753 goto err; 754 755 r = hdmi5_core_init(pdev, &hdmi.core); 756 if (r) 757 goto err; 758 759 irq = platform_get_irq(pdev, 0); 760 if (irq < 0) { 761 DSSERR("platform_get_irq failed\n"); 762 r = -ENODEV; 763 goto err; 764 } 765 766 r = devm_request_threaded_irq(&pdev->dev, irq, 767 NULL, hdmi_irq_handler, 768 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 769 if (r) { 770 DSSERR("HDMI IRQ request failed\n"); 771 goto err; 772 } 773 774 pm_runtime_enable(&pdev->dev); 775 776 hdmi_init_output(pdev); 777 778 r = hdmi_audio_register(&pdev->dev); 779 if (r) { 780 DSSERR("Registering HDMI audio failed %d\n", r); 781 hdmi_uninit_output(pdev); 782 pm_runtime_disable(&pdev->dev); 783 return r; 784 } 785 786 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 787 788 return 0; 789 err: 790 hdmi_pll_uninit(&hdmi.pll); 791 return r; 792 } 793 794 static void hdmi5_unbind(struct device *dev, struct device *master, void *data) 795 { 796 struct platform_device *pdev = to_platform_device(dev); 797 798 if (hdmi.audio_pdev) 799 platform_device_unregister(hdmi.audio_pdev); 800 801 hdmi_uninit_output(pdev); 802 803 hdmi_pll_uninit(&hdmi.pll); 804 805 pm_runtime_disable(&pdev->dev); 806 } 807 808 static const struct component_ops hdmi5_component_ops = { 809 .bind = hdmi5_bind, 810 .unbind = hdmi5_unbind, 811 }; 812 813 static int hdmi5_probe(struct platform_device *pdev) 814 { 815 return component_add(&pdev->dev, &hdmi5_component_ops); 816 } 817 818 static int hdmi5_remove(struct platform_device *pdev) 819 { 820 component_del(&pdev->dev, &hdmi5_component_ops); 821 return 0; 822 } 823 824 static int hdmi_runtime_suspend(struct device *dev) 825 { 826 dispc_runtime_put(); 827 828 return 0; 829 } 830 831 static int hdmi_runtime_resume(struct device *dev) 832 { 833 int r; 834 835 r = dispc_runtime_get(); 836 if (r < 0) 837 return r; 838 839 return 0; 840 } 841 842 static const struct dev_pm_ops hdmi_pm_ops = { 843 .runtime_suspend = hdmi_runtime_suspend, 844 .runtime_resume = hdmi_runtime_resume, 845 }; 846 847 static const struct of_device_id hdmi_of_match[] = { 848 { .compatible = "ti,omap5-hdmi", }, 849 { .compatible = "ti,dra7-hdmi", }, 850 {}, 851 }; 852 853 static struct platform_driver omapdss_hdmihw_driver = { 854 .probe = hdmi5_probe, 855 .remove = hdmi5_remove, 856 .driver = { 857 .name = "omapdss_hdmi5", 858 .pm = &hdmi_pm_ops, 859 .of_match_table = hdmi_of_match, 860 .suppress_bind_attrs = true, 861 }, 862 }; 863 864 int __init hdmi5_init_platform_driver(void) 865 { 866 return platform_driver_register(&omapdss_hdmihw_driver); 867 } 868 869 void hdmi5_uninit_platform_driver(void) 870 { 871 platform_driver_unregister(&omapdss_hdmihw_driver); 872 } 873