... | ... | ||
---|---|---|---|
6 | and link training process will reset to beginning, and never try | 6 | and link training process will reset to beginning, and never try |
7 | step training method. | 7 | step training method. |
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 | v1 -> v2: | 11 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> |
12 | 1. Split [PATCH 1/3] into 3 commits | 12 | --- |
13 | 2. Drop non necessary variable auto_ttrain_retry | 13 | Changes in v3: |
14 | v1 link: https://lore.kernel.org/all/20250318-fix-link-training-v1-0-19266711142c@ite.com.tw/ | 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 | ||
15 | 19 | ||
16 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> | 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 | |||
17 | --- | 25 | --- |
18 | Hermes Wu (5): | 26 | Hermes Wu (5): |
19 | drm/bridge: it6505: fix link training state HW register reset | 27 | drm/bridge: it6505: fix link training state HW register reset |
20 | drm/bridge: it6505: check INT_LINK_TRAIN_FAIL while link auto training | 28 | drm/bridge: it6505: check INT_LINK_TRAIN_FAIL while link auto training |
21 | drm/bridge: it6505: modify DP link auto training | 29 | drm/bridge: it6505: modify DP link auto training |
22 | drm/bridge: it6505: modify DP link training work | 30 | drm/bridge: it6505: modify DP link training work |
23 | drm/bridge: it6505: skip auto training when previous try fail | 31 | drm/bridge: it6505: skip auto training when previous try fail |
24 | 32 | ||
25 | drivers/gpu/drm/bridge/ite-it6505.c | 112 +++++++++++++++++++++--------------- | 33 | drivers/gpu/drm/bridge/ite-it6505.c | 88 +++++++++++++++++++++---------------- |
26 | 1 file changed, 65 insertions(+), 47 deletions(-) | 34 | 1 file changed, 50 insertions(+), 38 deletions(-) |
27 | --- | 35 | --- |
28 | base-commit: 938fbb16aba8f7b88e0fdcf56f315a5bbad41aad | 36 | base-commit: 938fbb16aba8f7b88e0fdcf56f315a5bbad41aad |
29 | change-id: 20250121-fix-link-training-461495494655 | 37 | change-id: 20250121-fix-link-training-461495494655 |
30 | 38 | ||
31 | Best regards, | 39 | Best regards, |
32 | -- | 40 | -- |
33 | Hermes Wu <Hermes.wu@ite.com.tw> | 41 | Hermes Wu <Hermes.wu@ite.com.tw> | 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 | In order to reset HW link auto training state, | 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, | ||
4 | bits FORCE_RETRAIN and MANUAL_TRAIN at REG_TRAIN_CTRL1 must be set | 11 | bits FORCE_RETRAIN and MANUAL_TRAIN at REG_TRAIN_CTRL1 must be set |
5 | at the same time. | 12 | at the same time to reset HW state. |
6 | 13 | ||
7 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> | 14 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> |
8 | --- | 15 | --- |
9 | drivers/gpu/drm/bridge/ite-it6505.c | 6 ++++-- | 16 | drivers/gpu/drm/bridge/ite-it6505.c | 6 ++++-- |
10 | 1 file changed, 4 insertions(+), 2 deletions(-) | 17 | 1 file changed, 4 insertions(+), 2 deletions(-) |
... | ... | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
5 | 5 | ||
6 | it6505_irq_link_train_fail() remove from interrupt and no longer used. | 6 | it6505_irq_link_train_fail() remove from interrupt and no longer used. |
7 | 7 | ||
8 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> | 8 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> |
9 | --- | 9 | --- |
10 | drivers/gpu/drm/bridge/ite-it6505.c | 25 ++++++++++++++----------- | 10 | drivers/gpu/drm/bridge/ite-it6505.c | 26 +++++++++++++++----------- |
11 | 1 file changed, 14 insertions(+), 11 deletions(-) | 11 | 1 file changed, 15 insertions(+), 11 deletions(-) |
12 | 12 | ||
13 | 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 |
14 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/drivers/gpu/drm/bridge/ite-it6505.c | 15 | --- a/drivers/gpu/drm/bridge/ite-it6505.c |
16 | +++ b/drivers/gpu/drm/bridge/ite-it6505.c | 16 | +++ b/drivers/gpu/drm/bridge/ite-it6505.c |
... | ... | ||
28 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) | 28 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) |
29 | { | 29 | { |
30 | int timeout = 500, link_training_state; | 30 | int timeout = 500, link_training_state; |
31 | bool state = false; | 31 | bool state = false; |
32 | + int int03; | 32 | + int int03; |
33 | + struct device *dev = it6505->dev; | ||
33 | 34 | ||
34 | mutex_lock(&it6505->aux_lock); | 35 | mutex_lock(&it6505->aux_lock); |
35 | it6505_set_bits(it6505, REG_TRAIN_CTRL0, | 36 | it6505_set_bits(it6505, REG_TRAIN_CTRL0, |
36 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) | 37 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) |
37 | while (timeout > 0) { | 38 | while (timeout > 0) { |
... | ... | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
13 | Modify link auto training with disable INT_VID_FIFO_ERROR to avoid loop | 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. | 14 | and check INT_LINK_TRAIN_FAIL event to abort wait training done. |
15 | 15 | ||
16 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> | 16 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> |
17 | --- | 17 | --- |
18 | drivers/gpu/drm/bridge/ite-it6505.c | 38 +++++++++++++++++++++++++++---------- | 18 | drivers/gpu/drm/bridge/ite-it6505.c | 14 +++++++++++++- |
19 | 1 file changed, 28 insertions(+), 10 deletions(-) | 19 | 1 file changed, 13 insertions(+), 1 deletion(-) |
20 | 20 | ||
21 | 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 |
22 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/drivers/gpu/drm/bridge/ite-it6505.c | 23 | --- a/drivers/gpu/drm/bridge/ite-it6505.c |
24 | +++ b/drivers/gpu/drm/bridge/ite-it6505.c | 24 | +++ b/drivers/gpu/drm/bridge/ite-it6505.c |
25 | @@ -XXX,XX +XXX,XX @@ static void it6505_link_training_setup(struct it6505 *it6505) | 25 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) |
26 | 26 | struct device *dev = it6505->dev; | |
27 | static bool it6505_link_start_auto_train(struct it6505 *it6505) | 27 | |
28 | { | 28 | mutex_lock(&it6505->aux_lock); |
29 | - int timeout = 500, link_training_state; | ||
30 | + int link_training_state; | ||
31 | bool state = false; | ||
32 | int int03; | ||
33 | + struct device *dev = it6505->dev; | ||
34 | + unsigned long timeout; | ||
35 | + | 29 | + |
36 | + guard(mutex)(&it6505->aux_lock); | ||
37 | + /* Disable FIFO error interrupt trigger */ | 30 | + /* Disable FIFO error interrupt trigger */ |
38 | + /* to prevent training fail loop issue */ | 31 | + /* to prevent training fail loop issue */ |
39 | + it6505_set_bits(it6505, INT_MASK_03, BIT(INT_VID_FIFO_ERROR), 0); | 32 | + it6505_set_bits(it6505, INT_MASK_03, BIT(INT_VID_FIFO_ERROR), 0); |
40 | + | 33 | + |
41 | + it6505_write(it6505, INT_STATUS_03, | 34 | + it6505_write(it6505, INT_STATUS_03, |
42 | + BIT(INT_LINK_TRAIN_FAIL) | BIT(INT_VID_FIFO_ERROR)); | 35 | + BIT(INT_LINK_TRAIN_FAIL) | BIT(INT_VID_FIFO_ERROR)); |
43 | |||
44 | - mutex_lock(&it6505->aux_lock); | ||
45 | it6505_set_bits(it6505, REG_TRAIN_CTRL0, | 36 | it6505_set_bits(it6505, REG_TRAIN_CTRL0, |
46 | FORCE_CR_DONE | FORCE_EQ_DONE, 0x00); | 37 | FORCE_CR_DONE | FORCE_EQ_DONE, 0x00); |
47 | /* reset link state machine and re start training*/ | 38 | /* reset link state machine and re start training*/ |
48 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) | 39 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) |
49 | FORCE_RETRAIN | MANUAL_TRAIN); | ||
50 | it6505_write(it6505, REG_TRAIN_CTRL1, AUTO_TRAIN); | ||
51 | |||
52 | - while (timeout > 0) { | ||
53 | + timeout = jiffies + msecs_to_jiffies(100) + 1; | ||
54 | + for (;;) { | ||
55 | usleep_range(1000, 2000); | ||
56 | link_training_state = it6505_read(it6505, REG_LINK_TRAIN_STS); | 40 | link_training_state = it6505_read(it6505, REG_LINK_TRAIN_STS); |
57 | int03 = it6505_read(it6505, INT_STATUS_03); | 41 | int03 = it6505_read(it6505, INT_STATUS_03); |
58 | if (int03 & BIT(INT_LINK_TRAIN_FAIL)) { | 42 | if (int03 & BIT(INT_LINK_TRAIN_FAIL)) { |
59 | - it6505_write(it6505, INT_STATUS_03, | 43 | + /* Ignore INT_VID_FIFO_ERROR when auto training fail*/ |
44 | it6505_write(it6505, INT_STATUS_03, | ||
60 | - BIT(INT_LINK_TRAIN_FAIL)); | 45 | - BIT(INT_LINK_TRAIN_FAIL)); |
61 | - | 46 | + BIT(INT_LINK_TRAIN_FAIL) | |
47 | + BIT(INT_VID_FIFO_ERROR)); | ||
48 | |||
62 | DRM_DEV_DEBUG_DRIVER(dev, | 49 | DRM_DEV_DEBUG_DRIVER(dev, |
63 | "INT_LINK_TRAIN_FAIL(%x)!", | 50 | "INT_LINK_TRAIN_FAIL(%x)!", |
64 | int03); | 51 | @@ -XXX,XX +XXX,XX @@ static bool it6505_link_start_auto_train(struct it6505 *it6505) |
65 | 52 | timeout--; | |
66 | + /* Ignore INT_VID_FIFO_ERROR when auto training fail*/ | ||
67 | + it6505_write(it6505, INT_STATUS_03, | ||
68 | + BIT(INT_LINK_TRAIN_FAIL) | | ||
69 | + BIT(INT_VID_FIFO_ERROR)); | ||
70 | + | ||
71 | + if (int03 & BIT(INT_VID_FIFO_ERROR)) | ||
72 | + DRM_DEV_DEBUG_DRIVER(dev, | ||
73 | + "video fifo error when training fail"); | ||
74 | + | ||
75 | break; | ||
76 | } | ||
77 | |||
78 | if (link_training_state > 0 && | ||
79 | (link_training_state & LINK_STATE_NORP)) { | ||
80 | state = true; | ||
81 | - goto unlock; | ||
82 | + break; | ||
83 | } | ||
84 | |||
85 | - timeout--; | ||
86 | + if (time_after(jiffies, timeout)) | ||
87 | + break; | ||
88 | } | 53 | } |
89 | -unlock: | 54 | unlock: |
90 | - mutex_unlock(&it6505->aux_lock); | ||
91 | |||
92 | + /* recover interrupt trigger*/ | 55 | + /* recover interrupt trigger*/ |
93 | + it6505_set_bits(it6505, INT_MASK_03, | 56 | + it6505_set_bits(it6505, INT_MASK_03, |
94 | + BIT(INT_VID_FIFO_ERROR), BIT(INT_VID_FIFO_ERROR)); | 57 | + BIT(INT_VID_FIFO_ERROR), BIT(INT_VID_FIFO_ERROR)); |
58 | mutex_unlock(&it6505->aux_lock); | ||
59 | |||
95 | return state; | 60 | return state; |
96 | } | ||
97 | |||
98 | 61 | ||
99 | -- | 62 | -- |
100 | 2.34.1 | 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 | Drop auto_train_retry from it6505 structure, | 11 | Drop auto_train_retry from it6505 structure, |
12 | and it6505_dump() is remove from link trainig work, | 12 | and it6505_dump() is remove from link trainig work, |
13 | it takes too much time to read all register area, | 13 | it takes too much time to read all register area, |
14 | and is not necessary. | 14 | and is not necessary. |
15 | 15 | ||
16 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> | 16 | Signed-off-by: Hermes Wu <Hermes.wu@ite.com.tw> |
17 | --- | 17 | --- |
18 | drivers/gpu/drm/bridge/ite-it6505.c | 40 ++++++++++++++----------------------- | 18 | drivers/gpu/drm/bridge/ite-it6505.c | 40 ++++++++++++++----------------------- |
19 | 1 file changed, 15 insertions(+), 25 deletions(-) | 19 | 1 file changed, 15 insertions(+), 25 deletions(-) |
20 | 20 | ||
21 | 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 |
22 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/drivers/gpu/drm/bridge/ite-it6505.c | 23 | --- a/drivers/gpu/drm/bridge/ite-it6505.c |
24 | +++ b/drivers/gpu/drm/bridge/ite-it6505.c | 24 | +++ b/drivers/gpu/drm/bridge/ite-it6505.c |
25 | @@ -XXX,XX +XXX,XX @@ struct it6505 { | 25 | @@ -XXX,XX +XXX,XX @@ struct it6505 { |
26 | struct delayed_work hdcp_work; | 26 | struct delayed_work hdcp_work; |
27 | struct work_struct hdcp_wait_ksv_list; | 27 | struct work_struct hdcp_wait_ksv_list; |
28 | struct completion extcon_completion; | 28 | struct completion extcon_completion; |
29 | - u8 auto_train_retry; | 29 | - u8 auto_train_retry; |
30 | bool hdcp_desired; | 30 | bool hdcp_desired; |
31 | bool is_repeater; | 31 | bool is_repeater; |
32 | u8 hdcp_down_stream_count; | 32 | u8 hdcp_down_stream_count; |
33 | @@ -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) |
34 | return 0; | 34 | return 0; |
35 | } | 35 | } |
36 | 36 | ||
37 | -static void it6505_dump(struct it6505 *it6505) | 37 | -static void it6505_dump(struct it6505 *it6505) |
38 | +static void __maybe_unused it6505_dump(struct it6505 *it6505) | 38 | +static void __maybe_unused it6505_dump(struct it6505 *it6505) |
39 | { | 39 | { |
40 | unsigned int i, j; | 40 | unsigned int i, j; |
41 | u8 regs[16]; | 41 | u8 regs[16]; |
42 | @@ -XXX,XX +XXX,XX @@ static void it6505_variable_config(struct it6505 *it6505) | 42 | @@ -XXX,XX +XXX,XX @@ static void it6505_variable_config(struct it6505 *it6505) |
43 | it6505->lane_count = MAX_LANE_COUNT; | 43 | it6505->lane_count = MAX_LANE_COUNT; |
44 | it6505->link_state = LINK_IDLE; | 44 | it6505->link_state = LINK_IDLE; |
45 | it6505->hdcp_desired = HDCP_DESIRED; | 45 | it6505->hdcp_desired = HDCP_DESIRED; |
46 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; | 46 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; |
47 | it6505->audio.select = AUDIO_SELECT; | 47 | it6505->audio.select = AUDIO_SELECT; |
48 | it6505->audio.sample_rate = AUDIO_SAMPLE_RATE; | 48 | it6505->audio.sample_rate = AUDIO_SAMPLE_RATE; |
49 | it6505->audio.channel_count = AUDIO_CHANNEL_COUNT; | 49 | it6505->audio.channel_count = AUDIO_CHANNEL_COUNT; |
50 | @@ -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) |
51 | { | 51 | { |
52 | struct it6505 *it6505 = container_of(work, struct it6505, link_works); | 52 | struct it6505 *it6505 = container_of(work, struct it6505, link_works); |
53 | struct device *dev = it6505->dev; | 53 | struct device *dev = it6505->dev; |
54 | - int ret; | 54 | - int ret; |
55 | + int ret, retry; | 55 | + int ret, retry; |
56 | 56 | ||
57 | DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", | 57 | DRM_DEV_DEBUG_DRIVER(dev, "it6505->sink_count: %d", |
58 | it6505->sink_count); | 58 | it6505->sink_count); |
59 | @@ -XXX,XX +XXX,XX @@ static void it6505_link_training_work(struct work_struct *work) | 59 | @@ -XXX,XX +XXX,XX @@ static void it6505_link_training_work(struct work_struct *work) |
60 | if (!it6505_get_sink_hpd_status(it6505)) | 60 | if (!it6505_get_sink_hpd_status(it6505)) |
61 | return; | 61 | return; |
62 | 62 | ||
63 | - it6505_link_training_setup(it6505); | 63 | - it6505_link_training_setup(it6505); |
64 | - it6505_reset_hdcp(it6505); | 64 | - it6505_reset_hdcp(it6505); |
65 | - it6505_aux_reset(it6505); | 65 | - it6505_aux_reset(it6505); |
66 | - | 66 | - |
67 | - if (it6505->auto_train_retry < 1) { | 67 | - if (it6505->auto_train_retry < 1) { |
68 | - it6505_link_step_train_process(it6505); | 68 | - it6505_link_step_train_process(it6505); |
69 | - return; | 69 | - return; |
70 | - } | 70 | - } |
71 | - | 71 | - |
72 | - ret = it6505_link_start_auto_train(it6505); | 72 | - ret = it6505_link_start_auto_train(it6505); |
73 | - DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d", | 73 | - DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d", |
74 | - ret ? "pass" : "failed", it6505->auto_train_retry); | 74 | - ret ? "pass" : "failed", it6505->auto_train_retry); |
75 | + for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) { | 75 | + for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) { |
76 | + it6505_link_training_setup(it6505); | 76 | + it6505_link_training_setup(it6505); |
77 | + it6505_reset_hdcp(it6505); | 77 | + it6505_reset_hdcp(it6505); |
78 | + it6505_aux_reset(it6505); | 78 | + it6505_aux_reset(it6505); |
79 | 79 | ||
80 | - if (ret) { | 80 | - if (ret) { |
81 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; | 81 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; |
82 | - it6505_link_train_ok(it6505); | 82 | - it6505_link_train_ok(it6505); |
83 | - } else { | 83 | - } else { |
84 | - it6505->auto_train_retry--; | 84 | - it6505->auto_train_retry--; |
85 | - it6505_dump(it6505); | 85 | - it6505_dump(it6505); |
86 | + ret = it6505_link_start_auto_train(it6505); | 86 | + ret = it6505_link_start_auto_train(it6505); |
87 | + DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,", | 87 | + DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,", |
88 | + ret ? "pass" : "failed"); | 88 | + ret ? "pass" : "failed"); |
89 | + if (ret) { | 89 | + if (ret) { |
90 | + it6505_link_train_ok(it6505); | 90 | + it6505_link_train_ok(it6505); |
91 | + return; | 91 | + return; |
92 | + } | 92 | + } |
93 | } | 93 | } |
94 | 94 | ||
95 | + /*After HW auto training fail, try link training step by step*/ | 95 | + /*After HW auto training fail, try link training step by step*/ |
96 | + it6505_link_step_train_process(it6505); | 96 | + it6505_link_step_train_process(it6505); |
97 | } | 97 | } |
98 | 98 | ||
99 | static void it6505_plugged_status_to_codec(struct it6505 *it6505) | 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) | 100 | @@ -XXX,XX +XXX,XX @@ static int it6505_process_hpd_irq(struct it6505 *it6505) |
101 | (int)ARRAY_SIZE(link_status), link_status); | 101 | (int)ARRAY_SIZE(link_status), link_status); |
102 | 102 | ||
103 | if (!drm_dp_channel_eq_ok(link_status, it6505->lane_count)) { | 103 | if (!drm_dp_channel_eq_ok(link_status, it6505->lane_count)) { |
104 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; | 104 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; |
105 | it6505_video_reset(it6505); | 105 | it6505_video_reset(it6505); |
106 | } | 106 | } |
107 | 107 | ||
108 | @@ -XXX,XX +XXX,XX @@ static void it6505_irq_hpd(struct it6505 *it6505) | 108 | @@ -XXX,XX +XXX,XX @@ static void it6505_irq_hpd(struct it6505 *it6505) |
109 | it6505_variable_config(it6505); | 109 | it6505_variable_config(it6505); |
110 | it6505_parse_link_capabilities(it6505); | 110 | it6505_parse_link_capabilities(it6505); |
111 | } | 111 | } |
112 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; | 112 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; |
113 | 113 | ||
114 | it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, | 114 | it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, |
115 | DP_SET_POWER_D0); | 115 | DP_SET_POWER_D0); |
116 | @@ -XXX,XX +XXX,XX @@ static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_statu | 116 | @@ -XXX,XX +XXX,XX @@ static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_statu |
117 | (unsigned int *)int_status)) || | 117 | (unsigned int *)int_status)) || |
118 | (it6505_test_bit(BIT_INT_VID_FIFO_ERROR, | 118 | (it6505_test_bit(BIT_INT_VID_FIFO_ERROR, |
119 | (unsigned int *)int_status))) { | 119 | (unsigned int *)int_status))) { |
120 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; | 120 | - it6505->auto_train_retry = AUTO_TRAIN_RETRY; |
121 | flush_work(&it6505->link_works); | 121 | flush_work(&it6505->link_works); |
122 | it6505_stop_hdcp(it6505); | 122 | it6505_stop_hdcp(it6505); |
123 | it6505_video_reset(it6505); | 123 | it6505_video_reset(it6505); |
124 | 124 | ||
125 | -- | 125 | -- |
126 | 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 | 29 +++++++++++++++++------------ | 9 | drivers/gpu/drm/bridge/ite-it6505.c | 8 ++++++-- |
10 | 1 file changed, 17 insertions(+), 12 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 |
... | ... | ||
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 | - for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) { | 42 | - for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) { |
44 | - it6505_link_training_setup(it6505); | 43 | + for (retry = AUTO_TRAIN_RETRY; retry > 0 && !it6505->step_train_only; retry--) { |
45 | - it6505_reset_hdcp(it6505); | 44 | it6505_link_training_setup(it6505); |
46 | - it6505_aux_reset(it6505); | 45 | it6505_reset_hdcp(it6505); |
47 | - | 46 | it6505_aux_reset(it6505); |
48 | - ret = it6505_link_start_auto_train(it6505); | 47 | |
49 | - DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,", | 48 | ret = it6505_link_start_auto_train(it6505); |
49 | DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,", | ||
50 | - ret ? "pass" : "failed"); | 50 | - ret ? "pass" : "failed"); |
51 | - if (ret) { | 51 | + ret ? "pass" : "failed"); |
52 | - it6505_link_train_ok(it6505); | 52 | if (ret) { |
53 | - return; | 53 | it6505_link_train_ok(it6505); |
54 | + if (!it6505->step_train_only) { | 54 | return; |
55 | + for (retry = AUTO_TRAIN_RETRY; retry > 0; retry--) { | ||
56 | + it6505_link_training_setup(it6505); | ||
57 | + it6505_reset_hdcp(it6505); | ||
58 | + it6505_aux_reset(it6505); | ||
59 | + | ||
60 | + ret = it6505_link_start_auto_train(it6505); | ||
61 | + DRM_DEV_DEBUG_DRIVER(dev, "auto train %s,", | ||
62 | + ret ? "pass" : "failed"); | ||
63 | + if (ret) { | ||
64 | + it6505_link_train_ok(it6505); | ||
65 | + return; | ||
66 | + } | ||
67 | } | ||
68 | } | ||
69 | |||
70 | @@ -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) |
71 | it6505_variable_config(it6505); | 56 | it6505_variable_config(it6505); |
72 | it6505_parse_link_capabilities(it6505); | 57 | it6505_parse_link_capabilities(it6505); |
73 | } | 58 | } |
74 | + it6505->step_train_only = false; | 59 | + it6505->step_train_only = false; |
75 | 60 | ||
76 | it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, | 61 | it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link, |
77 | DP_SET_POWER_D0); | 62 | DP_SET_POWER_D0); |
78 | 63 | ||
79 | -- | 64 | -- |
80 | 2.34.1 | 65 | 2.34.1 | diff view generated by jsdifflib |