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