Home | History | Annotate | Line # | Download | only in inc
      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