OSDN Git Service

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