...
...
8
8
9
Modify training method improve compatibility to these DP devices.
9
Modify training method improve compatibility to these DP devices.
10
10
11
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
11
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
12
---
12
---
13
Hermes Wu (3):
13
Changes in v3:
14
- Patch 1/5 : add commit message for detial about changes
15
- Patch 2/5 : fix lost variable struct device *dev;
16
- Patch 3/5 : keep changes and remove refactoring
17
- Patch 5/5 : merge condition "it6505->step_train_only" check form if condiction into for loop.
18
- Link to v2: https://lore.kernel.org/r/20250326-fix-link-training-v2-0-756c8306f500@ite.com.tw
19
20
Changes in v2:
21
- 1. Split [PATCH 1/3] into 3 commits
22
- 2. Drop non necessary variable auto_ttrain_retry
23
- Link to v1: https://lore.kernel.org/all/20250318-fix-link-training-v1-0-19266711142c@ite.com.tw/
24
25
---
26
Hermes Wu (5):
27
drm/bridge: it6505: fix link training state HW register reset
28
drm/bridge: it6505: check INT_LINK_TRAIN_FAIL while link auto training
14
drm/bridge: it6505: modify DP link auto training
29
drm/bridge: it6505: modify DP link auto training
15
drm/bridge: it6505: modify DP link training work
30
drm/bridge: it6505: modify DP link training work
16
drm/bridge: it6505: skip auto training when previous try fail
31
drm/bridge: it6505: skip auto training when previous try fail
17
32
18
drivers/gpu/drm/bridge/ite-it6505.c | 106 ++++++++++++++++++++++--------------
33
drivers/gpu/drm/bridge/ite-it6505.c | 88 +++++++++++++++++++++----------------
19
1 file changed, 66 insertions(+), 40 deletions(-)
34
1 file changed, 50 insertions(+), 38 deletions(-)
20
---
35
---
21
base-commit: 938fbb16aba8f7b88e0fdcf56f315a5bbad41aad
36
base-commit: 938fbb16aba8f7b88e0fdcf56f315a5bbad41aad
22
change-id: 20250121-fix-link-training-461495494655
37
change-id: 20250121-fix-link-training-461495494655
23
38
24
Best regards,
39
Best regards,
25
--
40
--
26
Hermes Wu <Hermes.wu@ite.com.tw>
41
Hermes Wu <Hermes.wu@ite.com.tw>
diff view generated by jsdifflib
New patch
1
From: Hermes Wu <Hermes.wu@ite.com.tw>
1
2
3
When connect to a DP-to-HDMI device which does not connect
4
to HDMI sink, it will report DPCD 00200h with SINK_COUNT = "0",
5
and issue HPD_IRQ when SINK_COUNT change to "1".
6
7
IT6505 can not recive HPD_IRQ before training done and driver will
8
force HW enter training done state when connect to such devices.
9
10
When HW is force to training done state and restart link training,
11
bits FORCE_RETRAIN and MANUAL_TRAIN at REG_TRAIN_CTRL1 must be set
12
at the same time to reset HW state.
13
14
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
15
---
16
drivers/gpu/drm/bridge/ite-it6505.c | 6 ++++--
17
1 file changed, 4 insertions(+), 2 deletions(-)
18
19
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/drivers/gpu/drm/bridge/ite-it6505.c
22
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
23
@@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505)
24
    mutex_lock(&it6505->aux_lock);
25
    it6505_set_bits(it6505, REG_TRAIN_CTRL0,
26
            FORCE_CR_DONE | FORCE_EQ_DONE, 0x00);
27
-    it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN);
28
+    /* reset link state machine and re start training*/
29
+    it6505_write(it6505, REG_TRAIN_CTRL1,
30
+         FORCE_RETRAIN | MANUAL_TRAIN);
31
    it6505_write(it6505, REG_TRAIN_CTRL1, AUTO_TRAIN);
