video: exynos: dp: Clean up SW link training
authorSean Paul <seanpaul@chromium.org>
Mon, 16 Jul 2012 22:12:06 +0000 (15:12 -0700)
committerGerrit <chrome-bot@google.com>
Tue, 17 Jul 2012 20:11:28 +0000 (13:11 -0700)
Clean up some of the SW training code to make it more clear and reduce
duplicate code.

BUG=chrome-os-partner:11325
TEST=Tested on snow

Change-Id: I22c572e4f856596b26178dff41c1bb0757fa9c16
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/27548
Reviewed-by: Mandeep Singh Baines <msb@chromium.org>
drivers/video/exynos/exynos_dp_core.c

index 1999fcb..3e705d0 100644 (file)
@@ -260,10 +260,8 @@ static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp,
 
 static int exynos_dp_link_start(struct exynos_dp_device *dp)
 {
-       int ret;
-       u8 buf[5];
-       int lane;
-       int lane_count;
+       int ret, lane, lane_count;
+       u8 buf[4];
 
        lane_count = dp->link_train.lane_count;
 
@@ -286,8 +284,7 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
        /* Setup RX configuration */
        buf[0] = dp->link_train.link_rate;
        buf[1] = dp->link_train.lane_count;
-       ret = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET,
-                               2, buf);
+       ret = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, 2, buf);
        if (ret)
                return ret;
 
@@ -300,14 +297,16 @@ static int exynos_dp_link_start(struct exynos_dp_device *dp)
        exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
        /* Set RX training pattern */
-       buf[0] = DPCD_SCRAMBLING_DISABLED |
-                DPCD_TRAINING_PATTERN_1;
-       for (lane = 1; lane <= lane_count; lane++)
+       ret = exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_TRAINING_PATTERN_SET,
+               DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1);
+       if (ret)
+               return ret;
+
+       for (lane = 0; lane < lane_count; lane++)
                buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
                            DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
-       ret = exynos_dp_write_bytes_to_dpcd(dp,
-               DPCD_ADDR_TRAINING_PATTERN_SET,
-               lane_count + 1, buf);
+       ret = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET,
+               lane_count, buf);
        if (ret)
                return ret;
 
@@ -478,55 +477,30 @@ static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
 
 static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 {
-       int ret;
-       u8 data;
-       u8 link_status[6];
-       int lane;
-       int lane_count;
-       u8 buf[5];
-
-       u8 adjust_request[2];
-       u8 voltage_swing = 0;
-       u8 pre_emphasis;
-       u8 training_lane;
+       int ret, lane, lane_count;
+       u8 voltage_swing, pre_emphasis, training_lane, link_status[6];
+       u8 *adjust_request;
 
        udelay(100);
 
-       ret = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
-                               6, link_status);
+       ret = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS, 6,
+                       link_status);
        if (ret)
                return ret;
 
        lane_count = dp->link_train.lane_count;
-
-       adjust_request[0] = link_status[4];
-       adjust_request[1] = link_status[5];
+       adjust_request = link_status + 4;
 
        if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
                /* set training pattern 2 for EQ */
                exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-               exynos_dp_get_adjust_train(dp, adjust_request);
-
-               buf[0] = DPCD_SCRAMBLING_DISABLED |
-                        DPCD_TRAINING_PATTERN_2;
                ret = exynos_dp_write_byte_to_dpcd(dp,
                        DPCD_ADDR_TRAINING_PATTERN_SET,
-                       buf[0]);
+                       DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_2);
                if (ret)
                        return ret;
 
-               for (lane = 0; lane < lane_count; lane++) {
-                       exynos_dp_set_lane_link_training(dp,
-                               dp->link_train.training_lane[lane],
-                               lane);
-                       buf[lane] = dp->link_train.training_lane[lane];
-                       ret = exynos_dp_write_byte_to_dpcd(dp,
-                               DPCD_ADDR_TRAINING_LANE0_SET + lane,
-                               buf[lane]);
-                       if (ret)
-                               return ret;
-               }
                dp->link_train.lt_state = EQUALIZER_TRAINING;
        } else {
                for (lane = 0; lane < lane_count; lane++) {
@@ -544,36 +518,31 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 
                if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
                        exynos_dp_reduce_link_rate(dp);
-               } else {
-                       exynos_dp_get_adjust_train(dp, adjust_request);
-
-                       for (lane = 0; lane < lane_count; lane++) {
-                               exynos_dp_set_lane_link_training(dp,
-                                       dp->link_train.training_lane[lane],
-                                       lane);
-                               buf[lane] = dp->link_train.training_lane[lane];
-                               ret = exynos_dp_write_byte_to_dpcd(dp,
-                                       DPCD_ADDR_TRAINING_LANE0_SET + lane,
-                                       buf[lane]);
-                               if (ret)
-                                       return ret;
-                       }
+                       return ret;
                }
        }
 
