1 /*
2 * Copyright 2022 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25 #include "link_dp_trace.h"
26 #include "link/protocols/link_dpcd.h"
27
dp_trace_init(struct dc_link * link)28 void dp_trace_init(struct dc_link *link)
29 {
30 memset(&link->dp_trace, 0, sizeof(link->dp_trace));
31 link->dp_trace.is_initialized = true;
32 }
33
dp_trace_reset(struct dc_link * link)34 void dp_trace_reset(struct dc_link *link)
35 {
36 memset(&link->dp_trace, 0, sizeof(link->dp_trace));
37 }
38
dp_trace_is_initialized(struct dc_link * link)39 bool dp_trace_is_initialized(struct dc_link *link)
40 {
41 return link->dp_trace.is_initialized;
42 }
43
dp_trace_detect_lt_init(struct dc_link * link)44 void dp_trace_detect_lt_init(struct dc_link *link)
45 {
46 memset(&link->dp_trace.detect_lt_trace, 0, sizeof(link->dp_trace.detect_lt_trace));
47 }
48
dp_trace_commit_lt_init(struct dc_link * link)49 void dp_trace_commit_lt_init(struct dc_link *link)
50 {
51 memset(&link->dp_trace.commit_lt_trace, 0, sizeof(link->dp_trace.commit_lt_trace));
52 }
53
dp_trace_link_loss_increment(struct dc_link * link)54 void dp_trace_link_loss_increment(struct dc_link *link)
55 {
56 link->dp_trace.link_loss_count++;
57 }
58
dp_trace_lt_fail_count_update(struct dc_link * link,unsigned int fail_count,bool in_detection)59 void dp_trace_lt_fail_count_update(struct dc_link *link,
60 unsigned int fail_count,
61 bool in_detection)
62 {
63 if (in_detection)
64 link->dp_trace.detect_lt_trace.counts.fail = fail_count;
65 else
66 link->dp_trace.commit_lt_trace.counts.fail = fail_count;
67 }
68
dp_trace_lt_total_count_increment(struct dc_link * link,bool in_detection)69 void dp_trace_lt_total_count_increment(struct dc_link *link,
70 bool in_detection)
71 {
72 if (in_detection)
73 link->dp_trace.detect_lt_trace.counts.total++;
74 else
75 link->dp_trace.commit_lt_trace.counts.total++;
76 }
77
dp_trace_set_is_logged_flag(struct dc_link * link,bool in_detection,bool is_logged)78 void dp_trace_set_is_logged_flag(struct dc_link *link,
79 bool in_detection,
80 bool is_logged)
81 {
82 if (in_detection)
83 link->dp_trace.detect_lt_trace.is_logged = is_logged;
84 else
85 link->dp_trace.commit_lt_trace.is_logged = is_logged;
86 }
87
dp_trace_is_logged(struct dc_link * link,bool in_detection)88 bool dp_trace_is_logged(struct dc_link *link, bool in_detection)
89 {
90 if (in_detection)
91 return link->dp_trace.detect_lt_trace.is_logged;
92 else
93 return link->dp_trace.commit_lt_trace.is_logged;
94 }
95
dp_trace_lt_result_update(struct dc_link * link,enum link_training_result result,bool in_detection)96 void dp_trace_lt_result_update(struct dc_link *link,
97 enum link_training_result result,
98 bool in_detection)
99 {
100 if (in_detection)
101 link->dp_trace.detect_lt_trace.result = result;
102 else
103 link->dp_trace.commit_lt_trace.result = result;
104 }
105
dp_trace_set_lt_start_timestamp(struct dc_link * link,bool in_detection)106 void dp_trace_set_lt_start_timestamp(struct dc_link *link,
107 bool in_detection)
108 {
109 if (in_detection)
110 link->dp_trace.detect_lt_trace.timestamps.start = dm_get_timestamp(link->dc->ctx);
111 else
112 link->dp_trace.commit_lt_trace.timestamps.start = dm_get_timestamp(link->dc->ctx);
113 }
114
dp_trace_set_lt_end_timestamp(struct dc_link * link,bool in_detection)115 void dp_trace_set_lt_end_timestamp(struct dc_link *link,
116 bool in_detection)
117 {
118 if (in_detection)
119 link->dp_trace.detect_lt_trace.timestamps.end = dm_get_timestamp(link->dc->ctx);
120 else
121 link->dp_trace.commit_lt_trace.timestamps.end = dm_get_timestamp(link->dc->ctx);
122 }
123
dp_trace_get_lt_end_timestamp(struct dc_link * link,bool in_detection)124 unsigned long long dp_trace_get_lt_end_timestamp(struct dc_link *link,
125 bool in_detection)
126 {
127 if (in_detection)
128 return link->dp_trace.detect_lt_trace.timestamps.end;
129 else
130 return link->dp_trace.commit_lt_trace.timestamps.end;
131 }
132
dp_trace_get_lt_counts(struct dc_link * link,bool in_detection)133 const struct dp_trace_lt_counts *dp_trace_get_lt_counts(struct dc_link *link,
134 bool in_detection)
135 {
136 if (in_detection)
137 return &link->dp_trace.detect_lt_trace.counts;
138 else
139 return &link->dp_trace.commit_lt_trace.counts;
140 }
141
dp_trace_get_link_loss_count(struct dc_link * link)142 unsigned int dp_trace_get_link_loss_count(struct dc_link *link)
143 {
144 return link->dp_trace.link_loss_count;
145 }
146
dp_trace_set_edp_power_timestamp(struct dc_link * link,bool power_up)147 void dp_trace_set_edp_power_timestamp(struct dc_link *link,
148 bool power_up)
149 {
150 if (!power_up)
151 /*save driver power off time stamp*/
152 link->dp_trace.edp_trace_power_timestamps.poweroff = dm_get_timestamp(link->dc->ctx);
153 else
154 link->dp_trace.edp_trace_power_timestamps.poweron = dm_get_timestamp(link->dc->ctx);
155 }
156
dp_trace_get_edp_poweron_timestamp(struct dc_link * link)157 uint64_t dp_trace_get_edp_poweron_timestamp(struct dc_link *link)
158 {
159 return link->dp_trace.edp_trace_power_timestamps.poweron;
160 }
161
dp_trace_get_edp_poweroff_timestamp(struct dc_link * link)162 uint64_t dp_trace_get_edp_poweroff_timestamp(struct dc_link *link)
163 {
164 return link->dp_trace.edp_trace_power_timestamps.poweroff;
165 }
166
dp_trace_source_sequence(struct dc_link * link,uint8_t dp_test_mode)167 void dp_trace_source_sequence(struct dc_link *link, uint8_t dp_test_mode)
168 {
169 if (link != NULL && link->dc->debug.enable_driver_sequence_debug)
170 core_link_write_dpcd(link, DP_SOURCE_SEQUENCE,
171 &dp_test_mode, sizeof(dp_test_mode));
172 }
173