| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Analogix DP (Display port) core register interface driver. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2012 Samsung Electronics Co., Ltd. |
|---|
| 5 | 6 | * Author: Jingoo Han <jg1.han@samsung.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 8 | | - * under the terms of the GNU General Public License as published by the |
|---|
| 9 | | - * Free Software Foundation; either version 2 of the License, or (at your |
|---|
| 10 | | - * option) any later version. |
|---|
| 11 | 7 | */ |
|---|
| 12 | 8 | |
|---|
| 13 | 9 | #include <linux/delay.h> |
|---|
| .. | .. |
|---|
| 18 | 14 | #include <linux/phy/phy.h> |
|---|
| 19 | 15 | |
|---|
| 20 | 16 | #include <drm/bridge/analogix_dp.h> |
|---|
| 17 | +#include <drm/drm_probe_helper.h> |
|---|
| 21 | 18 | |
|---|
| 22 | 19 | #include "analogix_dp_core.h" |
|---|
| 23 | 20 | #include "analogix_dp_reg.h" |
|---|
| 24 | | - |
|---|
| 25 | | -#define COMMON_INT_MASK_1 0 |
|---|
| 26 | | -#define COMMON_INT_MASK_2 0 |
|---|
| 27 | | -#define COMMON_INT_MASK_3 0 |
|---|
| 28 | | -#define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) |
|---|
| 29 | 21 | |
|---|
| 30 | 22 | static void analogix_dp_write(struct analogix_dp_device *dp, u32 reg, u32 val) |
|---|
| 31 | 23 | { |
|---|
| .. | .. |
|---|
| 69 | 61 | analogix_dp_write(dp, ANALOGIX_DP_VIDEO_CTL_1, reg); |
|---|
| 70 | 62 | } |
|---|
| 71 | 63 | |
|---|
| 72 | | -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable) |
|---|
| 64 | +static void analogix_dp_set_lane_map(struct analogix_dp_device *dp) |
|---|
| 73 | 65 | { |
|---|
| 74 | | - u32 reg; |
|---|
| 66 | + struct video_info *video_info = &dp->video_info; |
|---|
| 67 | + u32 i, reg = 0; |
|---|
| 75 | 68 | |
|---|
| 76 | | - if (enable) |
|---|
| 77 | | - reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | |
|---|
| 78 | | - LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; |
|---|
| 79 | | - else |
|---|
| 80 | | - reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | |
|---|
| 81 | | - LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; |
|---|
| 69 | + for (i = 0; i < video_info->max_lane_count; i++) |
|---|
| 70 | + reg |= video_info->lane_map[i] << (2 * i); |
|---|
| 82 | 71 | |
|---|
| 83 | 72 | analogix_dp_write(dp, ANALOGIX_DP_LANE_MAP, reg); |
|---|
| 84 | 73 | } |
|---|
| .. | .. |
|---|
| 95 | 84 | |
|---|
| 96 | 85 | if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) { |
|---|
| 97 | 86 | reg = REF_CLK_24M; |
|---|
| 98 | | - if (dp->plat_data->dev_type == RK3288_DP || |
|---|
| 99 | | - dp->plat_data->dev_type == RK3368_EDP) |
|---|
| 87 | + if (dp->plat_data->dev_type == RK3288_DP) |
|---|
| 100 | 88 | reg ^= REF_CLK_MASK; |
|---|
| 101 | 89 | |
|---|
| 102 | 90 | analogix_dp_write(dp, ANALOGIX_DP_PLL_REG_1, reg); |
|---|
| .. | .. |
|---|
| 163 | 151 | |
|---|
| 164 | 152 | usleep_range(20, 30); |
|---|
| 165 | 153 | |
|---|
| 166 | | - analogix_dp_lane_swap(dp, 0); |
|---|
| 154 | + analogix_dp_set_lane_map(dp); |
|---|
| 167 | 155 | |
|---|
| 168 | 156 | analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_1, 0x0); |
|---|
| 169 | 157 | analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_2, 0x40); |
|---|
| .. | .. |
|---|
| 172 | 160 | |
|---|
| 173 | 161 | analogix_dp_write(dp, ANALOGIX_DP_PKT_SEND_CTL, 0x0); |
|---|
| 174 | 162 | analogix_dp_write(dp, ANALOGIX_DP_HDCP_CTL, 0x0); |
|---|
| 175 | | - |
|---|
| 176 | | - analogix_dp_write(dp, ANALOGIX_DP_HPD_DEGLITCH_L, 0x5e); |
|---|
| 177 | | - analogix_dp_write(dp, ANALOGIX_DP_HPD_DEGLITCH_H, 0x1a); |
|---|
| 178 | 163 | |
|---|
| 179 | 164 | analogix_dp_write(dp, ANALOGIX_DP_LINK_DEBUG_CTL, 0x10); |
|---|
| 180 | 165 | |
|---|
| .. | .. |
|---|
| 196 | 181 | |
|---|
| 197 | 182 | void analogix_dp_config_interrupt(struct analogix_dp_device *dp) |
|---|
| 198 | 183 | { |
|---|
| 199 | | - u32 reg; |
|---|
| 200 | | - |
|---|
| 201 | 184 | /* 0: mask, 1: unmask */ |
|---|
| 202 | | - reg = COMMON_INT_MASK_1; |
|---|
| 203 | | - analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_1, reg); |
|---|
| 204 | | - |
|---|
| 205 | | - reg = COMMON_INT_MASK_2; |
|---|
| 206 | | - analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_2, reg); |
|---|
| 207 | | - |
|---|
| 208 | | - reg = COMMON_INT_MASK_3; |
|---|
| 209 | | - analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_3, reg); |
|---|
| 185 | + analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_1, 0); |
|---|
| 186 | + analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_2, 0); |
|---|
| 187 | + analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_3, 0); |
|---|
| 210 | 188 | |
|---|
| 211 | 189 | if (dp->force_hpd || dp->hpd_gpiod) |
|---|
| 212 | 190 | analogix_dp_mute_hpd_interrupt(dp); |
|---|
| .. | .. |
|---|
| 220 | 198 | |
|---|
| 221 | 199 | /* 0: mask, 1: unmask */ |
|---|
| 222 | 200 | reg = analogix_dp_read(dp, ANALOGIX_DP_COMMON_INT_MASK_4); |
|---|
| 223 | | - reg &= ~COMMON_INT_MASK_4; |
|---|
| 201 | + reg &= ~HOTPLUG_CHG; |
|---|
| 224 | 202 | analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_4, reg); |
|---|
| 225 | 203 | |
|---|
| 226 | 204 | reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA_MASK); |
|---|
| .. | .. |
|---|
| 233 | 211 | u32 reg; |
|---|
| 234 | 212 | |
|---|
| 235 | 213 | /* 0: mask, 1: unmask */ |
|---|
| 236 | | - reg = COMMON_INT_MASK_4; |
|---|
| 214 | + reg = analogix_dp_read(dp, ANALOGIX_DP_COMMON_INT_MASK_4); |
|---|
| 215 | + reg |= HOTPLUG_CHG; |
|---|
| 237 | 216 | analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_MASK_4, reg); |
|---|
| 238 | 217 | |
|---|
| 239 | 218 | reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA_MASK); |
|---|
| .. | .. |
|---|
| 424 | 403 | if (dp->hpd_gpiod) |
|---|
| 425 | 404 | return; |
|---|
| 426 | 405 | |
|---|
| 427 | | - analogix_dp_clear_hotplug_interrupts(dp); |
|---|
| 406 | + analogix_dp_write(dp, ANALOGIX_DP_HPD_DEGLITCH_H, 0xbb); |
|---|
| 407 | + analogix_dp_write(dp, ANALOGIX_DP_HPD_DEGLITCH_L, 0x80); |
|---|
| 428 | 408 | |
|---|
| 429 | 409 | reg = analogix_dp_read(dp, ANALOGIX_DP_SYS_CTL_3); |
|---|
| 430 | 410 | reg &= ~(F_HPD | HPD_CTRL); |
|---|
| .. | .. |
|---|
| 440 | 420 | analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_3, reg); |
|---|
| 441 | 421 | } |
|---|
| 442 | 422 | |
|---|
| 443 | | -enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp) |
|---|
| 423 | +static void analogix_dp_handle_hpd_event(struct analogix_dp_device *dp) |
|---|
| 444 | 424 | { |
|---|
| 425 | + bool changed = false; |
|---|
| 445 | 426 | u32 reg; |
|---|
| 446 | 427 | |
|---|
| 447 | | - /* Parse hotplug interrupt status register */ |
|---|
| 428 | + reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA); |
|---|
| 429 | + if (reg & INT_HPD) { |
|---|
| 430 | + analogix_dp_write(dp, ANALOGIX_DP_INT_STA, INT_HPD); |
|---|
| 431 | + |
|---|
| 432 | + memset(&dp->compliance, 0, sizeof(dp->compliance)); |
|---|
| 433 | + |
|---|
| 434 | + analogix_dp_check_device_service_irq(dp); |
|---|
| 435 | + |
|---|
| 436 | + if (dp->compliance.test_active && |
|---|
| 437 | + dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) { |
|---|
| 438 | + analogix_dp_phy_test(dp); |
|---|
| 439 | + return; |
|---|
| 440 | + } |
|---|
| 441 | + } |
|---|
| 442 | + |
|---|
| 448 | 443 | reg = analogix_dp_read(dp, ANALOGIX_DP_COMMON_INT_STA_4); |
|---|
| 444 | + if (reg & HOTPLUG_CHG) { |
|---|
| 445 | + analogix_dp_write(dp, ANALOGIX_DP_COMMON_INT_STA_4, HOTPLUG_CHG); |
|---|
| 446 | + changed = true; |
|---|
| 447 | + } |
|---|
| 449 | 448 | |
|---|
| 450 | | - if (reg & PLUG) |
|---|
| 451 | | - return DP_IRQ_TYPE_HP_CABLE_IN; |
|---|
| 449 | + if (changed) |
|---|
| 450 | + drm_helper_hpd_irq_event(dp->drm_dev); |
|---|
| 451 | +} |
|---|
| 452 | 452 | |
|---|
| 453 | | - if (reg & HPD_LOST) |
|---|
| 454 | | - return DP_IRQ_TYPE_HP_CABLE_OUT; |
|---|
| 455 | | - |
|---|
| 456 | | - if (reg & HOTPLUG_CHG) |
|---|
| 457 | | - return DP_IRQ_TYPE_HP_CHANGE; |
|---|
| 458 | | - |
|---|
| 459 | | - return DP_IRQ_TYPE_UNKNOWN; |
|---|
| 453 | +void analogix_dp_irq_handler(struct analogix_dp_device *dp) |
|---|
| 454 | +{ |
|---|
| 455 | + analogix_dp_handle_hpd_event(dp); |
|---|
| 460 | 456 | } |
|---|
| 461 | 457 | |
|---|
| 462 | 458 | void analogix_dp_reset_aux(struct analogix_dp_device *dp) |
|---|
| .. | .. |
|---|
| 531 | 527 | analogix_dp_write(dp, ANALOGIX_DP_FUNC_EN_1, reg); |
|---|
| 532 | 528 | } |
|---|
| 533 | 529 | |
|---|
| 534 | | -int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp) |
|---|
| 535 | | -{ |
|---|
| 536 | | - int reg; |
|---|
| 537 | | - int retval = 0; |
|---|
| 538 | | - int timeout_loop = 0; |
|---|
| 539 | | - |
|---|
| 540 | | - /* Enable AUX CH operation */ |
|---|
| 541 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_AUX_CH_CTL_2); |
|---|
| 542 | | - reg |= AUX_EN; |
|---|
| 543 | | - analogix_dp_write(dp, ANALOGIX_DP_AUX_CH_CTL_2, reg); |
|---|
| 544 | | - |
|---|
| 545 | | - /* Is AUX CH command reply received? */ |
|---|
| 546 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA); |
|---|
| 547 | | - while (!(reg & RPLY_RECEIV)) { |
|---|
| 548 | | - timeout_loop++; |
|---|
| 549 | | - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { |
|---|
| 550 | | - dev_err(dp->dev, "AUX CH command reply failed!\n"); |
|---|
| 551 | | - return -ETIMEDOUT; |
|---|
| 552 | | - } |
|---|
| 553 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA); |
|---|
| 554 | | - usleep_range(10, 11); |
|---|
| 555 | | - } |
|---|
| 556 | | - |
|---|
| 557 | | - /* Clear interrupt source for AUX CH command reply */ |
|---|
| 558 | | - analogix_dp_write(dp, ANALOGIX_DP_INT_STA, RPLY_RECEIV); |
|---|
| 559 | | - |
|---|
| 560 | | - /* Clear interrupt source for AUX CH access error */ |
|---|
| 561 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA); |
|---|
| 562 | | - if (reg & AUX_ERR) { |
|---|
| 563 | | - analogix_dp_write(dp, ANALOGIX_DP_INT_STA, AUX_ERR); |
|---|
| 564 | | - return -EREMOTEIO; |
|---|
| 565 | | - } |
|---|
| 566 | | - |
|---|
| 567 | | - /* Check AUX CH error access status */ |
|---|
| 568 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_AUX_CH_STA); |
|---|
| 569 | | - if ((reg & AUX_STATUS_MASK) != 0) { |
|---|
| 570 | | - dev_err(dp->dev, "AUX CH error happens: %d\n\n", |
|---|
| 571 | | - reg & AUX_STATUS_MASK); |
|---|
| 572 | | - return -EREMOTEIO; |
|---|
| 573 | | - } |
|---|
| 574 | | - |
|---|
| 575 | | - return retval; |
|---|
| 576 | | -} |
|---|
| 577 | | - |
|---|
| 578 | | -int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp, |
|---|
| 579 | | - unsigned int reg_addr, |
|---|
| 580 | | - unsigned char data) |
|---|
| 581 | | -{ |
|---|
| 582 | | - u32 reg; |
|---|
| 583 | | - int i; |
|---|
| 584 | | - int retval; |
|---|
| 585 | | - |
|---|
| 586 | | - for (i = 0; i < 3; i++) { |
|---|
| 587 | | - /* Clear AUX CH data buffer */ |
|---|
| 588 | | - reg = BUF_CLR; |
|---|
| 589 | | - analogix_dp_write(dp, ANALOGIX_DP_BUFFER_DATA_CTL, reg); |
|---|
| 590 | | - |
|---|
| 591 | | - /* Select DPCD device address */ |
|---|
| 592 | | - reg = AUX_ADDR_7_0(reg_addr); |
|---|
| 593 | | - analogix_dp_write(dp, ANALOGIX_DP_AUX_ADDR_7_0, reg); |
|---|
| 594 | | - reg = AUX_ADDR_15_8(reg_addr); |
|---|
| 595 | | - analogix_dp_write(dp, ANALOGIX_DP_AUX_ADDR_15_8, reg); |
|---|
| 596 | | - reg = AUX_ADDR_19_16(reg_addr); |
|---|
| 597 | | - analogix_dp_write(dp, ANALOGIX_DP_AUX_ADDR_19_16, reg); |
|---|
| 598 | | - |
|---|
| 599 | | - /* Write data buffer */ |
|---|
| 600 | | - reg = (unsigned int)data; |
|---|
| 601 | | - analogix_dp_write(dp, ANALOGIX_DP_BUF_DATA_0, reg); |
|---|
| 602 | | - |
|---|
| 603 | | - /* |
|---|
| 604 | | - * Set DisplayPort transaction and write 1 byte |
|---|
| 605 | | - * If bit 3 is 1, DisplayPort transaction. |
|---|
| 606 | | - * If Bit 3 is 0, I2C transaction. |
|---|
| 607 | | - */ |
|---|
| 608 | | - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; |
|---|
| 609 | | - analogix_dp_write(dp, ANALOGIX_DP_AUX_CH_CTL_1, reg); |
|---|
| 610 | | - |
|---|
| 611 | | - /* Start AUX transaction */ |
|---|
| 612 | | - retval = analogix_dp_start_aux_transaction(dp); |
|---|
| 613 | | - if (retval == 0) |
|---|
| 614 | | - break; |
|---|
| 615 | | - |
|---|
| 616 | | - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); |
|---|
| 617 | | - } |
|---|
| 618 | | - |
|---|
| 619 | | - return retval; |
|---|
| 620 | | -} |
|---|
| 621 | | - |
|---|
| 622 | 530 | static void analogix_dp_ssc_enable(struct analogix_dp_device *dp) |
|---|
| 623 | 531 | { |
|---|
| 624 | 532 | u32 reg; |
|---|
| 625 | 533 | |
|---|
| 626 | | - writel(0x17, dp->reg_base + ANALOGIX_DP_SSC_REG); |
|---|
| 534 | + /* 4500ppm */ |
|---|
| 535 | + writel(0x19, dp->reg_base + ANALOIGX_DP_SSC_REG); |
|---|
| 627 | 536 | /* |
|---|
| 628 | 537 | * To apply updated SSC parameters into SSC operation, |
|---|
| 629 | 538 | * firmware must disable and enable this bit. |
|---|
| .. | .. |
|---|
| 658 | 567 | analogix_dp_write(dp, ANALOGIX_DP_LINK_BW_SET, bwtype); |
|---|
| 659 | 568 | |
|---|
| 660 | 569 | if (dp->phy) { |
|---|
| 661 | | - union phy_configure_opts phy_cfg; |
|---|
| 570 | + union phy_configure_opts phy_cfg = {0}; |
|---|
| 662 | 571 | |
|---|
| 663 | 572 | phy_cfg.dp.lanes = dp->link_train.lane_count; |
|---|
| 664 | | - phy_cfg.dp.link_rate = drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100; |
|---|
| 573 | + phy_cfg.dp.link_rate = |
|---|
| 574 | + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100; |
|---|
| 665 | 575 | phy_cfg.dp.ssc = analogix_dp_ssc_supported(dp); |
|---|
| 666 | 576 | phy_cfg.dp.set_lanes = false; |
|---|
| 667 | 577 | phy_cfg.dp.set_rate = true; |
|---|
| 668 | 578 | phy_cfg.dp.set_voltages = false; |
|---|
| 669 | 579 | ret = phy_configure(dp->phy, &phy_cfg); |
|---|
| 670 | 580 | if (ret && ret != -EOPNOTSUPP) { |
|---|
| 671 | | - dev_err(dp->dev, "%s: phy_configure() failed: %d\n", |
|---|
| 581 | + dev_err(dp->dev, "%s: phy_configure failed: %d\n", |
|---|
| 672 | 582 | __func__, ret); |
|---|
| 673 | 583 | return; |
|---|
| 674 | 584 | } |
|---|
| .. | .. |
|---|
| 705 | 615 | analogix_dp_write(dp, ANALOGIX_DP_LANE_COUNT_SET, reg); |
|---|
| 706 | 616 | |
|---|
| 707 | 617 | if (dp->phy) { |
|---|
| 708 | | - union phy_configure_opts phy_cfg; |
|---|
| 618 | + union phy_configure_opts phy_cfg = {0}; |
|---|
| 709 | 619 | |
|---|
| 710 | 620 | phy_cfg.dp.lanes = dp->link_train.lane_count; |
|---|
| 711 | 621 | phy_cfg.dp.set_lanes = true; |
|---|
| .. | .. |
|---|
| 728 | 638 | *count = reg; |
|---|
| 729 | 639 | } |
|---|
| 730 | 640 | |
|---|
| 731 | | -struct swing_pre_emp_ctrl { |
|---|
| 732 | | - u8 amp; |
|---|
| 733 | | - u8 emp; |
|---|
| 734 | | -}; |
|---|
| 735 | | - |
|---|
| 736 | | -static const struct swing_pre_emp_ctrl swing_pre_emp_ctrl_rbr[4][4] = { |
|---|
| 737 | | - /* voltage swing 0, pre-emphasis 0->3 */ |
|---|
| 738 | | - { |
|---|
| 739 | | - { .amp = 0x50, .emp = 0x00 }, |
|---|
| 740 | | - { .amp = 0x6c, .emp = 0x28 }, |
|---|
| 741 | | - { .amp = 0x80, .emp = 0x60 }, |
|---|
| 742 | | - { .amp = 0xb0, .emp = 0xc4 }, |
|---|
| 743 | | - }, |
|---|
| 744 | | - /* voltage swing 1, pre-emphasis 0->3 */ |
|---|
| 745 | | - { |
|---|
| 746 | | - { .amp = 0x78, .emp = 0x00 }, |
|---|
| 747 | | - { .amp = 0xa4, .emp = 0x50 }, |
|---|
| 748 | | - { .amp = 0xcc, .emp = 0xa6 }, |
|---|
| 749 | | - }, |
|---|
| 750 | | - /* voltage swing 2, pre-emphasis 0->3 */ |
|---|
| 751 | | - { |
|---|
| 752 | | - { .amp = 0xa0, .emp = 0x00 }, |
|---|
| 753 | | - { .amp = 0xe4, .emp = 0x72 }, |
|---|
| 754 | | - }, |
|---|
| 755 | | - /* voltage swing 3, pre-emphasis 0->3 */ |
|---|
| 756 | | - { |
|---|
| 757 | | - { .amp = 0xf0, .emp = 0x00 }, |
|---|
| 758 | | - }, |
|---|
| 759 | | -}; |
|---|
| 760 | | - |
|---|
| 761 | | -static const struct swing_pre_emp_ctrl swing_pre_emp_ctrl_hbr[4][4] = { |
|---|
| 762 | | - /* voltage swing 0, pre-emphasis 0->3 */ |
|---|
| 763 | | - { |
|---|
| 764 | | - { .amp = 0x50, .emp = 0x00 }, |
|---|
| 765 | | - { .amp = 0x6c, .emp = 0x34 }, |
|---|
| 766 | | - { .amp = 0x80, .emp = 0x64 }, |
|---|
| 767 | | - { .amp = 0xb8, .emp = 0xdc }, |
|---|
| 768 | | - }, |
|---|
| 769 | | - /* voltage swing 1, pre-emphasis 0->3 */ |
|---|
| 770 | | - { |
|---|
| 771 | | - { .amp = 0x78, .emp = 0x00 }, |
|---|
| 772 | | - { .amp = 0xa8, .emp = 0x58 }, |
|---|
| 773 | | - { .amp = 0xcc, .emp = 0xa8 }, |
|---|
| 774 | | - }, |
|---|
| 775 | | - /* voltage swing 2, pre-emphasis 0->3 */ |
|---|
| 776 | | - { |
|---|
| 777 | | - { .amp = 0xa0, .emp = 0x00 }, |
|---|
| 778 | | - { .amp = 0xdd, .emp = 0x74 }, |
|---|
| 779 | | - }, |
|---|
| 780 | | - /* voltage swing 3, pre-emphasis 0->3 */ |
|---|
| 781 | | - { |
|---|
| 782 | | - { .amp = 0xf0, .emp = 0x00 }, |
|---|
| 783 | | - }, |
|---|
| 784 | | -}; |
|---|
| 785 | | - |
|---|
| 786 | | -static const struct swing_pre_emp_ctrl swing_pre_emp_ctrl_hbr2[4][4] = { |
|---|
| 787 | | - /* voltage swing 0, pre-emphasis 0->3 */ |
|---|
| 788 | | - { |
|---|
| 789 | | - { .amp = 0x64, .emp = 0x1c }, |
|---|
| 790 | | - { .amp = 0x90, .emp = 0x78 }, |
|---|
| 791 | | - { .amp = 0xc4, .emp = 0xe0 }, |
|---|
| 792 | | - { .amp = 0xa0, .emp = 0xa0 }, |
|---|
| 793 | | - }, |
|---|
| 794 | | - /* voltage swing 1, pre-emphasis 0->3 */ |
|---|
| 795 | | - { |
|---|
| 796 | | - { .amp = 0x9c, .emp = 0x3c }, |
|---|
| 797 | | - { .amp = 0xe8, .emp = 0xd0 }, |
|---|
| 798 | | - { .amp = 0xb4, .emp = 0x78 }, |
|---|
| 799 | | - }, |
|---|
| 800 | | - /* voltage swing 2, pre-emphasis 0->3 */ |
|---|
| 801 | | - { |
|---|
| 802 | | - { .amp = 0xe0, .emp = 0x68 }, |
|---|
| 803 | | - { .amp = 0xe8, .emp = 0xd0 }, |
|---|
| 804 | | - }, |
|---|
| 805 | | - /* voltage swing 3, pre-emphasis 0->3 */ |
|---|
| 806 | | - { |
|---|
| 807 | | - { .amp = 0xf0, .emp = 0x00 }, |
|---|
| 808 | | - }, |
|---|
| 809 | | -}; |
|---|
| 810 | | - |
|---|
| 811 | 641 | void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp) |
|---|
| 812 | 642 | { |
|---|
| 813 | 643 | u8 lane; |
|---|
| .. | .. |
|---|
| 819 | 649 | dp->link_train.training_lane[lane]); |
|---|
| 820 | 650 | |
|---|
| 821 | 651 | if (dp->phy) { |
|---|
| 822 | | - union phy_configure_opts phy_cfg; |
|---|
| 652 | + union phy_configure_opts phy_cfg = {0}; |
|---|
| 823 | 653 | |
|---|
| 824 | 654 | for (lane = 0; lane < dp->link_train.lane_count; lane++) { |
|---|
| 825 | 655 | u8 training_lane = dp->link_train.training_lane[lane]; |
|---|
| .. | .. |
|---|
| 834 | 664 | } |
|---|
| 835 | 665 | |
|---|
| 836 | 666 | phy_cfg.dp.lanes = dp->link_train.lane_count; |
|---|
| 667 | + phy_cfg.dp.link_rate = |
|---|
| 668 | + drm_dp_bw_code_to_link_rate(dp->link_train.link_rate) / 100; |
|---|
| 837 | 669 | phy_cfg.dp.set_lanes = false; |
|---|
| 838 | 670 | phy_cfg.dp.set_rate = false; |
|---|
| 839 | 671 | phy_cfg.dp.set_voltages = true; |
|---|
| .. | .. |
|---|
| 842 | 674 | dev_err(dp->dev, "%s: phy_configure() failed: %d\n", |
|---|
| 843 | 675 | __func__, ret); |
|---|
| 844 | 676 | return; |
|---|
| 845 | | - } |
|---|
| 846 | | - } else { |
|---|
| 847 | | - const struct swing_pre_emp_ctrl *ctrl; |
|---|
| 848 | | - |
|---|
| 849 | | - for (lane = 0; lane < dp->link_train.lane_count; lane++) { |
|---|
| 850 | | - u8 training_lane = dp->link_train.training_lane[lane]; |
|---|
| 851 | | - u8 vs, pe; |
|---|
| 852 | | - u32 reg; |
|---|
| 853 | | - |
|---|
| 854 | | - vs = (training_lane & DP_TRAIN_VOLTAGE_SWING_MASK) >> |
|---|
| 855 | | - DP_TRAIN_VOLTAGE_SWING_SHIFT; |
|---|
| 856 | | - pe = (training_lane & DP_TRAIN_PRE_EMPHASIS_MASK) >> |
|---|
| 857 | | - DP_TRAIN_PRE_EMPHASIS_SHIFT; |
|---|
| 858 | | - |
|---|
| 859 | | - switch (dp->link_train.link_rate) { |
|---|
| 860 | | - case DP_LINK_BW_1_62: |
|---|
| 861 | | - ctrl = &swing_pre_emp_ctrl_rbr[vs][pe]; |
|---|
| 862 | | - break; |
|---|
| 863 | | - case DP_LINK_BW_2_7: |
|---|
| 864 | | - ctrl = &swing_pre_emp_ctrl_hbr[vs][pe]; |
|---|
| 865 | | - break; |
|---|
| 866 | | - case DP_LINK_BW_5_4: |
|---|
| 867 | | - default: |
|---|
| 868 | | - ctrl = &swing_pre_emp_ctrl_hbr2[vs][pe]; |
|---|
| 869 | | - break; |
|---|
| 870 | | - } |
|---|
| 871 | | - |
|---|
| 872 | | - switch (lane) { |
|---|
| 873 | | - case 0: |
|---|
| 874 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_ANALOG_CTL_42); |
|---|
| 875 | | - reg |= R_FORCE_CH0_AMP | R_FORCE_CH0_EMP; |
|---|
| 876 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_42, reg); |
|---|
| 877 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_36, ctrl->amp); |
|---|
| 878 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_37, ctrl->emp); |
|---|
| 879 | | - break; |
|---|
| 880 | | - case 1: |
|---|
| 881 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_ANALOG_CTL_42); |
|---|
| 882 | | - reg |= R_FORCE_CH1_AMP | R_FORCE_CH1_EMP; |
|---|
| 883 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_42, reg); |
|---|
| 884 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_39, ctrl->amp); |
|---|
| 885 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_40, ctrl->emp); |
|---|
| 886 | | - break; |
|---|
| 887 | | - case 2: |
|---|
| 888 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_ANALOG_CTL_49); |
|---|
| 889 | | - reg |= R_FORCE_CH2_AMP | R_FORCE_CH2_EMP; |
|---|
| 890 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_49, reg); |
|---|
| 891 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_43, ctrl->amp); |
|---|
| 892 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_44, ctrl->emp); |
|---|
| 893 | | - break; |
|---|
| 894 | | - case 3: |
|---|
| 895 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_ANALOG_CTL_49); |
|---|
| 896 | | - reg |= R_FORCE_CH3_AMP | R_FORCE_CH3_EMP; |
|---|
| 897 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_49, reg); |
|---|
| 898 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_46, ctrl->amp); |
|---|
| 899 | | - analogix_dp_write(dp, ANALOGIX_DP_ANALOG_CTL_47, ctrl->emp); |
|---|
| 900 | | - break; |
|---|
| 901 | | - } |
|---|
| 902 | 677 | } |
|---|
| 903 | 678 | } |
|---|
| 904 | 679 | } |
|---|
| .. | .. |
|---|
| 925 | 700 | } |
|---|
| 926 | 701 | } |
|---|
| 927 | 702 | |
|---|
| 703 | +bool analogix_dp_get_enhanced_mode(struct analogix_dp_device *dp) |
|---|
| 704 | +{ |
|---|
| 705 | + u32 reg; |
|---|
| 706 | + |
|---|
| 707 | + reg = analogix_dp_read(dp, ANALOGIX_DP_SYS_CTL_4); |
|---|
| 708 | + |
|---|
| 709 | + return !!(reg & ENHANCED); |
|---|
| 710 | +} |
|---|
| 711 | + |
|---|
| 928 | 712 | void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, |
|---|
| 929 | 713 | enum pattern_set pattern) |
|---|
| 930 | 714 | { |
|---|
| .. | .. |
|---|
| 949 | 733 | break; |
|---|
| 950 | 734 | case TRAINING_PTN3: |
|---|
| 951 | 735 | reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN3; |
|---|
| 736 | + analogix_dp_write(dp, ANALOGIX_DP_TRAINING_PTN_SET, reg); |
|---|
| 737 | + break; |
|---|
| 738 | + case TEST_PATTERN_80BIT: |
|---|
| 739 | + reg = 0x3e0f83e0; |
|---|
| 740 | + analogix_dp_write(dp, ANALOGIX_DP_TEST_80B_PATTERN0, reg); |
|---|
| 741 | + reg = 0x0f83e0f8; |
|---|
| 742 | + analogix_dp_write(dp, ANALOGIX_DP_TEST_80B_PATTERN1, reg); |
|---|
| 743 | + reg = 0x0000f83e; |
|---|
| 744 | + analogix_dp_write(dp, ANALOGIX_DP_TEST_80B_PATTERN2, reg); |
|---|
| 745 | + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_80BIT; |
|---|
| 746 | + analogix_dp_write(dp, ANALOGIX_DP_TRAINING_PTN_SET, reg); |
|---|
| 747 | + break; |
|---|
| 748 | + case TEST_PATTERN_HBR2: |
|---|
| 749 | + reg = 0xfb; |
|---|
| 750 | + analogix_dp_write(dp, ANALOGIX_DP_TEST_HBR2_PATTERN, reg); |
|---|
| 751 | + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_HBR2; |
|---|
| 952 | 752 | analogix_dp_write(dp, ANALOGIX_DP_TRAINING_PTN_SET, reg); |
|---|
| 953 | 753 | break; |
|---|
| 954 | 754 | case DP_NONE: |
|---|
| .. | .. |
|---|
| 990 | 790 | reg = CHA_CRI(4) | CHA_CTRL; |
|---|
| 991 | 791 | analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_2, reg); |
|---|
| 992 | 792 | |
|---|
| 993 | | - reg = 0x0; |
|---|
| 994 | | - analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_3, reg); |
|---|
| 793 | + if (dp->video_info.force_stream_valid) { |
|---|
| 794 | + reg = analogix_dp_read(dp, ANALOGIX_DP_SYS_CTL_3); |
|---|
| 795 | + reg |= VALID_CTRL | F_VALID; |
|---|
| 796 | + analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_3, reg); |
|---|
| 797 | + } |
|---|
| 995 | 798 | |
|---|
| 996 | 799 | reg = VID_HRES_TH(2) | VID_VRES_TH(0); |
|---|
| 997 | 800 | analogix_dp_write(dp, ANALOGIX_DP_VIDEO_CTL_8, reg); |
|---|
| .. | .. |
|---|
| 1204 | 1007 | return status; |
|---|
| 1205 | 1008 | } |
|---|
| 1206 | 1009 | |
|---|
| 1010 | +static void analogix_dp_reuse_spd(struct analogix_dp_device *dp) |
|---|
| 1011 | +{ |
|---|
| 1012 | + u32 reg, val; |
|---|
| 1013 | + |
|---|
| 1014 | + switch (dp->plat_data->dev_type) { |
|---|
| 1015 | + case RK3588_EDP: |
|---|
| 1016 | + reg = ANALOGIX_DP_SPDIF_AUDIO_CTL_0; |
|---|
| 1017 | + break; |
|---|
| 1018 | + default: |
|---|
| 1019 | + reg = ANALOGIX_DP_VIDEO_CTL_3; |
|---|
| 1020 | + break; |
|---|
| 1021 | + } |
|---|
| 1022 | + |
|---|
| 1023 | + val = analogix_dp_read(dp, reg); |
|---|
| 1024 | + val |= REUSE_SPD_EN; |
|---|
| 1025 | + analogix_dp_write(dp, reg, val); |
|---|
| 1026 | +} |
|---|
| 1027 | + |
|---|
| 1207 | 1028 | int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, |
|---|
| 1208 | | - struct edp_vsc_psr *vsc, bool blocking) |
|---|
| 1029 | + struct dp_sdp *vsc, bool blocking) |
|---|
| 1209 | 1030 | { |
|---|
| 1210 | 1031 | unsigned int val; |
|---|
| 1211 | 1032 | int ret; |
|---|
| .. | .. |
|---|
| 1233 | 1054 | analogix_dp_write(dp, ANALOGIX_DP_SPD_PB3, 0x5D); |
|---|
| 1234 | 1055 | |
|---|
| 1235 | 1056 | /* configure DB0 / DB1 values */ |
|---|
| 1236 | | - analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB0, vsc->DB0); |
|---|
| 1237 | | - analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB1, vsc->DB1); |
|---|
| 1057 | + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB0, vsc->db[0]); |
|---|
| 1058 | + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_DB1, vsc->db[1]); |
|---|
| 1059 | + |
|---|
| 1060 | + /* configure PB0 / PB1 values */ |
|---|
| 1061 | + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_PB0, |
|---|
| 1062 | + vsc->db[1] ? 0x8d : 0x00); |
|---|
| 1063 | + analogix_dp_write(dp, ANALOGIX_DP_VSC_SHADOW_PB1, 0x00); |
|---|
| 1238 | 1064 | |
|---|
| 1239 | 1065 | /* set reuse spd inforframe */ |
|---|
| 1240 | | - val = analogix_dp_read(dp, ANALOGIX_DP_VIDEO_CTL_3); |
|---|
| 1241 | | - val |= REUSE_SPD_EN; |
|---|
| 1242 | | - analogix_dp_write(dp, ANALOGIX_DP_VIDEO_CTL_3, val); |
|---|
| 1066 | + analogix_dp_reuse_spd(dp); |
|---|
| 1243 | 1067 | |
|---|
| 1244 | 1068 | /* mark info frame update */ |
|---|
| 1245 | 1069 | val = analogix_dp_read(dp, ANALOGIX_DP_PKT_SEND_CTL); |
|---|
| .. | .. |
|---|
| 1254 | 1078 | if (!blocking) |
|---|
| 1255 | 1079 | return 0; |
|---|
| 1256 | 1080 | |
|---|
| 1081 | + /* |
|---|
| 1082 | + * db[1]!=0: entering PSR, wait for fully active remote frame buffer. |
|---|
| 1083 | + * db[1]==0: exiting PSR, wait for either |
|---|
| 1084 | + * (a) ACTIVE_RESYNC - the sink "must display the |
|---|
| 1085 | + * incoming active frames from the Source device with no visible |
|---|
| 1086 | + * glitches and/or artifacts", even though timings may still be |
|---|
| 1087 | + * re-synchronizing; or |
|---|
| 1088 | + * (b) INACTIVE - the transition is fully complete. |
|---|
| 1089 | + */ |
|---|
| 1257 | 1090 | ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status, |
|---|
| 1258 | 1091 | psr_status >= 0 && |
|---|
| 1259 | | - ((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) || |
|---|
| 1260 | | - (!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500, |
|---|
| 1261 | | - DP_TIMEOUT_PSR_LOOP_MS * 1000); |
|---|
| 1092 | + ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) || |
|---|
| 1093 | + (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC || |
|---|
| 1094 | + psr_status == DP_PSR_SINK_INACTIVE))), |
|---|
| 1095 | + 1500, DP_TIMEOUT_PSR_LOOP_MS * 1000); |
|---|
| 1262 | 1096 | if (ret) { |
|---|
| 1263 | 1097 | dev_warn(dp->dev, "Failed to apply PSR %d\n", ret); |
|---|
| 1264 | 1098 | return ret; |
|---|
| .. | .. |
|---|
| 1266 | 1100 | return 0; |
|---|
| 1267 | 1101 | } |
|---|
| 1268 | 1102 | |
|---|
| 1269 | | -void analogix_dp_phy_power_on(struct analogix_dp_device *dp) |
|---|
| 1103 | +int analogix_dp_phy_power_on(struct analogix_dp_device *dp) |
|---|
| 1270 | 1104 | { |
|---|
| 1271 | | - if (dp->phy_enabled) |
|---|
| 1272 | | - return; |
|---|
| 1105 | + int ret; |
|---|
| 1273 | 1106 | |
|---|
| 1274 | | - phy_power_on(dp->phy); |
|---|
| 1107 | + ret = phy_set_mode(dp->phy, PHY_MODE_DP); |
|---|
| 1108 | + if (ret) { |
|---|
| 1109 | + dev_err(dp->dev, "phy_set_mode failed: %d\n", ret); |
|---|
| 1110 | + return ret; |
|---|
| 1111 | + } |
|---|
| 1275 | 1112 | |
|---|
| 1276 | | - dp->phy_enabled = true; |
|---|
| 1113 | + ret = phy_power_on(dp->phy); |
|---|
| 1114 | + if (ret) { |
|---|
| 1115 | + dev_err(dp->dev, "phy_power_on failed: %d\n", ret); |
|---|
| 1116 | + return ret; |
|---|
| 1117 | + } |
|---|
| 1118 | + |
|---|
| 1119 | + return ret; |
|---|
| 1277 | 1120 | } |
|---|
| 1278 | 1121 | |
|---|
| 1279 | 1122 | void analogix_dp_phy_power_off(struct analogix_dp_device *dp) |
|---|
| 1280 | 1123 | { |
|---|
| 1281 | | - if (!dp->phy_enabled) |
|---|
| 1282 | | - return; |
|---|
| 1283 | | - |
|---|
| 1284 | 1124 | phy_power_off(dp->phy); |
|---|
| 1285 | | - |
|---|
| 1286 | | - dp->phy_enabled = false; |
|---|
| 1287 | 1125 | } |
|---|
| 1126 | + |
|---|
| 1127 | +enum { |
|---|
| 1128 | + AUX_STATUS_OK, |
|---|
| 1129 | + AUX_STATUS_NACK_ERROR, |
|---|
| 1130 | + AUX_STATUS_TIMEOUT_ERROR, |
|---|
| 1131 | + AUX_STATUS_UNKNOWN_ERROR, |
|---|
| 1132 | + AUX_STATUS_MUCH_DEFER_ERROR, |
|---|
| 1133 | + AUX_STATUS_TX_SHORT_ERROR, |
|---|
| 1134 | + AUX_STATUS_RX_SHORT_ERROR, |
|---|
| 1135 | + AUX_STATUS_NACK_WITHOUT_M_ERROR, |
|---|
| 1136 | + AUX_STATUS_I2C_NACK_ERROR |
|---|
| 1137 | +}; |
|---|
| 1288 | 1138 | |
|---|
| 1289 | 1139 | ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, |
|---|
| 1290 | 1140 | struct drm_dp_aux_msg *msg) |
|---|
| 1291 | 1141 | { |
|---|
| 1292 | 1142 | u32 reg; |
|---|
| 1293 | | - u32 status_reg; |
|---|
| 1294 | 1143 | u8 *buffer = msg->buffer; |
|---|
| 1295 | 1144 | unsigned int i; |
|---|
| 1296 | 1145 | int num_transferred = 0; |
|---|
| .. | .. |
|---|
| 1299 | 1148 | /* Buffer size of AUX CH is 16 bytes */ |
|---|
| 1300 | 1149 | if (WARN_ON(msg->size > 16)) |
|---|
| 1301 | 1150 | return -E2BIG; |
|---|
| 1302 | | - |
|---|
| 1303 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_FUNC_EN_2); |
|---|
| 1304 | | - if (reg & AUX_FUNC_EN_N) { |
|---|
| 1305 | | - analogix_dp_phy_power_on(dp); |
|---|
| 1306 | | - analogix_dp_init_aux(dp); |
|---|
| 1307 | | - } |
|---|
| 1308 | 1151 | |
|---|
| 1309 | 1152 | /* Clear AUX CH data buffer */ |
|---|
| 1310 | 1153 | reg = BUF_CLR; |
|---|
| .. | .. |
|---|
| 1383 | 1226 | /* Clear interrupt source for AUX CH command reply */ |
|---|
| 1384 | 1227 | analogix_dp_write(dp, ANALOGIX_DP_INT_STA, RPLY_RECEIV); |
|---|
| 1385 | 1228 | |
|---|
| 1386 | | - /* Clear interrupt source for AUX CH access error */ |
|---|
| 1387 | | - reg = analogix_dp_read(dp, ANALOGIX_DP_INT_STA); |
|---|
| 1388 | | - status_reg = analogix_dp_read(dp, ANALOGIX_DP_AUX_CH_STA); |
|---|
| 1389 | | - if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) { |
|---|
| 1390 | | - analogix_dp_write(dp, ANALOGIX_DP_INT_STA, AUX_ERR); |
|---|
| 1391 | | - |
|---|
| 1392 | | - dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n", |
|---|
| 1393 | | - status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR)); |
|---|
| 1394 | | - goto aux_error; |
|---|
| 1395 | | - } |
|---|
| 1229 | + reg = analogix_dp_read(dp, ANALOGIX_DP_AUX_CH_STA); |
|---|
| 1230 | + if ((reg & AUX_STATUS_MASK) == AUX_STATUS_TIMEOUT_ERROR) |
|---|
| 1231 | + return -ETIMEDOUT; |
|---|
| 1396 | 1232 | |
|---|
| 1397 | 1233 | if (msg->request & DP_AUX_I2C_READ) { |
|---|
| 1234 | + size_t buf_data_count; |
|---|
| 1235 | + |
|---|
| 1236 | + reg = analogix_dp_read(dp, ANALOGIX_DP_BUFFER_DATA_CTL); |
|---|
| 1237 | + buf_data_count = BUF_DATA_COUNT(reg); |
|---|
| 1238 | + |
|---|
| 1239 | + if (buf_data_count != msg->size) |
|---|
| 1240 | + return -EBUSY; |
|---|
| 1241 | + |
|---|
| 1398 | 1242 | for (i = 0; i < msg->size; i++) { |
|---|
| 1399 | 1243 | reg = analogix_dp_read(dp, ANALOGIX_DP_BUF_DATA_0 + |
|---|
| 1400 | 1244 | 4 * i); |
|---|
| .. | .. |
|---|
| 1540 | 1384 | reg |= AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N; |
|---|
| 1541 | 1385 | analogix_dp_write(dp, ANALOGIX_DP_FUNC_EN_1, reg); |
|---|
| 1542 | 1386 | } |
|---|
| 1387 | + |
|---|
| 1388 | +void analogix_dp_init(struct analogix_dp_device *dp) |
|---|
| 1389 | +{ |
|---|
| 1390 | + analogix_dp_init_interrupt(dp); |
|---|
| 1391 | + analogix_dp_config_interrupt(dp); |
|---|
| 1392 | + analogix_dp_init_hpd(dp); |
|---|
| 1393 | + analogix_dp_init_aux(dp); |
|---|
| 1394 | +} |
|---|