32
33
    while (timeout > 0) {
34
@@ -XXX,XX +XXX,XX @@ static void it6505_stop_link_train(struct it6505 *it6505)
35
{
36
    it6505->link_state = LINK_IDLE;
37
    cancel_work_sync(&it6505->link_works);
38
-    it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN);
39
+    it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN | MANUAL_TRAIN);
40
}
41
42
static void it6505_link_train_ok(struct it6505 *it6505)
43
44
--
45
2.34.1
diff view generated by jsdifflib
1
From: Hermes Wu <Hermes.wu@ite.com.tw>
1
From: Hermes Wu <Hermes.wu@ite.com.tw>
2
2
3
IT6505 supports HW link training which will write DPCD and check
3
When start link training, interrupt status INT_LINK_TRAIN_FAIL can
4
training status automatically.
4
use to check link training fail and no need to wait until timeout.
5
5
6
In the case that driver set link rate at 2.7G and HW fail to training,
6
it6505_irq_link_train_fail() remove from interrupt and no longer used.
7
it will change link configuration and try 1.65G. And this will cause
8
INT_VID_FIFO_ERROR triggered when link clock is changed.
9
10
When video error occurs, video logic is reset and link training restart,
11
this will cause endless auto link training.
12
13
Modify link auto training with disable INT_VID_FIFO_ERROR to avoid loop
14
and check INT_LINK_TRAIN_FAIL event to abort wait training done.
15
16
Since INT_LINK_TRAIN_FAIL is checked when auto training, it is remove
17
from it6505_int_threaded_handler()
18
19
In order to reset HW link auto training state,
20
bits FORCE_RETRAIN and MANUAL_TRAIN at REG_TRAIN_CTRL1 must be set
21
at the same time.
22
7
23
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
8
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
24
---
9
---
25
drivers/gpu/drm/bridge/ite-it6505.c | 61 +++++++++++++++++++++++++------------
10
drivers/gpu/drm/bridge/ite-it6505.c | 26 +++++++++++++++-----------
26
1 file changed, 42 insertions(+), 19 deletions(-)
11
1 file changed, 15 insertions(+), 11 deletions(-)
27
12
28
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
13
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
29
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
30
--- a/drivers/gpu/drm/bridge/ite-it6505.c
15
--- a/drivers/gpu/drm/bridge/ite-it6505.c
31
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
16
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
32
@@ -XXX,XX +XXX,XX @@ static void it6505_int_mask_enable(struct it6505 *it6505)
17
@@ -XXX,XX +XXX,XX @@ static void it6505_int_mask_enable(struct it6505 *it6505)
33
    it6505_write(it6505, INT_MASK_02, BIT(INT_AUX_CMD_FAIL) |
18
    it6505_write(it6505, INT_MASK_02, BIT(INT_AUX_CMD_FAIL) |
34
         BIT(INT_HDCP_KSV_CHECK) | BIT(INT_AUDIO_FIFO_ERROR));
19
         BIT(INT_HDCP_KSV_CHECK) | BIT(INT_AUDIO_FIFO_ERROR));
