Commit | Line | Data |
---|---|---|
7c008829 NK |
1 | /* |
2 | * Copyright 2019 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 _DMUB_CMD_H_ | |
27 | #define _DMUB_CMD_H_ | |
28 | ||
8b19a4e3 AK |
29 | #if defined(_TEST_HARNESS) || defined(FPGA_USB4) |
30 | #include "dmub_fw_types.h" | |
31 | #include "include_legacy/atomfirmware.h" | |
32 | ||
33 | #if defined(_TEST_HARNESS) | |
34 | #include <string.h> | |
35 | #endif | |
36 | #else | |
37 | ||
84034ad4 AK |
38 | #include <asm/byteorder.h> |
39 | #include <linux/types.h> | |
40 | #include <linux/string.h> | |
41 | #include <linux/delay.h> | |
42 | #include <stdarg.h> | |
43 | ||
7c008829 | 44 | #include "atomfirmware.h" |
22aa5614 | 45 | |
8b19a4e3 AK |
46 | #endif // defined(_TEST_HARNESS) || defined(FPGA_USB4) |
47 | ||
8598a722 AK |
48 | /* Firmware versioning. */ |
49 | #ifdef DMUB_EXPOSE_VERSION | |
0abd224e | 50 | #define DMUB_FW_VERSION_GIT_HASH 0x3ac600697 |
b2265774 | 51 | #define DMUB_FW_VERSION_MAJOR 0 |
8598a722 | 52 | #define DMUB_FW_VERSION_MINOR 0 |
0abd224e | 53 | #define DMUB_FW_VERSION_REVISION 53 |
ded750e6 AK |
54 | #define DMUB_FW_VERSION_TEST 0 |
55 | #define DMUB_FW_VERSION_VBIOS 0 | |
56 | #define DMUB_FW_VERSION_HOTFIX 0 | |
57 | #define DMUB_FW_VERSION_UCODE (((DMUB_FW_VERSION_MAJOR & 0xFF) << 24) | \ | |
58 | ((DMUB_FW_VERSION_MINOR & 0xFF) << 16) | \ | |
59 | ((DMUB_FW_VERSION_REVISION & 0xFF) << 8) | \ | |
60 | ((DMUB_FW_VERSION_TEST & 0x1) << 7) | \ | |
61 | ((DMUB_FW_VERSION_VBIOS & 0x1) << 6) | \ | |
62 | (DMUB_FW_VERSION_HOTFIX & 0x3F)) | |
63 | ||
8598a722 | 64 | #endif |
84034ad4 AK |
65 | |
66 | //<DMUB_TYPES>================================================================== | |
67 | /* Basic type definitions. */ | |
7c008829 | 68 | |
8b19a4e3 AK |
69 | #define __forceinline inline |
70 | ||
474ac4a8 YS |
71 | #define SET_ABM_PIPE_GRADUALLY_DISABLE 0 |
72 | #define SET_ABM_PIPE_IMMEDIATELY_DISABLE 255 | |
d9beecfc | 73 | #define SET_ABM_PIPE_IMMEDIATE_KEEP_GAIN_DISABLE 254 |
474ac4a8 | 74 | #define SET_ABM_PIPE_NORMAL 1 |
8c019253 | 75 | |
84034ad4 AK |
76 | /* Maximum number of streams on any ASIC. */ |
77 | #define DMUB_MAX_STREAMS 6 | |
78 | ||
79 | /* Maximum number of planes on any ASIC. */ | |
80 | #define DMUB_MAX_PLANES 6 | |
81 | ||
70732504 YS |
82 | /* Trace buffer offset for entry */ |
83 | #define TRACE_BUFFER_ENTRY_OFFSET 16 | |
84 | ||
84034ad4 AK |
85 | #ifndef PHYSICAL_ADDRESS_LOC |
86 | #define PHYSICAL_ADDRESS_LOC union large_integer | |
87 | #endif | |
88 | ||
84034ad4 AK |
89 | #ifndef dmub_memcpy |
90 | #define dmub_memcpy(dest, source, bytes) memcpy((dest), (source), (bytes)) | |
91 | #endif | |
92 | ||
93 | #ifndef dmub_memset | |
94 | #define dmub_memset(dest, val, bytes) memset((dest), (val), (bytes)) | |
95 | #endif | |
96 | ||
d9beecfc AK |
97 | #if defined(__cplusplus) |
98 | extern "C" { | |
99 | #endif | |
100 | ||
84034ad4 AK |
101 | #ifndef dmub_udelay |
102 | #define dmub_udelay(microseconds) udelay(microseconds) | |
103 | #endif | |
104 | ||
105 | union dmub_addr { | |
106 | struct { | |
107 | uint32_t low_part; | |
108 | uint32_t high_part; | |
109 | } u; | |
110 | uint64_t quad_part; | |
111 | }; | |
112 | ||
113 | union dmub_psr_debug_flags { | |
114 | struct { | |
447f3d0f AK |
115 | uint32_t visual_confirm : 1; |
116 | uint32_t use_hw_lock_mgr : 1; | |
8b3f6b98 | 117 | uint32_t log_line_nums : 1; |
84034ad4 AK |
118 | } bitfields; |
119 | ||
447f3d0f | 120 | uint32_t u32All; |
84034ad4 AK |
121 | }; |
122 | ||
34ba432c AK |
123 | struct dmub_feature_caps { |
124 | uint8_t psr; | |
125 | uint8_t reserved[7]; | |
126 | }; | |
127 | ||
84034ad4 AK |
128 | #if defined(__cplusplus) |
129 | } | |
130 | #endif | |
131 | ||
84034ad4 AK |
132 | //============================================================================== |
133 | //</DMUB_TYPES>================================================================= | |
134 | //============================================================================== | |
135 | //< DMUB_META>================================================================== | |
136 | //============================================================================== | |
137 | #pragma pack(push, 1) | |
138 | ||
139 | /* Magic value for identifying dmub_fw_meta_info */ | |
140 | #define DMUB_FW_META_MAGIC 0x444D5542 | |
141 | ||
142 | /* Offset from the end of the file to the dmub_fw_meta_info */ | |
143 | #define DMUB_FW_META_OFFSET 0x24 | |
144 | ||
145 | /** | |
146 | * struct dmub_fw_meta_info - metadata associated with fw binary | |
147 | * | |
148 | * NOTE: This should be considered a stable API. Fields should | |
149 | * not be repurposed or reordered. New fields should be | |
150 | * added instead to extend the structure. | |
151 | * | |
152 | * @magic_value: magic value identifying DMUB firmware meta info | |
153 | * @fw_region_size: size of the firmware state region | |
154 | * @trace_buffer_size: size of the tracebuffer region | |
155 | * @fw_version: the firmware version information | |
b2265774 | 156 | * @dal_fw: 1 if the firmware is DAL |
84034ad4 AK |
157 | */ |
158 | struct dmub_fw_meta_info { | |
159 | uint32_t magic_value; | |
160 | uint32_t fw_region_size; | |
161 | uint32_t trace_buffer_size; | |
162 | uint32_t fw_version; | |
b2265774 AK |
163 | uint8_t dal_fw; |
164 | uint8_t reserved[3]; | |
84034ad4 AK |
165 | }; |
166 | ||
167 | /* Ensure that the structure remains 64 bytes. */ | |
168 | union dmub_fw_meta { | |
169 | struct dmub_fw_meta_info info; | |
170 | uint8_t reserved[64]; | |
171 | }; | |
172 | ||
173 | #pragma pack(pop) | |
788408b7 AK |
174 | |
175 | //============================================================================== | |
176 | //< DMUB_STATUS>================================================================ | |
177 | //============================================================================== | |
178 | ||
179 | /** | |
180 | * DMCUB scratch registers can be used to determine firmware status. | |
181 | * Current scratch register usage is as follows: | |
182 | * | |
492dd8a8 AK |
183 | * SCRATCH0: FW Boot Status register |
184 | * SCRATCH15: FW Boot Options register | |
788408b7 AK |
185 | */ |
186 | ||
492dd8a8 AK |
187 | /* Register bit definition for SCRATCH0 */ |
188 | union dmub_fw_boot_status { | |
189 | struct { | |
190 | uint32_t dal_fw : 1; | |
191 | uint32_t mailbox_rdy : 1; | |
192 | uint32_t optimized_init_done : 1; | |
3b37260b | 193 | uint32_t restore_required : 1; |
492dd8a8 AK |
194 | } bits; |
195 | uint32_t all; | |
196 | }; | |
197 | ||
198 | enum dmub_fw_boot_status_bit { | |
199 | DMUB_FW_BOOT_STATUS_BIT_DAL_FIRMWARE = (1 << 0), | |
200 | DMUB_FW_BOOT_STATUS_BIT_MAILBOX_READY = (1 << 1), | |
201 | DMUB_FW_BOOT_STATUS_BIT_OPTIMIZED_INIT_DONE = (1 << 2), | |
3b37260b | 202 | DMUB_FW_BOOT_STATUS_BIT_RESTORE_REQUIRED = (1 << 3), |
492dd8a8 AK |
203 | }; |
204 | ||
205 | /* Register bit definition for SCRATCH15 */ | |
206 | union dmub_fw_boot_options { | |
207 | struct { | |
208 | uint32_t pemu_env : 1; | |
209 | uint32_t fpga_env : 1; | |
210 | uint32_t optimized_init : 1; | |
fd0f1d21 AK |
211 | uint32_t skip_phy_access : 1; |
212 | uint32_t disable_clk_gate: 1; | |
5fe6b98a BL |
213 | uint32_t skip_phy_init_panel_sequence: 1; |
214 | uint32_t reserved : 26; | |
492dd8a8 AK |
215 | } bits; |
216 | uint32_t all; | |
217 | }; | |
218 | ||
219 | enum dmub_fw_boot_options_bit { | |
220 | DMUB_FW_BOOT_OPTION_BIT_PEMU_ENV = (1 << 0), | |
221 | DMUB_FW_BOOT_OPTION_BIT_FPGA_ENV = (1 << 1), | |
222 | DMUB_FW_BOOT_OPTION_BIT_OPTIMIZED_INIT_DONE = (1 << 2), | |
223 | }; | |
224 | ||
84034ad4 | 225 | //============================================================================== |
788408b7 | 226 | //</DMUB_STATUS>================================================================ |
84034ad4 AK |
227 | //============================================================================== |
228 | //< DMUB_VBIOS>================================================================= | |
229 | //============================================================================== | |
230 | ||
231 | /* | |
232 | * Command IDs should be treated as stable ABI. | |
233 | * Do not reuse or modify IDs. | |
234 | */ | |
235 | ||
236 | enum dmub_cmd_vbios_type { | |
237 | DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL = 0, | |
238 | DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL = 1, | |
239 | DMUB_CMD__VBIOS_SET_PIXEL_CLOCK = 2, | |
240 | DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING = 3, | |
2ac685bf | 241 | DMUB_CMD__VBIOS_LVTMA_CONTROL = 15, |
84034ad4 AK |
242 | }; |
243 | ||
244 | //============================================================================== | |
245 | //</DMUB_VBIOS>================================================================= | |
246 | //============================================================================== | |
247 | //< DMUB_GPINT>================================================================= | |
248 | //============================================================================== | |
249 | ||
250 | /** | |
251 | * The shifts and masks below may alternatively be used to format and read | |
252 | * the command register bits. | |
253 | */ | |
254 | ||
255 | #define DMUB_GPINT_DATA_PARAM_MASK 0xFFFF | |
256 | #define DMUB_GPINT_DATA_PARAM_SHIFT 0 | |
257 | ||
258 | #define DMUB_GPINT_DATA_COMMAND_CODE_MASK 0xFFF | |
259 | #define DMUB_GPINT_DATA_COMMAND_CODE_SHIFT 16 | |
260 | ||
261 | #define DMUB_GPINT_DATA_STATUS_MASK 0xF | |
262 | #define DMUB_GPINT_DATA_STATUS_SHIFT 28 | |
263 | ||
264 | /** | |
265 | * Command responses. | |
266 | */ | |
267 | ||
268 | #define DMUB_GPINT__STOP_FW_RESPONSE 0xDEADDEAD | |
269 | ||
270 | /** | |
271 | * The register format for sending a command via the GPINT. | |
272 | */ | |
273 | union dmub_gpint_data_register { | |
274 | struct { | |
275 | uint32_t param : 16; | |
276 | uint32_t command_code : 12; | |
277 | uint32_t status : 4; | |
278 | } bits; | |
279 | uint32_t all; | |
280 | }; | |
281 | ||
282 | /* | |
283 | * Command IDs should be treated as stable ABI. | |
284 | * Do not reuse or modify IDs. | |
285 | */ | |
286 | ||
287 | enum dmub_gpint_command { | |
288 | DMUB_GPINT__INVALID_COMMAND = 0, | |
289 | DMUB_GPINT__GET_FW_VERSION = 1, | |
290 | DMUB_GPINT__STOP_FW = 2, | |
291 | DMUB_GPINT__GET_PSR_STATE = 7, | |
80eba958 AK |
292 | /** |
293 | * DESC: Notifies DMCUB of the currently active streams. | |
294 | * ARGS: Stream mask, 1 bit per active stream index. | |
295 | */ | |
296 | DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK = 8, | |
672251b2 | 297 | DMUB_GPINT__PSR_RESIDENCY = 9, |
84034ad4 AK |
298 | }; |
299 | ||
300 | //============================================================================== | |
301 | //</DMUB_GPINT>================================================================= | |
302 | //============================================================================== | |
303 | //< DMUB_CMD>=================================================================== | |
304 | //============================================================================== | |
305 | ||
306 | #define DMUB_RB_CMD_SIZE 64 | |
307 | #define DMUB_RB_MAX_ENTRY 128 | |
308 | #define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY) | |
309 | #define REG_SET_MASK 0xFFFF | |
310 | ||
d4bbcecb NK |
311 | /* |
312 | * Command IDs should be treated as stable ABI. | |
313 | * Do not reuse or modify IDs. | |
314 | */ | |
7c008829 | 315 | |
d4bbcecb NK |
316 | enum dmub_cmd_type { |
317 | DMUB_CMD__NULL = 0, | |
318 | DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE = 1, | |
319 | DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ = 2, | |
320 | DMUB_CMD__REG_SEQ_BURST_WRITE = 3, | |
321 | DMUB_CMD__REG_REG_WAIT = 4, | |
bae9c49b | 322 | DMUB_CMD__PLAT_54186_WA = 5, |
34ba432c | 323 | DMUB_CMD__QUERY_FEATURE_CAPS = 6, |
d4bbcecb | 324 | DMUB_CMD__PSR = 64, |
52f2e83e | 325 | DMUB_CMD__MALL = 65, |
e6ea8c34 | 326 | DMUB_CMD__ABM = 66, |
788408b7 | 327 | DMUB_CMD__HW_LOCK = 69, |
d9beecfc AK |
328 | DMUB_CMD__DP_AUX_ACCESS = 70, |
329 | DMUB_CMD__OUTBOX1_ENABLE = 71, | |
d4bbcecb | 330 | DMUB_CMD__VBIOS = 128, |
7c008829 NK |
331 | }; |
332 | ||
3b37260b AK |
333 | enum dmub_out_cmd_type { |
334 | DMUB_OUT_CMD__NULL = 0, | |
d9beecfc AK |
335 | DMUB_OUT_CMD__DP_AUX_REPLY = 1, |
336 | DMUB_OUT_CMD__DP_HPD_NOTIFY = 2, | |
3b37260b AK |
337 | }; |
338 | ||
7c008829 NK |
339 | #pragma pack(push, 1) |
340 | ||
341 | struct dmub_cmd_header { | |
d4bbcecb NK |
342 | unsigned int type : 8; |
343 | unsigned int sub_type : 8; | |
34ba432c AK |
344 | unsigned int ret_status : 1; |
345 | unsigned int reserved0 : 7; | |
7c008829 | 346 | unsigned int payload_bytes : 6; /* up to 60 bytes */ |
d4bbcecb | 347 | unsigned int reserved1 : 2; |
7c008829 NK |
348 | }; |
349 | ||
350 | /* | |
351 | * Read modify write | |
352 | * | |
353 | * 60 payload bytes can hold up to 5 sets of read modify writes, | |
354 | * each take 3 dwords. | |
355 | * | |
356 | * number of sequences = header.payload_bytes / sizeof(struct dmub_cmd_read_modify_write_sequence) | |
357 | * | |
358 | * modify_mask = 0xffff'ffff means all fields are going to be updated. in this case | |
359 | * command parser will skip the read and we can use modify_mask = 0xffff'ffff as reg write | |
360 | */ | |
361 | struct dmub_cmd_read_modify_write_sequence { | |
362 | uint32_t addr; | |
363 | uint32_t modify_mask; | |
364 | uint32_t modify_value; | |
365 | }; | |
366 | ||
367 | #define DMUB_READ_MODIFY_WRITE_SEQ__MAX 5 | |
368 | struct dmub_rb_cmd_read_modify_write { | |
369 | struct dmub_cmd_header header; // type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE | |
370 | struct dmub_cmd_read_modify_write_sequence seq[DMUB_READ_MODIFY_WRITE_SEQ__MAX]; | |
371 | }; | |
372 | ||
373 | /* | |
374 | * Update a register with specified masks and values sequeunce | |
375 | * | |
376 | * 60 payload bytes can hold address + up to 7 sets of mask/value combo, each take 2 dword | |
377 | * | |
378 | * number of field update sequence = (header.payload_bytes - sizeof(addr)) / sizeof(struct read_modify_write_sequence) | |
379 | * | |
380 | * | |
381 | * USE CASE: | |
382 | * 1. auto-increment register where additional read would update pointer and produce wrong result | |
383 | * 2. toggle a bit without read in the middle | |
384 | */ | |
385 | ||
386 | struct dmub_cmd_reg_field_update_sequence { | |
387 | uint32_t modify_mask; // 0xffff'ffff to skip initial read | |
388 | uint32_t modify_value; | |
389 | }; | |
390 | ||
391 | #define DMUB_REG_FIELD_UPDATE_SEQ__MAX 7 | |
7c008829 NK |
392 | struct dmub_rb_cmd_reg_field_update_sequence { |
393 | struct dmub_cmd_header header; | |
394 | uint32_t addr; | |
395 | struct dmub_cmd_reg_field_update_sequence seq[DMUB_REG_FIELD_UPDATE_SEQ__MAX]; | |
396 | }; | |
397 | ||
7c008829 NK |
398 | /* |
399 | * Burst write | |
400 | * | |
401 | * support use case such as writing out LUTs. | |
402 | * | |
403 | * 60 payload bytes can hold up to 14 values to write to given address | |
404 | * | |
405 | * number of payload = header.payload_bytes / sizeof(struct read_modify_write_sequence) | |
406 | */ | |
407 | #define DMUB_BURST_WRITE_VALUES__MAX 14 | |
408 | struct dmub_rb_cmd_burst_write { | |
409 | struct dmub_cmd_header header; // type = DMUB_CMD__REG_SEQ_BURST_WRITE | |
410 | uint32_t addr; | |
411 | uint32_t write_values[DMUB_BURST_WRITE_VALUES__MAX]; | |
412 | }; | |
413 | ||
414 | ||
415 | struct dmub_rb_cmd_common { | |
416 | struct dmub_cmd_header header; | |
417 | uint8_t cmd_buffer[DMUB_RB_CMD_SIZE - sizeof(struct dmub_cmd_header)]; | |
418 | }; | |
419 | ||
420 | struct dmub_cmd_reg_wait_data { | |
421 | uint32_t addr; | |
422 | uint32_t mask; | |
423 | uint32_t condition_field_value; | |
424 | uint32_t time_out_us; | |
425 | }; | |
426 | ||
427 | struct dmub_rb_cmd_reg_wait { | |
428 | struct dmub_cmd_header header; | |
429 | struct dmub_cmd_reg_wait_data reg_wait; | |
430 | }; | |
431 | ||
bae9c49b | 432 | struct dmub_cmd_PLAT_54186_wa { |
8c019253 | 433 | uint32_t DCSURF_SURFACE_CONTROL; |
8c019253 YS |
434 | uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; |
435 | uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; | |
8c019253 YS |
436 | uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; |
437 | uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; | |
22aa5614 YS |
438 | struct { |
439 | uint8_t hubp_inst : 4; | |
440 | uint8_t tmz_surface : 1; | |
441 | uint8_t immediate :1; | |
442 | uint8_t vmid : 4; | |
443 | uint8_t grph_stereo : 1; | |
444 | uint32_t reserved : 21; | |
445 | } flip_params; | |
bae9c49b | 446 | uint32_t reserved[9]; |
8c019253 YS |
447 | }; |
448 | ||
bae9c49b | 449 | struct dmub_rb_cmd_PLAT_54186_wa { |
8c019253 | 450 | struct dmub_cmd_header header; |
bae9c49b | 451 | struct dmub_cmd_PLAT_54186_wa flip; |
8c019253 YS |
452 | }; |
453 | ||
52f2e83e BL |
454 | struct dmub_rb_cmd_mall { |
455 | struct dmub_cmd_header header; | |
456 | union dmub_addr cursor_copy_src; | |
457 | union dmub_addr cursor_copy_dst; | |
458 | uint32_t tmr_delay; | |
459 | uint32_t tmr_scale; | |
460 | uint16_t cursor_width; | |
461 | uint16_t cursor_pitch; | |
462 | uint16_t cursor_height; | |
463 | uint8_t cursor_bpp; | |
ea7154d8 BL |
464 | uint8_t debug_bits; |
465 | ||
466 | uint8_t reserved1; | |
467 | uint8_t reserved2; | |
52f2e83e BL |
468 | }; |
469 | ||
7c008829 NK |
470 | struct dmub_cmd_digx_encoder_control_data { |
471 | union dig_encoder_control_parameters_v1_5 dig; | |
472 | }; | |
473 | ||
474 | struct dmub_rb_cmd_digx_encoder_control { | |
475 | struct dmub_cmd_header header; | |
476 | struct dmub_cmd_digx_encoder_control_data encoder_control; | |
477 | }; | |
478 | ||
479 | struct dmub_cmd_set_pixel_clock_data { | |
480 | struct set_pixel_clock_parameter_v1_7 clk; | |
481 | }; | |
482 | ||
483 | struct dmub_rb_cmd_set_pixel_clock { | |
484 | struct dmub_cmd_header header; | |
485 | struct dmub_cmd_set_pixel_clock_data pixel_clock; | |
486 | }; | |
487 | ||
488 | struct dmub_cmd_enable_disp_power_gating_data { | |
489 | struct enable_disp_power_gating_parameters_v2_1 pwr; | |
490 | }; | |
491 | ||
492 | struct dmub_rb_cmd_enable_disp_power_gating { | |
493 | struct dmub_cmd_header header; | |
494 | struct dmub_cmd_enable_disp_power_gating_data power_gating; | |
495 | }; | |
496 | ||
d448521e AK |
497 | struct dmub_dig_transmitter_control_data_v1_7 { |
498 | uint8_t phyid; /**< 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4=UNIPHYE, 5=UNIPHYF */ | |
499 | uint8_t action; /**< Defined as ATOM_TRANSMITER_ACTION_xxx */ | |
500 | union { | |
501 | uint8_t digmode; /**< enum atom_encode_mode_def */ | |
502 | uint8_t dplaneset; /**< DP voltage swing and pre-emphasis value, "DP_LANE_SET__xDB_y_zV" */ | |
503 | } mode_laneset; | |
504 | uint8_t lanenum; /**< Number of lanes */ | |
505 | union { | |
506 | uint32_t symclk_10khz; /**< Symbol Clock in 10Khz */ | |
507 | } symclk_units; | |
508 | uint8_t hpdsel; /**< =1: HPD1, =2: HPD2, ..., =6: HPD6, =0: HPD is not assigned */ | |
509 | uint8_t digfe_sel; /**< DIG front-end selection, bit0 means DIG0 FE is enabled */ | |
510 | uint8_t connobj_id; /**< Connector Object Id defined in ObjectId.h */ | |
511 | uint8_t reserved0; /**< For future use */ | |
512 | uint8_t reserved1; /**< For future use */ | |
513 | uint8_t reserved2[3]; /**< For future use */ | |
514 | uint32_t reserved3[11]; /**< For future use */ | |
515 | }; | |
516 | ||
517 | union dmub_cmd_dig1_transmitter_control_data { | |
7c008829 | 518 | struct dig_transmitter_control_parameters_v1_6 dig; |
d448521e | 519 | struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7; |
7c008829 NK |
520 | }; |
521 | ||
522 | struct dmub_rb_cmd_dig1_transmitter_control { | |
523 | struct dmub_cmd_header header; | |
d448521e | 524 | union dmub_cmd_dig1_transmitter_control_data transmitter_control; |
7c008829 NK |
525 | }; |
526 | ||
527 | struct dmub_rb_cmd_dpphy_init { | |
528 | struct dmub_cmd_header header; | |
529 | uint8_t reserved[60]; | |
530 | }; | |
531 | ||
d9beecfc AK |
532 | enum dp_aux_request_action { |
533 | DP_AUX_REQ_ACTION_I2C_WRITE = 0x00, | |
534 | DP_AUX_REQ_ACTION_I2C_READ = 0x10, | |
535 | DP_AUX_REQ_ACTION_I2C_STATUS_REQ = 0x20, | |
536 | DP_AUX_REQ_ACTION_I2C_WRITE_MOT = 0x40, | |
537 | DP_AUX_REQ_ACTION_I2C_READ_MOT = 0x50, | |
538 | DP_AUX_REQ_ACTION_I2C_STATUS_REQ_MOT = 0x60, | |
539 | DP_AUX_REQ_ACTION_DPCD_WRITE = 0x80, | |
540 | DP_AUX_REQ_ACTION_DPCD_READ = 0x90 | |
541 | }; | |
542 | ||
fd0f1d21 AK |
543 | enum aux_return_code_type { |
544 | AUX_RET_SUCCESS = 0, | |
b6402afe AK |
545 | AUX_RET_ERROR_UNKNOWN, |
546 | AUX_RET_ERROR_INVALID_REPLY, | |
fd0f1d21 | 547 | AUX_RET_ERROR_TIMEOUT, |
b6402afe AK |
548 | AUX_RET_ERROR_HPD_DISCON, |
549 | AUX_RET_ERROR_ENGINE_ACQUIRE, | |
fd0f1d21 AK |
550 | AUX_RET_ERROR_INVALID_OPERATION, |
551 | AUX_RET_ERROR_PROTOCOL_ERROR, | |
552 | }; | |
553 | ||
b6402afe AK |
554 | enum aux_channel_type { |
555 | AUX_CHANNEL_LEGACY_DDC, | |
556 | AUX_CHANNEL_DPIA | |
557 | }; | |
558 | ||
d9beecfc AK |
559 | /* DP AUX command */ |
560 | struct aux_transaction_parameters { | |
561 | uint8_t is_i2c_over_aux; | |
562 | uint8_t action; | |
563 | uint8_t length; | |
564 | uint8_t pad; | |
565 | uint32_t address; | |
566 | uint8_t data[16]; | |
567 | }; | |
568 | ||
569 | struct dmub_cmd_dp_aux_control_data { | |
b6402afe | 570 | uint8_t instance; |
e5e25818 | 571 | uint8_t manual_acq_rel_enable; |
d9beecfc | 572 | uint8_t sw_crc_enabled; |
e5e25818 AK |
573 | uint8_t pad; |
574 | uint16_t handle; | |
d9beecfc | 575 | uint16_t timeout; |
b6402afe | 576 | enum aux_channel_type type; |
d9beecfc AK |
577 | struct aux_transaction_parameters dpaux; |
578 | }; | |
579 | ||
580 | struct dmub_rb_cmd_dp_aux_access { | |
581 | struct dmub_cmd_header header; | |
582 | struct dmub_cmd_dp_aux_control_data aux_control; | |
583 | }; | |
584 | ||
585 | struct dmub_rb_cmd_outbox1_enable { | |
586 | struct dmub_cmd_header header; | |
587 | uint32_t enable; | |
588 | }; | |
589 | ||
590 | /* DP AUX Reply command - OutBox Cmd */ | |
591 | struct aux_reply_data { | |
592 | uint8_t command; | |
593 | uint8_t length; | |
594 | uint8_t pad[2]; | |
595 | uint8_t data[16]; | |
596 | }; | |
597 | ||
598 | struct aux_reply_control_data { | |
599 | uint32_t handle; | |
b6402afe | 600 | uint8_t instance; |
d9beecfc AK |
601 | uint8_t result; |
602 | uint16_t pad; | |
603 | }; | |
604 | ||
605 | struct dmub_rb_cmd_dp_aux_reply { | |
606 | struct dmub_cmd_header header; | |
607 | struct aux_reply_control_data control; | |
608 | struct aux_reply_data reply_data; | |
609 | }; | |
610 | ||
fd0f1d21 AK |
611 | /* DP HPD Notify command - OutBox Cmd */ |
612 | enum dp_hpd_type { | |
613 | DP_HPD = 0, | |
614 | DP_IRQ | |
615 | }; | |
616 | ||
617 | enum dp_hpd_status { | |
618 | DP_HPD_UNPLUG = 0, | |
619 | DP_HPD_PLUG | |
620 | }; | |
621 | ||
d9beecfc | 622 | struct dp_hpd_data { |
b6402afe | 623 | uint8_t instance; |
d9beecfc AK |
624 | uint8_t hpd_type; |
625 | uint8_t hpd_status; | |
626 | uint8_t pad; | |
627 | }; | |
628 | ||
629 | struct dmub_rb_cmd_dp_hpd_notify { | |
630 | struct dmub_cmd_header header; | |
631 | struct dp_hpd_data hpd_data; | |
632 | }; | |
633 | ||
84034ad4 AK |
634 | /* |
635 | * Command IDs should be treated as stable ABI. | |
636 | * Do not reuse or modify IDs. | |
637 | */ | |
638 | ||
639 | enum dmub_cmd_psr_type { | |
640 | DMUB_CMD__PSR_SET_VERSION = 0, | |
641 | DMUB_CMD__PSR_COPY_SETTINGS = 1, | |
642 | DMUB_CMD__PSR_ENABLE = 2, | |
643 | DMUB_CMD__PSR_DISABLE = 3, | |
644 | DMUB_CMD__PSR_SET_LEVEL = 4, | |
672251b2 | 645 | DMUB_CMD__PSR_FORCE_STATIC = 5, |
84034ad4 AK |
646 | }; |
647 | ||
648 | enum psr_version { | |
649 | PSR_VERSION_1 = 0, | |
650 | PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, | |
651 | }; | |
652 | ||
52f2e83e BL |
653 | enum dmub_cmd_mall_type { |
654 | DMUB_CMD__MALL_ACTION_ALLOW = 0, | |
655 | DMUB_CMD__MALL_ACTION_DISALLOW = 1, | |
656 | DMUB_CMD__MALL_ACTION_COPY_CURSOR = 2, | |
ea7154d8 | 657 | DMUB_CMD__MALL_ACTION_NO_DF_REQ = 3, |
52f2e83e BL |
658 | }; |
659 | ||
7c008829 | 660 | struct dmub_cmd_psr_copy_settings_data { |
7b8a6362 | 661 | union dmub_psr_debug_flags debug; |
4c1a1335 | 662 | uint16_t psr_level; |
4c1a1335 | 663 | uint8_t dpp_inst; |
34ba432c AK |
664 | /* opp_inst and mpcc_inst will not be used in dmub fw, |
665 | * dmub fw will get active opp by reading odm registers. | |
666 | */ | |
4c1a1335 WW |
667 | uint8_t mpcc_inst; |
668 | uint8_t opp_inst; | |
34ba432c | 669 | |
4c1a1335 WW |
670 | uint8_t otg_inst; |
671 | uint8_t digfe_inst; | |
672 | uint8_t digbe_inst; | |
673 | uint8_t dpphy_inst; | |
674 | uint8_t aux_inst; | |
4c1a1335 | 675 | uint8_t smu_optimizations_en; |
4c1a1335 | 676 | uint8_t frame_delay; |
4c1a1335 | 677 | uint8_t frame_cap_ind; |
175f0971 YS |
678 | uint8_t pad[2]; |
679 | uint8_t multi_disp_optimizations_en; | |
78ead771 AK |
680 | uint16_t init_sdp_deadline; |
681 | uint16_t pad2; | |
9b56f6bc | 682 | uint32_t line_time_in_us; |
7c008829 NK |
683 | }; |
684 | ||
685 | struct dmub_rb_cmd_psr_copy_settings { | |
686 | struct dmub_cmd_header header; | |
687 | struct dmub_cmd_psr_copy_settings_data psr_copy_settings_data; | |
688 | }; | |
689 | ||
690 | struct dmub_cmd_psr_set_level_data { | |
691 | uint16_t psr_level; | |
7b8a6362 | 692 | uint8_t pad[2]; |
7c008829 NK |
693 | }; |
694 | ||
695 | struct dmub_rb_cmd_psr_set_level { | |
696 | struct dmub_cmd_header header; | |
697 | struct dmub_cmd_psr_set_level_data psr_set_level_data; | |
698 | }; | |
699 | ||
7c008829 NK |
700 | struct dmub_rb_cmd_psr_enable { |
701 | struct dmub_cmd_header header; | |
702 | }; | |
703 | ||
d4b8573e | 704 | struct dmub_cmd_psr_set_version_data { |
ec256f44 | 705 | enum psr_version version; // PSR version 1 or 2 |
7c008829 NK |
706 | }; |
707 | ||
d4b8573e | 708 | struct dmub_rb_cmd_psr_set_version { |
7c008829 | 709 | struct dmub_cmd_header header; |
d4b8573e | 710 | struct dmub_cmd_psr_set_version_data psr_set_version_data; |
7c008829 NK |
711 | }; |
712 | ||
672251b2 AK |
713 | struct dmub_rb_cmd_psr_force_static { |
714 | struct dmub_cmd_header header; | |
715 | }; | |
716 | ||
788408b7 AK |
717 | union dmub_hw_lock_flags { |
718 | struct { | |
719 | uint8_t lock_pipe : 1; | |
720 | uint8_t lock_cursor : 1; | |
721 | uint8_t lock_dig : 1; | |
722 | uint8_t triple_buffer_lock : 1; | |
723 | } bits; | |
724 | ||
725 | uint8_t u8All; | |
726 | }; | |
727 | ||
728 | struct dmub_hw_lock_inst_flags { | |
729 | uint8_t otg_inst; | |
730 | uint8_t opp_inst; | |
731 | uint8_t dig_inst; | |
732 | uint8_t pad; | |
733 | }; | |
734 | ||
735 | enum hw_lock_client { | |
736 | HW_LOCK_CLIENT_DRIVER = 0, | |
737 | HW_LOCK_CLIENT_FW, | |
738 | HW_LOCK_CLIENT_INVALID = 0xFFFFFFFF, | |
739 | }; | |
740 | ||
741 | struct dmub_cmd_lock_hw_data { | |
742 | enum hw_lock_client client; | |
743 | struct dmub_hw_lock_inst_flags inst_flags; | |
744 | union dmub_hw_lock_flags hw_locks; | |
745 | uint8_t lock; | |
746 | uint8_t should_release; | |
747 | uint8_t pad; | |
748 | }; | |
749 | ||
750 | struct dmub_rb_cmd_lock_hw { | |
751 | struct dmub_cmd_header header; | |
752 | struct dmub_cmd_lock_hw_data lock_hw_data; | |
753 | }; | |
754 | ||
84034ad4 AK |
755 | enum dmub_cmd_abm_type { |
756 | DMUB_CMD__ABM_INIT_CONFIG = 0, | |
757 | DMUB_CMD__ABM_SET_PIPE = 1, | |
758 | DMUB_CMD__ABM_SET_BACKLIGHT = 2, | |
759 | DMUB_CMD__ABM_SET_LEVEL = 3, | |
760 | DMUB_CMD__ABM_SET_AMBIENT_LEVEL = 4, | |
761 | DMUB_CMD__ABM_SET_PWM_FRAC = 5, | |
762 | }; | |
763 | ||
764 | #define NUM_AMBI_LEVEL 5 | |
765 | #define NUM_AGGR_LEVEL 4 | |
766 | #define NUM_POWER_FN_SEGS 8 | |
767 | #define NUM_BL_CURVE_SEGS 16 | |
768 | ||
769 | /* | |
770 | * Parameters for ABM2.4 algorithm. | |
771 | * Padded explicitly to 32-bit boundary. | |
772 | */ | |
773 | struct abm_config_table { | |
774 | /* Parameters for crgb conversion */ | |
775 | uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; // 0B | |
b6402afe AK |
776 | uint16_t crgb_offset[NUM_POWER_FN_SEGS]; // 16B |
777 | uint16_t crgb_slope[NUM_POWER_FN_SEGS]; // 32B | |
84034ad4 AK |
778 | |
779 | /* Parameters for custom curve */ | |
b6402afe AK |
780 | uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; // 48B |
781 | uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; // 78B | |
782 | ||
783 | uint16_t ambient_thresholds_lux[NUM_AMBI_LEVEL]; // 112B | |
784 | uint16_t min_abm_backlight; // 122B | |
785 | ||
786 | uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 124B | |
787 | uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 144B | |
788 | uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 164B | |
789 | uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 184B | |
790 | uint8_t hybrid_factor[NUM_AGGR_LEVEL]; // 204B | |
791 | uint8_t contrast_factor[NUM_AGGR_LEVEL]; // 208B | |
792 | uint8_t deviation_gain[NUM_AGGR_LEVEL]; // 212B | |
793 | uint8_t min_knee[NUM_AGGR_LEVEL]; // 216B | |
794 | uint8_t max_knee[NUM_AGGR_LEVEL]; // 220B | |
795 | uint8_t iir_curve[NUM_AMBI_LEVEL]; // 224B | |
796 | uint8_t pad3[3]; // 229B | |
797 | ||
798 | uint16_t blRampReduction[NUM_AGGR_LEVEL]; // 232B | |
799 | uint16_t blRampStart[NUM_AGGR_LEVEL]; // 240B | |
84034ad4 AK |
800 | }; |
801 | ||
e6ea8c34 | 802 | struct dmub_cmd_abm_set_pipe_data { |
7b8a6362 AK |
803 | uint8_t otg_inst; |
804 | uint8_t panel_inst; | |
805 | uint8_t set_pipe_option; | |
806 | uint8_t ramping_boundary; // TODO: Remove this | |
e6ea8c34 WW |
807 | }; |
808 | ||
809 | struct dmub_rb_cmd_abm_set_pipe { | |
810 | struct dmub_cmd_header header; | |
811 | struct dmub_cmd_abm_set_pipe_data abm_set_pipe_data; | |
812 | }; | |
813 | ||
814 | struct dmub_cmd_abm_set_backlight_data { | |
815 | uint32_t frame_ramp; | |
474ac4a8 | 816 | uint32_t backlight_user_level; |
e6ea8c34 WW |
817 | }; |
818 | ||
819 | struct dmub_rb_cmd_abm_set_backlight { | |
820 | struct dmub_cmd_header header; | |
821 | struct dmub_cmd_abm_set_backlight_data abm_set_backlight_data; | |
822 | }; | |
823 | ||
824 | struct dmub_cmd_abm_set_level_data { | |
825 | uint32_t level; | |
826 | }; | |
827 | ||
828 | struct dmub_rb_cmd_abm_set_level { | |
829 | struct dmub_cmd_header header; | |
830 | struct dmub_cmd_abm_set_level_data abm_set_level_data; | |
831 | }; | |
832 | ||
833 | struct dmub_cmd_abm_set_ambient_level_data { | |
834 | uint32_t ambient_lux; | |
835 | }; | |
836 | ||
837 | struct dmub_rb_cmd_abm_set_ambient_level { | |
838 | struct dmub_cmd_header header; | |
839 | struct dmub_cmd_abm_set_ambient_level_data abm_set_ambient_level_data; | |
840 | }; | |
841 | ||
842 | struct dmub_cmd_abm_set_pwm_frac_data { | |
843 | uint32_t fractional_pwm; | |
844 | }; | |
845 | ||
846 | struct dmub_rb_cmd_abm_set_pwm_frac { | |
847 | struct dmub_cmd_header header; | |
848 | struct dmub_cmd_abm_set_pwm_frac_data abm_set_pwm_frac_data; | |
849 | }; | |
850 | ||
16012806 WW |
851 | struct dmub_cmd_abm_init_config_data { |
852 | union dmub_addr src; | |
853 | uint16_t bytes; | |
854 | }; | |
855 | ||
856 | struct dmub_rb_cmd_abm_init_config { | |
857 | struct dmub_cmd_header header; | |
858 | struct dmub_cmd_abm_init_config_data abm_init_config_data; | |
859 | }; | |
860 | ||
34ba432c AK |
861 | struct dmub_cmd_query_feature_caps_data { |
862 | struct dmub_feature_caps feature_caps; | |
863 | }; | |
864 | ||
865 | struct dmub_rb_cmd_query_feature_caps { | |
866 | struct dmub_cmd_header header; | |
867 | struct dmub_cmd_query_feature_caps_data query_feature_caps_data; | |
868 | }; | |
869 | ||
870 | union dmub_rb_cmd { | |
dc6e2448 | 871 | struct dmub_rb_cmd_lock_hw lock_hw; |
7c008829 NK |
872 | struct dmub_rb_cmd_read_modify_write read_modify_write; |
873 | struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq; | |
874 | struct dmub_rb_cmd_burst_write burst_write; | |
875 | struct dmub_rb_cmd_reg_wait reg_wait; | |
876 | struct dmub_rb_cmd_common cmd_common; | |
877 | struct dmub_rb_cmd_digx_encoder_control digx_encoder_control; | |
878 | struct dmub_rb_cmd_set_pixel_clock set_pixel_clock; | |
879 | struct dmub_rb_cmd_enable_disp_power_gating enable_disp_power_gating; | |
880 | struct dmub_rb_cmd_dpphy_init dpphy_init; | |
881 | struct dmub_rb_cmd_dig1_transmitter_control dig1_transmitter_control; | |
d4b8573e | 882 | struct dmub_rb_cmd_psr_set_version psr_set_version; |
7c008829 | 883 | struct dmub_rb_cmd_psr_copy_settings psr_copy_settings; |
d4b8573e | 884 | struct dmub_rb_cmd_psr_enable psr_enable; |
7c008829 | 885 | struct dmub_rb_cmd_psr_set_level psr_set_level; |
672251b2 | 886 | struct dmub_rb_cmd_psr_force_static psr_force_static; |
bae9c49b | 887 | struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa; |
52f2e83e | 888 | struct dmub_rb_cmd_mall mall; |
e6ea8c34 WW |
889 | struct dmub_rb_cmd_abm_set_pipe abm_set_pipe; |
890 | struct dmub_rb_cmd_abm_set_backlight abm_set_backlight; | |
891 | struct dmub_rb_cmd_abm_set_level abm_set_level; | |
892 | struct dmub_rb_cmd_abm_set_ambient_level abm_set_ambient_level; | |
893 | struct dmub_rb_cmd_abm_set_pwm_frac abm_set_pwm_frac; | |
16012806 | 894 | struct dmub_rb_cmd_abm_init_config abm_init_config; |
d9beecfc AK |
895 | struct dmub_rb_cmd_dp_aux_access dp_aux_access; |
896 | struct dmub_rb_cmd_outbox1_enable outbox1_enable; | |
34ba432c | 897 | struct dmub_rb_cmd_query_feature_caps query_feature_caps; |
7c008829 NK |
898 | }; |
899 | ||
d9beecfc AK |
900 | union dmub_rb_out_cmd { |
901 | struct dmub_rb_cmd_common cmd_common; | |
902 | struct dmub_rb_cmd_dp_aux_reply dp_aux_reply; | |
903 | struct dmub_rb_cmd_dp_hpd_notify dp_hpd_notify; | |
904 | }; | |
7c008829 NK |
905 | #pragma pack(pop) |
906 | ||
84034ad4 AK |
907 | |
908 | //============================================================================== | |
909 | //</DMUB_CMD>=================================================================== | |
910 | //============================================================================== | |
911 | //< DMUB_RB>==================================================================== | |
912 | //============================================================================== | |
913 | ||
914 | #if defined(__cplusplus) | |
915 | extern "C" { | |
916 | #endif | |
917 | ||
918 | struct dmub_rb_init_params { | |
919 | void *ctx; | |
920 | void *base_address; | |
921 | uint32_t capacity; | |
922 | uint32_t read_ptr; | |
923 | uint32_t write_ptr; | |
924 | }; | |
925 | ||
926 | struct dmub_rb { | |
927 | void *base_address; | |
928 | uint32_t data_count; | |
929 | uint32_t rptr; | |
930 | uint32_t wrpt; | |
931 | uint32_t capacity; | |
932 | ||
933 | void *ctx; | |
934 | void *dmub; | |
935 | }; | |
936 | ||
937 | ||
938 | static inline bool dmub_rb_empty(struct dmub_rb *rb) | |
939 | { | |
940 | return (rb->wrpt == rb->rptr); | |
941 | } | |
942 | ||
943 | static inline bool dmub_rb_full(struct dmub_rb *rb) | |
944 | { | |
945 | uint32_t data_count; | |
946 | ||
947 | if (rb->wrpt >= rb->rptr) | |
948 | data_count = rb->wrpt - rb->rptr; | |
949 | else | |
950 | data_count = rb->capacity - (rb->rptr - rb->wrpt); | |
951 | ||
952 | return (data_count == (rb->capacity - DMUB_RB_CMD_SIZE)); | |
953 | } | |
954 | ||
955 | static inline bool dmub_rb_push_front(struct dmub_rb *rb, | |
956 | const union dmub_rb_cmd *cmd) | |
957 | { | |
958 | uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t); | |
959 | const uint64_t *src = (const uint64_t *)cmd; | |
34ba432c | 960 | uint8_t i; |
84034ad4 AK |
961 | |
962 | if (dmub_rb_full(rb)) | |
963 | return false; | |
964 | ||
965 | // copying data | |
966 | for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) | |
967 | *dst++ = *src++; | |
968 | ||
969 | rb->wrpt += DMUB_RB_CMD_SIZE; | |
970 | ||
971 | if (rb->wrpt >= rb->capacity) | |
972 | rb->wrpt %= rb->capacity; | |
973 | ||
974 | return true; | |
975 | } | |
976 | ||
d9beecfc AK |
977 | static inline bool dmub_rb_out_push_front(struct dmub_rb *rb, |
978 | const union dmub_rb_out_cmd *cmd) | |
979 | { | |
980 | uint8_t *dst = (uint8_t *)(rb->base_address) + rb->wrpt; | |
981 | const uint8_t *src = (uint8_t *)cmd; | |
982 | ||
983 | if (dmub_rb_full(rb)) | |
984 | return false; | |
985 | ||
986 | dmub_memcpy(dst, src, DMUB_RB_CMD_SIZE); | |
987 | ||
988 | rb->wrpt += DMUB_RB_CMD_SIZE; | |
989 | ||
990 | if (rb->wrpt >= rb->capacity) | |
991 | rb->wrpt %= rb->capacity; | |
992 | ||
993 | return true; | |
994 | } | |
995 | ||
84034ad4 | 996 | static inline bool dmub_rb_front(struct dmub_rb *rb, |
34ba432c | 997 | union dmub_rb_cmd **cmd) |
84034ad4 | 998 | { |
34ba432c | 999 | uint8_t *rb_cmd = (uint8_t *)(rb->base_address) + rb->rptr; |
84034ad4 AK |
1000 | |
1001 | if (dmub_rb_empty(rb)) | |
1002 | return false; | |
1003 | ||
34ba432c | 1004 | *cmd = (union dmub_rb_cmd *)rb_cmd; |
84034ad4 AK |
1005 | |
1006 | return true; | |
1007 | } | |
1008 | ||
d9beecfc AK |
1009 | static inline bool dmub_rb_out_front(struct dmub_rb *rb, |
1010 | union dmub_rb_out_cmd *cmd) | |
1011 | { | |
1012 | const uint64_t volatile *src = (const uint64_t volatile *)(rb->base_address) + rb->rptr / sizeof(uint64_t); | |
1013 | uint64_t *dst = (uint64_t *)cmd; | |
34ba432c | 1014 | uint8_t i; |
d9beecfc AK |
1015 | |
1016 | if (dmub_rb_empty(rb)) | |
1017 | return false; | |
1018 | ||
1019 | // copying data | |
1020 | for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) | |
1021 | *dst++ = *src++; | |
1022 | ||
1023 | return true; | |
1024 | } | |
1025 | ||
84034ad4 AK |
1026 | static inline bool dmub_rb_pop_front(struct dmub_rb *rb) |
1027 | { | |
1028 | if (dmub_rb_empty(rb)) | |
1029 | return false; | |
1030 | ||
1031 | rb->rptr += DMUB_RB_CMD_SIZE; | |
1032 | ||
1033 | if (rb->rptr >= rb->capacity) | |
1034 | rb->rptr %= rb->capacity; | |
1035 | ||
1036 | return true; | |
1037 | } | |
1038 | ||
1039 | static inline void dmub_rb_flush_pending(const struct dmub_rb *rb) | |
1040 | { | |
1041 | uint32_t rptr = rb->rptr; | |
1042 | uint32_t wptr = rb->wrpt; | |
1043 | ||
1044 | while (rptr != wptr) { | |
1045 | uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t); | |
34ba432c | 1046 | uint8_t i; |
84034ad4 AK |
1047 | |
1048 | for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) | |
8906e5bc | 1049 | *data++; |
84034ad4 AK |
1050 | |
1051 | rptr += DMUB_RB_CMD_SIZE; | |
1052 | if (rptr >= rb->capacity) | |
1053 | rptr %= rb->capacity; | |
1054 | } | |
1055 | } | |
1056 | ||
1057 | static inline void dmub_rb_init(struct dmub_rb *rb, | |
1058 | struct dmub_rb_init_params *init_params) | |
1059 | { | |
1060 | rb->base_address = init_params->base_address; | |
1061 | rb->capacity = init_params->capacity; | |
1062 | rb->rptr = init_params->read_ptr; | |
1063 | rb->wrpt = init_params->write_ptr; | |
1064 | } | |
1065 | ||
34ba432c AK |
1066 | static inline void dmub_rb_get_return_data(struct dmub_rb *rb, |
1067 | union dmub_rb_cmd *cmd) | |
1068 | { | |
1069 | // Copy rb entry back into command | |
1070 | uint8_t *rd_ptr = (rb->rptr == 0) ? | |
1071 | (uint8_t *)rb->base_address + rb->capacity - DMUB_RB_CMD_SIZE : | |
1072 | (uint8_t *)rb->base_address + rb->rptr - DMUB_RB_CMD_SIZE; | |
1073 | ||
1074 | dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE); | |
1075 | } | |
1076 | ||
84034ad4 AK |
1077 | #if defined(__cplusplus) |
1078 | } | |
1079 | #endif | |
1080 | ||
1081 | //============================================================================== | |
1082 | //</DMUB_RB>==================================================================== | |
1083 | //============================================================================== | |
1084 | ||
7c008829 | 1085 | #endif /* _DMUB_CMD_H_ */ |