+       exynos_dp_get_adjust_train(dp, adjust_request);
+
+       for (lane = 0; lane < lane_count; lane++) {
+               exynos_dp_set_lane_link_training(dp,
+                       dp->link_train.training_lane[lane], lane);
+               ret = exynos_dp_write_byte_to_dpcd(dp,
+                       DPCD_ADDR_TRAINING_LANE0_SET + lane,
+                       dp->link_train.training_lane[lane]);
+               if (ret)
+                       return ret;
+       }
+
        return ret;
 }
 
 static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 {
-       int ret;
+       int ret, lane, lane_count;
        u8 link_status[6];
-       int lane;
-       int lane_count;
-       u8 buf[5];
        u32 reg;
-
-       u8 adjust_request[2];
+       u8 *adjust_request;
 
        udelay(400);
 
@@ -581,55 +550,53 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
                                6, link_status);
        if (ret)
                return ret;
+
+       adjust_request = link_status + 4;
        lane_count = dp->link_train.lane_count;
 
-       if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
-               adjust_request[0] = link_status[4];
-               adjust_request[1] = link_status[5];
+       if (exynos_dp_clock_recovery_ok(link_status, lane_count)) {
+               exynos_dp_reduce_link_rate(dp);
+               return ret;
+       }
+       if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
+               /* traing pattern Set to Normal */
+               exynos_dp_training_pattern_dis(dp);
 
-               if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
-                       /* traing pattern Set to Normal */
-                       exynos_dp_training_pattern_dis(dp);
+               dev_info(dp->dev, "Link Training success!\n");
 
-                       dev_info(dp->dev, "Link Training success!\n");
+               exynos_dp_get_link_bandwidth(dp, &reg);
+               dp->link_train.link_rate = reg;
+               dev_dbg(dp->dev, "final bandwidth = %.2x\n",
+                       dp->link_train.link_rate);
 
-                       exynos_dp_get_link_bandwidth(dp, &reg);
-                       dp->link_train.link_rate = reg;
-                       dev_dbg(dp->dev, "final bandwidth = %.2x\n",
-                               dp->link_train.link_rate);
+               exynos_dp_get_lane_count(dp, &reg);
+               dp->link_train.lane_count = reg;
+               dev_dbg(dp->dev, "final lane count = %.2x\n",
+                       dp->link_train.lane_count);
+               /* set enhanced mode if available */
+               exynos_dp_set_enhanced_mode(dp);
 
-                       exynos_dp_get_lane_count(dp, &reg);
-                       dp->link_train.lane_count = reg;
-                       dev_dbg(dp->dev, "final lane count = %.2x\n",
-                               dp->link_train.lane_count);
-                       /* set enhanced mode if available */
-                       exynos_dp_set_enhanced_mode(dp);
+               dp->link_train.lt_state = FINISHED;
+       } else {
+               /* not all locked */
+               dp->link_train.eq_loop++;
 
-                       dp->link_train.lt_state = FINISHED;
+               if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
+                       exynos_dp_reduce_link_rate(dp);
                } else {
-                       /* not all locked */
-                       dp->link_train.eq_loop++;
-
-                       if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
-                               exynos_dp_reduce_link_rate(dp);
-                       } else {
-                               exynos_dp_get_adjust_train(dp, adjust_request);
-
-                               for (lane = 0; lane < lane_count; lane++) {
-                                       exynos_dp_set_lane_link_training(dp,
-                                               dp->link_train.training_lane[lane],
-                                               lane);
-                                       buf[lane] = dp->link_train.training_lane[lane];
-                                       ret = exynos_dp_write_byte_to_dpcd(dp,
-                                               DPCD_ADDR_TRAINING_LANE0_SET + lane,
-                                               buf[lane]);
-                                       if (ret)
-                                               return ret;
-                               }
+                       exynos_dp_get_adjust_train(dp, adjust_request);
+
+                       for (lane = 0; lane < lane_count; lane++) {
+                               exynos_dp_set_lane_link_training(dp,
+                                       dp->link_train.training_lane[lane],
+                                       lane);
+                               ret = exynos_dp_write_byte_to_dpcd(dp,
+                                       DPCD_ADDR_TRAINING_LANE0_SET + lane,
+                                       dp->link_train.training_lane[lane]);
+                               if (ret)
+                                       return ret;
                        }
                }
-       } else {
-               exynos_dp_reduce_link_rate(dp);
        }
 
        return ret;
@@ -702,13 +669,16 @@ static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 {
        int ret = 0, training_finished = 0;
 
-       /* Turn off unnecessary lane */
-       if (dp->link_train.lane_count == 1)
+       /* Turn off unnecessary lanes */
+       switch (dp->link_train.lane_count) {
+       case LANE_COUNT1:
                exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
-
-       if (dp->link_train.lane_count <= 2) {
+       case LANE_COUNT2:
                exynos_dp_set_analog_power_down(dp, CH2_BLOCK, 1);
                exynos_dp_set_analog_power_down(dp, CH3_BLOCK, 1);
+               break;
+       default:
+               break;
        }
 
        dp->link_train.lt_state = START;