35
20
36
-    it6505_write(it6505, INT_MASK_03, BIT(INT_LINK_TRAIN_FAIL) |
21
-    it6505_write(it6505, INT_MASK_03, BIT(INT_LINK_TRAIN_FAIL) |
37
+    it6505_write(it6505, INT_MASK_03,
22
-         BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
38
         BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
23
+    it6505_write(it6505, INT_MASK_03, BIT(INT_VID_FIFO_ERROR) |
24
+         BIT(INT_IO_LATCH_FIFO_OVERFLOW));
39
}
25
}
40
26
41
@@ -XXX,XX +XXX,XX @@ static void it6505_link_training_setup(struct it6505 *it6505)
27
static void it6505_int_mask_disable(struct it6505 *it6505)
42
28
@@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505)
43
static bool it6505_link_start_auto_train(struct it6505 *it6505)
44
{
29
{
45
-    int timeout = 500, link_training_state;
30
    int timeout = 500, link_training_state;
46
+    int link_training_state;
47
    bool state = false;
31
    bool state = false;
32
+    int int03;
48
+    struct device *dev = it6505->dev;
33
+    struct device *dev = it6505->dev;
49
+    int int03;
34
50
+    unsigned long timeout;
35
    mutex_lock(&it6505->aux_lock);
51
+
52
+    guard(mutex)(&it6505->aux_lock);
53
+    /* Disable FIFO error interrupt trigger */
54
+    /* to prevent training fail loop issue */
55
+    it6505_set_bits(it6505, INT_MASK_03, BIT(INT_VID_FIFO_ERROR), 0);
56
+
57
+    it6505_write(it6505, INT_STATUS_03,
58
+         BIT(INT_LINK_TRAIN_FAIL) | BIT(INT_VID_FIFO_ERROR));
59
+    int03 = it6505_read(it6505, INT_STATUS_03);
60
61
-    mutex_lock(&it6505->aux_lock);
62
    it6505_set_bits(it6505, REG_TRAIN_CTRL0,
36
    it6505_set_bits(it6505, REG_TRAIN_CTRL0,
63
            FORCE_CR_DONE | FORCE_EQ_DONE, 0x00);
37
@@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505)
64
-    it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN);
38
    while (timeout > 0) {
65
+
66
+    /* reset link state machine and re start training*/
67
+    it6505_write(it6505, REG_TRAIN_CTRL1,
68
+         FORCE_RETRAIN | MANUAL_TRAIN);
69
    it6505_write(it6505, REG_TRAIN_CTRL1, AUTO_TRAIN);
70
71
-    while (timeout > 0) {
72
+    timeout = jiffies + msecs_to_jiffies(100) + 1;
73
+    for (;;) {
74
        usleep_range(1000, 2000);
39
        usleep_range(1000, 2000);
75
        link_training_state = it6505_read(it6505, REG_LINK_TRAIN_STS);
40
        link_training_state = it6505_read(it6505, REG_LINK_TRAIN_STS);
76
+        int03 = it6505_read(it6505, INT_STATUS_03);
41
+        int03 = it6505_read(it6505, INT_STATUS_03);
77
+        if (int03 & BIT(INT_LINK_TRAIN_FAIL)) {
42
+        if (int03 & BIT(INT_LINK_TRAIN_FAIL)) {
78
+            /* Ignore INT_VID_FIFO_ERROR when auto training fail*/
79
+            it6505_write(it6505, INT_STATUS_03,
43
+            it6505_write(it6505, INT_STATUS_03,
80
+                 BIT(INT_LINK_TRAIN_FAIL) |
44
+                 BIT(INT_LINK_TRAIN_FAIL));
81
+                 BIT(INT_VID_FIFO_ERROR));
82
+
45
+
83
+            if (int03 & BIT(INT_VID_FIFO_ERROR)) {
46
+            DRM_DEV_DEBUG_DRIVER(dev,
84
+                DRM_DEV_DEBUG_DRIVER(dev,
47
+                     "INT_LINK_TRAIN_FAIL(%x)!",
85
+                "video fifo error when training fail (%x)!",
48
+                     int03);
86
+                int03);
87
+            }
88
+
49
+
89
+            break;
50
+            break;
90
+        }
51
+        }
91
52
92
        if (link_training_state > 0 &&
53
        if (link_training_state > 0 &&
93
         (link_training_state & LINK_STATE_NORP)) {
54
         (link_training_state & LINK_STATE_NORP)) {
94
            state = true;
95
-            goto unlock;
96
+            break;
97
        }
98
99
-        timeout--;
100
+        if (time_after(jiffies, timeout))
101
+            break;
102
    }
103
-unlock:
104
-    mutex_unlock(&it6505->aux_lock);
105
106
+    /* recover interrupt trigger*/
107
+    it6505_set_bits(it6505, INT_MASK_03,
108
+            BIT(INT_VID_FIFO_ERROR), BIT(INT_VID_FIFO_ERROR));
109
    return state;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static void it6505_stop_link_train(struct it6505 *it6505)
113
{
114
    it6505->link_state = LINK_IDLE;
115
    cancel_work_sync(&it6505->link_works);
116
-    it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN);
117
+    it6505_write(it6505, REG_TRAIN_CTRL1, FORCE_RETRAIN | MANUAL_TRAIN);
118
}
119
120
static void it6505_link_train_ok(struct it6505 *it6505)
121
@@ -XXX,XX +XXX,XX @@ static void it6505_irq_audio_fifo_error(struct it6505 *it6505)
55
@@ -XXX,XX +XXX,XX @@ static void it6505_irq_audio_fifo_error(struct it6505 *it6505)
122
        it6505_enable_audio(it6505);
56
        it6505_enable_audio(it6505);
123
}
57
}
124
58
125
-static void it6505_irq_link_train_fail(struct it6505 *it6505)
59
-static void it6505_irq_link_train_fail(struct it6505 *it6505)
...
...
diff view generated by jsdifflib
New patch
1
From: Hermes Wu <Hermes.wu@ite.com.tw>
1
2
3
IT6505 supports HW link training which will write DPCD and check
4
training status automatically.
5
6
In the case that driver set link rate at 2.7G and HW fail to training,
7
it will change link configuration and try 1.65G. And this will cause
8
INT_VID_FIFO_ERROR triggered when link clock is changed.
9
10
When video error occurs, video logic is reset and link training restart,
11
this will cause endless auto link training.
12
13
Modify link auto training with disable INT_VID_FIFO_ERROR to avoid loop
14
and check INT_LINK_TRAIN_FAIL event to abort wait training done.
15
16
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
17
---
18
drivers/gpu/drm/bridge/ite-it6505.c | 14 +++++++++++++-
19
1 file changed, 13 insertions(+), 1 deletion(-)
20
21
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/drivers/gpu/drm/bridge/ite-it6505.c
24
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
25
@@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505)
26
    struct device *dev = it6505->dev;
