1 /* 2 * Copyright (C) 2013 NVIDIA Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/delay.h> 11 #include <linux/gpio.h> 12 #include <linux/interrupt.h> 13 #include <linux/io.h> 14 #include <linux/of_gpio.h> 15 #include <linux/pinctrl/pinconf-generic.h> 16 #include <linux/pinctrl/pinctrl.h> 17 #include <linux/pinctrl/pinmux.h> 18 #include <linux/pm_runtime.h> 19 #include <linux/platform_device.h> 20 #include <linux/reset.h> 21 #include <linux/regulator/consumer.h> 22 #include <linux/workqueue.h> 23 24 #include <drm/drm_dp_helper.h> 25 #include <drm/drm_panel.h> 26 27 #include "dpaux.h" 28 #include "drm.h" 29 #include "trace.h" 30 31 static DEFINE_MUTEX(dpaux_lock); 32 static LIST_HEAD(dpaux_list); 33 34 struct tegra_dpaux { 35 struct drm_dp_aux aux; 36 struct device *dev; 37 38 void __iomem *regs; 39 int irq; 40 41 struct tegra_output *output; 42 43 struct reset_control *rst; 44 struct clk *clk_parent; 45 struct clk *clk; 46 47 struct regulator *vdd; 48 49 struct completion complete; 50 struct work_struct work; 51 struct list_head list; 52 53 #ifdef CONFIG_GENERIC_PINCONF 54 struct pinctrl_dev *pinctrl; 55 struct pinctrl_desc desc; 56 #endif 57 }; 58 59 static inline struct tegra_dpaux *to_dpaux(struct drm_dp_aux *aux) 60 { 61 return container_of(aux, struct tegra_dpaux, aux); 62 } 63 64 static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work) 65 { 66 return container_of(work, struct tegra_dpaux, work); 67 } 68 69 static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux, 70 unsigned int offset) 71 { 72 u32 value = readl(dpaux->regs + (offset << 2)); 73 74 trace_dpaux_readl(dpaux->dev, offset, value); 75 76 return value; 77 } 78 79 static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux, 80 u32 value, unsigned int offset) 81 { 82 trace_dpaux_writel(dpaux->dev, offset, value); 83 writel(value, dpaux->regs + (offset << 2)); 84 } 85 86 static void tegra_dpaux_write_fifo(struct tegra_dpaux *dpaux, const u8 *buffer, 87 size_t size) 88 { 89 size_t i, j; 90 91 for (i = 0; i < DIV_ROUND_UP(size, 4); i++) { 92 size_t num = min_t(size_t, size - i * 4, 4); 93 u32 value = 0; 94 95 for (j = 0; j < num; j++) 96 value |= buffer[i * 4 + j] << (j * 8); 97 98 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXDATA_WRITE(i)); 99 } 100 } 101 102 static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer, 103 size_t size) 104 { 105 size_t i, j; 106 107 for (i = 0; i < DIV_ROUND_UP(size, 4); i++) { 108 size_t num = min_t(size_t, size - i * 4, 4); 109 u32 value; 110 111 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXDATA_READ(i)); 112 113 for (j = 0; j < num; j++) 114 buffer[i * 4 + j] = value >> (j * 8); 115 } 116 } 117 118 static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux, 119 struct drm_dp_aux_msg *msg) 120 { 121 unsigned long timeout = msecs_to_jiffies(250); 122 struct tegra_dpaux *dpaux = to_dpaux(aux); 123 unsigned long status; 124 ssize_t ret = 0; 125 u32 value; 126 127 /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */ 128 if (msg->size > 16) 129 return -EINVAL; 130 131 /* 132 * Allow zero-sized messages only for I2C, in which case they specify 133 * address-only transactions. 134 */ 135 if (msg->size < 1) { 136 switch (msg->request & ~DP_AUX_I2C_MOT) { 137 case DP_AUX_I2C_WRITE_STATUS_UPDATE: 138 case DP_AUX_I2C_WRITE: 139 case DP_AUX_I2C_READ: 140 value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY; 141 break; 142 143 default: 144 return -EINVAL; 145 } 146 } else { 147 /* For non-zero-sized messages, set the CMDLEN field. */ 148 value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1); 149 } 150 151 switch (msg->request & ~DP_AUX_I2C_MOT) { 152 case DP_AUX_I2C_WRITE: 153 if (msg->request & DP_AUX_I2C_MOT) 154 value |= DPAUX_DP_AUXCTL_CMD_MOT_WR; 155 else 156 value |= DPAUX_DP_AUXCTL_CMD_I2C_WR; 157 158 break; 159 160 case DP_AUX_I2C_READ: 161 if (msg->request & DP_AUX_I2C_MOT) 162 value |= DPAUX_DP_AUXCTL_CMD_MOT_RD; 163 else 164 value |= DPAUX_DP_AUXCTL_CMD_I2C_RD; 165 166 break; 167 168 case DP_AUX_I2C_WRITE_STATUS_UPDATE: 169 if (msg->request & DP_AUX_I2C_MOT) 170 value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ; 171 else 172 value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ; 173 174 break; 175 176 case DP_AUX_NATIVE_WRITE: 177 value |= DPAUX_DP_AUXCTL_CMD_AUX_WR; 178 break; 179 180 case DP_AUX_NATIVE_READ: 181 value |= DPAUX_DP_AUXCTL_CMD_AUX_RD; 182 break; 183 184 default: 185 return -EINVAL; 186 } 187 188 tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR); 189 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL); 190 191 if ((msg->request & DP_AUX_I2C_READ) == 0) { 192 tegra_dpaux_write_fifo(dpaux, msg->buffer, msg->size); 193 ret = msg->size; 194 } 195 196 /* start transaction */ 197 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXCTL); 198 value |= DPAUX_DP_AUXCTL_TRANSACTREQ; 199 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL); 200 201 status = wait_for_completion_timeout(&dpaux->complete, timeout); 202 if (!status) 203 return -ETIMEDOUT; 204 205 /* read status and clear errors */ 206 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT); 207 tegra_dpaux_writel(dpaux, 0xf00, DPAUX_DP_AUXSTAT); 208 209 if (value & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR) 210 return -ETIMEDOUT; 211 212 if ((value & DPAUX_DP_AUXSTAT_RX_ERROR) || 213 (value & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR) || 214 (value & DPAUX_DP_AUXSTAT_NO_STOP_ERROR)) 215 return -EIO; 216 217 switch ((value & DPAUX_DP_AUXSTAT_REPLY_TYPE_MASK) >> 16) { 218 case 0x00: 219 msg->reply = DP_AUX_NATIVE_REPLY_ACK; 220 break; 221 222 case 0x01: 223 msg->reply = DP_AUX_NATIVE_REPLY_NACK; 224 break; 225 226 case 0x02: 227 msg->reply = DP_AUX_NATIVE_REPLY_DEFER; 228 break; 229 230 case 0x04: 231 msg->reply = DP_AUX_I2C_REPLY_NACK; 232 break; 233 234 case 0x08: 235 msg->reply = DP_AUX_I2C_REPLY_DEFER; 236 break; 237 } 238 239 if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) { 240 if (msg->request & DP_AUX_I2C_READ) { 241 size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK; 242 243 if (WARN_ON(count != msg->size)) 244 count = min_t(size_t, count, msg->size); 245 246 tegra_dpaux_read_fifo(dpaux, msg->buffer, count); 247 ret = count; 248 } 249 } 250 251 return ret; 252 } 253 254 static void tegra_dpaux_hotplug(struct work_struct *work) 255 { 256 struct tegra_dpaux *dpaux = work_to_dpaux(work); 257 258 if (dpaux->output) 259 drm_helper_hpd_irq_event(dpaux->output->connector.dev); 260 } 261 262 static irqreturn_t tegra_dpaux_irq(int irq, void *data) 263 { 264 struct tegra_dpaux *dpaux = data; 265 irqreturn_t ret = IRQ_HANDLED; 266 u32 value; 267 268 /* clear interrupts */ 269 value = tegra_dpaux_readl(dpaux, DPAUX_INTR_AUX); 270 tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX); 271 272 if (value & (DPAUX_INTR_PLUG_EVENT | DPAUX_INTR_UNPLUG_EVENT)) 273 schedule_work(&dpaux->work); 274 275 if (value & DPAUX_INTR_IRQ_EVENT) { 276 /* TODO: handle this */ 277 } 278 279 if (value & DPAUX_INTR_AUX_DONE) 280 complete(&dpaux->complete); 281 282 return ret; 283 } 284 285 enum tegra_dpaux_functions { 286 DPAUX_PADCTL_FUNC_AUX, 287 DPAUX_PADCTL_FUNC_I2C, 288 DPAUX_PADCTL_FUNC_OFF, 289 }; 290 291 static void tegra_dpaux_pad_power_down(struct tegra_dpaux *dpaux) 292 { 293 u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE); 294 295 value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN; 296 297 tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE); 298 } 299 300 static void tegra_dpaux_pad_power_up(struct tegra_dpaux *dpaux) 301 { 302 u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE); 303 304 value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN; 305 306 tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE); 307 } 308 309 static int tegra_dpaux_pad_config(struct tegra_dpaux *dpaux, unsigned function) 310 { 311 u32 value; 312 313 switch (function) { 314 case DPAUX_PADCTL_FUNC_AUX: 315 value = DPAUX_HYBRID_PADCTL_AUX_CMH(2) | 316 DPAUX_HYBRID_PADCTL_AUX_DRVZ(4) | 317 DPAUX_HYBRID_PADCTL_AUX_DRVI(0x18) | 318 DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV | 319 DPAUX_HYBRID_PADCTL_MODE_AUX; 320 break; 321 322 case DPAUX_PADCTL_FUNC_I2C: 323 value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV | 324 DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV | 325 DPAUX_HYBRID_PADCTL_AUX_CMH(2) | 326 DPAUX_HYBRID_PADCTL_AUX_DRVZ(4) | 327 DPAUX_HYBRID_PADCTL_AUX_DRVI(0x18) | 328 DPAUX_HYBRID_PADCTL_MODE_I2C; 329 break; 330 331 case DPAUX_PADCTL_FUNC_OFF: 332 tegra_dpaux_pad_power_down(dpaux); 333 return 0; 334 335 default: 336 return -ENOTSUPP; 337 } 338 339 tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL); 340 tegra_dpaux_pad_power_up(dpaux); 341 342 return 0; 343 } 344 345 #ifdef CONFIG_GENERIC_PINCONF 346 static const struct pinctrl_pin_desc tegra_dpaux_pins[] = { 347 PINCTRL_PIN(0, "DP_AUX_CHx_P"), 348 PINCTRL_PIN(1, "DP_AUX_CHx_N"), 349 }; 350 351 static const unsigned tegra_dpaux_pin_numbers[] = { 0, 1 }; 352 353 static const char * const tegra_dpaux_groups[] = { 354 "dpaux-io", 355 }; 356 357 static const char * const tegra_dpaux_functions[] = { 358 "aux", 359 "i2c", 360 "off", 361 }; 362 363 static int tegra_dpaux_get_groups_count(struct pinctrl_dev *pinctrl) 364 { 365 return ARRAY_SIZE(tegra_dpaux_groups); 366 } 367 368 static const char *tegra_dpaux_get_group_name(struct pinctrl_dev *pinctrl, 369 unsigned int group) 370 { 371 return tegra_dpaux_groups[group]; 372 } 373 374 static int tegra_dpaux_get_group_pins(struct pinctrl_dev *pinctrl, 375 unsigned group, const unsigned **pins, 376 unsigned *num_pins) 377 { 378 *pins = tegra_dpaux_pin_numbers; 379 *num_pins = ARRAY_SIZE(tegra_dpaux_pin_numbers); 380 381 return 0; 382 } 383 384 static const struct pinctrl_ops tegra_dpaux_pinctrl_ops = { 385 .get_groups_count = tegra_dpaux_get_groups_count, 386 .get_group_name = tegra_dpaux_get_group_name, 387 .get_group_pins = tegra_dpaux_get_group_pins, 388 .dt_node_to_map = pinconf_generic_dt_node_to_map_group, 389 .dt_free_map = pinconf_generic_dt_free_map, 390 }; 391 392 static int tegra_dpaux_get_functions_count(struct pinctrl_dev *pinctrl) 393 { 394 return ARRAY_SIZE(tegra_dpaux_functions); 395 } 396 397 static const char *tegra_dpaux_get_function_name(struct pinctrl_dev *pinctrl, 398 unsigned int function) 399 { 400 return tegra_dpaux_functions[function]; 401 } 402 403 static int tegra_dpaux_get_function_groups(struct pinctrl_dev *pinctrl, 404 unsigned int function, 405 const char * const **groups, 406 unsigned * const num_groups) 407 { 408 *num_groups = ARRAY_SIZE(tegra_dpaux_groups); 409 *groups = tegra_dpaux_groups; 410 411 return 0; 412 } 413 414 static int tegra_dpaux_set_mux(struct pinctrl_dev *pinctrl, 415 unsigned int function, unsigned int group) 416 { 417 struct tegra_dpaux *dpaux = pinctrl_dev_get_drvdata(pinctrl); 418 419 return tegra_dpaux_pad_config(dpaux, function); 420 } 421 422 static const struct pinmux_ops tegra_dpaux_pinmux_ops = { 423 .get_functions_count = tegra_dpaux_get_functions_count, 424 .get_function_name = tegra_dpaux_get_function_name, 425 .get_function_groups = tegra_dpaux_get_function_groups, 426 .set_mux = tegra_dpaux_set_mux, 427 }; 428 #endif 429 430 static int tegra_dpaux_probe(struct platform_device *pdev) 431 { 432 struct tegra_dpaux *dpaux; 433 struct resource *regs; 434 u32 value; 435 int err; 436 437 dpaux = devm_kzalloc(&pdev->dev, sizeof(*dpaux), GFP_KERNEL); 438 if (!dpaux) 439 return -ENOMEM; 440 441 INIT_WORK(&dpaux->work, tegra_dpaux_hotplug); 442 init_completion(&dpaux->complete); 443 INIT_LIST_HEAD(&dpaux->list); 444 dpaux->dev = &pdev->dev; 445 446 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 447 dpaux->regs = devm_ioremap_resource(&pdev->dev, regs); 448 if (IS_ERR(dpaux->regs)) 449 return PTR_ERR(dpaux->regs); 450 451 dpaux->irq = platform_get_irq(pdev, 0); 452 if (dpaux->irq < 0) { 453 dev_err(&pdev->dev, "failed to get IRQ\n"); 454 return -ENXIO; 455 } 456 457 if (!pdev->dev.pm_domain) { 458 dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux"); 459 if (IS_ERR(dpaux->rst)) { 460 dev_err(&pdev->dev, 461 "failed to get reset control: %ld\n", 462 PTR_ERR(dpaux->rst)); 463 return PTR_ERR(dpaux->rst); 464 } 465 } 466 467 dpaux->clk = devm_clk_get(&pdev->dev, NULL); 468 if (IS_ERR(dpaux->clk)) { 469 dev_err(&pdev->dev, "failed to get module clock: %ld\n", 470 PTR_ERR(dpaux->clk)); 471 return PTR_ERR(dpaux->clk); 472 } 473 474 dpaux->clk_parent = devm_clk_get(&pdev->dev, "parent"); 475 if (IS_ERR(dpaux->clk_parent)) { 476 dev_err(&pdev->dev, "failed to get parent clock: %ld\n", 477 PTR_ERR(dpaux->clk_parent)); 478 return PTR_ERR(dpaux->clk_parent); 479 } 480 481 err = clk_set_rate(dpaux->clk_parent, 270000000); 482 if (err < 0) { 483 dev_err(&pdev->dev, "failed to set clock to 270 MHz: %d\n", 484 err); 485 return err; 486 } 487 488 dpaux->vdd = devm_regulator_get(&pdev->dev, "vdd"); 489 if (IS_ERR(dpaux->vdd)) { 490 dev_err(&pdev->dev, "failed to get VDD supply: %ld\n", 491 PTR_ERR(dpaux->vdd)); 492 return PTR_ERR(dpaux->vdd); 493 } 494 495 platform_set_drvdata(pdev, dpaux); 496 pm_runtime_enable(&pdev->dev); 497 pm_runtime_get_sync(&pdev->dev); 498 499 err = devm_request_irq(dpaux->dev, dpaux->irq, tegra_dpaux_irq, 0, 500 dev_name(dpaux->dev), dpaux); 501 if (err < 0) { 502 dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n", 503 dpaux->irq, err); 504 return err; 505 } 506 507 disable_irq(dpaux->irq); 508 509 dpaux->aux.transfer = tegra_dpaux_transfer; 510 dpaux->aux.dev = &pdev->dev; 511 512 err = drm_dp_aux_register(&dpaux->aux); 513 if (err < 0) 514 return err; 515 516 /* 517 * Assume that by default the DPAUX/I2C pads will be used for HDMI, 518 * so power them up and configure them in I2C mode. 519 * 520 * The DPAUX code paths reconfigure the pads in AUX mode, but there 521 * is no possibility to perform the I2C mode configuration in the 522 * HDMI path. 523 */ 524 err = tegra_dpaux_pad_config(dpaux, DPAUX_HYBRID_PADCTL_MODE_I2C); 525 if (err < 0) 526 return err; 527 528 #ifdef CONFIG_GENERIC_PINCONF 529 dpaux->desc.name = dev_name(&pdev->dev); 530 dpaux->desc.pins = tegra_dpaux_pins; 531 dpaux->desc.npins = ARRAY_SIZE(tegra_dpaux_pins); 532 dpaux->desc.pctlops = &tegra_dpaux_pinctrl_ops; 533 dpaux->desc.pmxops = &tegra_dpaux_pinmux_ops; 534 dpaux->desc.owner = THIS_MODULE; 535 536 dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux); 537 if (IS_ERR(dpaux->pinctrl)) { 538 dev_err(&pdev->dev, "failed to register pincontrol\n"); 539 return PTR_ERR(dpaux->pinctrl); 540 } 541 #endif 542 /* enable and clear all interrupts */ 543 value = DPAUX_INTR_AUX_DONE | DPAUX_INTR_IRQ_EVENT | 544 DPAUX_INTR_UNPLUG_EVENT | DPAUX_INTR_PLUG_EVENT; 545 tegra_dpaux_writel(dpaux, value, DPAUX_INTR_EN_AUX); 546 tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX); 547 548 mutex_lock(&dpaux_lock); 549 list_add_tail(&dpaux->list, &dpaux_list); 550 mutex_unlock(&dpaux_lock); 551 552 return 0; 553 } 554 555 static int tegra_dpaux_remove(struct platform_device *pdev) 556 { 557 struct tegra_dpaux *dpaux = platform_get_drvdata(pdev); 558 559 cancel_work_sync(&dpaux->work); 560 561 /* make sure pads are powered down when not in use */ 562 tegra_dpaux_pad_power_down(dpaux); 563 564 pm_runtime_put(&pdev->dev); 565 pm_runtime_disable(&pdev->dev); 566 567 drm_dp_aux_unregister(&dpaux->aux); 568 569 mutex_lock(&dpaux_lock); 570 list_del(&dpaux->list); 571 mutex_unlock(&dpaux_lock); 572 573 return 0; 574 } 575 576 #ifdef CONFIG_PM 577 static int tegra_dpaux_suspend(struct device *dev) 578 { 579 struct tegra_dpaux *dpaux = dev_get_drvdata(dev); 580 int err = 0; 581 582 if (dpaux->rst) { 583 err = reset_control_assert(dpaux->rst); 584 if (err < 0) { 585 dev_err(dev, "failed to assert reset: %d\n", err); 586 return err; 587 } 588 } 589 590 usleep_range(1000, 2000); 591 592 clk_disable_unprepare(dpaux->clk_parent); 593 clk_disable_unprepare(dpaux->clk); 594 595 return err; 596 } 597 598 static int tegra_dpaux_resume(struct device *dev) 599 { 600 struct tegra_dpaux *dpaux = dev_get_drvdata(dev); 601 int err; 602 603 err = clk_prepare_enable(dpaux->clk); 604 if (err < 0) { 605 dev_err(dev, "failed to enable clock: %d\n", err); 606 return err; 607 } 608 609 err = clk_prepare_enable(dpaux->clk_parent); 610 if (err < 0) { 611 dev_err(dev, "failed to enable parent clock: %d\n", err); 612 goto disable_clk; 613 } 614 615 usleep_range(1000, 2000); 616 617 if (dpaux->rst) { 618 err = reset_control_deassert(dpaux->rst); 619 if (err < 0) { 620 dev_err(dev, "failed to deassert reset: %d\n", err); 621 goto disable_parent; 622 } 623 624 usleep_range(1000, 2000); 625 } 626 627 return 0; 628 629 disable_parent: 630 clk_disable_unprepare(dpaux->clk_parent); 631 disable_clk: 632 clk_disable_unprepare(dpaux->clk); 633 return err; 634 } 635 #endif 636 637 static const struct dev_pm_ops tegra_dpaux_pm_ops = { 638 SET_RUNTIME_PM_OPS(tegra_dpaux_suspend, tegra_dpaux_resume, NULL) 639 }; 640 641 static const struct of_device_id tegra_dpaux_of_match[] = { 642 { .compatible = "nvidia,tegra186-dpaux", }, 643 { .compatible = "nvidia,tegra210-dpaux", }, 644 { .compatible = "nvidia,tegra124-dpaux", }, 645 { }, 646 }; 647 MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match); 648 649 struct platform_driver tegra_dpaux_driver = { 650 .driver = { 651 .name = "tegra-dpaux", 652 .of_match_table = tegra_dpaux_of_match, 653 .pm = &tegra_dpaux_pm_ops, 654 }, 655 .probe = tegra_dpaux_probe, 656 .remove = tegra_dpaux_remove, 657 }; 658 659 struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np) 660 { 661 struct tegra_dpaux *dpaux; 662 663 mutex_lock(&dpaux_lock); 664 665 list_for_each_entry(dpaux, &dpaux_list, list) 666 if (np == dpaux->dev->of_node) { 667 mutex_unlock(&dpaux_lock); 668 return &dpaux->aux; 669 } 670 671 mutex_unlock(&dpaux_lock); 672 673 return NULL; 674 } 675 676 int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output) 677 { 678 struct tegra_dpaux *dpaux = to_dpaux(aux); 679 unsigned long timeout; 680 int err; 681 682 output->connector.polled = DRM_CONNECTOR_POLL_HPD; 683 dpaux->output = output; 684 685 err = regulator_enable(dpaux->vdd); 686 if (err < 0) 687 return err; 688 689 timeout = jiffies + msecs_to_jiffies(250); 690 691 while (time_before(jiffies, timeout)) { 692 enum drm_connector_status status; 693 694 status = drm_dp_aux_detect(aux); 695 if (status == connector_status_connected) { 696 enable_irq(dpaux->irq); 697 return 0; 698 } 699 700 usleep_range(1000, 2000); 701 } 702 703 return -ETIMEDOUT; 704 } 705 706 int drm_dp_aux_detach(struct drm_dp_aux *aux) 707 { 708 struct tegra_dpaux *dpaux = to_dpaux(aux); 709 unsigned long timeout; 710 int err; 711 712 disable_irq(dpaux->irq); 713 714 err = regulator_disable(dpaux->vdd); 715 if (err < 0) 716 return err; 717 718 timeout = jiffies + msecs_to_jiffies(250); 719 720 while (time_before(jiffies, timeout)) { 721 enum drm_connector_status status; 722 723 status = drm_dp_aux_detect(aux); 724 if (status == connector_status_disconnected) { 725 dpaux->output = NULL; 726 return 0; 727 } 728 729 usleep_range(1000, 2000); 730 } 731 732 return -ETIMEDOUT; 733 } 734 735 enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux) 736 { 737 struct tegra_dpaux *dpaux = to_dpaux(aux); 738 u32 value; 739 740 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT); 741 742 if (value & DPAUX_DP_AUXSTAT_HPD_STATUS) 743 return connector_status_connected; 744 745 return connector_status_disconnected; 746 } 747 748 int drm_dp_aux_enable(struct drm_dp_aux *aux) 749 { 750 struct tegra_dpaux *dpaux = to_dpaux(aux); 751 752 return tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_AUX); 753 } 754 755 int drm_dp_aux_disable(struct drm_dp_aux *aux) 756 { 757 struct tegra_dpaux *dpaux = to_dpaux(aux); 758 759 tegra_dpaux_pad_power_down(dpaux); 760 761 return 0; 762 } 763 764 int drm_dp_aux_prepare(struct drm_dp_aux *aux, u8 encoding) 765 { 766 int err; 767 768 err = drm_dp_dpcd_writeb(aux, DP_MAIN_LINK_CHANNEL_CODING_SET, 769 encoding); 770 if (err < 0) 771 return err; 772 773 return 0; 774 } 775 776 int drm_dp_aux_train(struct drm_dp_aux *aux, struct drm_dp_link *link, 777 u8 pattern) 778 { 779 u8 tp = pattern & DP_TRAINING_PATTERN_MASK; 780 u8 status[DP_LINK_STATUS_SIZE], values[4]; 781 unsigned int i; 782 int err; 783 784 err = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET, pattern); 785 if (err < 0) 786 return err; 787 788 if (tp == DP_TRAINING_PATTERN_DISABLE) 789 return 0; 790 791 for (i = 0; i < link->num_lanes; i++) 792 values[i] = DP_TRAIN_MAX_PRE_EMPHASIS_REACHED | 793 DP_TRAIN_PRE_EMPH_LEVEL_0 | 794 DP_TRAIN_MAX_SWING_REACHED | 795 DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 796 797 err = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, values, 798 link->num_lanes); 799 if (err < 0) 800 return err; 801 802 usleep_range(500, 1000); 803 804 err = drm_dp_dpcd_read_link_status(aux, status); 805 if (err < 0) 806 return err; 807 808 switch (tp) { 809 case DP_TRAINING_PATTERN_1: 810 if (!drm_dp_clock_recovery_ok(status, link->num_lanes)) 811 return -EAGAIN; 812 813 break; 814 815 case DP_TRAINING_PATTERN_2: 816 if (!drm_dp_channel_eq_ok(status, link->num_lanes)) 817 return -EAGAIN; 818 819 break; 820 821 default: 822 dev_err(aux->dev, "unsupported training pattern %u\n", tp); 823 return -EINVAL; 824 } 825 826 err = drm_dp_dpcd_writeb(aux, DP_EDP_CONFIGURATION_SET, 0); 827 if (err < 0) 828 return err; 829 830 return 0; 831 } 832