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 
69 #if defined(__cplusplus)
70 extern "C" {
71 #endif
72 
73 /* Forward declarations */
74 struct dmub_srv;
75 struct dmub_srv_common_regs;
76 
77 /* enum dmub_status - return code for dmcub functions */
78 enum dmub_status {
79 	DMUB_STATUS_OK = 0,
80 	DMUB_STATUS_NO_CTX,
81 	DMUB_STATUS_QUEUE_FULL,
82 	DMUB_STATUS_TIMEOUT,
83 	DMUB_STATUS_INVALID,
84 };
85 
86 /* enum dmub_asic - dmub asic identifier */
87 enum dmub_asic {
88 	DMUB_ASIC_NONE = 0,
89 	DMUB_ASIC_DCN20,
90 	DMUB_ASIC_DCN21,
91 #ifdef CONFIG_DRM_AMD_DC_DCN3_0
92 	DMUB_ASIC_DCN30,
93 #endif
94 #ifdef CONFIG_DRM_AMD_DC_DCN3_01
95 	DMUB_ASIC_DCN301,
96 #endif
97 	DMUB_ASIC_MAX,
98 };
99 
100 /* enum dmub_window_id - dmub window identifier */
101 enum dmub_window_id {
102 	DMUB_WINDOW_0_INST_CONST = 0,
103 	DMUB_WINDOW_1_STACK,
104 	DMUB_WINDOW_2_BSS_DATA,
105 	DMUB_WINDOW_3_VBIOS,
106 	DMUB_WINDOW_4_MAILBOX,
107 	DMUB_WINDOW_5_TRACEBUFF,
108 	DMUB_WINDOW_6_FW_STATE,
109 	DMUB_WINDOW_7_SCRATCH_MEM,
110 	DMUB_WINDOW_TOTAL,
111 };
112 
113 /**
114  * struct dmub_region - dmub hw memory region
115  * @base: base address for region, must be 256 byte aligned
116  * @top: top address for region
117  */
118 struct dmub_region {
119 	uint32_t base;
120 	uint32_t top;
121 };
122 
123 /**
124  * struct dmub_window - dmub hw cache window
125  * @off: offset to the fb memory in gpu address space
126  * @r: region in uc address space for cache window
127  */
128 struct dmub_window {
129 	union dmub_addr offset;
130 	struct dmub_region region;
131 };
132 
133 /**
134  * struct dmub_fb - defines a dmub framebuffer memory region
135  * @cpu_addr: cpu virtual address for the region, NULL if invalid
136  * @gpu_addr: gpu virtual address for the region, NULL if invalid
137  * @size: size of the region in bytes, zero if invalid
138  */
139 struct dmub_fb {
140 	void *cpu_addr;
141 	uint64_t gpu_addr;
142 	uint32_t size;
143 };
144 
145 /**
146  * struct dmub_srv_region_params - params used for calculating dmub regions
147  * @inst_const_size: size of the fw inst const section
148  * @bss_data_size: size of the fw bss data section
149  * @vbios_size: size of the vbios data
150  * @fw_bss_data: raw firmware bss data section
151  */
152 struct dmub_srv_region_params {
153 	uint32_t inst_const_size;
154 	uint32_t bss_data_size;
155 	uint32_t vbios_size;
156 	const uint8_t *fw_inst_const;
157 	const uint8_t *fw_bss_data;
158 };
159 
160 /**
161  * struct dmub_srv_region_info - output region info from the dmub service
162  * @fb_size: required minimum fb size for all regions, aligned to 4096 bytes
163  * @num_regions: number of regions used by the dmub service
164  * @regions: region info
165  *
166  * The regions are aligned such that they can be all placed within the
167  * same framebuffer but they can also be placed into different framebuffers.
168  *
169  * The size of each region can be calculated by the caller:
170  * size = reg.top - reg.base
171  *
172  * Care must be taken when performing custom allocations to ensure that each
173  * region base address is 256 byte aligned.
174  */
175 struct dmub_srv_region_info {
176 	uint32_t fb_size;
177 	uint8_t num_regions;
178 	struct dmub_region regions[DMUB_WINDOW_TOTAL];
179 };
180 
181 /**
182  * struct dmub_srv_fb_params - parameters used for driver fb setup
183  * @region_info: region info calculated by dmub service
184  * @cpu_addr: base cpu address for the framebuffer
185  * @gpu_addr: base gpu virtual address for the framebuffer
186  */
187 struct dmub_srv_fb_params {
188 	const struct dmub_srv_region_info *region_info;
189 	void *cpu_addr;
190 	uint64_t gpu_addr;
191 };
192 
193 /**
194  * struct dmub_srv_fb_info - output fb info from the dmub service
195  * @num_fbs: number of required dmub framebuffers
196  * @fbs: fb data for each region
197  *
198  * Output from the dmub service helper that can be used by the
199  * driver to prepare dmub_fb that can be passed into the dmub
200  * hw init service.
201  *
202  * Assumes that all regions are within the same framebuffer
203  * and have been setup according to the region_info generated
204  * by the dmub service.
205  */
206 struct dmub_srv_fb_info {
207 	uint8_t num_fb;
208 	struct dmub_fb fb[DMUB_WINDOW_TOTAL];
209 };
210 
211 /**
212  * struct dmub_srv_base_funcs - Driver specific base callbacks
213  */
214 struct dmub_srv_base_funcs {
215 	/**
216 	 * @reg_read:
217 	 *
218 	 * Hook for reading a register.
219 	 *
220 	 * Return: The 32-bit register value from the given address.
221 	 */
222 	uint32_t (*reg_read)(void *ctx, uint32_t address);
223 
224 	/**
225 	 * @reg_write:
226 	 *
227 	 * Hook for writing a value to the register specified by address.
228 	 */
229 	void (*reg_write)(void *ctx, uint32_t address, uint32_t value);
230 };
231 
232 /**
233  * struct dmub_srv_hw_funcs - hardware sequencer funcs for dmub
234  */
235 struct dmub_srv_hw_funcs {
236 	/* private: internal use only */
237 
238 	void (*init)(struct dmub_srv *dmub);
239 
240 	void (*reset)(struct dmub_srv *dmub);
241 
242 	void (*reset_release)(struct dmub_srv *dmub);
243 
244 	void (*backdoor_load)(struct dmub_srv *dmub,
245 			      const struct dmub_window *cw0,
246 			      const struct dmub_window *cw1);
247 
248 	void (*setup_windows)(struct dmub_srv *dmub,
249 			      const struct dmub_window *cw2,
250 			      const struct dmub_window *cw3,
251 			      const struct dmub_window *cw4,
252 			      const struct dmub_window *cw5,
253 			      const struct dmub_window *cw6);
254 
255 	void (*setup_mailbox)(struct dmub_srv *dmub,
256 			      const struct dmub_region *inbox1);
257 
258 	uint32_t (*get_inbox1_rptr)(struct dmub_srv *dmub);
259 
260 	void (*set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
261 
262 	uint32_t (*emul_get_inbox1_rptr)(struct dmub_srv *dmub);
263 
264 	void (*emul_set_inbox1_wptr)(struct dmub_srv *dmub, uint32_t wptr_offset);
265 
266 	bool (*is_supported)(struct dmub_srv *dmub);
267 
268 	bool (*is_hw_init)(struct dmub_srv *dmub);
269 
270 	bool (*is_phy_init)(struct dmub_srv *dmub);
271 
272 	bool (*is_auto_load_done)(struct dmub_srv *dmub);
273 
274 	void (*set_gpint)(struct dmub_srv *dmub,
275 			  union dmub_gpint_data_register reg);
276 
277 	bool (*is_gpint_acked)(struct dmub_srv *dmub,
278 			       union dmub_gpint_data_register reg);
279 
280 	uint32_t (*get_gpint_response)(struct dmub_srv *dmub);
281 };
282 
283 /**
284  * struct dmub_srv_create_params - params for dmub service creation
285  * @base_funcs: driver supplied base routines
286  * @hw_funcs: optional overrides for hw funcs
287  * @user_ctx: context data for callback funcs
288  * @asic: driver supplied asic
289  * @fw_version: the current firmware version, if any
290  * @is_virtual: false for hw support only
291  */
292 struct dmub_srv_create_params {
293 	struct dmub_srv_base_funcs funcs;
294 	struct dmub_srv_hw_funcs *hw_funcs;
295 	void *user_ctx;
296 	enum dmub_asic asic;
297 	uint32_t fw_version;
298 	bool is_virtual;
299 };
300 
301 /*
302  * struct dmub_srv_hw_params - params for dmub hardware initialization
303  * @fb: framebuffer info for each region
304  * @fb_base: base of the framebuffer aperture
305  * @fb_offset: offset of the framebuffer aperture
306  * @psp_version: psp version to pass for DMCU init
307  * @load_inst_const: true if DMUB should load inst const fw
308  */
309 struct dmub_srv_hw_params {
310 	struct dmub_fb *fb[DMUB_WINDOW_TOTAL];
311 	uint64_t fb_base;
312 	uint64_t fb_offset;
313 	uint32_t psp_version;
314 	bool load_inst_const;
315 };
316 
317 /**
318  * struct dmub_srv - software state for dmcub
319  * @asic: dmub asic identifier
320  * @user_ctx: user provided context for the dmub_srv
321  * @fw_version: the current firmware version, if any
322  * @is_virtual: false if hardware support only
323  * @fw_state: dmub firmware state pointer
324  */
325 struct dmub_srv {
326 	enum dmub_asic asic;
327 	void *user_ctx;
328 	uint32_t fw_version;
329 	bool is_virtual;
330 	struct dmub_fb scratch_mem_fb;
331 	volatile const struct dmub_fw_state *fw_state;
332 
333 	/* private: internal use only */
334 	const struct dmub_srv_common_regs *regs;
335 
336 	struct dmub_srv_base_funcs funcs;
337 	struct dmub_srv_hw_funcs hw_funcs;
338 	struct dmub_rb inbox1_rb;
339 
340 	bool sw_init;
341 	bool hw_init;
342 
343 	uint64_t fb_base;
344 	uint64_t fb_offset;
345 	uint32_t psp_version;
346 };
347 
348 /**
349  * DMUB firmware version helper macro - useful for checking if the version
350  * of a firmware to know if feature or functionality is supported or present.
351  */
352 #define DMUB_FW_VERSION(major, minor, revision) \
353 	((((major) & 0xFF) << 24) | (((minor) & 0xFF) << 16) | ((revision) & 0xFFFF))
354 
355 /**
356  * dmub_srv_create() - creates the DMUB service.
357  * @dmub: the dmub service
358  * @params: creation parameters for the service
359  *
360  * Return:
361  *   DMUB_STATUS_OK - success
362  *   DMUB_STATUS_INVALID - unspecified error
363  */
364 enum dmub_status dmub_srv_create(struct dmub_srv *dmub,
365 				 const struct dmub_srv_create_params *params);
366 
367 /**
368  * dmub_srv_destroy() - destroys the DMUB service.
369  * @dmub: the dmub service
370  */
371 void dmub_srv_destroy(struct dmub_srv *dmub);
372 
373 /**
374  * dmub_srv_calc_region_info() - retreives region info from the dmub service
375  * @dmub: the dmub service
376  * @params: parameters used to calculate region locations
377  * @info_out: the output region info from dmub
378  *
379  * Calculates the base and top address for all relevant dmub regions
380  * using the parameters given (if any).
381  *
382  * Return:
383  *   DMUB_STATUS_OK - success
384  *   DMUB_STATUS_INVALID - unspecified error
385  */
386 enum dmub_status
387 dmub_srv_calc_region_info(struct dmub_srv *dmub,
388 			  const struct dmub_srv_region_params *params,
389 			  struct dmub_srv_region_info *out);
390 
391 /**
392  * dmub_srv_calc_region_info() - retreives fb info from the dmub service
393  * @dmub: the dmub service
394  * @params: parameters used to calculate fb locations
395  * @info_out: the output fb info from dmub
396  *
397  * Calculates the base and top address for all relevant dmub regions
398  * using the parameters given (if any).
399  *
400  * Return:
401  *   DMUB_STATUS_OK - success
402  *   DMUB_STATUS_INVALID - unspecified error
403  */
404 enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub,
405 				       const struct dmub_srv_fb_params *params,
406 				       struct dmub_srv_fb_info *out);
407 
408 /**
409  * dmub_srv_has_hw_support() - returns hw support state for dmcub
410  * @dmub: the dmub service
411  * @is_supported: hw support state
412  *
413  * Queries the hardware for DMCUB support and returns the result.
414  *
415  * Can be called before dmub_srv_hw_init().
416  *
417  * Return:
418  *   DMUB_STATUS_OK - success
419  *   DMUB_STATUS_INVALID - unspecified error
420  */
421 enum dmub_status dmub_srv_has_hw_support(struct dmub_srv *dmub,
422 					 bool *is_supported);
423 
424 /**
425  * dmub_srv_is_hw_init() - returns hardware init state
426  *
427  * Return:
428  *   DMUB_STATUS_OK - success
429  *   DMUB_STATUS_INVALID - unspecified error
430  */
431 enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init);
432 
433 /**
434  * dmub_srv_hw_init() - initializes the underlying DMUB hardware
435  * @dmub: the dmub service
436  * @params: params for hardware initialization
437  *
438  * Resets the DMUB hardware and performs backdoor loading of the
439  * required cache regions based on the input framebuffer regions.
440  *
441  * Return:
442  *   DMUB_STATUS_OK - success
443  *   DMUB_STATUS_NO_CTX - dmcub context not initialized
444  *   DMUB_STATUS_INVALID - unspecified error
445  */
446 enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
447 				  const struct dmub_srv_hw_params *params);
448 
449 /**
450  * dmub_srv_hw_reset() - puts the DMUB hardware in reset state if initialized
451  * @dmub: the dmub service
452  *
453  * Before destroying the DMUB service or releasing the backing framebuffer
454  * memory we'll need to put the DMCUB into reset first.
455  *
456  * A subsequent call to dmub_srv_hw_init() will re-enable the DMCUB.
457  *
458  * Return:
459  *   DMUB_STATUS_OK - success
460  *   DMUB_STATUS_INVALID - unspecified error
461  */
462 enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
463 
464 /**
465  * dmub_srv_cmd_queue() - queues a command to the DMUB
466  * @dmub: the dmub service
467  * @cmd: the command to queue
468  *
469  * Queues a command to the DMUB service but does not begin execution
470  * immediately.
471  *
472  * Return:
473  *   DMUB_STATUS_OK - success
474  *   DMUB_STATUS_QUEUE_FULL - no remaining room in queue
475  *   DMUB_STATUS_INVALID - unspecified error
476  */
477 enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
478 				    const union dmub_rb_cmd *cmd);
479 
480 /**
481  * dmub_srv_cmd_execute() - Executes a queued sequence to the dmub
482  * @dmub: the dmub service
483  *
484  * Begins execution of queued commands on the dmub.
485  *
486  * Return:
487  *   DMUB_STATUS_OK - success
488  *   DMUB_STATUS_INVALID - unspecified error
489  */
490 enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub);
491 
492 /**
493  * dmub_srv_wait_for_auto_load() - Waits for firmware auto load to complete
494  * @dmub: the dmub service
495  * @timeout_us: the maximum number of microseconds to wait
496  *
497  * Waits until firmware has been autoloaded by the DMCUB. The maximum
498  * wait time is given in microseconds to prevent spinning forever.
499  *
500  * On ASICs without firmware autoload support this function will return
501  * immediately.
502  *
503  * Return:
504  *   DMUB_STATUS_OK - success
505  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
506  *   DMUB_STATUS_INVALID - unspecified error
507  */
508 enum dmub_status dmub_srv_wait_for_auto_load(struct dmub_srv *dmub,
509 					     uint32_t timeout_us);
510 
511 /**
512  * dmub_srv_wait_for_phy_init() - Waits for DMUB PHY init to complete
513  * @dmub: the dmub service
514  * @timeout_us: the maximum number of microseconds to wait
515  *
516  * Waits until the PHY has been initialized by the DMUB. The maximum
517  * wait time is given in microseconds to prevent spinning forever.
518  *
519  * On ASICs without PHY init support this function will return
520  * immediately.
521  *
522  * Return:
523  *   DMUB_STATUS_OK - success
524  *   DMUB_STATUS_TIMEOUT - wait for phy init timed out
525  *   DMUB_STATUS_INVALID - unspecified error
526  */
527 enum dmub_status dmub_srv_wait_for_phy_init(struct dmub_srv *dmub,
528 					    uint32_t timeout_us);
529 
530 /**
531  * dmub_srv_wait_for_idle() - Waits for the DMUB to be idle
532  * @dmub: the dmub service
533  * @timeout_us: the maximum number of microseconds to wait
534  *
535  * Waits until the DMUB buffer is empty and all commands have
536  * finished processing. The maximum wait time is given in
537  * microseconds to prevent spinning forever.
538  *
539  * Return:
540  *   DMUB_STATUS_OK - success
541  *   DMUB_STATUS_TIMEOUT - wait for buffer to flush timed out
542  *   DMUB_STATUS_INVALID - unspecified error
543  */
544 enum dmub_status dmub_srv_wait_for_idle(struct dmub_srv *dmub,
545 					uint32_t timeout_us);
546 
547 /**
548  * dmub_srv_send_gpint_command() - Sends a GPINT based command.
549  * @dmub: the dmub service
550  * @command_code: the command code to send
551  * @param: the command parameter to send
552  * @timeout_us: the maximum number of microseconds to wait
553  *
554  * Sends a command via the general purpose interrupt (GPINT).
555  * Waits for the number of microseconds specified by timeout_us
556  * for the command ACK before returning.
557  *
558  * Can be called after software initialization.
559  *
560  * Return:
561  *   DMUB_STATUS_OK - success
562  *   DMUB_STATUS_TIMEOUT - wait for ACK timed out
563  *   DMUB_STATUS_INVALID - unspecified error
564  */
565 enum dmub_status
566 dmub_srv_send_gpint_command(struct dmub_srv *dmub,
567 			    enum dmub_gpint_command command_code,
568 			    uint16_t param, uint32_t timeout_us);
569 
570 /**
571  * dmub_srv_get_gpint_response() - Queries the GPINT response.
572  * @dmub: the dmub service
573  * @response: the response for the last GPINT
574  *
575  * Returns the response code for the last GPINT interrupt.
576  *
577  * Can be called after software initialization.
578  *
579  * Return:
580  *   DMUB_STATUS_OK - success
581  *   DMUB_STATUS_INVALID - unspecified error
582  */
583 enum dmub_status dmub_srv_get_gpint_response(struct dmub_srv *dmub,
584 					     uint32_t *response);
585 
586 /**
587  * dmub_flush_buffer_mem() - Read back entire frame buffer region.
588  * This ensures that the write from x86 has been flushed and will not
589  * hang the DMCUB.
590  * @fb: frame buffer to flush
591  *
592  * Can be called after software initialization.
593  */
594 void dmub_flush_buffer_mem(const struct dmub_fb *fb);
595 
596 #if defined(__cplusplus)
597 }
598 #endif
599 
600 #endif /* _DMUB_SRV_H_ */
601