27
28
    mutex_lock(&it6505->aux_lock);
29
+
30
+    /* Disable FIFO error interrupt trigger */
31
+    /* to prevent training fail loop issue */
32
+    it6505_set_bits(it6505, INT_MASK_03, BIT(INT_VID_FIFO_ERROR), 0);
33
+
34
+    it6505_write(it6505, INT_STATUS_03,
35
+         BIT(INT_LINK_TRAIN_FAIL) | BIT(INT_VID_FIFO_ERROR));
36
    it6505_set_bits(it6505, REG_TRAIN_CTRL0,
37
            FORCE_CR_DONE | FORCE_EQ_DONE, 0x00);
38
    /* reset link state machine and re start training*/
39
@@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505)
40
        link_training_state = it6505_read(it6505, REG_LINK_TRAIN_STS);
41
        int03 = it6505_read(it6505, INT_STATUS_03);
42
        if (int03 & BIT(INT_LINK_TRAIN_FAIL)) {
43
+            /* Ignore INT_VID_FIFO_ERROR when auto training fail*/
44
            it6505_write(it6505, INT_STATUS_03,
45
-                 BIT(INT_LINK_TRAIN_FAIL));
46
+                 BIT(INT_LINK_TRAIN_FAIL) |
47
+                 BIT(INT_VID_FIFO_ERROR));
48
49
            DRM_DEV_DEBUG_DRIVER(dev,
50
                     "INT_LINK_TRAIN_FAIL(%x)!",
51
@@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505)
52
        timeout--;
53
    }
54
unlock:
55
+    /* recover interrupt trigger*/
56
+    it6505_set_bits(it6505, INT_MASK_03,
57
+            BIT(INT_VID_FIFO_ERROR), BIT(INT_VID_FIFO_ERROR));
58
    mutex_unlock(&it6505->aux_lock);
59
60
    return state;
