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