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_SRV_H_ |
27 | #define _DMUB_SRV_H_ |
28 | |
29 | /** |
30 | * DOC: DMUB interface and operation |
31 | * |
32 | * DMUB is the interface to the display DMCUB microcontroller on DCN hardware. |
33 | * It delegates hardware initialization and command submission to the |
34 | * microcontroller. DMUB is the shortname for DMCUB. |
35 | * |
36 | * This interface is not thread-safe. Ensure that all access to the interface |
37 | * is properly synchronized by the caller. |
38 | * |
39 | * Initialization and usage of the DMUB service should be done in the |
40 | * steps given below: |
41 | * |
42 | * 1. dmub_srv_create() |
43 | * 2. dmub_srv_has_hw_support() |
44 | * 3. dmub_srv_calc_region_info() |
45 | * 4. dmub_srv_hw_init() |
46 | * |
47 | * The call to dmub_srv_create() is required to use the server. |
48 | * |
49 | * The calls to dmub_srv_has_hw_support() and dmub_srv_calc_region_info() |
50 | * are helpers to query cache window size and allocate framebuffer(s) |
51 | * for the cache windows. |
52 | * |
53 | * The call to dmub_srv_hw_init() programs the DMCUB registers to prepare |
54 | * for command submission. Commands can be queued via dmub_srv_cmd_queue() |
55 | * and executed via dmub_srv_cmd_execute(). |
56 | * |
57 | * If the queue is full the dmub_srv_wait_for_idle() call can be used to |
58 | * wait until the queue has been cleared. |
59 | * |
60 | * Destroying the DMUB service can be done by calling dmub_srv_destroy(). |
61 | * This does not clear DMUB hardware state, only software state. |
62 | * |
63 | * The interface is intended to be standalone and should not depend on any |
64 | * other component within DAL. |
65 | */ |
66 | |
67 | #include "inc/dmub_cmd.h" |
68 | #include "dc/dc_types.h" |
69 | |
70 | #if defined(__cplusplus) |
71 | extern "C" { |
72 | #endif |
73 | |
74 | /* Forward declarations */ |
75 | struct dmub_srv; |
76 | struct dmub_srv_common_regs; |
77 | struct dmub_srv_dcn31_regs; |
78 | |
79 | struct dmcub_trace_buf_entry; |
80 | |
81 | /* enum dmub_window_memory_type - memory location type specification for windows */ |
82 | enum dmub_window_memory_type { |
83 | DMUB_WINDOW_MEMORY_TYPE_FB = 0, |
84 | DMUB_WINDOW_MEMORY_TYPE_GART |
85 | }; |
86 | |
87 | /* enum dmub_status - return code for dmcub functions */ |
88 | enum dmub_status { |
89 | DMUB_STATUS_OK = 0, |
90 | DMUB_STATUS_NO_CTX, |
91 | DMUB_STATUS_QUEUE_FULL, |
92 | DMUB_STATUS_TIMEOUT, |
93 | DMUB_STATUS_INVALID, |
94 | DMUB_STATUS_HW_FAILURE, |
95 | DMUB_STATUS_POWER_STATE_D3 |
96 | }; |
97 | |
98 | /* enum dmub_asic - dmub asic identifier */ |
99 | enum dmub_asic { |
100 | DMUB_ASIC_NONE = 0, |
101 | DMUB_ASIC_DCN20, |
102 | DMUB_ASIC_DCN21, |
103 | DMUB_ASIC_DCN30, |
104 | DMUB_ASIC_DCN301, |
105 | DMUB_ASIC_DCN302, |
106 | DMUB_ASIC_DCN303, |
107 | DMUB_ASIC_DCN31, |
108 | DMUB_ASIC_DCN31B, |
109 | DMUB_ASIC_DCN314, |
110 | DMUB_ASIC_DCN315, |
111 | DMUB_ASIC_DCN316, |
112 | DMUB_ASIC_DCN32, |
113 | DMUB_ASIC_DCN321, |
114 | DMUB_ASIC_DCN35, |
115 | DMUB_ASIC_DCN351, |
116 | DMUB_ASIC_MAX, |
117 | }; |
118 | |
119 | /* enum dmub_window_id - dmub window identifier */ |
120 | enum dmub_window_id { |
121 | DMUB_WINDOW_0_INST_CONST = 0, |
122 | DMUB_WINDOW_1_STACK, |
123 | DMUB_WINDOW_2_BSS_DATA, |
124 | DMUB_WINDOW_3_VBIOS, |
125 | DMUB_WINDOW_4_MAILBOX, |
126 | DMUB_WINDOW_5_TRACEBUFF, |
127 | DMUB_WINDOW_6_FW_STATE, |
128 | DMUB_WINDOW_7_SCRATCH_MEM, |
129 | DMUB_WINDOW_SHARED_STATE, |
130 | DMUB_WINDOW_TOTAL, |
131 | }; |
132 | |
133 | /* enum dmub_notification_type - dmub outbox notification identifier */ |
134 | enum dmub_notification_type { |
135 | DMUB_NOTIFICATION_NO_DATA = 0, |
136 | DMUB_NOTIFICATION_AUX_REPLY, |
137 | DMUB_NOTIFICATION_HPD, |
138 | DMUB_NOTIFICATION_HPD_IRQ, |
139 | DMUB_NOTIFICATION_SET_CONFIG_REPLY, |
140 | DMUB_NOTIFICATION_DPIA_NOTIFICATION, |
141 | DMUB_NOTIFICATION_MAX |
142 | }; |
143 | |
144 | /** |
145 | * DPIA NOTIFICATION Response Type |
146 | */ |
147 | enum dpia_notify_bw_alloc_status { |
148 | |
149 | DPIA_BW_REQ_FAILED = 0, |
150 | DPIA_BW_REQ_SUCCESS, |
151 | DPIA_EST_BW_CHANGED, |
152 | DPIA_BW_ALLOC_CAPS_CHANGED |
153 | }; |
154 | |
155 | /* enum dmub_memory_access_type - memory access method */ |
156 | enum dmub_memory_access_type { |
157 | DMUB_MEMORY_ACCESS_DEFAULT, |
158 | DMUB_MEMORY_ACCESS_CPU = DMUB_MEMORY_ACCESS_DEFAULT, |
159 | DMUB_MEMORY_ACCESS_DMA |
160 | }; |
161 | |
162 | /* enum dmub_power_state type - to track DC power state in dmub_srv */ |
163 | enum dmub_srv_power_state_type { |
164 | DMUB_POWER_STATE_UNDEFINED = 0, |
165 | DMUB_POWER_STATE_D0 = 1, |
166 | DMUB_POWER_STATE_D3 = 8 |
167 | }; |
168 | |
169 | /** |
170 | * struct dmub_region - dmub hw memory region |
171 | * @base: base address for region, must be 256 byte aligned |
172 | * @top: top address for region |
173 | */ |
174 | struct dmub_region { |
175 | uint32_t base; |
176 | uint32_t top; |
177 | }; |
178 | |
179 | /** |
180 | * struct dmub_window - dmub hw cache window |
181 | * @off: offset to the fb memory in gpu address space |
182 | * @r: region in uc address space for cache window |
183 | */ |
184 | struct dmub_window { |
185 | union dmub_addr offset; |
186 | struct dmub_region region; |
187 | }; |
188 | |
189 | /** |
190 | * struct dmub_fb - defines a dmub framebuffer memory region |
191 | * @cpu_addr: cpu virtual address for the region, NULL if invalid |
192 | * @gpu_addr: gpu virtual address for the region, NULL if invalid |
193 | * @size: size of the region in bytes, zero if invalid |
194 | */ |
195 | struct dmub_fb { |
196 | void *cpu_addr; |
197 | uint64_t gpu_addr; |
198 | uint32_t size; |
199 | }; |
200 | |
201 | /** |
202 | * struct dmub_srv_region_params - params used for calculating dmub regions |
203 | * @inst_const_size: size of the fw inst const section |
204 | * @bss_data_size: size of the fw bss data section |
205 | * @vbios_size: size of the vbios data |
206 | * @fw_bss_data: raw firmware bss data section |
207 | */ |
208 | struct dmub_srv_region_params { |
209 | uint32_t inst_const_size; |
210 | uint32_t bss_data_size; |
211 | uint32_t vbios_size; |
212 | const uint8_t *fw_inst_const; |
213 | const uint8_t *fw_bss_data; |
214 | const enum dmub_window_memory_type *window_memory_type; |
215 | }; |
216 | |
217 | /** |
218 | * struct dmub_srv_region_info - output region info from the dmub service |
219 | * @fb_size: required minimum fb size for all regions, aligned to 4096 bytes |
220 | * @num_regions: number of regions used by the dmub service |
221 | * @regions: region info |
222 | * |
223 | * The regions are aligned such that they can be all placed within the |
224 | * same framebuffer but they can also be placed into different framebuffers. |
225 | * |
226 | * The size of each region can be calculated by the caller: |
227 | * size = reg.top - reg.base |
228 | * |
229 | * Care must be taken when performing custom allocations to ensure that each |
230 | * region base address is 256 byte aligned. |
231 | */ |
232 | struct dmub_srv_region_info { |
233 | uint32_t fb_size; |
234 | uint32_t gart_size; |
235 | uint8_t num_regions; |
236 | struct dmub_region regions[DMUB_WINDOW_TOTAL]; |
237 | }; |
238 | |
239 | /** |
240 | * struct dmub_srv_memory_params - parameters used for driver fb setup |
241 | * @region_info: region info calculated by dmub service |
242 | * @cpu_fb_addr: base cpu address for the framebuffer |
243 | * @cpu_inbox_addr: base cpu address for the gart |
244 | * @gpu_fb_addr: base gpu virtual address for the framebuffer |
245 | * @gpu_inbox_addr: base gpu virtual address for the gart |
246 | */ |
247 | struct dmub_srv_memory_params { |
248 | const struct dmub_srv_region_info *region_info; |
249 | void *cpu_fb_addr; |
250 | void *cpu_gart_addr; |
251 | uint64_t gpu_fb_addr; |
252 | uint64_t gpu_gart_addr; |
253 | const enum dmub_window_memory_type *window_memory_type; |
254 | }; |
255 | |
256 | /** |
257 | * struct dmub_srv_fb_info - output fb info from the dmub service |
258 | * @num_fbs: number of required dmub framebuffers |
259 | * @fbs: fb data for each region |
260 | * |
261 | * Output from the dmub service helper that can be used by the |
262 | * driver to prepare dmub_fb that can be passed into the dmub |
263 | * hw init service. |
264 | * |
265 | * Assumes that all regions are within the same framebuffer |
266 | * and have been setup according to the region_info generated |
267 | * by the dmub service. |
268 | */ |
269 | struct dmub_srv_fb_info { |
270 | uint8_t num_fb; |
271 | struct dmub_fb fb[DMUB_WINDOW_TOTAL]; |
272 | }; |
273 | |
274 | /* |
275 | * struct dmub_srv_hw_params - params for dmub hardware initialization |
276 | * @fb: framebuffer info for each region |
277 | * @fb_base: base of the framebuffer aperture |
278 | * @fb_offset: offset of the framebuffer aperture |
279 | * @psp_version: psp version to pass for DMCU init |
280 | * @load_inst_const: true if DMUB should load inst const fw |
281 | */ |
282 | struct dmub_srv_hw_params { |
283 | struct dmub_fb *fb[DMUB_WINDOW_TOTAL]; |
284 | uint64_t fb_base; |
285 | uint64_t fb_offset; |
286 | uint32_t psp_version; |
287 | bool load_inst_const; |
288 | bool skip_panel_power_sequence; |
289 | bool disable_z10; |
290 | bool power_optimization; |
291 | bool dpia_supported; |
292 | bool disable_dpia; |
293 | bool usb4_cm_version; |
294 | bool fw_in_system_memory; |
295 | bool dpia_hpd_int_enable_supported; |
296 | bool disable_clock_gate; |
297 | bool disallow_dispclk_dppclk_ds; |
298 | enum dmub_memory_access_type mem_access_type; |
299 | enum dmub_ips_disable_type disable_ips; |
300 | }; |
301 | |
302 | /** |
303 | * struct dmub_diagnostic_data - Diagnostic data retrieved from DMCUB for |
304 | * debugging purposes, including logging, crash analysis, etc. |
305 | */ |
306 | struct dmub_diagnostic_data { |
307 | uint32_t dmcub_version; |
308 | uint32_t scratch[17]; |
309 | uint32_t pc; |
310 | uint32_t undefined_address_fault_addr; |
311 | uint32_t inst_fetch_fault_addr; |
312 | uint32_t data_write_fault_addr; |
313 | uint32_t inbox1_rptr; |
314 | uint32_t inbox1_wptr; |
315 | uint32_t inbox1_size; |
316 | uint32_t inbox0_rptr; |
317 | uint32_t inbox0_wptr; |
318 | uint32_t inbox0_size; |
319 | uint32_t gpint_datain0; |
320 | uint8_t is_dmcub_enabled : 1; |
321 | uint8_t is_dmcub_soft_reset : 1; |
322 | uint8_t is_dmcub_secure_reset : 1; |
323 | uint8_t is_traceport_en : 1; |
324 | uint8_t is_cw0_enabled : 1; |
325 | uint8_t is_cw6_enabled : 1; |
326 | }; |
327 | |
328 | /** |
329 | * struct dmub_srv_base_funcs - Driver specific base callbacks |
330 | */ |
331 | struct dmub_srv_base_funcs { |
332 | /** |
333 | * @reg_read: |
334 | * |
335 | * Hook for reading a register. |
336 | * |
337 | * Return: The 32-bit register value from the given address. |
338 | */ |
339 | uint32_t (*reg_read)(void *ctx, uint32_t address); |
340 | |
341 | /** |
342 | * @reg_write: |
343 | * |
344 | * Hook for writing a value to the register specified by address. |
345 | */ |
346 | void (*reg_write)(void *ctx, uint32_t address, uint32_t value); |
347 | }; |
348 | |
349 | /** |
350 | * struct dmub_srv_hw_funcs - hardware sequencer funcs for dmub |
351 | */ |
352 | struct dmub_srv_hw_funcs { |
353 | /* private: internal use only */ |
354 | |
355 | void (*init)(struct dmub_srv *dmub); |
356 | |
357 | void (*reset)(struct dmub_srv *dmub); |
358 | |
359 | void (*reset_release)(struct dmub_srv *dmub); |
360 | |
361 | void (*backdoor_load)(struct dmub_srv *dmub, |
362 | const struct dmub_window *cw0, |
363 | const struct dmub_window *cw1); |
364 | |
365 | void (*backdoor_load_zfb_mode)(struct dmub_srv *dmub, |
366 | const struct dmub_window *cw0, |
367 | const struct dmub_window *cw1); |
368 | void (*setup_windows)(struct dmub_srv *dmub, |
369 | const struct dmub_window *cw2, |
370 | const struct dmub_window *cw3, |
371 | const struct dmub_window *cw4, |
372 | const struct dmub_window *cw5, |
373 | const struct dmub_window *cw6, |
374 | const struct dmub_window *region6); |
375 | |
376 | void (*setup_mailbox)(struct dmub_srv *dmub, |
377 | const struct dmub_region *inbox1); |
378 | |
379 | uint32_t (*get_inbox1_wptr)(struct dmub_srv *dmub); |
380 | |
381 | uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub); |
382 | |
383 | void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset); |
384 | |
385 | void (*setup_out_mailbox)(struct dmub_srv *dmub, |
386 | const struct dmub_region *outbox1); |
387 | |
388 | uint32_t (*get_outbox1_wptr)(struct dmub_srv *dmub); |
389 | |
390 | void (*set_outbox1_rptr)(struct dmub_srv *dmub, uint32_t rptr_offset); |
391 | |
392 | void (*setup_outbox0)(struct dmub_srv *dmub, |
393 | const struct dmub_region *outbox0); |
394 | |
395 | uint32_t (*get_outbox0_wptr)(struct dmub_srv *dmub); |
396 | |
397 | void (*set_outbox0_rptr)(struct dmub_srv *dmub, uint32_t rptr_offset); |
398 | |
399 | uint32_t (*emul_get_inbox1_rptr)(struct dmub_srv *dmub); |
400 | |
401 | void (*emul_set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset); |
402 | |
403 | bool (*is_supported)(struct dmub_srv *dmub); |
404 | |
405 | bool (*is_psrsu_supported)(struct dmub_srv *dmub); |
406 | |
407 | bool (*is_hw_init)(struct dmub_srv *dmub); |
408 | bool (*is_hw_powered_up)(struct dmub_srv *dmub); |
409 | |
410 | void (*enable_dmub_boot_options)(struct dmub_srv *dmub, |
411 | const struct dmub_srv_hw_params *params); |
412 | |
413 | void (*skip_dmub_panel_power_sequence)(struct dmub_srv *dmub, bool skip); |
414 | |
415 | union dmub_fw_boot_status (*get_fw_status)(struct dmub_srv *dmub); |
416 | |
417 | union dmub_fw_boot_options (*get_fw_boot_option)(struct dmub_srv *dmub); |
418 | |
419 | void (*set_gpint)(struct dmub_srv *dmub, |
420 | union dmub_gpint_data_register reg); |
421 | |
422 | bool (*is_gpint_acked)(struct dmub_srv *dmub, |
423 | union dmub_gpint_data_register reg); |
424 | |
425 | uint32_t (*get_gpint_response)(struct dmub_srv *dmub); |
426 | |
427 | uint32_t (*get_gpint_dataout)(struct dmub_srv *dmub); |
428 | |
429 | void (*configure_dmub_in_system_memory)(struct dmub_srv *dmub); |
430 | void (*clear_inbox0_ack_register)(struct dmub_srv *dmub); |
431 | uint32_t (*read_inbox0_ack_register)(struct dmub_srv *dmub); |
432 | void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data); |
433 | uint32_t (*get_current_time)(struct dmub_srv *dmub); |
434 | |
435 | void (*get_diagnostic_data)(struct dmub_srv *dmub, struct dmub_diagnostic_data *dmub_oca); |
436 | |
437 | bool (*should_detect)(struct dmub_srv *dmub); |
438 | void (*init_reg_offsets)(struct dmub_srv *dmub, struct dc_context *ctx); |
439 | |
440 | void (*subvp_save_surf_addr)(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index); |
441 | }; |
442 | |
443 | /** |
444 | * struct dmub_srv_create_params - params for dmub service creation |
445 | * @base_funcs: driver supplied base routines |
446 | * @hw_funcs: optional overrides for hw funcs |
447 | * @user_ctx: context data for callback funcs |
448 | * @asic: driver supplied asic |
449 | * @fw_version: the current firmware version, if any |
450 | * @is_virtual: false for hw support only |
451 | */ |
452 | struct dmub_srv_create_params { |
453 | struct dmub_srv_base_funcs funcs; |
454 | struct dmub_srv_hw_funcs *hw_funcs; |
455 | void *user_ctx; |
456 | enum dmub_asic asic; |
457 | uint32_t fw_version; |
458 | bool is_virtual; |
459 | }; |
460 | |
461 | /** |
462 | * struct dmub_srv - software state for dmcub |
463 | * @asic: dmub asic identifier |
464 | * @user_ctx: user provided context for the dmub_srv |
465 | * @fw_version: the current firmware version, if any |
466 | * @is_virtual: false if hardware support only |
467 | * @shared_state: dmub shared state between firmware and driver |
468 | * @fw_state: dmub firmware state pointer |
469 | */ |
470 | struct dmub_srv { |
471 | enum dmub_asic asic; |
472 | void *user_ctx; |
473 | uint32_t fw_version; |
474 | bool is_virtual; |
475 | struct dmub_fb scratch_mem_fb; |
476 | volatile struct dmub_shared_state_feature_block *shared_state; |
477 | volatile const struct dmub_fw_state *fw_state; |
478 | |
479 | /* private: internal use only */ |
480 | const struct dmub_srv_common_regs *regs; |
481 | const struct dmub_srv_dcn31_regs *regs_dcn31; |
482 | struct dmub_srv_dcn32_regs *regs_dcn32; |
483 | struct dmub_srv_dcn35_regs *regs_dcn35; |
484 | |
485 | struct dmub_srv_base_funcs funcs; |
486 | struct dmub_srv_hw_funcs hw_funcs; |
487 | struct dmub_rb inbox1_rb; |
488 | uint32_t inbox1_last_wptr; |
489 | /** |
490 | * outbox1_rb is accessed without locks (dal & dc) |
491 | * and to be used only in dmub_srv_stat_get_notification() |
492 | */ |
493 | struct dmub_rb outbox1_rb; |
494 | |
495 | struct dmub_rb outbox0_rb; |
496 | |
497 | bool sw_init; |
498 | bool hw_init; |
499 | |
500 | uint64_t fb_base; |
501 | uint64_t fb_offset; |
502 | uint32_t psp_version; |
503 | |
504 | /* Feature capabilities reported by fw */ |
505 | struct dmub_feature_caps feature_caps; |
506 | struct dmub_visual_confirm_color visual_confirm_color; |
507 | |
508 | enum dmub_srv_power_state_type power_state; |
509 | }; |
510 | |
511 | /** |
512 | * struct dmub_notification - dmub notification data |
513 | * @type: dmub notification type |
514 | * @link_index: link index to identify aux connection |
515 | * @result: USB4 status returned from dmub |
516 | * @pending_notification: Indicates there are other pending notifications |
517 | * @aux_reply: aux reply |
518 | * @hpd_status: hpd status |
519 | * @bw_alloc_reply: BW Allocation reply from CM/DPIA |
520 | */ |
521 | struct dmub_notification { |
522 | enum dmub_notification_type type; |
523 | uint8_t link_index; |
524 | uint8_t result; |
525 | bool pending_notification; |
526 | union { |
527 | struct aux_reply_data aux_reply; |
528 | enum dp_hpd_status hpd_status; |
529 | enum set_config_status sc_status; |
530 | /** |
531 | * DPIA notification command. |
532 | */ |
533 | struct dmub_rb_cmd_dpia_notification dpia_notification; |
534 | }; |
535 | }; |
536 | |
537 | /** |
538 | * DMUB firmware version helper macro - useful for checking if the version |
539 | * of a firmware to know if feature or functionality is supported or present. |
540 | */ |
541 | #define DMUB_FW_VERSION(major, minor, revision) \ |
542 | ((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | (((revision) & 0xFF) << 8)) |
543 | |
544 | /** |
545 | * dmub_srv_create() - creates the DMUB service. |
546 | * @dmub: the dmub service |
547 | * @params: creation parameters for the service |
548 | * |
549 | * Return: |
550 | * DMUB_STATUS_OK - success |
551 | * DMUB_STATUS_INVALID - unspecified error |
552 | */ |
553 | enum dmub_status dmub_srv_create(struct dmub_srv *dmub, |
554 | const struct dmub_srv_create_params *params); |
555 | |
556 | /** |
557 | * dmub_srv_destroy() - destroys the DMUB service. |
558 | * @dmub: the dmub service |
559 | */ |
560 | void dmub_srv_destroy(struct dmub_srv *dmub); |
561 | |
562 | /** |
563 | * dmub_srv_calc_region_info() - retreives region info from the dmub service |
564 | * @dmub: the dmub service |
565 | * @params: parameters used to calculate region locations |
566 | * @info_out: the output region info from dmub |
567 | * |
568 | * Calculates the base and top address for all relevant dmub regions |
569 | * using the parameters given (if any). |
570 | * |
571 | * Return: |
572 | * DMUB_STATUS_OK - success |
573 | * DMUB_STATUS_INVALID - unspecified error |
574 | */ |
575 | enum dmub_status |
576 | dmub_srv_calc_region_info(struct dmub_srv *dmub, |
577 | const struct dmub_srv_region_params *params, |
578 | struct dmub_srv_region_info *out); |
579 | |
580 | /** |
581 | * dmub_srv_calc_region_info() - retreives fb info from the dmub service |
582 | * @dmub: the dmub service |
583 | * @params: parameters used to calculate fb locations |
584 | * @info_out: the output fb info from dmub |
585 | * |
586 | * Calculates the base and top address for all relevant dmub regions |
587 | * using the parameters given (if any). |
588 | * |
589 | * Return: |
590 | * DMUB_STATUS_OK - success |
591 | * DMUB_STATUS_INVALID - unspecified error |
592 | */ |
593 | enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, |
594 | const struct dmub_srv_memory_params *params, |
595 | struct dmub_srv_fb_info *out); |
596 | |
597 | /** |
598 | * dmub_srv_has_hw_support() - returns hw support state for dmcub |
599 | * @dmub: the dmub service |
600 | * @is_supported: hw support state |
601 | * |
602 | * Queries the hardware for DMCUB support and returns the result. |
603 | * |
604 | * Can be called before dmub_srv_hw_init(). |
605 | * |
606 | * Return: |
607 | * DMUB_STATUS_OK - success |
608 | * DMUB_STATUS_INVALID - unspecified error |
609 | */ |
610 | enum dmub_status dmub_srv_has_hw_support(struct dmub_srv *dmub, |
611 | bool *is_supported); |
612 | |
613 | /** |
614 | * dmub_srv_is_hw_init() - returns hardware init state |
615 | * |
616 | * Return: |
617 | * DMUB_STATUS_OK - success |
618 | * DMUB_STATUS_INVALID - unspecified error |
619 | */ |
620 | enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init); |
621 | |
622 | /** |
623 | * dmub_srv_hw_init() - initializes the underlying DMUB hardware |
624 | * @dmub: the dmub service |
625 | * @params: params for hardware initialization |
626 | * |
627 | * Resets the DMUB hardware and performs backdoor loading of the |
628 | * required cache regions based on the input framebuffer regions. |
629 | * |
630 | * Return: |
631 | * DMUB_STATUS_OK - success |
632 | * DMUB_STATUS_NO_CTX - dmcub context not initialized |
633 | * DMUB_STATUS_INVALID - unspecified error |
634 | */ |
635 | enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub, |
636 | const struct dmub_srv_hw_params *params); |
637 | |
638 | /** |
639 | * dmub_srv_hw_reset() - puts the DMUB hardware in reset state if initialized |
640 | * @dmub: the dmub service |
641 | * |
642 | * Before destroying the DMUB service or releasing the backing framebuffer |
643 | * memory we'll need to put the DMCUB into reset first. |
644 | * |
645 | * A subsequent call to dmub_srv_hw_init() will re-enable the DMCUB. |
646 | * |
647 | * Return: |
648 | * DMUB_STATUS_OK - success |
649 | * DMUB_STATUS_INVALID - unspecified error |
650 | */ |
651 | enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub); |
652 | |
653 | /** |
654 | * dmub_srv_sync_inbox1() - sync sw state with hw state |
655 | * @dmub: the dmub service |
656 | * |
657 | * Sync sw state with hw state when resume from S0i3 |
658 | * |
659 | * Return: |
660 | * DMUB_STATUS_OK - success |
661 | * DMUB_STATUS_INVALID - unspecified error |
662 | */ |
663 | enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub); |
664 | |
665 | /** |
666 | * dmub_srv_cmd_queue() - queues a command to the DMUB |
667 | * @dmub: the dmub service |
668 | * @cmd: the command to queue |
669 | * |
670 | * Queues a command to the DMUB service but does not begin execution |
671 | * immediately. |
672 | * |
673 | * Return: |
674 | * DMUB_STATUS_OK - success |
675 | * DMUB_STATUS_QUEUE_FULL - no remaining room in queue |
676 | * DMUB_STATUS_INVALID - unspecified error |
677 | */ |
678 | enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, |
679 | const union dmub_rb_cmd *cmd); |
680 | |
681 | /** |
682 | * dmub_srv_cmd_execute() - Executes a queued sequence to the dmub |
683 | * @dmub: the dmub service |
684 | * |
685 | * Begins execution of queued commands on the dmub. |
686 | * |
687 | * Return: |
688 | * DMUB_STATUS_OK - success |
689 | * DMUB_STATUS_INVALID - unspecified error |
690 | */ |
691 | enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub); |
692 | |
693 | /** |
694 | * dmub_srv_wait_for_hw_pwr_up() - Waits for firmware hardware power up is completed |
695 | * @dmub: the dmub service |
696 | * @timeout_us: the maximum number of microseconds to wait |
697 | * |
698 | * Waits until firmware hardware is powered up. The maximum |
699 | * wait time is given in microseconds to prevent spinning forever. |
700 | * |
701 | * Return: |
702 | * DMUB_STATUS_OK - success |
703 | * DMUB_STATUS_TIMEOUT - timed out |
704 | * DMUB_STATUS_INVALID - unspecified error |
705 | */ |
706 | enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub, |
707 | uint32_t timeout_us); |
708 | |
709 | bool dmub_srv_is_hw_pwr_up(struct dmub_srv *dmub); |
710 | |
711 | /** |
712 | * dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete |
713 | * @dmub: the dmub service |
714 | * @timeout_us: the maximum number of microseconds to wait |
715 | * |
716 | * Waits until firmware has been autoloaded by the DMCUB. The maximum |
717 | * wait time is given in microseconds to prevent spinning forever. |
718 | * |
719 | * On ASICs without firmware autoload support this function will return |
720 | * immediately. |
721 | * |
722 | * Return: |
723 | * DMUB_STATUS_OK - success |
724 | * DMUB_STATUS_TIMEOUT - wait for phy init timed out |
725 | * DMUB_STATUS_INVALID - unspecified error |
726 | */ |
727 | enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub, |
728 | uint32_t timeout_us); |
729 | |
730 | /** |
731 | * dmub_srv_wait_for_phy_init() - Waits for DMUB PHY init to complete |
732 | * @dmub: the dmub service |
733 | * @timeout_us: the maximum number of microseconds to wait |
734 | * |
735 | * Waits until the PHY has been initialized by the DMUB. The maximum |
736 | * wait time is given in microseconds to prevent spinning forever. |
737 | * |
738 | * On ASICs without PHY init support this function will return |
739 | * immediately. |
740 | * |
741 | * Return: |
742 | * DMUB_STATUS_OK - success |
743 | * DMUB_STATUS_TIMEOUT - wait for phy init timed out |
744 | * DMUB_STATUS_INVALID - unspecified error |
745 | */ |
746 | enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub, |
747 | uint32_t timeout_us); |
748 | |
749 | /** |
750 | * dmub_srv_wait_for_idle() - Waits for the DMUB to be idle |
751 | * @dmub: the dmub service |
752 | * @timeout_us: the maximum number of microseconds to wait |
753 | * |
754 | * Waits until the DMUB buffer is empty and all commands have |
755 | * finished processing. The maximum wait time is given in |
756 | * microseconds to prevent spinning forever. |
757 | * |
758 | * Return: |
759 | * DMUB_STATUS_OK - success |
760 | * DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out |
761 | * DMUB_STATUS_INVALID - unspecified error |
762 | */ |
763 | enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub, |
764 | uint32_t timeout_us); |
765 | |
766 | /** |
767 | * dmub_srv_send_gpint_command() - Sends a GPINT based command. |
768 | * @dmub: the dmub service |
769 | * @command_code: the command code to send |
770 | * @param: the command parameter to send |
771 | * @timeout_us: the maximum number of microseconds to wait |
772 | * |
773 | * Sends a command via the general purpose interrupt (GPINT). |
774 | * Waits for the number of microseconds specified by timeout_us |
775 | * for the command ACK before returning. |
776 | * |
777 | * Can be called after software initialization. |
778 | * |
779 | * Return: |
780 | * DMUB_STATUS_OK - success |
781 | * DMUB_STATUS_TIMEOUT - wait for ACK timed out |
782 | * DMUB_STATUS_INVALID - unspecified error |
783 | */ |
784 | enum dmub_status |
785 | dmub_srv_send_gpint_command(struct dmub_srv *dmub, |
786 | enum dmub_gpint_command command_code, |
787 | uint16_t param, uint32_t timeout_us); |
788 | |
789 | /** |
790 | * dmub_srv_get_gpint_response() - Queries the GPINT response. |
791 | * @dmub: the dmub service |
792 | * @response: the response for the last GPINT |
793 | * |
794 | * Returns the response code for the last GPINT interrupt. |
795 | * |
796 | * Can be called after software initialization. |
797 | * |
798 | * Return: |
799 | * DMUB_STATUS_OK - success |
800 | * DMUB_STATUS_INVALID - unspecified error |
801 | */ |
802 | enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub, |
803 | uint32_t *response); |
804 | |
805 | /** |
806 | * dmub_srv_get_gpint_dataout() - Queries the GPINT DATAOUT. |
807 | * @dmub: the dmub service |
808 | * @dataout: the data for the GPINT DATAOUT |
809 | * |
810 | * Returns the response code for the last GPINT DATAOUT interrupt. |
811 | * |
812 | * Can be called after software initialization. |
813 | * |
814 | * Return: |
815 | * DMUB_STATUS_OK - success |
816 | * DMUB_STATUS_INVALID - unspecified error |
817 | */ |
818 | enum dmub_status dmub_srv_get_gpint_dataout(struct dmub_srv *dmub, |
819 | uint32_t *dataout); |
820 | |
821 | /** |
822 | * dmub_flush_buffer_mem() - Read back entire frame buffer region. |
823 | * This ensures that the write from x86 has been flushed and will not |
824 | * hang the DMCUB. |
825 | * @fb: frame buffer to flush |
826 | * |
827 | * Can be called after software initialization. |
828 | */ |
829 | void dmub_flush_buffer_mem(const struct dmub_fb *fb); |
830 | |
831 | /** |
832 | * dmub_srv_get_fw_boot_status() - Returns the DMUB boot status bits. |
833 | * |
834 | * @dmub: the dmub service |
835 | * @status: out pointer for firmware status |
836 | * |
837 | * Return: |
838 | * DMUB_STATUS_OK - success |
839 | * DMUB_STATUS_INVALID - unspecified error, unsupported |
840 | */ |
841 | enum dmub_status dmub_srv_get_fw_boot_status(struct dmub_srv *dmub, |
842 | union dmub_fw_boot_status *status); |
843 | |
844 | enum dmub_status dmub_srv_get_fw_boot_option(struct dmub_srv *dmub, |
845 | union dmub_fw_boot_options *option); |
846 | |
847 | enum dmub_status dmub_srv_cmd_with_reply_data(struct dmub_srv *dmub, |
848 | union dmub_rb_cmd *cmd); |
849 | |
850 | enum dmub_status dmub_srv_set_skip_panel_power_sequence(struct dmub_srv *dmub, |
851 | bool skip); |
852 | |
853 | bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry); |
854 | |
855 | bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data); |
856 | |
857 | bool dmub_srv_should_detect(struct dmub_srv *dmub); |
858 | |
859 | /** |
860 | * dmub_srv_send_inbox0_cmd() - Send command to DMUB using INBOX0 |
861 | * @dmub: the dmub service |
862 | * @data: the data to be sent in the INBOX0 command |
863 | * |
864 | * Send command by writing directly to INBOX0 WPTR |
865 | * |
866 | * Return: |
867 | * DMUB_STATUS_OK - success |
868 | * DMUB_STATUS_INVALID - hw_init false or hw function does not exist |
869 | */ |
870 | enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data); |
871 | |
872 | /** |
873 | * dmub_srv_wait_for_inbox0_ack() - wait for DMUB to ACK INBOX0 command |
874 | * @dmub: the dmub service |
875 | * @timeout_us: the maximum number of microseconds to wait |
876 | * |
877 | * Wait for DMUB to ACK the INBOX0 message |
878 | * |
879 | * Return: |
880 | * DMUB_STATUS_OK - success |
881 | * DMUB_STATUS_INVALID - hw_init false or hw function does not exist |
882 | * DMUB_STATUS_TIMEOUT - wait for ack timed out |
883 | */ |
884 | enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t timeout_us); |
885 | |
886 | /** |
887 | * dmub_srv_wait_for_inbox0_ack() - clear ACK register for INBOX0 |
888 | * @dmub: the dmub service |
889 | * |
890 | * Clear ACK register for INBOX0 |
891 | * |
892 | * Return: |
893 | * DMUB_STATUS_OK - success |
894 | * DMUB_STATUS_INVALID - hw_init false or hw function does not exist |
895 | */ |
896 | enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub); |
897 | |
898 | /** |
899 | * dmub_srv_subvp_save_surf_addr() - Save primary and meta address for subvp on each flip |
900 | * @dmub: The dmub service |
901 | * @addr: The surface address to be programmed on the current flip |
902 | * @subvp_index: Index of subvp pipe, indicates which subvp pipe the address should be saved for |
903 | * |
904 | * Function to save the surface flip addr into scratch registers. This is to fix a race condition |
905 | * between FW and driver reading / writing to the surface address at the same time. This is |
906 | * required because there is no EARLIEST_IN_USE_META. |
907 | * |
908 | * Return: |
909 | * void |
910 | */ |
911 | void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index); |
912 | |
913 | /** |
914 | * dmub_srv_set_power_state() - Track DC power state in dmub_srv |
915 | * @dmub: The dmub service |
916 | * @power_state: DC power state setting |
917 | * |
918 | * Store DC power state in dmub_srv. If dmub_srv is in D3, then don't send messages to DMUB |
919 | * |
920 | * Return: |
921 | * void |
922 | */ |
923 | void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state); |
924 | |
925 | #if defined(__cplusplus) |
926 | } |
927 | #endif |
928 | |
929 | #endif /* _DMUB_SRV_H_ */ |
930 | |