61
62
--
63
2.34.1
diff view generated by jsdifflib
1
From: Hermes Wu <Hermes.wu@ite.com.tw>
1
From: Hermes Wu <Hermes.wu@ite.com.tw>
2
2
3
The DP link training work include auto training and after
3
The DP link training work include auto training and after
4
auto training failed "auto_train_retry" times, it switch to
4
auto training failed "AUTO_TRAIN_RETRY" times, it switch to
5
step training mode.
5
step training mode.
6
6
7
It will more efficiency that finish link auto training,
7
It will more efficiency that finish link auto training,
8
include retry, and step training in a work, rather than
8
include retry, and step training in a work, rather than
9
re-schedule train work when each training fail.
9
re-schedule train work when each training fail.
10
10
11
it6505_dump() is remove from link trainig work, it takes too much
11
Drop auto_train_retry from it6505 structure,
12
time to read all register area, and is not necessary.
12
and it6505_dump() is remove from link trainig work,
13
it takes too much time to read all register area,
14
and is not necessary.
13
15
14
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
16
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
15
---
17
---
16
drivers/gpu/drm/bridge/ite-it6505.c | 35 ++++++++++++++++-------------------
18
drivers/gpu/drm/bridge/ite-it6505.c | 40 ++++++++++++++-----------------------
17
1 file changed, 16 insertions(+), 19 deletions(-)
19
1 file changed, 15 insertions(+), 25 deletions(-)
18
20
19
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
21
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/drivers/gpu/drm/bridge/ite-it6505.c
23
--- a/drivers/gpu/drm/bridge/ite-it6505.c
22
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
24
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
25
@@ -XXX,XX +XXX,XX @@ struct it6505 {
26
    struct delayed_work hdcp_work;
27
    struct work_struct hdcp_wait_ksv_list;
28
    struct completion extcon_completion;
29
-    u8 auto_train_retry;
30
    bool hdcp_desired;
31
    bool is_repeater;
32
    u8 hdcp_down_stream_count;
23
@@ -XXX,XX +XXX,XX @@ static int it6505_get_dpcd(struct it6505 *it6505, int offset, u8 *dpcd, int num)
33
@@ -XXX,XX +XXX,XX @@ static int it6505_get_dpcd(struct it6505 *it6505, int offset, u8 *dpcd, int num)
24
    return 0;
34
    return 0;
25
}
35
}
26
36
27
-static void it6505_dump(struct it6505 *it6505)
37
-static void it6505_dump(struct it6505 *it6505)
28
+static void __maybe_unused it6505_dump(struct it6505 *it6505)
38
+static void __maybe_unused it6505_dump(struct it6505 *it6505)
29
{
39
{
30
    unsigned int i, j;
40
    unsigned int i, j;
31
    u8 regs[16];
41
    u8 regs[16];
42
@@ -XXX,XX +XXX,XX @@ static void it6505_variable_config(struct it6505 *it6505)
43
    it6505->lane_count = MAX_LANE_COUNT;
44
    it6505->link_state = LINK_IDLE;
45
    it6505->hdcp_desired = HDCP_DESIRED;
46
-    it6505->auto_train_retry = AUTO_TRAIN_RETRY;
47
    it6505->audio.select = AUDIO_SELECT;
48
    it6505->audio.sample_rate = AUDIO_SAMPLE_RATE;
49
    it6505->audio.channel_count = AUDIO_CHANNEL_COUNT;
32
@@ -XXX,XX +XXX,XX @@ static void it6505_link_training_work(struct work_struct *work)
50
@@ -XXX,XX +XXX,XX @@ static void it6505_link_training_work(struct work_struct *work)
33
{
51
{
34
    struct it6505 *it6505 = container_of(work, struct it6505, link_works);
52
    struct it6505 *it6505 = container_of(work, struct it6505, link_works);
35
    struct device *dev = it6505->dev;
53
    struct device *dev = it6505->dev;
36
-    int ret;
54
-    int ret;
...
...
48
-
66
-
49
-    if (it6505->auto_train_retry < 1) {
67
-    if (it6505->auto_train_retry < 1) {
50
-        it6505_link_step_train_process(it6505);
68
-        it6505_link_step_train_process(it6505);
51
-        return;
69
-        return;
52
-    }
70
-    }
53
+    retry = it6505->auto_train_retry;
71
-
54
+    do {
72
-    ret = it6505_link_start_auto_train(it6505);
73
-    DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
74
-             ret ? "pass" : "failed", it6505->auto_train_retry);
75
+    for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) {
55
+        it6505_link_training_setup(it6505);
76
+        it6505_link_training_setup(it6505);
56
+        it6505_reset_hdcp(it6505);
77
+        it6505_reset_hdcp(it6505);
57
+        it6505_aux_reset(it6505);
78
+        it6505_aux_reset(it6505);
58
59
-    ret = it6505_link_start_auto_train(it6505);
60
-    DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
61
+        ret = it6505_link_start_auto_train(it6505);
62
+        DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
63
             ret ? "pass" : "failed", it6505->auto_train_retry);
64
+        if (ret) {
65
+            it6505_link_train_ok(it6505);
66
+            return;
67
+        }
68
+    } while (retry--);
69
79
70
-    if (ret) {
80
-    if (ret) {
71
-        it6505->auto_train_retry = AUTO_TRAIN_RETRY;
81
-        it6505->auto_train_retry = AUTO_TRAIN_RETRY;
72
-        it6505_link_train_ok(it6505);
82
-        it6505_link_train_ok(it6505);
73
-    } else {
83
-    } else {
74
-        it6505->auto_train_retry--;
84
-        it6505->auto_train_retry--;
75
-        it6505_dump(it6505);
85
-        it6505_dump(it6505);
76
-    }
86
+        ret = it6505_link_start_auto_train(it6505);
87
+        DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,",
88
+                 ret ? "pass" : "failed");
89
+        if (ret) {
90
+            it6505_link_train_ok(it6505);
91
+            return;
92
+        }
93
    }
94
77
+    /*After HW auto training fail, try link training step by step*/
95
+    /*After HW auto training fail, try link training step by step*/
78
+    it6505_link_step_train_process(it6505);
96
+    it6505_link_step_train_process(it6505);
79
80
}
97
}
81
98
99
static void it6505_plugged_status_to_codec(struct it6505 *it6505)
100
@@ -XXX,XX +XXX,XX @@ static int it6505_process_hpd_irq(struct it6505 *it6505)
101
             (int)ARRAY_SIZE(link_status), link_status);
