xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/amd/display/dmub/inc/dmub_srv.h (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: dmub_srv.h,v 1.2 2021/12/18 23:45:06 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2019 Advanced Micro Devices, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: AMD
25  *
26  */
27 
28 #ifndef _DMUB_SRV_H_
29 #define _DMUB_SRV_H_
30 
31 /**
32  * DOC: DMUB interface and operation
33  *
34  * DMUB is the interface to the display DMCUB microcontroller on DCN hardware.
35  * It delegates hardware initialization and command submission to the
36  * microcontroller. DMUB is the shortname for DMCUB.
37  *
38  * This interface is not thread-safe. Ensure that all access to the interface
39  * is properly synchronized by the caller.
40  *
41  * Initialization and usage of the DMUB service should be done in the
42  * steps given below:
43  *
44  * 1. dmub_srv_create()
45  * 2. dmub_srv_has_hw_support()
46  * 3. dmub_srv_calc_region_info()
47  * 4. dmub_srv_hw_init()
48  *
49  * The call to dmub_srv_create() is required to use the server.
50  *
51  * The calls to dmub_srv_has_hw_support() and dmub_srv_calc_region_info()
52  * are helpers to query cache window size and allocate framebuffer(s)
53  * for the cache windows.
54  *
55  * The call to dmub_srv_hw_init() programs the DMCUB registers to prepare
56  * for command submission. Commands can be queued via dmub_srv_cmd_queue()
57  * and executed via dmub_srv_cmd_execute().
58  *
59  * If the queue is full the dmub_srv_wait_for_idle() call can be used to
60  * wait until the queue has been cleared.
61  *
62  * Destroying the DMUB service can be done by calling dmub_srv_destroy().
63  * This does not clear DMUB hardware state, only software state.
64  *
65  * The interface is intended to be standalone and should not depend on any
66  * other component within DAL.
67  */
68 
69 #include "dmub_types.h"
70 #include "dmub_cmd.h"
71 #include "dmub_rb.h"
72 
73 #if defined(__cplusplus)
74 extern "C" {
75 #endif
76 
77 /* Forward declarations */
78 struct dmub_srv;
79 struct dmub_cmd_header;
80 struct dmub_srv_common_regs;
81 
82 /* enum dmub_status - return code for dmcub functions */
83 enum dmub_status {
84 	DMUB_STATUS_OK = 0,
85 	DMUB_STATUS_NO_CTX,
86 	DMUB_STATUS_QUEUE_FULL,
87 	DMUB_STATUS_TIMEOUT,
88 	DMUB_STATUS_INVALID,
89 };
90 
91 /* enum dmub_asic - dmub asic identifier */
92 enum dmub_asic {
93 	DMUB_ASIC_NONE = 0,
94 	DMUB_ASIC_DCN20,
95 	DMUB_ASIC_DCN21,
96 	DMUB_ASIC_MAX,
97 };
98 
99 /* enum dmub_window_id - dmub window identifier */
100 enum dmub_window_id {
101 	DMUB_WINDOW_0_INST_CONST = 0,
102 	DMUB_WINDOW_1_STACK,
103 	DMUB_WINDOW_2_BSS_DATA,
104 	DMUB_WINDOW_3_VBIOS,
105 	DMUB_WINDOW_4_MAILBOX,
106 	DMUB_WINDOW_5_TRACEBUFF,
107 	DMUB_WINDOW_6_FW_STATE,
108 	DMUB_WINDOW_7_RESERVED,
109 	DMUB_WINDOW_TOTAL,
110 };
111 
112 /**
113  * struct dmub_region - dmub hw memory region
114  * @base: base address for region, must be 256 byte aligned
115  * @top: top address for region
116  */
117 struct dmub_region {
118 	uint32_t base;
119 	uint32_t top;
120 };
121 
122 /**
123  * struct dmub_window - dmub hw cache window
124  * @off: offset to the fb memory in gpu address space
125  * @r: region in uc address space for cache window
126  */
127 struct dmub_window {
128 	union dmub_addr offset;
129 	struct dmub_region region;
130 };
131 
132 /**
133  * struct dmub_fb - defines a dmub framebuffer memory region
134  * @cpu_addr: cpu virtual address for the region, NULL if invalid
135  * @gpu_addr: gpu virtual address for the region, NULL if invalid
136  * @size: size of the region in bytes, zero if invalid
137  */
138 struct dmub_fb {
139 	void *cpu_addr;
140 	uint64_t gpu_addr;
141 	uint32_t size;
142 };
143 
144 /**
145  * struct dmub_srv_region_params - params used for calculating dmub regions
146  * @inst_const_size: size of the fw inst const section
147  * @bss_data_size: size of the fw bss data section
148  * @vbios_size: size of the vbios data
149  * @fw_bss_data: raw firmware bss data section
150  */
151 struct dmub_srv_region_params {
152 	uint32_t inst_const_size;
153 	uint32_t bss_data_size;
154 	uint32_t vbios_size;
155 	const uint8_t *fw_bss_data;
156 };
157 
158 /**
159  * struct dmub_srv_region_info - output region info from the dmub service
160  * @fb_size: required minimum fb size for all regions, aligned to 4096 bytes
161  * @num_regions: number of regions used by the dmub service
162  * @regions: region info
163  *
164  * The regions are aligned such that they can be all placed within the
165  * same framebuffer but they can also be placed into different framebuffers.
166  *
167  * The size of each region can be calculated by the caller:
168  * size = reg.top - reg.base
169  *
170  * Care must be taken when performing custom allocations to ensure that each
171  * region base address is 256 byte aligned.
172  */
173 struct dmub_srv_region_info {
174 	uint32_t fb_size;
175 	uint8_t num_regions;
176 	struct dmub_region regions[DMUB_WINDOW_TOTAL];
177 };
178 
179 /**
180  * struct dmub_srv_fb_params - parameters used for driver fb setup
181  * @region_info: region info calculated by dmub service
182  * @cpu_addr: base cpu address for the framebuffer
183  * @gpu_addr: base gpu virtual address for the framebuffer
184  */
185 struct dmub_srv_fb_params {
186 	const struct dmub_srv_region_info *region_info;
187 	void *cpu_addr;
188 	uint64_t gpu_addr;
189 };
190 
191 /**
192  * struct dmub_srv_fb_info - output fb info from the dmub service
193  * @num_fbs: number of required dmub framebuffers
194  * @fbs: fb data for each region
195  *
196  * Output from the dmub service helper that can be used by the
197  * driver to prepare dmub_fb that can be passed into the dmub
198  * hw init service.
199  *
200  * Assumes that all regions are within the same framebuffer
201  * and have been setup according to the region_info generated
202  * by the dmub service.
203  */
204 struct dmub_srv_fb_info {
205 	uint8_t num_fb;
206 	struct dmub_fb fb[DMUB_WINDOW_TOTAL];
207 };
208 
209 /**
210  * struct dmub_srv_base_funcs - Driver specific base callbacks
211  */
212 struct dmub_srv_base_funcs {
213 	/**
214 	 * @reg_read:
215 	 *
216 	 * Hook for reading a register.
217 	 *
218 	 * Return: The 32-bit register value from the given address.
219 	 */
220 	uint32_t (*reg_read)(void *ctx, uint32_t address);
221 
222 	/**
223 	 * @reg_write:
224 	 *
225 	 * Hook for writing a value to the register specified by address.
226 	 */
227 	void (*reg_write)(void *ctx, uint32_t address, uint32_t value);
228 };
229 
230 /**
231  * struct dmub_srv_hw_funcs - hardware sequencer funcs for dmub
232  */
233 struct dmub_srv_hw_funcs {
234 	/* private: internal use only */
235 
236 	void (*init)(struct dmub_srv *dmub);
237 
238 	void (*reset)(struct dmub_srv *dmub);
239 
240 	void (*reset_release)(struct dmub_srv *dmub);
241 
242 	void (*backdoor_load)(struct dmub_srv *dmub,
243 			      const struct dmub_window *cw0,
244 			      const struct dmub_window *cw1);
245 
246 	void (*setup_windows)(struct dmub_srv *dmub,
247 			      const struct dmub_window *cw2,
248 			      const struct dmub_window *cw3,
249 			      const struct dmub_window *cw4,
250 			      const struct dmub_window *cw5,
251 			      const struct dmub_window *cw6);
252 
253 	void (*setup_mailbox)(struct dmub_srv *dmub,
254 			      const struct dmub_region *inbox1);
255 
256 	uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub);
257 
258 	void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
259 
260 	bool (*is_supported)(struct dmub_srv *dmub);
261 
262 	bool (*is_hw_init)(struct dmub_srv *dmub);
263 
264 	bool (*is_phy_init)(struct dmub_srv *dmub);
265 
266 	bool (*is_auto_load_done)(struct dmub_srv *dmub);
267 };
268 
269 /**
270  * struct dmub_srv_create_params - params for dmub service creation
271  * @base_funcs: driver supplied base routines
272  * @hw_funcs: optional overrides for hw funcs
273  * @user_ctx: context data for callback funcs
274  * @asic: driver supplied asic
275  * @is_virtual: false for hw support only
276  */
277 struct dmub_srv_create_params {
278 	struct dmub_srv_base_funcs funcs;
279 	struct dmub_srv_hw_funcs *hw_funcs;
280 	void *user_ctx;
281 	enum dmub_asic asic;
282 	bool is_virtual;
283 };
284 
285 /*
286  * struct dmub_srv_hw_params - params for dmub hardware initialization
287  * @fb: framebuffer info for each region
288  * @fb_base: base of the framebuffer aperture
289  * @fb_offset: offset of the framebuffer aperture
290  * @psp_version: psp version to pass for DMCU init
291  * @load_inst_const: true if DMUB should load inst const fw
292  */
293 struct dmub_srv_hw_params {
294 	struct dmub_fb *fb[DMUB_WINDOW_TOTAL];
295 	uint64_t fb_base;
296 	uint64_t fb_offset;
297 	uint32_t psp_version;
298 	bool load_inst_const;
299 };
300 
301 /**
302  * struct dmub_srv - software state for dmcub
303  * @asic: dmub asic identifier
304  * @user_ctx: user provided context for the dmub_srv
305  * @is_virtual: false if hardware support only
306  * @fw_state: dmub firmware state pointer
307  */
308 struct dmub_srv {
309 	enum dmub_asic asic;
310 	void *user_ctx;
311 	bool is_virtual;
312 	volatile const struct dmub_fw_state *fw_state;
313 
314 	/* private: internal use only */
315 	const struct dmub_srv_common_regs *regs;
316 
317 	struct dmub_srv_base_funcs funcs;
318 	struct dmub_srv_hw_funcs hw_funcs;
319 	struct dmub_rb inbox1_rb;
320 
321 	bool sw_init;
322 	bool hw_init;
323 
324 	uint64_t fb_base;
325 	uint64_t fb_offset;
326 	uint32_t psp_version;
327 };
328 
329 /**
330  * dmub_srv_create() - creates the DMUB service.
331  * @dmub: the dmub service
332  * @params: creation parameters for the service
333  *
334  * Return:
335  *   DMUB_STATUS_OK - success
336  *   DMUB_STATUS_INVALID - unspecified error
337  */
338 enum dmub_status dmub_srv_create(struct dmub_srv *dmub,
339 				 const struct dmub_srv_create_params *params);
340 
341 /**
342  * dmub_srv_destroy() - destroys the DMUB service.
343  * @dmub: the dmub service
344  */
345 void dmub_srv_destroy(struct dmub_srv *dmub);
346 
347 /**
348  * dmub_srv_calc_region_info() - retreives region info from the dmub service
349  * @dmub: the dmub service
350  * @params: parameters used to calculate region locations
351  * @info_out: the output region info from dmub
352  *
353  * Calculates the base and top address for all relevant dmub regions
354  * using the parameters given (if any).
355  *
356  * Return:
357  *   DMUB_STATUS_OK - success
358  *   DMUB_STATUS_INVALID - unspecified error
359  */
360 enum dmub_status
361 dmub_srv_calc_region_info(struct dmub_srv *dmub,
362 			  const struct dmub_srv_region_params *params,
363 			  struct dmub_srv_region_info *out);
364 
365 /**
366  * dmub_srv_calc_region_info() - retreives fb info from the dmub service
367  * @dmub: the dmub service
368  * @params: parameters used to calculate fb locations
369  * @info_out: the output fb info from dmub
370  *
371  * Calculates the base and top address for all relevant dmub regions
372  * using the parameters given (if any).
373  *
374  * Return:
375  *   DMUB_STATUS_OK - success
376  *   DMUB_STATUS_INVALID - unspecified error
377  */
378 enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
379 				       const struct dmub_srv_fb_params *params,
380 				       struct dmub_srv_fb_info *out);
381 
382 /**
383  * dmub_srv_has_hw_support() - returns hw support state for dmcub
384  * @dmub: the dmub service
385  * @is_supported: hw support state
386  *
387  * Queries the hardware for DMCUB support and returns the result.
388  *
389  * Can be called before dmub_srv_hw_init().
390  *
391  * Return:
392  *   DMUB_STATUS_OK - success
393  *   DMUB_STATUS_INVALID - unspecified error
394  */
395 enum dmub_status dmub_srv_has_hw_support(struct dmub_srv *dmub,
396 					 bool *is_supported);
397 
398 /**
399  * dmub_srv_is_hw_init() - returns hardware init state
400  *
401  * Return:
402  *   DMUB_STATUS_OK - success
403  *   DMUB_STATUS_INVALID - unspecified error
404  */
405 enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init);
406 
407 /**
408  * dmub_srv_hw_init() - initializes the underlying DMUB hardware
409  * @dmub: the dmub service
410  * @params: params for hardware initialization
411  *
412  * Resets the DMUB hardware and performs backdoor loading of the
413  * required cache regions based on the input framebuffer regions.
414  *
415  * Return:
416  *   DMUB_STATUS_OK - success
417  *   DMUB_STATUS_NO_CTX - dmcub context not initialized
418  *   DMUB_STATUS_INVALID - unspecified error
419  */
420 enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
421 				  const struct dmub_srv_hw_params *params);
422 
423 /**
424  * dmub_srv_hw_reset() - puts the DMUB hardware in reset state if initialized
425  * @dmub: the dmub service
426  *
427  * Before destroying the DMUB service or releasing the backing framebuffer
428  * memory we'll need to put the DMCUB into reset first.
429  *
430  * A subsequent call to dmub_srv_hw_init() will re-enable the DMCUB.
431  *
432  * Return:
433  *   DMUB_STATUS_OK - success
434  *   DMUB_STATUS_INVALID - unspecified error
435  */
436 enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
437 
438 /**
439  * dmub_srv_cmd_queue() - queues a command to the DMUB
440  * @dmub: the dmub service
441  * @cmd: the command to queue
442  *
443  * Queues a command to the DMUB service but does not begin execution
444  * immediately.
445  *
446  * Return:
447  *   DMUB_STATUS_OK - success
448  *   DMUB_STATUS_QUEUE_FULL - no remaining room in queue
449  *   DMUB_STATUS_INVALID - unspecified error
450  */
451 enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
452 				    const struct dmub_cmd_header *cmd);
453 
454 /**
455  * dmub_srv_cmd_execute() - Executes a queued sequence to the dmub
456  * @dmub: the dmub service
457  *
458  * Begins execution of queued commands on the dmub.
459  *
460  * Return:
461  *   DMUB_STATUS_OK - success
462  *   DMUB_STATUS_INVALID - unspecified error
463  */
464 enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub);
465 
466 /**
467  * dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete
468  * @dmub: the dmub service
469  * @timeout_us: the maximum number of microseconds to wait
470  *
471  * Waits until firmware has been autoloaded by the DMCUB. The maximum
472  * wait time is given in microseconds to prevent spinning forever.
473  *
474  * On ASICs without firmware autoload support this function will return
475  * immediately.
476  *
477  * Return:
478  *   DMUB_STATUS_OK - success
479  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
480  *   DMUB_STATUS_INVALID - unspecified error
481  */
482 enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
483 					     uint32_t timeout_us);
484 
485 /**
486  * dmub_srv_wait_for_phy_init() - Waits for DMUB PHY init to complete
487  * @dmub: the dmub service
488  * @timeout_us: the maximum number of microseconds to wait
489  *
490  * Waits until the PHY has been initialized by the DMUB. The maximum
491  * wait time is given in microseconds to prevent spinning forever.
492  *
493  * On ASICs without PHY init support this function will return
494  * immediately.
495  *
496  * Return:
497  *   DMUB_STATUS_OK - success
498  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
499  *   DMUB_STATUS_INVALID - unspecified error
500  */
501 enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub,
502 					    uint32_t timeout_us);
503 
504 /**
505  * dmub_srv_wait_for_idle() - Waits for the DMUB to be idle
506  * @dmub: the dmub service
507  * @timeout_us: the maximum number of microseconds to wait
508  *
509  * Waits until the DMUB buffer is empty and all commands have
510  * finished processing. The maximum wait time is given in
511  * microseconds to prevent spinning forever.
512  *
513  * Return:
514  *   DMUB_STATUS_OK - success
515  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
516  *   DMUB_STATUS_INVALID - unspecified error
517  */
518 enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub,
519 					uint32_t timeout_us);
520 
521 #if defined(__cplusplus)
522 }
523 #endif
524 
525 #endif /* _DMUB_SRV_H_ */
526