diff options
author | Sean Paul <seanpaul@chromium.org> | 2012-10-31 22:13:00 -0400 |
---|---|---|
committer | Jingoo Han <jg1.han@samsung.com> | 2012-11-28 20:33:27 -0500 |
commit | 99f541524c8cd7b54a4f64a1c225de940e950833 (patch) | |
tree | e600839f98fbee8d71accebb990a10e123194202 | |
parent | 49ce41f38b307d00cbcbc76721e0db2208915b44 (diff) |
video: exynos_dp: Improve EDID error handling
EDID error handling has 2 problems:
- It doesn't fail as early as it can
- The retry counts for i2c and aux transactions are huge
This patch fails if the initial i2c transaction fails, and reduces the
aux and i2c retry counts down to 3.
[jg1.han@samsung.com: reduced the retry count of exynos_dp_read_byte_from_dpcd()]
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
-rw-r--r-- | drivers/video/exynos/exynos_dp_core.c | 13 | ||||
-rw-r--r-- | drivers/video/exynos/exynos_dp_reg.c | 14 |
2 files changed, 14 insertions, 13 deletions
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c index d60f8da720d1..a4c1dec763bd 100644 --- a/drivers/video/exynos/exynos_dp_core.c +++ b/drivers/video/exynos/exynos_dp_core.c | |||
@@ -91,9 +91,11 @@ static int exynos_dp_read_edid(struct exynos_dp_device *dp) | |||
91 | */ | 91 | */ |
92 | 92 | ||
93 | /* Read Extension Flag, Number of 128-byte EDID extension blocks */ | 93 | /* Read Extension Flag, Number of 128-byte EDID extension blocks */ |
94 | exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, | 94 | retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, |
95 | EDID_EXTENSION_FLAG, | 95 | EDID_EXTENSION_FLAG, |
96 | &extend_block); | 96 | &extend_block); |
97 | if (retval) | ||
98 | return retval; | ||
97 | 99 | ||
98 | if (extend_block > 0) { | 100 | if (extend_block > 0) { |
99 | dev_dbg(dp->dev, "EDID data includes a single extension!\n"); | 101 | dev_dbg(dp->dev, "EDID data includes a single extension!\n"); |
@@ -182,14 +184,15 @@ static int exynos_dp_handle_edid(struct exynos_dp_device *dp) | |||
182 | int retval; | 184 | int retval; |
183 | 185 | ||
184 | /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ | 186 | /* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ |
185 | exynos_dp_read_bytes_from_dpcd(dp, | 187 | retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV, |
186 | DPCD_ADDR_DPCD_REV, | 188 | 12, buf); |
187 | 12, buf); | 189 | if (retval) |
190 | return retval; | ||
188 | 191 | ||
189 | /* Read EDID */ | 192 | /* Read EDID */ |
190 | for (i = 0; i < 3; i++) { | 193 | for (i = 0; i < 3; i++) { |
191 | retval = exynos_dp_read_edid(dp); | 194 | retval = exynos_dp_read_edid(dp); |
192 | if (retval == 0) | 195 | if (!retval) |
193 | break; | 196 | break; |
194 | } | 197 | } |
195 | 198 | ||
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c index 3f5ca8a0d5ea..fc19ef651565 100644 --- a/drivers/video/exynos/exynos_dp_reg.c +++ b/drivers/video/exynos/exynos_dp_reg.c | |||
@@ -491,7 +491,7 @@ int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, | |||
491 | int i; | 491 | int i; |
492 | int retval; | 492 | int retval; |
493 | 493 | ||
494 | for (i = 0; i < 10; i++) { | 494 | for (i = 0; i < 3; i++) { |
495 | /* Clear AUX CH data buffer */ | 495 | /* Clear AUX CH data buffer */ |
496 | reg = BUF_CLR; | 496 | reg = BUF_CLR; |
497 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | 497 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); |
@@ -552,7 +552,7 @@ int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, | |||
552 | else | 552 | else |
553 | cur_data_count = count - start_offset; | 553 | cur_data_count = count - start_offset; |
554 | 554 | ||
555 | for (i = 0; i < 10; i++) { | 555 | for (i = 0; i < 3; i++) { |
556 | /* Select DPCD device address */ | 556 | /* Select DPCD device address */ |
557 | reg = AUX_ADDR_7_0(reg_addr + start_offset); | 557 | reg = AUX_ADDR_7_0(reg_addr + start_offset); |
558 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | 558 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); |
@@ -617,7 +617,7 @@ int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, | |||
617 | cur_data_count = count - start_offset; | 617 | cur_data_count = count - start_offset; |
618 | 618 | ||
619 | /* AUX CH Request Transaction process */ | 619 | /* AUX CH Request Transaction process */ |
620 | for (i = 0; i < 10; i++) { | 620 | for (i = 0; i < 3; i++) { |
621 | /* Select DPCD device address */ | 621 | /* Select DPCD device address */ |
622 | reg = AUX_ADDR_7_0(reg_addr + start_offset); | 622 | reg = AUX_ADDR_7_0(reg_addr + start_offset); |
623 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); | 623 | writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); |
@@ -700,17 +700,15 @@ int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, | |||
700 | int i; | 700 | int i; |
701 | int retval; | 701 | int retval; |
702 | 702 | ||
703 | for (i = 0; i < 10; i++) { | 703 | for (i = 0; i < 3; i++) { |
704 | /* Clear AUX CH data buffer */ | 704 | /* Clear AUX CH data buffer */ |
705 | reg = BUF_CLR; | 705 | reg = BUF_CLR; |
706 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | 706 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); |
707 | 707 | ||
708 | /* Select EDID device */ | 708 | /* Select EDID device */ |
709 | retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); | 709 | retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); |
710 | if (retval != 0) { | 710 | if (retval != 0) |
711 | dev_err(dp->dev, "Select EDID device fail!\n"); | ||
712 | continue; | 711 | continue; |
713 | } | ||
714 | 712 | ||
715 | /* | 713 | /* |
716 | * Set I2C transaction and read data | 714 | * Set I2C transaction and read data |
@@ -750,7 +748,7 @@ int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, | |||
750 | int retval = 0; | 748 | int retval = 0; |
751 | 749 | ||
752 | for (i = 0; i < count; i += 16) { | 750 | for (i = 0; i < count; i += 16) { |
753 | for (j = 0; j < 100; j++) { | 751 | for (j = 0; j < 3; j++) { |
754 | /* Clear AUX CH data buffer */ | 752 | /* Clear AUX CH data buffer */ |
755 | reg = BUF_CLR; | 753 | reg = BUF_CLR; |
756 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); | 754 | writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); |