102
103
    if (!drm_dp_channel_eq_ok(link_status, it6505->lane_count)) {
104
-        it6505->auto_train_retry = AUTO_TRAIN_RETRY;
105
        it6505_video_reset(it6505);
106
    }
107
108
@@ -XXX,XX +XXX,XX @@ static void it6505_irq_hpd(struct it6505 *it6505)
109
            it6505_variable_config(it6505);
110
            it6505_parse_link_capabilities(it6505);
111
        }
112
-        it6505->auto_train_retry = AUTO_TRAIN_RETRY;
113
114
        it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
115
                     DP_SET_POWER_D0);
116
@@ -XXX,XX +XXX,XX @@ static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_statu
117
             (unsigned int *)int_status)) ||
118
     (it6505_test_bit(BIT_INT_VID_FIFO_ERROR,
119
             (unsigned int *)int_status))) {
120
-        it6505->auto_train_retry = AUTO_TRAIN_RETRY;
121
        flush_work(&it6505->link_works);
122
        it6505_stop_hdcp(it6505);
123
        it6505_video_reset(it6505);
82
124
83
--
125
--
84
2.34.1
126
2.34.1
diff view generated by jsdifflib
...
...
4
step training, skip auto training when link training restart,
4
step training, skip auto training when link training restart,
5
usually happen when display resolution is changed.
5
usually happen when display resolution is changed.
6
6
7
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
7
Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw>
8
---
8
---
9
drivers/gpu/drm/bridge/ite-it6505.c | 36 +++++++++++++++++++++---------------
9
drivers/gpu/drm/bridge/ite-it6505.c | 8 ++++++--
10
1 file changed, 21 insertions(+), 15 deletions(-)
10
1 file changed, 6 insertions(+), 2 deletions(-)
11
11
12
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
12
diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/ite-it6505.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/drivers/gpu/drm/bridge/ite-it6505.c
14
--- a/drivers/gpu/drm/bridge/ite-it6505.c
15
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
15
+++ b/drivers/gpu/drm/bridge/ite-it6505.c
16
@@ -XXX,XX +XXX,XX @@ struct it6505 {
16
@@ -XXX,XX +XXX,XX @@ struct it6505 {
17
    struct delayed_work hdcp_work;
17
    struct work_struct hdcp_wait_ksv_list;
18
    struct work_struct hdcp_wait_ksv_list;
18
    struct completion extcon_completion;
19
    struct completion extcon_completion;
19
    u8 auto_train_retry;
20
+    u8 step_train_only;
20
+    u8 step_train_only;
21
    bool hdcp_desired;
21
    bool hdcp_desired;
22
    bool is_repeater;
22
    bool is_repeater;
23
    u8 hdcp_down_stream_count;
23
    u8 hdcp_down_stream_count;
24
@@ -XXX,XX +XXX,XX @@ static void it6505_link_step_train_process(struct it6505 *it6505)
24
@@ -XXX,XX +XXX,XX @@ static void it6505_link_step_train_process(struct it6505 *it6505)
...
...
34
+    it6505->step_train_only = false;
34
+    it6505->step_train_only = false;
35
    it6505->link_state = LINK_IDLE;
35
    it6505->link_state = LINK_IDLE;
36
    it6505_video_reset(it6505);
36
    it6505_video_reset(it6505);
37
}
37
}
38
@@ -XXX,XX +XXX,XX @@ static void it6505_link_training_work(struct work_struct *work)
38
@@ -XXX,XX +XXX,XX @@ static void it6505_link_training_work(struct work_struct *work)
39
40
    if (!it6505_get_sink_hpd_status(it6505))
39
    if (!it6505_get_sink_hpd_status(it6505))
41
        return;
40
        return;
42
-
41
43
-    retry = it6505->auto_train_retry;
42
-    for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) {
44
-    do {
43
+    for (retry = AUTO_TRAIN_RETRY; retry > 0 && !it6505->step_train_only; retry--) {
45
-        it6505_link_training_setup(it6505);
44
        it6505_link_training_setup(it6505);
46
-        it6505_reset_hdcp(it6505);
45
        it6505_reset_hdcp(it6505);
47
-        it6505_aux_reset(it6505);
46
        it6505_aux_reset(it6505);
48
-
47
49
-        ret = it6505_link_start_auto_train(it6505);
48
        ret = it6505_link_start_auto_train(it6505);
50
-        DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
49
        DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,",
51
-             ret ? "pass" : "failed", it6505->auto_train_retry);
50
-                 ret ? "pass" : "failed");
52
-        if (ret) {
51
+                    ret ? "pass" : "failed");
53
-            it6505_link_train_ok(it6505);
52
        if (ret) {
54
-            return;
53
            it6505_link_train_ok(it6505);
55
-        }
54
            return;
56
-    } while (retry--);
57
+    /* skip auto training if previous auto train is fail*/
58
+    if (!it6505->step_train_only) {
59
+        retry = it6505->auto_train_retry;
60
+        do {
61
+            it6505_link_training_setup(it6505);
62
+            it6505_reset_hdcp(it6505);
63
+            it6505_aux_reset(it6505);
64
+
65
+            ret = it6505_link_start_auto_train(it6505);
66
+            DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
67
+                ret ? "pass" : "failed", it6505->auto_train_retry);
68
+            if (ret) {
69
+                it6505_link_train_ok(it6505);
70
+                return;
71
+            }
72
+        } while (retry--);
73
+    }
74
75
    /*After HW auto training fail, try link training step by step*/
76
    it6505_link_step_train_process(it6505);
77
@@ -XXX,XX +XXX,XX @@ static void it6505_irq_hpd(struct it6505 *it6505)
55
@@ -XXX,XX +XXX,XX @@ static void it6505_irq_hpd(struct it6505 *it6505)
56
            it6505_variable_config(it6505);
78
            it6505_parse_link_capabilities(it6505);
57
            it6505_parse_link_capabilities(it6505);
79
        }
58
        }
80
        it6505->auto_train_retry = AUTO_TRAIN_RETRY;
81
+        it6505->step_train_only = false;
59
+        it6505->step_train_only = false;
82
60
83
        it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
61
        it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
84
                     DP_SET_POWER_D0);
62
                     DP_SET_POWER_D0);
85
63
86
--
64
--
87
2.34.1
65
2.34.1
diff view generated by jsdifflib