xref: /linux/drivers/gpu/drm/amd/display/dmub/dmub_srv.h (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright 2019-2026 Advanced Micro Devices, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors: AMD
24  *
25  */
26 
27 #ifndef _DMUB_SRV_H_
28 #define _DMUB_SRV_H_
29 
30 /**
31  * DOC: DMUB interface and operation
32  *
33  * DMUB is the interface to the display DMCUB microcontroller on DCN hardware.
34  * It delegates hardware initialization and command submission to the
35  * microcontroller. DMUB is the shortname for DMCUB.
36  *
37  * This interface is not thread-safe. Ensure that all access to the interface
38  * is properly synchronized by the caller.
39  *
40  * Initialization and usage of the DMUB service should be done in the
41  * steps given below:
42  *
43  * 1. dmub_srv_create()
44  * 2. dmub_srv_has_hw_support()
45  * 3. dmub_srv_calc_region_info()
46  * 4. dmub_srv_hw_init()
47  *
48  * The call to dmub_srv_create() is required to use the server.
49  *
50  * The calls to dmub_srv_has_hw_support() and dmub_srv_calc_region_info()
51  * are helpers to query cache window size and allocate framebuffer(s)
52  * for the cache windows.
53  *
54  * The call to dmub_srv_hw_init() programs the DMCUB registers to prepare
55  * for command submission. Commands can be queued via dmub_srv_fb_cmd_queue()
56  * and executed via dmub_srv_fb_cmd_execute().
57  *
58  * If the queue is full the dmub_srv_wait_for_idle() call can be used to
59  * wait until the queue has been cleared.
60  *
61  * Destroying the DMUB service can be done by calling dmub_srv_destroy().
62  * This does not clear DMUB hardware state, only software state.
63  *
64  * The interface is intended to be standalone and should not depend on any
65  * other component within DAL.
66  */
67 
68 #include "inc/dmub_cmd.h"
69 #include "dc/dc_types.h"
70 
71 #define DMUB_PC_SNAPSHOT_COUNT 10
72 
73 /* Default tracebuffer size if meta is absent. */
74 #define DMUB_TRACE_BUFFER_SIZE (64 * 1024)
75 
76 #define PSP_HEADER_BYTES_256 0x100 // 256 bytes
77 #define PSP_FOOTER_BYTES_256 0x100 // 256 bytes
78 
79 /* Forward declarations */
80 struct dmub_srv;
81 struct dmub_srv_common_regs;
82 struct dmub_srv_dcn31_regs;
83 
84 struct dmcub_trace_buf_entry;
85 
86 /* enum dmub_window_memory_type - memory location type specification for windows */
87 enum dmub_window_memory_type {
88 	DMUB_WINDOW_MEMORY_TYPE_FB = 0,
89 	DMUB_WINDOW_MEMORY_TYPE_GART
90 };
91 
92 /* enum dmub_status - return code for dmcub functions */
93 enum dmub_status {
94 	DMUB_STATUS_OK = 0,
95 	DMUB_STATUS_NO_CTX,
96 	DMUB_STATUS_QUEUE_FULL,
97 	DMUB_STATUS_TIMEOUT,
98 	DMUB_STATUS_INVALID,
99 	DMUB_STATUS_HW_FAILURE,
100 	DMUB_STATUS_POWER_STATE_D3
101 };
102 
103 /* enum dmub_asic - dmub asic identifier */
104 enum dmub_asic {
105 	DMUB_ASIC_NONE = 0,
106 	DMUB_ASIC_DCN20,
107 	DMUB_ASIC_DCN21,
108 	DMUB_ASIC_DCN30,
109 	DMUB_ASIC_DCN301,
110 	DMUB_ASIC_DCN302,
111 	DMUB_ASIC_DCN303,
112 	DMUB_ASIC_DCN31,
113 	DMUB_ASIC_DCN31B,
114 	DMUB_ASIC_DCN314,
115 	DMUB_ASIC_DCN315,
116 	DMUB_ASIC_DCN316,
117 	DMUB_ASIC_DCN32,
118 	DMUB_ASIC_DCN321,
119 	DMUB_ASIC_DCN35,
120 	DMUB_ASIC_DCN351,
121 	DMUB_ASIC_DCN36,
122 	DMUB_ASIC_DCN401,
123 	DMUB_ASIC_DCN42,
124 	DMUB_ASIC_DCN42B,
125 	DMUB_ASIC_DCN60,
126 
127 	DMUB_ASIC_MAX,
128 };
129 
130 /* enum dmub_window_id - dmub window identifier */
131 enum dmub_window_id {
132 	DMUB_WINDOW_0_INST_CONST = 0,
133 	DMUB_WINDOW_1_STACK,
134 	DMUB_WINDOW_2_BSS_DATA,
135 	DMUB_WINDOW_3_VBIOS,
136 	DMUB_WINDOW_4_MAILBOX,
137 	DMUB_WINDOW_5_TRACEBUFF,
138 	DMUB_WINDOW_6_FW_STATE,
139 	DMUB_WINDOW_7_SCRATCH_MEM,
140 	DMUB_WINDOW_IB_MEM,
141 	DMUB_WINDOW_SHARED_STATE,
142 	DMUB_WINDOW_LSDMA_BUFFER,
143 	DMUB_WINDOW_CURSOR_OFFLOAD,
144 	DMUB_WINDOW_TOTAL,
145 };
146 
147 /* enum dmub_notification_type - dmub outbox notification identifier */
148 enum dmub_notification_type {
149 	DMUB_NOTIFICATION_NO_DATA = 0,
150 	DMUB_NOTIFICATION_AUX_REPLY,
151 	DMUB_NOTIFICATION_HPD,
152 	DMUB_NOTIFICATION_HPD_IRQ,
153 	DMUB_NOTIFICATION_SET_CONFIG_REPLY,
154 	DMUB_NOTIFICATION_DPIA_NOTIFICATION,
155 	DMUB_NOTIFICATION_HPD_SENSE_NOTIFY,
156 	DMUB_NOTIFICATION_FUSED_IO,
157 	DMUB_NOTIFICATION_MAX
158 };
159 
160 /**
161  * DPIA NOTIFICATION Response Type
162  */
163 enum dpia_notify_bw_alloc_status {
164 
165 	DPIA_BW_REQ_FAILED = 0,
166 	DPIA_BW_REQ_SUCCESS,
167 	DPIA_EST_BW_CHANGED,
168 	DPIA_BW_ALLOC_CAPS_CHANGED
169 };
170 
171 /* enum dmub_memory_access_type - memory access method */
172 enum dmub_memory_access_type {
173 	DMUB_MEMORY_ACCESS_DEFAULT,
174 	DMUB_MEMORY_ACCESS_CPU = DMUB_MEMORY_ACCESS_DEFAULT,
175 	DMUB_MEMORY_ACCESS_DMA
176 };
177 
178 /* enum dmub_power_state type - to track DC power state in dmub_srv */
179 enum dmub_srv_power_state_type {
180 	DMUB_POWER_STATE_UNDEFINED = 0,
181 	DMUB_POWER_STATE_D0 = 1,
182 	DMUB_POWER_STATE_D3 = 8
183 };
184 
185 /* enum dmub_inbox_cmd_interface type - defines default interface for host->dmub commands */
186 enum dmub_inbox_cmd_interface_type {
187 	DMUB_CMD_INTERFACE_DEFAULT = 0,
188 	DMUB_CMD_INTERFACE_FB = 1,
189 	DMUB_CMD_INTERFACE_REG = 2,
190 };
191 
192 /**
193  * struct dmub_region - dmub hw memory region
194  * @base: base address for region, must be 256 byte aligned
195  * @top: top address for region
196  */
197 struct dmub_region {
198 	uint32_t base;
199 	uint32_t top;
200 };
201 
202 /**
203  * struct dmub_window - dmub hw cache window
204  * @off: offset to the fb memory in gpu address space
205  * @r: region in uc address space for cache window
206  */
207 struct dmub_window {
208 	union dmub_addr offset;
209 	struct dmub_region region;
210 };
211 
212 /**
213  * struct dmub_fb - defines a dmub framebuffer memory region
214  * @cpu_addr: cpu virtual address for the region, NULL if invalid
215  * @gpu_addr: gpu virtual address for the region, NULL if invalid
216  * @size: size of the region in bytes, zero if invalid
217  */
218 struct dmub_fb {
219 	void *cpu_addr;
220 	uint64_t gpu_addr;
221 	uint32_t size;
222 };
223 
224 /**
225  * struct dmub_srv_region_params - params used for calculating dmub regions
226  * @inst_const_size: size of the fw inst const section
227  * @bss_data_size: size of the fw bss data section
228  * @vbios_size: size of the vbios data
229  * @fw_bss_data: raw firmware bss data section
230  */
231 struct dmub_srv_region_params {
232 	uint32_t inst_const_size;
233 	uint32_t bss_data_size;
234 	uint32_t vbios_size;
235 	const uint8_t *fw_inst_const;
236 	const uint8_t *fw_bss_data;
237 	const enum dmub_window_memory_type *window_memory_type;
238 	const struct dmub_fw_meta_info *fw_info;
239 };
240 
241 /**
242  * struct dmub_srv_fw_meta_info_params - params used for fetching fw meta info from fw_image
243  * @inst_const_size: size of the fw inst const section
244  * @bss_data_size: size of the fw bss data section
245  * @fw_inst_const: raw firmware inst const section
246  * @fw_bss_data: raw firmware bss data section
247  * @custom_psp_footer_size: custom psp footer size to use when indexing for fw meta info
248  */
249 struct dmub_srv_fw_meta_info_params {
250 	uint32_t inst_const_size;
251 	uint32_t bss_data_size;
252 	const uint8_t *fw_inst_const;
253 	const uint8_t *fw_bss_data;
254 	uint32_t custom_psp_footer_size;
255 };
256 
257 /**
258  * struct dmub_srv_region_info - output region info from the dmub service
259  * @fb_size: required minimum fb size for all regions, aligned to 4096 bytes
260  * @num_regions: number of regions used by the dmub service
261  * @regions: region info
262  *
263  * The regions are aligned such that they can be all placed within the
264  * same framebuffer but they can also be placed into different framebuffers.
265  *
266  * The size of each region can be calculated by the caller:
267  * size = reg.top - reg.base
268  *
269  * Care must be taken when performing custom allocations to ensure that each
270  * region base address is 256 byte aligned.
271  */
272 struct dmub_srv_region_info {
273 	uint32_t fb_size;
274 	uint32_t gart_size;
275 	uint8_t num_regions;
276 	struct dmub_region regions[DMUB_WINDOW_TOTAL];
277 	uint32_t verified_psp_footer_size;
278 };
279 
280 /**
281  * struct dmub_srv_memory_params - parameters used for driver fb setup
282  * @region_info: region info calculated by dmub service
283  * @cpu_fb_addr: base cpu address for the framebuffer
284  * @cpu_inbox_addr: base cpu address for the gart
285  * @gpu_fb_addr: base gpu virtual address for the framebuffer
286  * @gpu_inbox_addr: base gpu virtual address for the gart
287  */
288 struct dmub_srv_memory_params {
289 	const struct dmub_srv_region_info *region_info;
290 	void *cpu_fb_addr;
291 	void *cpu_gart_addr;
292 	uint64_t gpu_fb_addr;
293 	uint64_t gpu_gart_addr;
294 	const enum dmub_window_memory_type *window_memory_type;
295 };
296 
297 /**
298  * struct dmub_srv_fb_info - output fb info from the dmub service
299  * @num_fbs: number of required dmub framebuffers
300  * @fbs: fb data for each region
301  *
302  * Output from the dmub service helper that can be used by the
303  * driver to prepare dmub_fb that can be passed into the dmub
304  * hw init service.
305  *
306  * Assumes that all regions are within the same framebuffer
307  * and have been setup according to the region_info generated
308  * by the dmub service.
309  */
310 struct dmub_srv_fb_info {
311 	uint8_t num_fb;
312 	struct dmub_fb fb[DMUB_WINDOW_TOTAL];
313 };
314 
315 /**
316  * struct dmub_soc_fb_info - relevant addresses from the frame buffer
317  * @fb_base: base of the framebuffer aperture
318  * @fb_offset: offset of the framebuffer aperture
319  */
320 struct dmub_soc_fb_info {
321 	uint64_t fb_base;
322 	uint64_t fb_offset;
323 	uint32_t alt_channel_region_size[2];
324 	uint64_t alt_channel_region_base[2]; /* mc address */
325 };
326 
327 /*
328  * struct dmub_srv_hw_params - params for dmub hardware initialization
329  * @fb: framebuffer info for each region
330  * @fb_base: base of the framebuffer aperture
331  * @fb_offset: offset of the framebuffer aperture
332  * @psp_version: psp version to pass for DMCU init
333  * @load_inst_const: true if DMUB should load inst const fw
334  */
335 struct dmub_srv_hw_params {
336 	struct dmub_srv_fb_info *fb_info;
337 	struct dmub_soc_fb_info soc_fb_info;
338 	uint32_t psp_version;
339 	bool load_inst_const;
340 	bool skip_panel_power_sequence;
341 	bool disable_z10;
342 	bool power_optimization;
343 	bool dpia_supported;
344 	bool disable_dpia;
345 	bool usb4_cm_version;
346 	bool fw_in_system_memory;
347 	bool dpia_hpd_int_enable_supported;
348 	bool disable_clock_gate;
349 	bool disallow_dispclk_dppclk_ds;
350 	bool ips_sequential_ono;
351 	enum dmub_memory_access_type mem_access_type;
352 	enum dmub_ips_disable_type disable_ips;
353 	bool disallow_phy_access;
354 	bool disable_sldo_opt;
355 	bool enable_non_transparent_setconfig;
356 	bool lower_hbr3_phy_ssc;
357 	bool override_hbr3_pll_vco;
358 	bool disable_dpia_bw_allocation;
359 };
360 
361 /**
362  * struct dmub_srv_debug - Debug info for dmub_srv
363  * @timeout_occured: Indicates a timeout occured on any message from driver to dmub
364  * @timeout_cmd: first cmd sent from driver that timed out - subsequent timeouts are not stored
365  */
366 struct dmub_timeout_info {
367 	bool timeout_occured;
368 	union dmub_rb_cmd timeout_cmd;
369 	unsigned long long timestamp;
370 };
371 
372 /**
373  * struct dmub_diagnostic_data - Diagnostic data retrieved from DMCUB for
374  * debugging purposes, including logging, crash analysis, etc.
375  */
376 struct dmub_diagnostic_data {
377 	uint32_t dmcub_version;
378 	uint32_t scratch[17];
379 	uint32_t pc[DMUB_PC_SNAPSHOT_COUNT];
380 	uint32_t undefined_address_fault_addr;
381 	uint32_t inst_fetch_fault_addr;
382 	uint32_t data_write_fault_addr;
383 	uint32_t inbox1_rptr;
384 	uint32_t inbox1_wptr;
385 	uint32_t inbox1_size;
386 	uint32_t inbox0_rptr;
387 	uint32_t inbox0_wptr;
388 	uint32_t inbox0_size;
389 	uint32_t outbox1_rptr;
390 	uint32_t outbox1_wptr;
391 	uint32_t outbox1_size;
392 	uint32_t gpint_datain0;
393 	struct dmub_timeout_info timeout_info;
394 	uint8_t is_dmcub_enabled : 1;
395 	uint8_t is_dmcub_soft_reset : 1;
396 	uint8_t is_dmcub_secure_reset : 1;
397 	uint8_t is_traceport_en : 1;
398 	uint8_t is_cw0_enabled : 1;
399 	uint8_t is_cw6_enabled : 1;
400 	uint8_t is_pwait : 1;
401 };
402 
403 /**
404  * struct dmub_preos_info - preos fw info before loading post os fw.
405  */
406 struct dmub_preos_info {
407 	uint64_t fb_base;
408 	uint64_t fb_offset;
409 	uint64_t trace_buffer_phy_addr;
410 	uint32_t trace_buffer_size;
411 	uint32_t fw_version;
412 	uint32_t boot_status;
413 	uint32_t boot_options;
414 };
415 
416 struct dmub_srv_inbox {
417 	/* generic status */
418 	uint64_t num_submitted;
419 	uint64_t num_reported;
420 	union {
421 		/* frame buffer mailbox status */
422 		struct dmub_rb rb;
423 		/* register mailbox status */
424 		struct {
425 			bool is_pending;
426 			bool is_multi_pending;
427 		};
428 	};
429 };
430 
431 /**
432  * struct dmub_srv_base_funcs - Driver specific base callbacks
433  */
434 struct dmub_srv_base_funcs {
435 	/**
436 	 * @reg_read:
437 	 *
438 	 * Hook for reading a register.
439 	 *
440 	 * Return: The 32-bit register value from the given address.
441 	 */
442 	uint32_t (*reg_read)(void *ctx, uint32_t address);
443 
444 	/**
445 	 * @reg_write:
446 	 *
447 	 * Hook for writing a value to the register specified by address.
448 	 */
449 	void (*reg_write)(void *ctx, uint32_t address, uint32_t value);
450 };
451 
452 /**
453  * struct dmub_srv_hw_funcs - hardware sequencer funcs for dmub
454  */
455 struct dmub_srv_hw_funcs {
456 	/* private: internal use only */
457 
458 	void (*init)(struct dmub_srv *dmub);
459 
460 	void (*reset)(struct dmub_srv *dmub);
461 
462 	void (*reset_release)(struct dmub_srv *dmub);
463 
464 	void (*backdoor_load)(struct dmub_srv *dmub,
465 			      const struct dmub_window *cw0,
466 			      const struct dmub_window *cw1);
467 
468 	void (*backdoor_load_zfb_mode)(struct dmub_srv *dmub,
469 			      const struct dmub_window *cw0,
470 			      const struct dmub_window *cw1);
471 	void (*setup_windows)(struct dmub_srv *dmub,
472 			      const struct dmub_window *cw2,
473 			      const struct dmub_window *cw3,
474 			      const struct dmub_window *cw4,
475 			      const struct dmub_window *cw5,
476 			      const struct dmub_window *cw6,
477 			      const struct dmub_window *region6);
478 
479 	void (*setup_mailbox)(struct dmub_srv *dmub,
480 			      const struct dmub_region *inbox1);
481 
482 	uint32_t (*get_inbox1_wptr)(struct dmub_srv *dmub);
483 
484 	uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub);
485 
486 	void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
487 
488 	void (*setup_out_mailbox)(struct dmub_srv *dmub,
489 			      const struct dmub_region *outbox1);
490 
491 	uint32_t (*get_outbox1_wptr)(struct dmub_srv *dmub);
492 
493 	void (*set_outbox1_rptr)(struct dmub_srv *dmub, uint32_t rptr_offset);
494 
495 	void (*setup_outbox0)(struct dmub_srv *dmub,
496 			      const struct dmub_region *outbox0);
497 
498 	uint32_t (*get_outbox0_wptr)(struct dmub_srv *dmub);
499 
500 	void (*set_outbox0_rptr)(struct dmub_srv *dmub, uint32_t rptr_offset);
501 
502 	uint32_t (*emul_get_inbox1_rptr)(struct dmub_srv *dmub);
503 
504 	uint32_t (*emul_get_inbox1_wptr)(struct dmub_srv *dmub);
505 
506 	void (*emul_set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
507 
508 	bool (*is_supported)(struct dmub_srv *dmub);
509 
510 	bool (*is_psrsu_supported)(struct dmub_srv *dmub);
511 
512 	bool (*is_hw_init)(struct dmub_srv *dmub);
513 	bool (*is_hw_powered_up)(struct dmub_srv *dmub);
514 
515 	void (*enable_dmub_boot_options)(struct dmub_srv *dmub,
516 				const struct dmub_srv_hw_params *params);
517 
518 	void (*skip_dmub_panel_power_sequence)(struct dmub_srv *dmub, bool skip);
519 
520 	union dmub_fw_boot_status (*get_fw_status)(struct dmub_srv *dmub);
521 
522 	union dmub_fw_boot_options (*get_fw_boot_option)(struct dmub_srv *dmub);
523 
524 	void (*set_gpint)(struct dmub_srv *dmub,
525 			  union dmub_gpint_data_register reg);
526 
527 	bool (*is_gpint_acked)(struct dmub_srv *dmub,
528 			       union dmub_gpint_data_register reg);
529 
530 	uint32_t (*get_gpint_response)(struct dmub_srv *dmub);
531 
532 	uint32_t (*get_gpint_dataout)(struct dmub_srv *dmub);
533 
534 	void (*configure_dmub_in_system_memory)(struct dmub_srv *dmub);
535 	void (*clear_inbox0_ack_register)(struct dmub_srv *dmub);
536 	uint32_t (*read_inbox0_ack_register)(struct dmub_srv *dmub);
537 	void (*send_inbox0_cmd)(struct dmub_srv *dmub, union dmub_inbox0_data_register data);
538 	uint32_t (*get_current_time)(struct dmub_srv *dmub);
539 
540 	void (*get_diagnostic_data)(struct dmub_srv *dmub);
541 	bool (*get_preos_fw_info)(struct dmub_srv *dmub);
542 
543 	bool (*should_detect)(struct dmub_srv *dmub);
544 	void (*init_reg_offsets)(struct dmub_srv *dmub, struct dc_context *ctx);
545 
546 	void (*subvp_save_surf_addr)(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index);
547 
548 	void (*send_reg_inbox0_cmd_msg)(struct dmub_srv *dmub,
549 			union dmub_rb_cmd *cmd);
550 	uint32_t (*read_reg_inbox0_rsp_int_status)(struct dmub_srv *dmub);
551 	void (*read_reg_inbox0_cmd_rsp)(struct dmub_srv *dmub,
552 			union dmub_rb_cmd *cmd);
553 	void (*write_reg_inbox0_rsp_int_ack)(struct dmub_srv *dmub);
554 	void (*clear_reg_inbox0_rsp_int_ack)(struct dmub_srv *dmub);
555 	void (*enable_reg_inbox0_rsp_int)(struct dmub_srv *dmub, bool enable);
556 
557 	uint32_t (*read_reg_outbox0_rdy_int_status)(struct dmub_srv *dmub);
558 	void (*write_reg_outbox0_rdy_int_ack)(struct dmub_srv *dmub);
559 	void (*read_reg_outbox0_msg)(struct dmub_srv *dmub, uint32_t *msg);
560 	void (*write_reg_outbox0_rsp)(struct dmub_srv *dmub, uint32_t *rsp);
561 	uint32_t (*read_reg_outbox0_rsp_int_status)(struct dmub_srv *dmub);
562 	void (*enable_reg_outbox0_rdy_int)(struct dmub_srv *dmub, bool enable);
563 };
564 
565 /**
566  * struct dmub_srv_create_params - params for dmub service creation
567  * @base_funcs: driver supplied base routines
568  * @hw_funcs: optional overrides for hw funcs
569  * @user_ctx: context data for callback funcs
570  * @asic: driver supplied asic
571  * @fw_version: the current firmware version, if any
572  * @is_virtual: false for hw support only
573  */
574 struct dmub_srv_create_params {
575 	struct dmub_srv_base_funcs funcs;
576 	struct dmub_srv_hw_funcs *hw_funcs;
577 	void *user_ctx;
578 	enum dmub_asic asic;
579 	uint32_t fw_version;
580 	bool is_virtual;
581 	enum dmub_inbox_cmd_interface_type inbox_type;
582 };
583 
584 /**
585  * struct dmub_srv - software state for dmcub
586  * @asic: dmub asic identifier
587  * @user_ctx: user provided context for the dmub_srv
588  * @fw_version: the current firmware version, if any
589  * @is_virtual: false if hardware support only
590  * @shared_state: dmub shared state between firmware and driver
591  * @cursor_offload_v1: Cursor offload state
592  * @fw_state: dmub firmware state pointer (debug purpose only)
593  */
594 struct dmub_srv {
595 	enum dmub_asic asic;
596 	void *user_ctx;
597 	uint32_t fw_version;
598 	bool is_virtual;
599 	bool no_ext_reg_access;
600 	struct dmub_fb scratch_mem_fb;
601 	struct dmub_fb ib_mem_gart;
602 	struct dmub_fb cursor_offload_fb;
603 	const struct dmub_srv_fb_info *fb_info;
604 	volatile struct dmub_shared_state_feature_block *shared_state;
605 	volatile struct dmub_cursor_offload_v1 *cursor_offload_v1;
606 	volatile const struct dmub_fw_state *fw_state;
607 
608 	/* private: internal use only */
609 	const struct dmub_srv_common_regs *regs;
610 	const struct dmub_srv_dcn31_regs *regs_dcn31;
611 	struct dmub_srv_dcn32_regs *regs_dcn32;
612 	struct dmub_srv_dcn35_regs *regs_dcn35;
613 	const struct dmub_srv_dcn401_regs *regs_dcn401;
614 	struct dmub_srv_dcn42_regs *regs_dcn42;
615     const struct dmub_srv_dcn60_regs *regs_dcn60;
616 	struct dmub_srv_base_funcs funcs;
617 	struct dmub_srv_hw_funcs hw_funcs;
618 	struct dmub_srv_inbox inbox1;
619 	uint32_t inbox1_last_wptr;
620 	struct dmub_srv_inbox reg_inbox0;
621 	/**
622 	 * outbox1_rb is accessed without locks (dal & dc)
623 	 * and to be used only in dmub_srv_stat_get_notification()
624 	 */
625 	struct dmub_rb outbox1_rb;
626 
627 	struct dmub_rb outbox0_rb;
628 
629 	bool sw_init;
630 	bool hw_init;
631 	bool dpia_supported;
632 
633 	struct dmub_soc_fb_info soc_fb_info;
634 	uint32_t psp_version;
635 
636 	/* Feature capabilities reported by fw */
637 	struct dmub_fw_meta_info meta_info;
638 	struct dmub_feature_caps feature_caps;
639 	struct dmub_visual_confirm_color visual_confirm_color;
640 	enum dmub_inbox_cmd_interface_type inbox_type;
641 
642 	enum dmub_srv_power_state_type power_state;
643 	struct dmub_diagnostic_data debug;
644 	struct dmub_fb lsdma_rb_fb;
645 	struct dmub_preos_info preos_info;
646 };
647 
648 /**
649  * struct dmub_notification - dmub notification data
650  * @type: dmub notification type
651  * @link_index: link index to identify aux connection
652  * @result: USB4 status returned from dmub
653  * @pending_notification: Indicates there are other pending notifications
654  * @aux_reply: aux reply
655  * @hpd_status: hpd status
656  * @bw_alloc_reply: BW Allocation reply from CM/DPIA
657  */
658 struct dmub_notification {
659 	enum dmub_notification_type type;
660 	uint8_t link_index;
661 	uint8_t result;
662 	/* notify instance from DMUB */
663 	uint8_t instance;
664 	bool pending_notification;
665 	union {
666 		struct aux_reply_data aux_reply;
667 		enum dp_hpd_status hpd_status;
668 		enum set_config_status sc_status;
669 		struct dmub_rb_cmd_hpd_sense_notify_data hpd_sense_notify;
670 		struct dmub_cmd_fused_request fused_request;
671 	};
672 };
673 
674 /**
675  * DMUB firmware version helper macro - useful for checking if the version
676  * of a firmware to know if feature or functionality is supported or present.
677  */
678 #define DMUB_FW_VERSION(major, minor, revision) \
679 	((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | (((revision) & 0xFF) << 8))
680 
681 /**
682  * dmub_srv_create() - creates the DMUB service.
683  * @dmub: the dmub service
684  * @params: creation parameters for the service
685  *
686  * Return:
687  *   DMUB_STATUS_OK - success
688  *   DMUB_STATUS_INVALID - unspecified error
689  */
690 enum dmub_status dmub_srv_create(struct dmub_srv *dmub,
691 				 const struct dmub_srv_create_params *params);
692 
693 /**
694  * dmub_srv_destroy() - destroys the DMUB service.
695  * @dmub: the dmub service
696  */
697 void dmub_srv_destroy(struct dmub_srv *dmub);
698 
699 /**
700  * dmub_srv_calc_region_info() - retreives region info from the dmub service
701  * @dmub: the dmub service
702  * @params: parameters used to calculate region locations
703  * @info_out: the output region info from dmub
704  *
705  * Calculates the base and top address for all relevant dmub regions
706  * using the parameters given (if any).
707  *
708  * Return:
709  *   DMUB_STATUS_OK - success
710  *   DMUB_STATUS_INVALID - unspecified error
711  */
712 enum dmub_status
713 dmub_srv_calc_region_info(struct dmub_srv *dmub,
714 			  const struct dmub_srv_region_params *params,
715 			  struct dmub_srv_region_info *out);
716 
717 /**
718  * dmub_srv_calc_region_info() - retreives fb info from the dmub service
719  * @dmub: the dmub service
720  * @params: parameters used to calculate fb locations
721  * @info_out: the output fb info from dmub
722  *
723  * Calculates the base and top address for all relevant dmub regions
724  * using the parameters given (if any).
725  *
726  * Return:
727  *   DMUB_STATUS_OK - success
728  *   DMUB_STATUS_INVALID - unspecified error
729  */
730 enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub,
731 				       const struct dmub_srv_memory_params *params,
732 				       struct dmub_srv_fb_info *out);
733 
734 /**
735  * dmub_srv_has_hw_support() - returns hw support state for dmcub
736  * @dmub: the dmub service
737  * @is_supported: hw support state
738  *
739  * Queries the hardware for DMCUB support and returns the result.
740  *
741  * Can be called before dmub_srv_hw_init().
742  *
743  * Return:
744  *   DMUB_STATUS_OK - success
745  *   DMUB_STATUS_INVALID - unspecified error
746  */
747 enum dmub_status dmub_srv_has_hw_support(struct dmub_srv *dmub,
748 					 bool *is_supported);
749 
750 /**
751  * dmub_srv_is_hw_init() - returns hardware init state
752  *
753  * Return:
754  *   DMUB_STATUS_OK - success
755  *   DMUB_STATUS_INVALID - unspecified error
756  */
757 enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init);
758 
759 /**
760  * dmub_srv_hw_init() - initializes the underlying DMUB hardware
761  * @dmub: the dmub service
762  * @params: params for hardware initialization
763  *
764  * Resets the DMUB hardware and performs backdoor loading of the
765  * required cache regions based on the input framebuffer regions.
766  *
767  * Return:
768  *   DMUB_STATUS_OK - success
769  *   DMUB_STATUS_NO_CTX - dmcub context not initialized
770  *   DMUB_STATUS_INVALID - unspecified error
771  */
772 enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
773 				  const struct dmub_srv_hw_params *params);
774 
775 /**
776  * dmub_srv_hw_reset() - puts the DMUB hardware in reset state if initialized
777  * @dmub: the dmub service
778  *
779  * Before destroying the DMUB service or releasing the backing framebuffer
780  * memory we'll need to put the DMCUB into reset first.
781  *
782  * A subsequent call to dmub_srv_hw_init() will re-enable the DMCUB.
783  *
784  * Return:
785  *   DMUB_STATUS_OK - success
786  *   DMUB_STATUS_INVALID - unspecified error
787  */
788 enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
789 
790 /**
791  * dmub_srv_fb_cmd_queue() - queues a command to the DMUB
792  * @dmub: the dmub service
793  * @cmd: the command to queue
794  *
795  * Queues a command to the DMUB service but does not begin execution
796  * immediately.
797  *
798  * Return:
799  *   DMUB_STATUS_OK - success
800  *   DMUB_STATUS_QUEUE_FULL - no remaining room in queue
801  *   DMUB_STATUS_INVALID - unspecified error
802  */
803 enum dmub_status dmub_srv_fb_cmd_queue(struct dmub_srv *dmub,
804 				    const union dmub_rb_cmd *cmd);
805 
806 /**
807  * dmub_srv_fb_cmd_execute() - Executes a queued sequence to the dmub
808  * @dmub: the dmub service
809  *
810  * Begins execution of queued commands on the dmub.
811  *
812  * Return:
813  *   DMUB_STATUS_OK - success
814  *   DMUB_STATUS_INVALID - unspecified error
815  */
816 enum dmub_status dmub_srv_fb_cmd_execute(struct dmub_srv *dmub);
817 
818 /**
819  * dmub_srv_wait_for_hw_pwr_up() - Waits for firmware hardware power up is completed
820  * @dmub: the dmub service
821  * @timeout_us: the maximum number of microseconds to wait
822  *
823  * Waits until firmware hardware is powered up. The maximum
824  * wait time is given in microseconds to prevent spinning forever.
825  *
826  * Return:
827  *   DMUB_STATUS_OK - success
828  *   DMUB_STATUS_TIMEOUT - timed out
829  *   DMUB_STATUS_INVALID - unspecified error
830  */
831 enum dmub_status dmub_srv_wait_for_hw_pwr_up(struct dmub_srv *dmub,
832 					     uint32_t timeout_us);
833 
834 bool dmub_srv_is_hw_pwr_up(struct dmub_srv *dmub);
835 
836 /**
837  * dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete
838  * @dmub: the dmub service
839  * @timeout_us: the maximum number of microseconds to wait
840  *
841  * Waits until firmware has been autoloaded by the DMCUB. The maximum
842  * wait time is given in microseconds to prevent spinning forever.
843  *
844  * On ASICs without firmware autoload support this function will return
845  * immediately.
846  *
847  * Return:
848  *   DMUB_STATUS_OK - success
849  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
850  *   DMUB_STATUS_INVALID - unspecified error
851  */
852 enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
853 					     uint32_t timeout_us);
854 
855 /**
856  * dmub_srv_wait_for_phy_init() - Waits for DMUB PHY init to complete
857  * @dmub: the dmub service
858  * @timeout_us: the maximum number of microseconds to wait
859  *
860  * Waits until the PHY has been initialized by the DMUB. The maximum
861  * wait time is given in microseconds to prevent spinning forever.
862  *
863  * On ASICs without PHY init support this function will return
864  * immediately.
865  *
866  * Return:
867  *   DMUB_STATUS_OK - success
868  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
869  *   DMUB_STATUS_INVALID - unspecified error
870  */
871 enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub,
872 					    uint32_t timeout_us);
873 
874 /**
875  * dmub_srv_wait_for_pending() - Re-entrant wait for messages currently pending
876  * @dmub: the dmub service
877  * @timeout_us: the maximum number of microseconds to wait
878  *
879  * Waits until the commands queued prior to this call are complete.
880  * If interfaces remain busy due to additional work being submitted
881  * concurrently, this function will not continue to wait.
882  *
883  * Return:
884  *   DMUB_STATUS_OK - success
885  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
886  *   DMUB_STATUS_INVALID - unspecified error
887  */
888 enum dmub_status dmub_srv_wait_for_pending(struct dmub_srv *dmub,
889 					uint32_t timeout_us);
890 
891 /**
892  * dmub_srv_wait_for_idle() - Waits for the DMUB to be idle
893  * @dmub: the dmub service
894  * @timeout_us: the maximum number of microseconds to wait
895  *
896  * Waits until the DMUB buffer is empty and all commands have
897  * finished processing. The maximum wait time is given in
898  * microseconds to prevent spinning forever.
899  *
900  * Return:
901  *   DMUB_STATUS_OK - success
902  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
903  *   DMUB_STATUS_INVALID - unspecified error
904  */
905 enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub,
906 					uint32_t timeout_us);
907 
908 /**
909  * dmub_srv_send_gpint_command() - Sends a GPINT based command.
910  * @dmub: the dmub service
911  * @command_code: the command code to send
912  * @param: the command parameter to send
913  * @timeout_us: the maximum number of microseconds to wait
914  *
915  * Sends a command via the general purpose interrupt (GPINT).
916  * Waits for the number of microseconds specified by timeout_us
917  * for the command ACK before returning.
918  *
919  * Can be called after software initialization.
920  *
921  * Return:
922  *   DMUB_STATUS_OK - success
923  *   DMUB_STATUS_TIMEOUT - wait for ACK timed out
924  *   DMUB_STATUS_INVALID - unspecified error
925  */
926 enum dmub_status
927 dmub_srv_send_gpint_command(struct dmub_srv *dmub,
928 			    enum dmub_gpint_command command_code,
929 			    uint16_t param, uint32_t timeout_us);
930 
931 /**
932  * dmub_srv_get_gpint_response() - Queries the GPINT response.
933  * @dmub: the dmub service
934  * @response: the response for the last GPINT
935  *
936  * Returns the response code for the last GPINT interrupt.
937  *
938  * Can be called after software initialization.
939  *
940  * Return:
941  *   DMUB_STATUS_OK - success
942  *   DMUB_STATUS_INVALID - unspecified error
943  */
944 enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub,
945 					     uint32_t *response);
946 
947 /**
948  * dmub_srv_get_gpint_dataout() - Queries the GPINT DATAOUT.
949  * @dmub: the dmub service
950  * @dataout: the data for the GPINT DATAOUT
951  *
952  * Returns the response code for the last GPINT DATAOUT interrupt.
953  *
954  * Can be called after software initialization.
955  *
956  * Return:
957  *   DMUB_STATUS_OK - success
958  *   DMUB_STATUS_INVALID - unspecified error
959  */
960 enum dmub_status dmub_srv_get_gpint_dataout(struct dmub_srv *dmub,
961 					     uint32_t *dataout);
962 
963 /**
964  * dmub_srv_flush_buffer_mem() - Read back entire frame buffer region.
965  * This ensures that the write from x86 has been flushed and will not
966  * hang the DMCUB.
967  * @dmub: the dmub service
968  * @fb: frame buffer to flush
969  *
970  * Can be called after software initialization.
971  */
972 void dmub_srv_flush_buffer_mem(struct dmub_srv *dmub, const struct dmub_fb *fb);
973 
974 /**
975  * dmub_srv_get_fw_boot_status() - Returns the DMUB boot status bits.
976  *
977  * @dmub: the dmub service
978  * @status: out pointer for firmware status
979  *
980  * Return:
981  *   DMUB_STATUS_OK - success
982  *   DMUB_STATUS_INVALID - unspecified error, unsupported
983  */
984 enum dmub_status dmub_srv_get_fw_boot_status(struct dmub_srv *dmub,
985 					     union dmub_fw_boot_status *status);
986 
987 enum dmub_status dmub_srv_get_fw_boot_option(struct dmub_srv *dmub,
988 					     union dmub_fw_boot_options *option);
989 
990 enum dmub_status dmub_srv_set_skip_panel_power_sequence(struct dmub_srv *dmub,
991 					     bool skip);
992 
993 bool dmub_srv_get_outbox0_msg(struct dmub_srv *dmub, struct dmcub_trace_buf_entry *entry);
994 
995 bool dmub_srv_get_diagnostic_data(struct dmub_srv *dmub);
996 
997 bool dmub_srv_should_detect(struct dmub_srv *dmub);
998 
999 /**
1000  * dmub_srv_send_inbox0_cmd() - Send command to DMUB using INBOX0
1001  * @dmub: the dmub service
1002  * @data: the data to be sent in the INBOX0 command
1003  *
1004  * Send command by writing directly to INBOX0 WPTR
1005  *
1006  * Return:
1007  *   DMUB_STATUS_OK - success
1008  *   DMUB_STATUS_INVALID - hw_init false or hw function does not exist
1009  */
1010 enum dmub_status dmub_srv_send_inbox0_cmd(struct dmub_srv *dmub, union dmub_inbox0_data_register data);
1011 
1012 /**
1013  * dmub_srv_wait_for_inbox0_ack() - wait for DMUB to ACK INBOX0 command
1014  * @dmub: the dmub service
1015  * @timeout_us: the maximum number of microseconds to wait
1016  *
1017  * Wait for DMUB to ACK the INBOX0 message
1018  *
1019  * Return:
1020  *   DMUB_STATUS_OK - success
1021  *   DMUB_STATUS_INVALID - hw_init false or hw function does not exist
1022  *   DMUB_STATUS_TIMEOUT - wait for ack timed out
1023  */
1024 enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t timeout_us);
1025 
1026 /**
1027  * dmub_srv_wait_for_inbox0_ack() - clear ACK register for INBOX0
1028  * @dmub: the dmub service
1029  *
1030  * Clear ACK register for INBOX0
1031  *
1032  * Return:
1033  *   DMUB_STATUS_OK - success
1034  *   DMUB_STATUS_INVALID - hw_init false or hw function does not exist
1035  */
1036 enum dmub_status dmub_srv_clear_inbox0_ack(struct dmub_srv *dmub);
1037 
1038 /**
1039  * dmub_srv_subvp_save_surf_addr() - Save primary and meta address for subvp on each flip
1040  * @dmub: The dmub service
1041  * @addr: The surface address to be programmed on the current flip
1042  * @subvp_index: Index of subvp pipe, indicates which subvp pipe the address should be saved for
1043  *
1044  * Function to save the surface flip addr into scratch registers. This is to fix a race condition
1045  * between FW and driver reading / writing to the surface address at the same time. This is
1046  * required because there is no EARLIEST_IN_USE_META.
1047  *
1048  * Return:
1049  *   void
1050  */
1051 void dmub_srv_subvp_save_surf_addr(struct dmub_srv *dmub, const struct dc_plane_address *addr, uint8_t subvp_index);
1052 
1053 /**
1054  * dmub_srv_set_power_state() - Track DC power state in dmub_srv
1055  * @dmub: The dmub service
1056  * @power_state: DC power state setting
1057  *
1058  * Store DC power state in dmub_srv.  If dmub_srv is in D3, then don't send messages to DMUB
1059  *
1060  * Return:
1061  *   void
1062  */
1063 void dmub_srv_set_power_state(struct dmub_srv *dmub, enum dmub_srv_power_state_type dmub_srv_power_state);
1064 
1065 /**
1066  * dmub_srv_reg_cmd_execute() - Executes provided command to the dmub
1067  * @dmub: the dmub service
1068  * @cmd: the command packet to be executed
1069  *
1070  * Executes a single command for the dmub.
1071  *
1072  * Return:
1073  *   DMUB_STATUS_OK - success
1074  *   DMUB_STATUS_INVALID - unspecified error
1075  */
1076 enum dmub_status dmub_srv_reg_cmd_execute(struct dmub_srv *dmub, union dmub_rb_cmd *cmd);
1077 
1078 
1079 /**
1080  * dmub_srv_cmd_get_response() - Copies return data for command into buffer
1081  * @dmub: the dmub service
1082  * @cmd_rsp: response buffer
1083  *
1084  * Copies return data for command into buffer
1085  */
1086 void dmub_srv_cmd_get_response(struct dmub_srv *dmub,
1087 		union dmub_rb_cmd *cmd_rsp);
1088 
1089 /**
1090  * dmub_srv_sync_inboxes() - Sync inbox state
1091  * @dmub: the dmub service
1092  *
1093  * Sync inbox state
1094  *
1095  * Return:
1096  *   DMUB_STATUS_OK - success
1097  *   DMUB_STATUS_INVALID - unspecified error
1098  */
1099 enum dmub_status dmub_srv_sync_inboxes(struct dmub_srv *dmub);
1100 
1101 /**
1102  * dmub_srv_wait_for_inbox_free() - Waits for space in the DMUB inbox to free up
1103  * @dmub: the dmub service
1104  * @timeout_us: the maximum number of microseconds to wait
1105  * @num_free_required: number of free entries required
1106  *
1107  * Waits until the DMUB buffer is freed to the specified number.
1108  *  The maximum wait time is given in microseconds to prevent spinning
1109  * forever.
1110  *
1111  * Return:
1112  *   DMUB_STATUS_OK - success
1113  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
1114  *   DMUB_STATUS_INVALID - unspecified error
1115  */
1116 enum dmub_status dmub_srv_wait_for_inbox_free(struct dmub_srv *dmub,
1117 		uint32_t timeout_us,
1118 		uint32_t num_free_required);
1119 
1120 /**
1121  * dmub_srv_update_inbox_status() - Updates pending status for inbox & reg inbox0
1122  * @dmub: the dmub service
1123  *
1124  * Return:
1125  *   DMUB_STATUS_OK - success
1126  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
1127  *   DMUB_STATUS_HW_FAILURE - issue with HW programming
1128  *   DMUB_STATUS_INVALID - unspecified error
1129  */
1130 enum dmub_status dmub_srv_update_inbox_status(struct dmub_srv *dmub);
1131 
1132 /**
1133  * dmub_srv_get_preos_info() - retrieves preos fw info
1134  * @dmub: the dmub service
1135  *
1136  * Return:
1137  *   true - preos fw info retrieved successfully
1138  *   false - preos fw info not retrieved successfully
1139  */
1140 bool dmub_srv_get_preos_info(struct dmub_srv *dmub);
1141 
1142 /**
1143  * dmub_srv_get_fw_meta_info_from_raw_fw() - Fetch firmware metadata info from raw firmware image
1144  * @params: parameters for fetching firmware metadata info
1145  * @fw_info_out: output buffer for firmware metadata info
1146  *
1147  * Return:
1148  *   DMUB_STATUS_OK - success
1149  *   DMUB_STATUS_INVALID - no FW meta info found
1150  */
1151 enum dmub_status dmub_srv_get_fw_meta_info_from_raw_fw(struct dmub_srv_fw_meta_info_params *params,
1152 						       struct dmub_fw_meta_info *fw_info_out);
1153 
1154 #endif /* _DMUB_SRV_H_ */
1155