1 | /* |
2 | * Copyright 2018 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 __DCE_I2C_HW_H__ |
27 | #define __DCE_I2C_HW_H__ |
28 | |
29 | enum dc_i2c_status { |
30 | DC_I2C_STATUS__DC_I2C_STATUS_IDLE, |
31 | DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_SW, |
32 | DC_I2C_STATUS__DC_I2C_STATUS_USED_BY_HW, |
33 | DC_I2C_REG_RW_CNTL_STATUS_DMCU_ONLY = 2, |
34 | }; |
35 | |
36 | enum dc_i2c_arbitration { |
37 | DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_NORMAL, |
38 | DC_I2C_ARBITRATION__DC_I2C_SW_PRIORITY_HIGH |
39 | }; |
40 | |
41 | enum i2c_channel_operation_result { |
42 | I2C_CHANNEL_OPERATION_SUCCEEDED, |
43 | I2C_CHANNEL_OPERATION_FAILED, |
44 | I2C_CHANNEL_OPERATION_NOT_GRANTED, |
45 | I2C_CHANNEL_OPERATION_IS_BUSY, |
46 | I2C_CHANNEL_OPERATION_NO_HANDLE_PROVIDED, |
47 | I2C_CHANNEL_OPERATION_CHANNEL_IN_USE, |
48 | I2C_CHANNEL_OPERATION_CHANNEL_CLIENT_MAX_ALLOWED, |
49 | I2C_CHANNEL_OPERATION_ENGINE_BUSY, |
50 | I2C_CHANNEL_OPERATION_TIMEOUT, |
51 | I2C_CHANNEL_OPERATION_NO_RESPONSE, |
52 | I2C_CHANNEL_OPERATION_HW_REQUEST_I2C_BUS, |
53 | I2C_CHANNEL_OPERATION_WRONG_PARAMETER, |
54 | I2C_CHANNEL_OPERATION_OUT_NB_OF_RETRIES, |
55 | I2C_CHANNEL_OPERATION_NOT_STARTED |
56 | }; |
57 | |
58 | |
59 | enum dce_i2c_transaction_action { |
60 | DCE_I2C_TRANSACTION_ACTION_I2C_WRITE = 0x00, |
61 | DCE_I2C_TRANSACTION_ACTION_I2C_READ = 0x10, |
62 | DCE_I2C_TRANSACTION_ACTION_I2C_STATUS_REQUEST = 0x20, |
63 | |
64 | DCE_I2C_TRANSACTION_ACTION_I2C_WRITE_MOT = 0x40, |
65 | DCE_I2C_TRANSACTION_ACTION_I2C_READ_MOT = 0x50, |
66 | DCE_I2C_TRANSACTION_ACTION_I2C_STATUS_REQUEST_MOT = 0x60, |
67 | |
68 | DCE_I2C_TRANSACTION_ACTION_DP_WRITE = 0x80, |
69 | DCE_I2C_TRANSACTION_ACTION_DP_READ = 0x90 |
70 | }; |
71 | |
72 | enum { |
73 | I2C_SETUP_TIME_LIMIT_DCE = 255, |
74 | I2C_SETUP_TIME_LIMIT_DCN = 3, |
75 | I2C_HW_BUFFER_SIZE_DCE100 = 538, |
76 | I2C_HW_BUFFER_SIZE_DCE = 144, |
77 | I2C_SEND_RESET_LENGTH_9 = 9, |
78 | I2C_SEND_RESET_LENGTH_10 = 10, |
79 | DEFAULT_I2C_HW_SPEED = 50, |
80 | DEFAULT_I2C_HW_SPEED_100KHZ = 100, |
81 | TRANSACTION_TIMEOUT_IN_I2C_CLOCKS = 32, |
82 | }; |
83 | |
84 | #define I2C_HW_ENGINE_COMMON_REG_LIST(id)\ |
85 | SRI(SETUP, DC_I2C_DDC, id),\ |
86 | SRI(SPEED, DC_I2C_DDC, id),\ |
87 | SRI(HW_STATUS, DC_I2C_DDC, id),\ |
88 | SR(DC_I2C_ARBITRATION),\ |
89 | SR(DC_I2C_CONTROL),\ |
90 | SR(DC_I2C_SW_STATUS),\ |
91 | SR(DC_I2C_TRANSACTION0),\ |
92 | SR(DC_I2C_TRANSACTION1),\ |
93 | SR(DC_I2C_TRANSACTION2),\ |
94 | SR(DC_I2C_TRANSACTION3),\ |
95 | SR(DC_I2C_DATA),\ |
96 | SR(MICROSECOND_TIME_BASE_DIV) |
97 | |
98 | #define I2C_HW_ENGINE_COMMON_REG_LIST_DCN30(id)\ |
99 | I2C_HW_ENGINE_COMMON_REG_LIST(id),\ |
100 | SR(DIO_MEM_PWR_CTRL),\ |
101 | SR(DIO_MEM_PWR_STATUS) |
102 | |
103 | #define I2C_SF(reg_name, field_name, post_fix)\ |
104 | .field_name = reg_name ## __ ## field_name ## post_fix |
105 | |
106 | #define I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh)\ |
107 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_ENABLE, mask_sh),\ |
108 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_TIME_LIMIT, mask_sh),\ |
109 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_EN, mask_sh),\ |
110 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_DRIVE_EN, mask_sh),\ |
111 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_DATA_DRIVE_SEL, mask_sh),\ |
112 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_TRANSACTION_DELAY, mask_sh),\ |
113 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_INTRA_BYTE_DELAY, mask_sh),\ |
114 | I2C_SF(DC_I2C_DDC1_HW_STATUS, DC_I2C_DDC1_HW_STATUS, mask_sh),\ |
115 | I2C_SF(DC_I2C_ARBITRATION, DC_I2C_SW_USE_I2C_REG_REQ, mask_sh),\ |
116 | I2C_SF(DC_I2C_ARBITRATION, DC_I2C_SW_DONE_USING_I2C_REG, mask_sh),\ |
117 | I2C_SF(DC_I2C_ARBITRATION, DC_I2C_NO_QUEUED_SW_GO, mask_sh),\ |
118 | I2C_SF(DC_I2C_ARBITRATION, DC_I2C_SW_PRIORITY, mask_sh),\ |
119 | I2C_SF(DC_I2C_CONTROL, DC_I2C_SOFT_RESET, mask_sh),\ |
120 | I2C_SF(DC_I2C_CONTROL, DC_I2C_SW_STATUS_RESET, mask_sh),\ |
121 | I2C_SF(DC_I2C_CONTROL, DC_I2C_GO, mask_sh),\ |
122 | I2C_SF(DC_I2C_CONTROL, DC_I2C_SEND_RESET, mask_sh),\ |
123 | I2C_SF(DC_I2C_CONTROL, DC_I2C_TRANSACTION_COUNT, mask_sh),\ |
124 | I2C_SF(DC_I2C_CONTROL, DC_I2C_DDC_SELECT, mask_sh),\ |
125 | I2C_SF(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE, mask_sh),\ |
126 | I2C_SF(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD, mask_sh),\ |
127 | I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_STOPPED_ON_NACK, mask_sh),\ |
128 | I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_TIMEOUT, mask_sh),\ |
129 | I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_ABORTED, mask_sh),\ |
130 | I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_DONE, mask_sh),\ |
131 | I2C_SF(DC_I2C_SW_STATUS, DC_I2C_SW_STATUS, mask_sh),\ |
132 | I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_STOP_ON_NACK0, mask_sh),\ |
133 | I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_START0, mask_sh),\ |
134 | I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_RW0, mask_sh),\ |
135 | I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_STOP0, mask_sh),\ |
136 | I2C_SF(DC_I2C_TRANSACTION0, DC_I2C_COUNT0, mask_sh),\ |
137 | I2C_SF(DC_I2C_DATA, DC_I2C_DATA_RW, mask_sh),\ |
138 | I2C_SF(DC_I2C_DATA, DC_I2C_DATA, mask_sh),\ |
139 | I2C_SF(DC_I2C_DATA, DC_I2C_INDEX, mask_sh),\ |
140 | I2C_SF(DC_I2C_DATA, DC_I2C_INDEX_WRITE, mask_sh),\ |
141 | I2C_SF(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, mask_sh),\ |
142 | I2C_SF(MICROSECOND_TIME_BASE_DIV, MICROSECOND_TIME_BASE_DIV, mask_sh),\ |
143 | I2C_SF(DC_I2C_ARBITRATION, DC_I2C_REG_RW_CNTL_STATUS, mask_sh) |
144 | |
145 | #define I2C_COMMON_MASK_SH_LIST_DCE110(mask_sh)\ |
146 | I2C_COMMON_MASK_SH_LIST_DCE_COMMON_BASE(mask_sh),\ |
147 | I2C_SF(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL, mask_sh) |
148 | |
149 | struct dce_i2c_shift { |
150 | uint8_t DC_I2C_DDC1_ENABLE; |
151 | uint8_t DC_I2C_DDC1_TIME_LIMIT; |
152 | uint8_t DC_I2C_DDC1_DATA_DRIVE_EN; |
153 | uint8_t DC_I2C_DDC1_CLK_DRIVE_EN; |
154 | uint8_t DC_I2C_DDC1_DATA_DRIVE_SEL; |
155 | uint8_t DC_I2C_DDC1_INTRA_TRANSACTION_DELAY; |
156 | uint8_t DC_I2C_DDC1_INTRA_BYTE_DELAY; |
157 | uint8_t DC_I2C_DDC1_HW_STATUS; |
158 | uint8_t DC_I2C_SW_DONE_USING_I2C_REG; |
159 | uint8_t DC_I2C_SW_USE_I2C_REG_REQ; |
160 | uint8_t DC_I2C_NO_QUEUED_SW_GO; |
161 | uint8_t DC_I2C_SW_PRIORITY; |
162 | uint8_t DC_I2C_SOFT_RESET; |
163 | uint8_t DC_I2C_SW_STATUS_RESET; |
164 | uint8_t DC_I2C_GO; |
165 | uint8_t DC_I2C_SEND_RESET; |
166 | uint8_t DC_I2C_TRANSACTION_COUNT; |
167 | uint8_t DC_I2C_DDC_SELECT; |
168 | uint8_t DC_I2C_DDC1_PRESCALE; |
169 | uint8_t DC_I2C_DDC1_THRESHOLD; |
170 | uint8_t DC_I2C_DDC1_START_STOP_TIMING_CNTL; |
171 | uint8_t DC_I2C_SW_STOPPED_ON_NACK; |
172 | uint8_t DC_I2C_SW_TIMEOUT; |
173 | uint8_t DC_I2C_SW_ABORTED; |
174 | uint8_t DC_I2C_SW_DONE; |
175 | uint8_t DC_I2C_SW_STATUS; |
176 | uint8_t DC_I2C_STOP_ON_NACK0; |
177 | uint8_t DC_I2C_START0; |
178 | uint8_t DC_I2C_RW0; |
179 | uint8_t DC_I2C_STOP0; |
180 | uint8_t DC_I2C_COUNT0; |
181 | uint8_t DC_I2C_DATA_RW; |
182 | uint8_t DC_I2C_DATA; |
183 | uint8_t DC_I2C_INDEX; |
184 | uint8_t DC_I2C_INDEX_WRITE; |
185 | uint8_t XTAL_REF_DIV; |
186 | uint8_t MICROSECOND_TIME_BASE_DIV; |
187 | uint8_t DC_I2C_DDC1_SEND_RESET_LENGTH; |
188 | uint8_t DC_I2C_REG_RW_CNTL_STATUS; |
189 | uint8_t I2C_LIGHT_SLEEP_FORCE; |
190 | uint8_t I2C_MEM_PWR_STATE; |
191 | uint8_t DC_I2C_DDC1_CLK_EN; |
192 | }; |
193 | |
194 | struct dce_i2c_mask { |
195 | uint32_t DC_I2C_DDC1_ENABLE; |
196 | uint32_t DC_I2C_DDC1_TIME_LIMIT; |
197 | uint32_t DC_I2C_DDC1_DATA_DRIVE_EN; |
198 | uint32_t DC_I2C_DDC1_CLK_DRIVE_EN; |
199 | uint32_t DC_I2C_DDC1_DATA_DRIVE_SEL; |
200 | uint32_t DC_I2C_DDC1_INTRA_TRANSACTION_DELAY; |
201 | uint32_t DC_I2C_DDC1_INTRA_BYTE_DELAY; |
202 | uint32_t DC_I2C_DDC1_HW_STATUS; |
203 | uint32_t DC_I2C_SW_DONE_USING_I2C_REG; |
204 | uint32_t DC_I2C_SW_USE_I2C_REG_REQ; |
205 | uint32_t DC_I2C_NO_QUEUED_SW_GO; |
206 | uint32_t DC_I2C_SW_PRIORITY; |
207 | uint32_t DC_I2C_SOFT_RESET; |
208 | uint32_t DC_I2C_SW_STATUS_RESET; |
209 | uint32_t DC_I2C_GO; |
210 | uint32_t DC_I2C_SEND_RESET; |
211 | uint32_t DC_I2C_TRANSACTION_COUNT; |
212 | uint32_t DC_I2C_DDC_SELECT; |
213 | uint32_t DC_I2C_DDC1_PRESCALE; |
214 | uint32_t DC_I2C_DDC1_THRESHOLD; |
215 | uint32_t DC_I2C_DDC1_START_STOP_TIMING_CNTL; |
216 | uint32_t DC_I2C_SW_STOPPED_ON_NACK; |
217 | uint32_t DC_I2C_SW_TIMEOUT; |
218 | uint32_t DC_I2C_SW_ABORTED; |
219 | uint32_t DC_I2C_SW_DONE; |
220 | uint32_t DC_I2C_SW_STATUS; |
221 | uint32_t DC_I2C_STOP_ON_NACK0; |
222 | uint32_t DC_I2C_START0; |
223 | uint32_t DC_I2C_RW0; |
224 | uint32_t DC_I2C_STOP0; |
225 | uint32_t DC_I2C_COUNT0; |
226 | uint32_t DC_I2C_DATA_RW; |
227 | uint32_t DC_I2C_DATA; |
228 | uint32_t DC_I2C_INDEX; |
229 | uint32_t DC_I2C_INDEX_WRITE; |
230 | uint32_t XTAL_REF_DIV; |
231 | uint32_t MICROSECOND_TIME_BASE_DIV; |
232 | uint32_t DC_I2C_DDC1_SEND_RESET_LENGTH; |
233 | uint32_t DC_I2C_REG_RW_CNTL_STATUS; |
234 | uint32_t I2C_LIGHT_SLEEP_FORCE; |
235 | uint32_t I2C_MEM_PWR_STATE; |
236 | uint32_t DC_I2C_DDC1_CLK_EN; |
237 | }; |
238 | |
239 | #define I2C_COMMON_MASK_SH_LIST_DCN2(mask_sh)\ |
240 | I2C_COMMON_MASK_SH_LIST_DCE110(mask_sh),\ |
241 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_SEND_RESET_LENGTH, mask_sh) |
242 | |
243 | #define I2C_COMMON_MASK_SH_LIST_DCN30(mask_sh)\ |
244 | I2C_COMMON_MASK_SH_LIST_DCN2(mask_sh),\ |
245 | I2C_SF(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh),\ |
246 | I2C_SF(DIO_MEM_PWR_STATUS, I2C_MEM_PWR_STATE, mask_sh) |
247 | |
248 | #define I2C_COMMON_MASK_SH_LIST_DCN35(mask_sh)\ |
249 | I2C_COMMON_MASK_SH_LIST_DCN30(mask_sh),\ |
250 | I2C_SF(DC_I2C_DDC1_SETUP, DC_I2C_DDC1_CLK_EN, mask_sh) |
251 | |
252 | struct dce_i2c_registers { |
253 | uint32_t SETUP; |
254 | uint32_t SPEED; |
255 | uint32_t HW_STATUS; |
256 | uint32_t DC_I2C_ARBITRATION; |
257 | uint32_t DC_I2C_CONTROL; |
258 | uint32_t DC_I2C_SW_STATUS; |
259 | uint32_t DC_I2C_TRANSACTION0; |
260 | uint32_t DC_I2C_TRANSACTION1; |
261 | uint32_t DC_I2C_TRANSACTION2; |
262 | uint32_t DC_I2C_TRANSACTION3; |
263 | uint32_t DC_I2C_DATA; |
264 | uint32_t MICROSECOND_TIME_BASE_DIV; |
265 | uint32_t DIO_MEM_PWR_CTRL; |
266 | uint32_t DIO_MEM_PWR_STATUS; |
267 | }; |
268 | |
269 | enum dce_i2c_transaction_address_space { |
270 | DCE_I2C_TRANSACTION_ADDRESS_SPACE_I2C = 1, |
271 | DCE_I2C_TRANSACTION_ADDRESS_SPACE_DPCD |
272 | }; |
273 | |
274 | struct i2c_request_transaction_data { |
275 | enum dce_i2c_transaction_action action; |
276 | enum i2c_channel_operation_result status; |
277 | uint8_t address; |
278 | uint32_t length; |
279 | uint8_t *data; |
280 | }; |
281 | |
282 | struct dce_i2c_hw { |
283 | struct ddc *ddc; |
284 | uint32_t engine_keep_power_up_count; |
285 | uint32_t transaction_count; |
286 | uint32_t buffer_used_bytes; |
287 | uint32_t buffer_used_write; |
288 | uint32_t reference_frequency; |
289 | uint32_t default_speed; |
290 | uint32_t engine_id; |
291 | uint32_t setup_limit; |
292 | uint32_t send_reset_length; |
293 | uint32_t buffer_size; |
294 | struct dc_context *ctx; |
295 | |
296 | const struct dce_i2c_registers *regs; |
297 | const struct dce_i2c_shift *shifts; |
298 | const struct dce_i2c_mask *masks; |
299 | }; |
300 | |
301 | void dce_i2c_hw_construct( |
302 | struct dce_i2c_hw *dce_i2c_hw, |
303 | struct dc_context *ctx, |
304 | uint32_t engine_id, |
305 | const struct dce_i2c_registers *regs, |
306 | const struct dce_i2c_shift *shifts, |
307 | const struct dce_i2c_mask *masks); |
308 | |
309 | void dce100_i2c_hw_construct( |
310 | struct dce_i2c_hw *dce_i2c_hw, |
311 | struct dc_context *ctx, |
312 | uint32_t engine_id, |
313 | const struct dce_i2c_registers *regs, |
314 | const struct dce_i2c_shift *shifts, |
315 | const struct dce_i2c_mask *masks); |
316 | |
317 | void dce112_i2c_hw_construct( |
318 | struct dce_i2c_hw *dce_i2c_hw, |
319 | struct dc_context *ctx, |
320 | uint32_t engine_id, |
321 | const struct dce_i2c_registers *regs, |
322 | const struct dce_i2c_shift *shifts, |
323 | const struct dce_i2c_mask *masks); |
324 | |
325 | void dcn1_i2c_hw_construct( |
326 | struct dce_i2c_hw *dce_i2c_hw, |
327 | struct dc_context *ctx, |
328 | uint32_t engine_id, |
329 | const struct dce_i2c_registers *regs, |
330 | const struct dce_i2c_shift *shifts, |
331 | const struct dce_i2c_mask *masks); |
332 | |
333 | void dcn2_i2c_hw_construct( |
334 | struct dce_i2c_hw *dce_i2c_hw, |
335 | struct dc_context *ctx, |
336 | uint32_t engine_id, |
337 | const struct dce_i2c_registers *regs, |
338 | const struct dce_i2c_shift *shifts, |
339 | const struct dce_i2c_mask *masks); |
340 | |
341 | bool dce_i2c_submit_command_hw( |
342 | struct resource_pool *pool, |
343 | struct ddc *ddc, |
344 | struct i2c_command *cmd, |
345 | struct dce_i2c_hw *dce_i2c_hw); |
346 | |
347 | struct dce_i2c_hw *acquire_i2c_hw_engine( |
348 | struct resource_pool *pool, |
349 | struct ddc *ddc); |
350 | |
351 | #endif |
352 | |