1 | /* |
2 | * Copyright 2012-15 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 | |
26 | #ifndef __DAL_AUX_ENGINE_DCE110_H__ |
27 | #define __DAL_AUX_ENGINE_DCE110_H__ |
28 | |
29 | #include "gpio_service_interface.h" |
30 | #include "inc/hw/aux_engine.h" |
31 | |
32 | enum aux_return_code_type; |
33 | |
34 | #define AUX_COMMON_REG_LIST0(id)\ |
35 | SRI(AUX_CONTROL, DP_AUX, id), \ |
36 | SRI(AUX_ARB_CONTROL, DP_AUX, id), \ |
37 | SRI(AUX_SW_DATA, DP_AUX, id), \ |
38 | SRI(AUX_SW_CONTROL, DP_AUX, id), \ |
39 | SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ |
40 | SRI(AUX_DPHY_RX_CONTROL1, DP_AUX, id), \ |
41 | SRI(AUX_SW_STATUS, DP_AUX, id) |
42 | |
43 | #define AUX_COMMON_REG_LIST(id)\ |
44 | SRI(AUX_CONTROL, DP_AUX, id), \ |
45 | SRI(AUX_ARB_CONTROL, DP_AUX, id), \ |
46 | SRI(AUX_SW_DATA, DP_AUX, id), \ |
47 | SRI(AUX_SW_CONTROL, DP_AUX, id), \ |
48 | SRI(AUX_INTERRUPT_CONTROL, DP_AUX, id), \ |
49 | SRI(AUX_SW_STATUS, DP_AUX, id), \ |
50 | SR(AUXN_IMPCAL), \ |
51 | SR(AUXP_IMPCAL) |
52 | |
53 | struct dce110_aux_registers { |
54 | uint32_t AUX_CONTROL; |
55 | uint32_t AUX_ARB_CONTROL; |
56 | uint32_t AUX_SW_DATA; |
57 | uint32_t AUX_SW_CONTROL; |
58 | uint32_t AUX_INTERRUPT_CONTROL; |
59 | uint32_t AUX_DPHY_RX_CONTROL1; |
60 | uint32_t AUX_SW_STATUS; |
61 | uint32_t AUXN_IMPCAL; |
62 | uint32_t AUXP_IMPCAL; |
63 | |
64 | uint32_t AUX_RESET_MASK; |
65 | }; |
66 | |
67 | #define DCE_AUX_REG_FIELD_LIST(type)\ |
68 | type AUX_EN;\ |
69 | type AUX_RESET;\ |
70 | type AUX_RESET_DONE;\ |
71 | type AUX_REG_RW_CNTL_STATUS;\ |
72 | type AUX_SW_USE_AUX_REG_REQ;\ |
73 | type AUX_SW_DONE_USING_AUX_REG;\ |
74 | type AUX_SW_AUTOINCREMENT_DISABLE;\ |
75 | type AUX_SW_DATA_RW;\ |
76 | type AUX_SW_INDEX;\ |
77 | type AUX_SW_GO;\ |
78 | type AUX_SW_DATA;\ |
79 | type AUX_SW_REPLY_BYTE_COUNT;\ |
80 | type AUX_SW_DONE;\ |
81 | type AUX_SW_DONE_ACK;\ |
82 | type AUXN_IMPCAL_ENABLE;\ |
83 | type AUXP_IMPCAL_ENABLE;\ |
84 | type AUXN_IMPCAL_OVERRIDE_ENABLE;\ |
85 | type AUXP_IMPCAL_OVERRIDE_ENABLE;\ |
86 | type AUX_RX_TIMEOUT_LEN;\ |
87 | type AUX_RX_TIMEOUT_LEN_MUL;\ |
88 | type AUXN_CALOUT_ERROR_AK;\ |
89 | type AUXP_CALOUT_ERROR_AK;\ |
90 | type AUX_SW_START_DELAY;\ |
91 | type AUX_SW_WR_BYTES |
92 | |
93 | #define DCE10_AUX_MASK_SH_LIST(mask_sh)\ |
94 | AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\ |
95 | AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ |
96 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ |
97 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ |
98 | AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ |
99 | AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ |
100 | AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ |
101 | AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
102 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ |
103 | AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ |
104 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ |
105 | AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ |
106 | AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ |
107 | AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ |
108 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ |
109 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ |
110 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ |
111 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ |
112 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ |
113 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) |
114 | |
115 | #define DCE_AUX_MASK_SH_LIST(mask_sh)\ |
116 | AUX_SF(AUX_CONTROL, AUX_EN, mask_sh),\ |
117 | AUX_SF(AUX_CONTROL, AUX_RESET, mask_sh),\ |
118 | AUX_SF(AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ |
119 | AUX_SF(AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ |
120 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ |
121 | AUX_SF(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ |
122 | AUX_SF(AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ |
123 | AUX_SF(AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ |
124 | AUX_SF(AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ |
125 | AUX_SF(AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
126 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ |
127 | AUX_SF(AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ |
128 | AUX_SF(AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ |
129 | AUX_SF(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ |
130 | AUX_SF(AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ |
131 | AUX_SF(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ |
132 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ |
133 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ |
134 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ |
135 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ |
136 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ |
137 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) |
138 | |
139 | #define DCE12_AUX_MASK_SH_LIST(mask_sh)\ |
140 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ |
141 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ |
142 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ |
143 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ |
144 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ |
145 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ |
146 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ |
147 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ |
148 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ |
149 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
150 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ |
151 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
152 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ |
153 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ |
154 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ |
155 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ |
156 | AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ |
157 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ |
158 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ |
159 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ |
160 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ |
161 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ |
162 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) |
163 | |
164 | /* DCN10 MASK */ |
165 | #define DCN10_AUX_MASK_SH_LIST(mask_sh)\ |
166 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ |
167 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ |
168 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ |
169 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ |
170 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ |
171 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ |
172 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ |
173 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ |
174 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ |
175 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
176 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ |
177 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
178 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ |
179 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ |
180 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ |
181 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ |
182 | AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ |
183 | AUX_SF(AUXN_IMPCAL, AUXN_CALOUT_ERROR_AK, mask_sh),\ |
184 | AUX_SF(AUXP_IMPCAL, AUXP_CALOUT_ERROR_AK, mask_sh),\ |
185 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_ENABLE, mask_sh),\ |
186 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_ENABLE, mask_sh),\ |
187 | AUX_SF(AUXP_IMPCAL, AUXP_IMPCAL_OVERRIDE_ENABLE, mask_sh),\ |
188 | AUX_SF(AUXN_IMPCAL, AUXN_IMPCAL_OVERRIDE_ENABLE, mask_sh) |
189 | |
190 | /* for all other DCN */ |
191 | #define DCN_AUX_MASK_SH_LIST(mask_sh)\ |
192 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_EN, mask_sh),\ |
193 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET, mask_sh),\ |
194 | AUX_SF(DP_AUX0_AUX_CONTROL, AUX_RESET_DONE, mask_sh),\ |
195 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_REG_RW_CNTL_STATUS, mask_sh),\ |
196 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, mask_sh),\ |
197 | AUX_SF(DP_AUX0_AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, mask_sh),\ |
198 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_START_DELAY, mask_sh),\ |
199 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_WR_BYTES, mask_sh),\ |
200 | AUX_SF(DP_AUX0_AUX_SW_CONTROL, AUX_SW_GO, mask_sh),\ |
201 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
202 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA_RW, mask_sh),\ |
203 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_AUTOINCREMENT_DISABLE, mask_sh),\ |
204 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_INDEX, mask_sh),\ |
205 | AUX_SF(DP_AUX0_AUX_SW_DATA, AUX_SW_DATA, mask_sh),\ |
206 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT, mask_sh),\ |
207 | AUX_SF(DP_AUX0_AUX_SW_STATUS, AUX_SW_DONE, mask_sh),\ |
208 | AUX_SF(DP_AUX0_AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, mask_sh),\ |
209 | AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, mask_sh),\ |
210 | AUX_SF(DP_AUX0_AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN_MUL, mask_sh) |
211 | |
212 | #define AUX_SF(reg_name, field_name, post_fix)\ |
213 | .field_name = reg_name ## __ ## field_name ## post_fix |
214 | |
215 | enum { /* This is the timeout as defined in DP 1.2a, |
216 | * 2.3.4 "Detailed uPacket TX AUX CH State Description". |
217 | */ |
218 | AUX_TIMEOUT_PERIOD = 400, |
219 | |
220 | /* Ideally, the SW timeout should be just above 550usec |
221 | * which is programmed in HW. |
222 | * But the SW timeout of 600usec is not reliable, |
223 | * because on some systems, delay_in_microseconds() |
224 | * returns faster than it should. |
225 | * EPR #379763: by trial-and-error on different systems, |
226 | * 700usec is the minimum reliable SW timeout for polling |
227 | * the AUX_SW_STATUS.AUX_SW_DONE bit. |
228 | * This timeout expires *only* when there is |
229 | * AUX Error or AUX Timeout conditions - not during normal operation. |
230 | * During normal operation, AUX_SW_STATUS.AUX_SW_DONE bit is set |
231 | * at most within ~240usec. That means, |
232 | * increasing this timeout will not affect normal operation, |
233 | * and we'll timeout after |
234 | * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 2400usec. |
235 | * This timeout is especially important for |
236 | * converters, resume from S3, and CTS. |
237 | */ |
238 | SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 6 |
239 | }; |
240 | |
241 | struct dce_aux { |
242 | uint32_t inst; |
243 | struct ddc *ddc; |
244 | struct dc_context *ctx; |
245 | /* following values are expressed in milliseconds */ |
246 | uint32_t delay; |
247 | uint32_t max_defer_write_retry; |
248 | |
249 | bool acquire_reset; |
250 | struct dce_aux_funcs *funcs; |
251 | }; |
252 | |
253 | struct dce110_aux_registers_mask { |
254 | DCE_AUX_REG_FIELD_LIST(uint32_t); |
255 | }; |
256 | |
257 | struct dce110_aux_registers_shift { |
258 | DCE_AUX_REG_FIELD_LIST(uint8_t); |
259 | }; |
260 | |
261 | |
262 | struct aux_engine_dce110 { |
263 | struct dce_aux base; |
264 | const struct dce110_aux_registers *regs; |
265 | const struct dce110_aux_registers_mask *mask; |
266 | const struct dce110_aux_registers_shift *shift; |
267 | struct { |
268 | uint32_t aux_control; |
269 | uint32_t aux_arb_control; |
270 | uint32_t aux_sw_data; |
271 | uint32_t aux_sw_control; |
272 | uint32_t aux_interrupt_control; |
273 | uint32_t aux_dphy_rx_control1; |
274 | uint32_t aux_dphy_rx_control0; |
275 | uint32_t aux_sw_status; |
276 | } addr; |
277 | uint32_t polling_timeout_period; |
278 | }; |
279 | |
280 | struct aux_engine_dce110_init_data { |
281 | uint32_t engine_id; |
282 | uint32_t timeout_period; |
283 | struct dc_context *ctx; |
284 | const struct dce110_aux_registers *regs; |
285 | }; |
286 | |
287 | struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110, |
288 | struct dc_context *ctx, |
289 | uint32_t inst, |
290 | uint32_t timeout_period, |
291 | const struct dce110_aux_registers *regs, |
292 | |
293 | const struct dce110_aux_registers_mask *mask, |
294 | const struct dce110_aux_registers_shift *shift, |
295 | bool is_ext_aux_timeout_configurable); |
296 | |
297 | void dce110_engine_destroy(struct dce_aux **engine); |
298 | |
299 | bool dce110_aux_engine_acquire( |
300 | struct dce_aux *aux_engine, |
301 | struct ddc *ddc); |
302 | |
303 | int dce_aux_transfer_raw(struct ddc_service *ddc, |
304 | struct aux_payload *cmd, |
305 | enum aux_return_code_type *operation_result); |
306 | |
307 | int dce_aux_transfer_dmub_raw(struct ddc_service *ddc, |
308 | struct aux_payload *payload, |
309 | enum aux_return_code_type *operation_result); |
310 | bool dce_aux_transfer_with_retries(struct ddc_service *ddc, |
311 | struct aux_payload *cmd); |
312 | |
313 | struct dce_aux_funcs { |
314 | uint32_t (*configure_timeout) |
315 | (struct ddc_service *ddc, |
316 | uint32_t timeout); |
317 | void (*destroy) |
318 | (struct aux_engine **ptr); |
319 | }; |
320 | |
321 | #endif |
322 | |