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_types.h"
68 #include "inc/dmub_cmd.h"
69 #include "inc/dmub_gpint_cmd.h"
70 #include "inc/dmub_cmd_dal.h"
71 #include "inc/dmub_rb.h"
72 
73 #if defined(__cplusplus)
74 extern "C" {
75 #endif
76 
77 /* Forward declarations */
78 struct dmub_srv;
79 struct dmub_srv_common_regs;
80 
81 /* enum dmub_status - return code for dmcub functions */
82 enum dmub_status {
83 	DMUB_STATUS_OK = 0,
84 	DMUB_STATUS_NO_CTX,
85 	DMUB_STATUS_QUEUE_FULL,
86 	DMUB_STATUS_TIMEOUT,
87 	DMUB_STATUS_INVALID,
88 };
89 
90 /* enum dmub_asic - dmub asic identifier */
91 enum dmub_asic {
92 	DMUB_ASIC_NONE = 0,
93 	DMUB_ASIC_DCN20,
94 	DMUB_ASIC_DCN21,
95 	DMUB_ASIC_MAX,
96 };
97 
98 /* enum dmub_window_id - dmub window identifier */
99 enum dmub_window_id {
100 	DMUB_WINDOW_0_INST_CONST = 0,
101 	DMUB_WINDOW_1_STACK,
102 	DMUB_WINDOW_2_BSS_DATA,
103 	DMUB_WINDOW_3_VBIOS,
104 	DMUB_WINDOW_4_MAILBOX,
105 	DMUB_WINDOW_5_TRACEBUFF,
106 	DMUB_WINDOW_6_FW_STATE,
107 	DMUB_WINDOW_7_SCRATCH_MEM,
108 	DMUB_WINDOW_TOTAL,
109 };
110 
111 /**
112  * struct dmub_region - dmub hw memory region
113  * @base: base address for region, must be 256 byte aligned
114  * @top: top address for region
115  */
116 struct dmub_region {
117 	uint32_t base;
118 	uint32_t top;
119 };
120 
121 /**
122  * struct dmub_window - dmub hw cache window
123  * @off: offset to the fb memory in gpu address space
124  * @r: region in uc address space for cache window
125  */
126 struct dmub_window {
127 	union dmub_addr offset;
128 	struct dmub_region region;
129 };
130 
131 /**
132  * struct dmub_fb - defines a dmub framebuffer memory region
133  * @cpu_addr: cpu virtual address for the region, NULL if invalid
134  * @gpu_addr: gpu virtual address for the region, NULL if invalid
135  * @size: size of the region in bytes, zero if invalid
136  */
137 struct dmub_fb {
138 	void *cpu_addr;
139 	uint64_t gpu_addr;
140 	uint32_t size;
141 };
142 
143 /**
144  * struct dmub_srv_region_params - params used for calculating dmub regions
145  * @inst_const_size: size of the fw inst const section
146  * @bss_data_size: size of the fw bss data section
147  * @vbios_size: size of the vbios data
148  * @fw_bss_data: raw firmware bss data section
149  */
150 struct dmub_srv_region_params {
151 	uint32_t inst_const_size;
152 	uint32_t bss_data_size;
153 	uint32_t vbios_size;
154 	const uint8_t *fw_inst_const;
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 	void (*set_gpint)(struct dmub_srv *dmub,
269 			  union dmub_gpint_data_register reg);
270 
271 	bool (*is_gpint_acked)(struct dmub_srv *dmub,
272 			       union dmub_gpint_data_register reg);
273 
274 	uint32_t (*get_gpint_response)(struct dmub_srv *dmub);
275 };
276 
277 /**
278  * struct dmub_srv_create_params - params for dmub service creation
279  * @base_funcs: driver supplied base routines
280  * @hw_funcs: optional overrides for hw funcs
281  * @user_ctx: context data for callback funcs
282  * @asic: driver supplied asic
283  * @is_virtual: false for hw support only
284  */
285 struct dmub_srv_create_params {
286 	struct dmub_srv_base_funcs funcs;
287 	struct dmub_srv_hw_funcs *hw_funcs;
288 	void *user_ctx;
289 	enum dmub_asic asic;
290 	bool is_virtual;
291 };
292 
293 /*
294  * struct dmub_srv_hw_params - params for dmub hardware initialization
295  * @fb: framebuffer info for each region
296  * @fb_base: base of the framebuffer aperture
297  * @fb_offset: offset of the framebuffer aperture
298  * @psp_version: psp version to pass for DMCU init
299  * @load_inst_const: true if DMUB should load inst const fw
300  */
301 struct dmub_srv_hw_params {
302 	struct dmub_fb *fb[DMUB_WINDOW_TOTAL];
303 	uint64_t fb_base;
304 	uint64_t fb_offset;
305 	uint32_t psp_version;
306 	bool load_inst_const;
307 };
308 
309 /**
310  * struct dmub_srv - software state for dmcub
311  * @asic: dmub asic identifier
312  * @user_ctx: user provided context for the dmub_srv
313  * @is_virtual: false if hardware support only
314  * @fw_state: dmub firmware state pointer
315  */
316 struct dmub_srv {
317 	enum dmub_asic asic;
318 	void *user_ctx;
319 	bool is_virtual;
320 	struct dmub_fb scratch_mem_fb;
321 	volatile const struct dmub_fw_state *fw_state;
322 
323 	/* private: internal use only */
324 	const struct dmub_srv_common_regs *regs;
325 
326 	struct dmub_srv_base_funcs funcs;
327 	struct dmub_srv_hw_funcs hw_funcs;
328 	struct dmub_rb inbox1_rb;
329 
330 	bool sw_init;
331 	bool hw_init;
332 
333 	uint64_t fb_base;
334 	uint64_t fb_offset;
335 	uint32_t psp_version;
336 };
337 
338 /**
339  * dmub_srv_create() - creates the DMUB service.
340  * @dmub: the dmub service
341  * @params: creation parameters for the service
342  *
343  * Return:
344  *   DMUB_STATUS_OK - success
345  *   DMUB_STATUS_INVALID - unspecified error
346  */
347 enum dmub_status dmub_srv_create(struct dmub_srv *dmub,
348 				 const struct dmub_srv_create_params *params);
349 
350 /**
351  * dmub_srv_destroy() - destroys the DMUB service.
352  * @dmub: the dmub service
353  */
354 void dmub_srv_destroy(struct dmub_srv *dmub);
355 
356 /**
357  * dmub_srv_calc_region_info() - retreives region info from the dmub service
358  * @dmub: the dmub service
359  * @params: parameters used to calculate region locations
360  * @info_out: the output region info from dmub
361  *
362  * Calculates the base and top address for all relevant dmub regions
363  * using the parameters given (if any).
364  *
365  * Return:
366  *   DMUB_STATUS_OK - success
367  *   DMUB_STATUS_INVALID - unspecified error
368  */
369 enum dmub_status
370 dmub_srv_calc_region_info(struct dmub_srv *dmub,
371 			  const struct dmub_srv_region_params *params,
372 			  struct dmub_srv_region_info *out);
373 
374 /**
375  * dmub_srv_calc_region_info() - retreives fb info from the dmub service
376  * @dmub: the dmub service
377  * @params: parameters used to calculate fb locations
378  * @info_out: the output fb info from dmub
379  *
380  * Calculates the base and top address for all relevant dmub regions
381  * using the parameters given (if any).
382  *
383  * Return:
384  *   DMUB_STATUS_OK - success
385  *   DMUB_STATUS_INVALID - unspecified error
386  */
387 enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
388 				       const struct dmub_srv_fb_params *params,
389 				       struct dmub_srv_fb_info *out);
390 
391 /**
392  * dmub_srv_has_hw_support() - returns hw support state for dmcub
393  * @dmub: the dmub service
394  * @is_supported: hw support state
395  *
396  * Queries the hardware for DMCUB support and returns the result.
397  *
398  * Can be called before dmub_srv_hw_init().
399  *
400  * Return:
401  *   DMUB_STATUS_OK - success
402  *   DMUB_STATUS_INVALID - unspecified error
403  */
404 enum dmub_status dmub_srv_has_hw_support(struct dmub_srv *dmub,
405 					 bool *is_supported);
406 
407 /**
408  * dmub_srv_is_hw_init() - returns hardware init state
409  *
410  * Return:
411  *   DMUB_STATUS_OK - success
412  *   DMUB_STATUS_INVALID - unspecified error
413  */
414 enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init);
415 
416 /**
417  * dmub_srv_hw_init() - initializes the underlying DMUB hardware
418  * @dmub: the dmub service
419  * @params: params for hardware initialization
420  *
421  * Resets the DMUB hardware and performs backdoor loading of the
422  * required cache regions based on the input framebuffer regions.
423  *
424  * Return:
425  *   DMUB_STATUS_OK - success
426  *   DMUB_STATUS_NO_CTX - dmcub context not initialized
427  *   DMUB_STATUS_INVALID - unspecified error
428  */
429 enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
430 				  const struct dmub_srv_hw_params *params);
431 
432 /**
433  * dmub_srv_hw_reset() - puts the DMUB hardware in reset state if initialized
434  * @dmub: the dmub service
435  *
436  * Before destroying the DMUB service or releasing the backing framebuffer
437  * memory we'll need to put the DMCUB into reset first.
438  *
439  * A subsequent call to dmub_srv_hw_init() will re-enable the DMCUB.
440  *
441  * Return:
442  *   DMUB_STATUS_OK - success
443  *   DMUB_STATUS_INVALID - unspecified error
444  */
445 enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
446 
447 /**
448  * dmub_srv_cmd_queue() - queues a command to the DMUB
449  * @dmub: the dmub service
450  * @cmd: the command to queue
451  *
452  * Queues a command to the DMUB service but does not begin execution
453  * immediately.
454  *
455  * Return:
456  *   DMUB_STATUS_OK - success
457  *   DMUB_STATUS_QUEUE_FULL - no remaining room in queue
458  *   DMUB_STATUS_INVALID - unspecified error
459  */
460 enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
461 				    const union dmub_rb_cmd *cmd);
462 
463 /**
464  * dmub_srv_cmd_execute() - Executes a queued sequence to the dmub
465  * @dmub: the dmub service
466  *
467  * Begins execution of queued commands on the dmub.
468  *
469  * Return:
470  *   DMUB_STATUS_OK - success
471  *   DMUB_STATUS_INVALID - unspecified error
472  */
473 enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub);
474 
475 /**
476  * dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete
477  * @dmub: the dmub service
478  * @timeout_us: the maximum number of microseconds to wait
479  *
480  * Waits until firmware has been autoloaded by the DMCUB. The maximum
481  * wait time is given in microseconds to prevent spinning forever.
482  *
483  * On ASICs without firmware autoload support this function will return
484  * immediately.
485  *
486  * Return:
487  *   DMUB_STATUS_OK - success
488  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
489  *   DMUB_STATUS_INVALID - unspecified error
490  */
491 enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
492 					     uint32_t timeout_us);
493 
494 /**
495  * dmub_srv_wait_for_phy_init() - Waits for DMUB PHY init to complete
496  * @dmub: the dmub service
497  * @timeout_us: the maximum number of microseconds to wait
498  *
499  * Waits until the PHY has been initialized by the DMUB. The maximum
500  * wait time is given in microseconds to prevent spinning forever.
501  *
502  * On ASICs without PHY init support this function will return
503  * immediately.
504  *
505  * Return:
506  *   DMUB_STATUS_OK - success
507  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
508  *   DMUB_STATUS_INVALID - unspecified error
509  */
510 enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub,
511 					    uint32_t timeout_us);
512 
513 /**
514  * dmub_srv_wait_for_idle() - Waits for the DMUB to be idle
515  * @dmub: the dmub service
516  * @timeout_us: the maximum number of microseconds to wait
517  *
518  * Waits until the DMUB buffer is empty and all commands have
519  * finished processing. The maximum wait time is given in
520  * microseconds to prevent spinning forever.
521  *
522  * Return:
523  *   DMUB_STATUS_OK - success
524  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
525  *   DMUB_STATUS_INVALID - unspecified error
526  */
527 enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub,
528 					uint32_t timeout_us);
529 
530 /**
531  * dmub_srv_send_gpint_command() - Sends a GPINT based command.
532  * @dmub: the dmub service
533  * @command_code: the command code to send
534  * @param: the command parameter to send
535  * @timeout_us: the maximum number of microseconds to wait
536  *
537  * Sends a command via the general purpose interrupt (GPINT).
538  * Waits for the number of microseconds specified by timeout_us
539  * for the command ACK before returning.
540  *
541  * Can be called after software initialization.
542  *
543  * Return:
544  *   DMUB_STATUS_OK - success
545  *   DMUB_STATUS_TIMEOUT - wait for ACK timed out
546  *   DMUB_STATUS_INVALID - unspecified error
547  */
548 enum dmub_status
549 dmub_srv_send_gpint_command(struct dmub_srv *dmub,
550 			    enum dmub_gpint_command command_code,
551 			    uint16_t param, uint32_t timeout_us);
552 
553 /**
554  * dmub_srv_get_gpint_response() - Queries the GPINT response.
555  * @dmub: the dmub service
556  * @response: the response for the last GPINT
557  *
558  * Returns the response code for the last GPINT interrupt.
559  *
560  * Can be called after software initialization.
561  *
562  * Return:
563  *   DMUB_STATUS_OK - success
564  *   DMUB_STATUS_INVALID - unspecified error
565  */
566 enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub,
567 					     uint32_t *response);
568 
569 /**
570  * dmub_flush_buffer_mem() - Read back entire frame buffer region.
571  * This ensures that the write from x86 has been flushed and will not
572  * hang the DMCUB.
573  * @fb: frame buffer to flush
574  *
575  * Can be called after software initialization.
576  */
577 void dmub_flush_buffer_mem(const struct dmub_fb *fb);
578 
579 #if defined(__cplusplus)
580 }
581 #endif
582 
583 #endif /* _DMUB_SRV_H_ */
584