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_CMD_H_ 27 #define _DMUB_CMD_H_ 28 29 #include <asm/byteorder.h> 30 #include <linux/types.h> 31 #include <linux/string.h> 32 #include <linux/delay.h> 33 #include <stdarg.h> 34 35 #include "atomfirmware.h" 36 37 /* Firmware versioning. */ 38 #ifdef DMUB_EXPOSE_VERSION 39 #define DMUB_FW_VERSION_GIT_HASH 0xe6d590b09 40 #define DMUB_FW_VERSION_MAJOR 0 41 #define DMUB_FW_VERSION_MINOR 0 42 #define DMUB_FW_VERSION_REVISION 25 43 #define DMUB_FW_VERSION_UCODE ((DMUB_FW_VERSION_MAJOR << 24) | (DMUB_FW_VERSION_MINOR << 16) | DMUB_FW_VERSION_REVISION) 44 #endif 45 46 //<DMUB_TYPES>================================================================== 47 /* Basic type definitions. */ 48 49 #define SET_ABM_PIPE_GRADUALLY_DISABLE 0 50 #define SET_ABM_PIPE_IMMEDIATELY_DISABLE 255 51 #define SET_ABM_PIPE_NORMAL 1 52 53 /* Maximum number of streams on any ASIC. */ 54 #define DMUB_MAX_STREAMS 6 55 56 /* Maximum number of planes on any ASIC. */ 57 #define DMUB_MAX_PLANES 6 58 59 #ifndef PHYSICAL_ADDRESS_LOC 60 #define PHYSICAL_ADDRESS_LOC union large_integer 61 #endif 62 63 #if defined(__cplusplus) 64 extern "C" { 65 #endif 66 67 #ifndef dmub_memcpy 68 #define dmub_memcpy(dest, source, bytes) memcpy((dest), (source), (bytes)) 69 #endif 70 71 #ifndef dmub_memset 72 #define dmub_memset(dest, val, bytes) memset((dest), (val), (bytes)) 73 #endif 74 75 #ifndef dmub_udelay 76 #define dmub_udelay(microseconds) udelay(microseconds) 77 #endif 78 79 union dmub_addr { 80 struct { 81 uint32_t low_part; 82 uint32_t high_part; 83 } u; 84 uint64_t quad_part; 85 }; 86 87 union dmub_psr_debug_flags { 88 struct { 89 uint32_t visual_confirm : 1; 90 uint32_t use_hw_lock_mgr : 1; 91 } bitfields; 92 93 uint32_t u32All; 94 }; 95 96 #if defined(__cplusplus) 97 } 98 #endif 99 100 101 102 //============================================================================== 103 //</DMUB_TYPES>================================================================= 104 //============================================================================== 105 //< DMUB_META>================================================================== 106 //============================================================================== 107 #pragma pack(push, 1) 108 109 /* Magic value for identifying dmub_fw_meta_info */ 110 #define DMUB_FW_META_MAGIC 0x444D5542 111 112 /* Offset from the end of the file to the dmub_fw_meta_info */ 113 #define DMUB_FW_META_OFFSET 0x24 114 115 /** 116 * struct dmub_fw_meta_info - metadata associated with fw binary 117 * 118 * NOTE: This should be considered a stable API. Fields should 119 * not be repurposed or reordered. New fields should be 120 * added instead to extend the structure. 121 * 122 * @magic_value: magic value identifying DMUB firmware meta info 123 * @fw_region_size: size of the firmware state region 124 * @trace_buffer_size: size of the tracebuffer region 125 * @fw_version: the firmware version information 126 * @dal_fw: 1 if the firmware is DAL 127 */ 128 struct dmub_fw_meta_info { 129 uint32_t magic_value; 130 uint32_t fw_region_size; 131 uint32_t trace_buffer_size; 132 uint32_t fw_version; 133 uint8_t dal_fw; 134 uint8_t reserved[3]; 135 }; 136 137 /* Ensure that the structure remains 64 bytes. */ 138 union dmub_fw_meta { 139 struct dmub_fw_meta_info info; 140 uint8_t reserved[64]; 141 }; 142 143 #pragma pack(pop) 144 145 //============================================================================== 146 //< DMUB_STATUS>================================================================ 147 //============================================================================== 148 149 /** 150 * DMCUB scratch registers can be used to determine firmware status. 151 * Current scratch register usage is as follows: 152 * 153 * SCRATCH0: FW Boot Status register 154 * SCRATCH15: FW Boot Options register 155 */ 156 157 /* Register bit definition for SCRATCH0 */ 158 union dmub_fw_boot_status { 159 struct { 160 uint32_t dal_fw : 1; 161 uint32_t mailbox_rdy : 1; 162 uint32_t optimized_init_done : 1; 163 uint32_t reserved : 29; 164 } bits; 165 uint32_t all; 166 }; 167 168 enum dmub_fw_boot_status_bit { 169 DMUB_FW_BOOT_STATUS_BIT_DAL_FIRMWARE = (1 << 0), 170 DMUB_FW_BOOT_STATUS_BIT_MAILBOX_READY = (1 << 1), 171 DMUB_FW_BOOT_STATUS_BIT_OPTIMIZED_INIT_DONE = (1 << 2), 172 }; 173 174 /* Register bit definition for SCRATCH15 */ 175 union dmub_fw_boot_options { 176 struct { 177 uint32_t pemu_env : 1; 178 uint32_t fpga_env : 1; 179 uint32_t optimized_init : 1; 180 uint32_t reserved : 29; 181 } bits; 182 uint32_t all; 183 }; 184 185 enum dmub_fw_boot_options_bit { 186 DMUB_FW_BOOT_OPTION_BIT_PEMU_ENV = (1 << 0), 187 DMUB_FW_BOOT_OPTION_BIT_FPGA_ENV = (1 << 1), 188 DMUB_FW_BOOT_OPTION_BIT_OPTIMIZED_INIT_DONE = (1 << 2), 189 }; 190 191 //============================================================================== 192 //</DMUB_STATUS>================================================================ 193 //============================================================================== 194 //< DMUB_VBIOS>================================================================= 195 //============================================================================== 196 197 /* 198 * Command IDs should be treated as stable ABI. 199 * Do not reuse or modify IDs. 200 */ 201 202 enum dmub_cmd_vbios_type { 203 DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL = 0, 204 DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL = 1, 205 DMUB_CMD__VBIOS_SET_PIXEL_CLOCK = 2, 206 DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING = 3, 207 }; 208 209 //============================================================================== 210 //</DMUB_VBIOS>================================================================= 211 //============================================================================== 212 //< DMUB_GPINT>================================================================= 213 //============================================================================== 214 215 /** 216 * The shifts and masks below may alternatively be used to format and read 217 * the command register bits. 218 */ 219 220 #define DMUB_GPINT_DATA_PARAM_MASK 0xFFFF 221 #define DMUB_GPINT_DATA_PARAM_SHIFT 0 222 223 #define DMUB_GPINT_DATA_COMMAND_CODE_MASK 0xFFF 224 #define DMUB_GPINT_DATA_COMMAND_CODE_SHIFT 16 225 226 #define DMUB_GPINT_DATA_STATUS_MASK 0xF 227 #define DMUB_GPINT_DATA_STATUS_SHIFT 28 228 229 /** 230 * Command responses. 231 */ 232 233 #define DMUB_GPINT__STOP_FW_RESPONSE 0xDEADDEAD 234 235 /** 236 * The register format for sending a command via the GPINT. 237 */ 238 union dmub_gpint_data_register { 239 struct { 240 uint32_t param : 16; 241 uint32_t command_code : 12; 242 uint32_t status : 4; 243 } bits; 244 uint32_t all; 245 }; 246 247 /* 248 * Command IDs should be treated as stable ABI. 249 * Do not reuse or modify IDs. 250 */ 251 252 enum dmub_gpint_command { 253 DMUB_GPINT__INVALID_COMMAND = 0, 254 DMUB_GPINT__GET_FW_VERSION = 1, 255 DMUB_GPINT__STOP_FW = 2, 256 DMUB_GPINT__GET_PSR_STATE = 7, 257 /** 258 * DESC: Notifies DMCUB of the currently active streams. 259 * ARGS: Stream mask, 1 bit per active stream index. 260 */ 261 DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK = 8, 262 }; 263 264 //============================================================================== 265 //</DMUB_GPINT>================================================================= 266 //============================================================================== 267 //< DMUB_CMD>=================================================================== 268 //============================================================================== 269 270 #define DMUB_RB_CMD_SIZE 64 271 #define DMUB_RB_MAX_ENTRY 128 272 #define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY) 273 #define REG_SET_MASK 0xFFFF 274 275 /* 276 * Command IDs should be treated as stable ABI. 277 * Do not reuse or modify IDs. 278 */ 279 280 enum dmub_cmd_type { 281 DMUB_CMD__NULL = 0, 282 DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE = 1, 283 DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ = 2, 284 DMUB_CMD__REG_SEQ_BURST_WRITE = 3, 285 DMUB_CMD__REG_REG_WAIT = 4, 286 DMUB_CMD__PLAT_54186_WA = 5, 287 DMUB_CMD__PSR = 64, 288 DMUB_CMD__ABM = 66, 289 DMUB_CMD__HW_LOCK = 69, 290 DMUB_CMD__VBIOS = 128, 291 }; 292 293 #pragma pack(push, 1) 294 295 struct dmub_cmd_header { 296 unsigned int type : 8; 297 unsigned int sub_type : 8; 298 unsigned int reserved0 : 8; 299 unsigned int payload_bytes : 6; /* up to 60 bytes */ 300 unsigned int reserved1 : 2; 301 }; 302 303 /* 304 * Read modify write 305 * 306 * 60 payload bytes can hold up to 5 sets of read modify writes, 307 * each take 3 dwords. 308 * 309 * number of sequences = header.payload_bytes / sizeof(struct dmub_cmd_read_modify_write_sequence) 310 * 311 * modify_mask = 0xffff'ffff means all fields are going to be updated. in this case 312 * command parser will skip the read and we can use modify_mask = 0xffff'ffff as reg write 313 */ 314 struct dmub_cmd_read_modify_write_sequence { 315 uint32_t addr; 316 uint32_t modify_mask; 317 uint32_t modify_value; 318 }; 319 320 #define DMUB_READ_MODIFY_WRITE_SEQ__MAX 5 321 struct dmub_rb_cmd_read_modify_write { 322 struct dmub_cmd_header header; // type = DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE 323 struct dmub_cmd_read_modify_write_sequence seq[DMUB_READ_MODIFY_WRITE_SEQ__MAX]; 324 }; 325 326 /* 327 * Update a register with specified masks and values sequeunce 328 * 329 * 60 payload bytes can hold address + up to 7 sets of mask/value combo, each take 2 dword 330 * 331 * number of field update sequence = (header.payload_bytes - sizeof(addr)) / sizeof(struct read_modify_write_sequence) 332 * 333 * 334 * USE CASE: 335 * 1. auto-increment register where additional read would update pointer and produce wrong result 336 * 2. toggle a bit without read in the middle 337 */ 338 339 struct dmub_cmd_reg_field_update_sequence { 340 uint32_t modify_mask; // 0xffff'ffff to skip initial read 341 uint32_t modify_value; 342 }; 343 344 #define DMUB_REG_FIELD_UPDATE_SEQ__MAX 7 345 struct dmub_rb_cmd_reg_field_update_sequence { 346 struct dmub_cmd_header header; 347 uint32_t addr; 348 struct dmub_cmd_reg_field_update_sequence seq[DMUB_REG_FIELD_UPDATE_SEQ__MAX]; 349 }; 350 351 /* 352 * Burst write 353 * 354 * support use case such as writing out LUTs. 355 * 356 * 60 payload bytes can hold up to 14 values to write to given address 357 * 358 * number of payload = header.payload_bytes / sizeof(struct read_modify_write_sequence) 359 */ 360 #define DMUB_BURST_WRITE_VALUES__MAX 14 361 struct dmub_rb_cmd_burst_write { 362 struct dmub_cmd_header header; // type = DMUB_CMD__REG_SEQ_BURST_WRITE 363 uint32_t addr; 364 uint32_t write_values[DMUB_BURST_WRITE_VALUES__MAX]; 365 }; 366 367 368 struct dmub_rb_cmd_common { 369 struct dmub_cmd_header header; 370 uint8_t cmd_buffer[DMUB_RB_CMD_SIZE - sizeof(struct dmub_cmd_header)]; 371 }; 372 373 struct dmub_cmd_reg_wait_data { 374 uint32_t addr; 375 uint32_t mask; 376 uint32_t condition_field_value; 377 uint32_t time_out_us; 378 }; 379 380 struct dmub_rb_cmd_reg_wait { 381 struct dmub_cmd_header header; 382 struct dmub_cmd_reg_wait_data reg_wait; 383 }; 384 385 struct dmub_cmd_PLAT_54186_wa { 386 uint32_t DCSURF_SURFACE_CONTROL; 387 uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; 388 uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; 389 uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; 390 uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; 391 struct { 392 uint8_t hubp_inst : 4; 393 uint8_t tmz_surface : 1; 394 uint8_t immediate :1; 395 uint8_t vmid : 4; 396 uint8_t grph_stereo : 1; 397 uint32_t reserved : 21; 398 } flip_params; 399 uint32_t reserved[9]; 400 }; 401 402 struct dmub_rb_cmd_PLAT_54186_wa { 403 struct dmub_cmd_header header; 404 struct dmub_cmd_PLAT_54186_wa flip; 405 }; 406 407 struct dmub_cmd_digx_encoder_control_data { 408 union dig_encoder_control_parameters_v1_5 dig; 409 }; 410 411 struct dmub_rb_cmd_digx_encoder_control { 412 struct dmub_cmd_header header; 413 struct dmub_cmd_digx_encoder_control_data encoder_control; 414 }; 415 416 struct dmub_cmd_set_pixel_clock_data { 417 struct set_pixel_clock_parameter_v1_7 clk; 418 }; 419 420 struct dmub_rb_cmd_set_pixel_clock { 421 struct dmub_cmd_header header; 422 struct dmub_cmd_set_pixel_clock_data pixel_clock; 423 }; 424 425 struct dmub_cmd_enable_disp_power_gating_data { 426 struct enable_disp_power_gating_parameters_v2_1 pwr; 427 }; 428 429 struct dmub_rb_cmd_enable_disp_power_gating { 430 struct dmub_cmd_header header; 431 struct dmub_cmd_enable_disp_power_gating_data power_gating; 432 }; 433 434 struct dmub_cmd_dig1_transmitter_control_data { 435 struct dig_transmitter_control_parameters_v1_6 dig; 436 }; 437 438 struct dmub_rb_cmd_dig1_transmitter_control { 439 struct dmub_cmd_header header; 440 struct dmub_cmd_dig1_transmitter_control_data transmitter_control; 441 }; 442 443 struct dmub_rb_cmd_dpphy_init { 444 struct dmub_cmd_header header; 445 uint8_t reserved[60]; 446 }; 447 448 /* 449 * Command IDs should be treated as stable ABI. 450 * Do not reuse or modify IDs. 451 */ 452 453 enum dmub_cmd_psr_type { 454 DMUB_CMD__PSR_SET_VERSION = 0, 455 DMUB_CMD__PSR_COPY_SETTINGS = 1, 456 DMUB_CMD__PSR_ENABLE = 2, 457 DMUB_CMD__PSR_DISABLE = 3, 458 DMUB_CMD__PSR_SET_LEVEL = 4, 459 }; 460 461 enum psr_version { 462 PSR_VERSION_1 = 0, 463 PSR_VERSION_UNSUPPORTED = 0xFFFFFFFF, 464 }; 465 466 struct dmub_cmd_psr_copy_settings_data { 467 union dmub_psr_debug_flags debug; 468 uint16_t psr_level; 469 uint8_t dpp_inst; 470 uint8_t mpcc_inst; 471 uint8_t opp_inst; 472 uint8_t otg_inst; 473 uint8_t digfe_inst; 474 uint8_t digbe_inst; 475 uint8_t dpphy_inst; 476 uint8_t aux_inst; 477 uint8_t smu_optimizations_en; 478 uint8_t frame_delay; 479 uint8_t frame_cap_ind; 480 uint8_t pad[3]; 481 uint16_t init_sdp_deadline; 482 uint16_t pad2; 483 }; 484 485 struct dmub_rb_cmd_psr_copy_settings { 486 struct dmub_cmd_header header; 487 struct dmub_cmd_psr_copy_settings_data psr_copy_settings_data; 488 }; 489 490 struct dmub_cmd_psr_set_level_data { 491 uint16_t psr_level; 492 uint8_t pad[2]; 493 }; 494 495 struct dmub_rb_cmd_psr_set_level { 496 struct dmub_cmd_header header; 497 struct dmub_cmd_psr_set_level_data psr_set_level_data; 498 }; 499 500 struct dmub_rb_cmd_psr_enable { 501 struct dmub_cmd_header header; 502 }; 503 504 struct dmub_cmd_psr_set_version_data { 505 enum psr_version version; // PSR version 1 or 2 506 }; 507 508 struct dmub_rb_cmd_psr_set_version { 509 struct dmub_cmd_header header; 510 struct dmub_cmd_psr_set_version_data psr_set_version_data; 511 }; 512 513 union dmub_hw_lock_flags { 514 struct { 515 uint8_t lock_pipe : 1; 516 uint8_t lock_cursor : 1; 517 uint8_t lock_dig : 1; 518 uint8_t triple_buffer_lock : 1; 519 } bits; 520 521 uint8_t u8All; 522 }; 523 524 struct dmub_hw_lock_inst_flags { 525 uint8_t otg_inst; 526 uint8_t opp_inst; 527 uint8_t dig_inst; 528 uint8_t pad; 529 }; 530 531 enum hw_lock_client { 532 HW_LOCK_CLIENT_DRIVER = 0, 533 HW_LOCK_CLIENT_FW, 534 HW_LOCK_CLIENT_INVALID = 0xFFFFFFFF, 535 }; 536 537 struct dmub_cmd_lock_hw_data { 538 enum hw_lock_client client; 539 struct dmub_hw_lock_inst_flags inst_flags; 540 union dmub_hw_lock_flags hw_locks; 541 uint8_t lock; 542 uint8_t should_release; 543 uint8_t pad; 544 }; 545 546 struct dmub_rb_cmd_lock_hw { 547 struct dmub_cmd_header header; 548 struct dmub_cmd_lock_hw_data lock_hw_data; 549 }; 550 551 enum dmub_cmd_abm_type { 552 DMUB_CMD__ABM_INIT_CONFIG = 0, 553 DMUB_CMD__ABM_SET_PIPE = 1, 554 DMUB_CMD__ABM_SET_BACKLIGHT = 2, 555 DMUB_CMD__ABM_SET_LEVEL = 3, 556 DMUB_CMD__ABM_SET_AMBIENT_LEVEL = 4, 557 DMUB_CMD__ABM_SET_PWM_FRAC = 5, 558 }; 559 560 #define NUM_AMBI_LEVEL 5 561 #define NUM_AGGR_LEVEL 4 562 #define NUM_POWER_FN_SEGS 8 563 #define NUM_BL_CURVE_SEGS 16 564 565 /* 566 * Parameters for ABM2.4 algorithm. 567 * Padded explicitly to 32-bit boundary. 568 */ 569 struct abm_config_table { 570 /* Parameters for crgb conversion */ 571 uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; // 0B 572 uint16_t crgb_offset[NUM_POWER_FN_SEGS]; // 15B 573 uint16_t crgb_slope[NUM_POWER_FN_SEGS]; // 31B 574 575 /* Parameters for custom curve */ 576 uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; // 47B 577 uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; // 79B 578 579 uint16_t ambient_thresholds_lux[NUM_AMBI_LEVEL]; // 111B 580 uint16_t min_abm_backlight; // 121B 581 582 uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 123B 583 uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 143B 584 uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 163B 585 uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 183B 586 uint8_t hybrid_factor[NUM_AGGR_LEVEL]; // 203B 587 uint8_t contrast_factor[NUM_AGGR_LEVEL]; // 207B 588 uint8_t deviation_gain[NUM_AGGR_LEVEL]; // 211B 589 uint8_t min_knee[NUM_AGGR_LEVEL]; // 215B 590 uint8_t max_knee[NUM_AGGR_LEVEL]; // 219B 591 uint8_t iir_curve[NUM_AMBI_LEVEL]; // 223B 592 uint8_t pad3[3]; // 228B 593 }; 594 595 struct dmub_cmd_abm_set_pipe_data { 596 uint8_t otg_inst; 597 uint8_t panel_inst; 598 uint8_t set_pipe_option; 599 uint8_t ramping_boundary; // TODO: Remove this 600 }; 601 602 struct dmub_rb_cmd_abm_set_pipe { 603 struct dmub_cmd_header header; 604 struct dmub_cmd_abm_set_pipe_data abm_set_pipe_data; 605 }; 606 607 struct dmub_cmd_abm_set_backlight_data { 608 uint32_t frame_ramp; 609 uint32_t backlight_user_level; 610 }; 611 612 struct dmub_rb_cmd_abm_set_backlight { 613 struct dmub_cmd_header header; 614 struct dmub_cmd_abm_set_backlight_data abm_set_backlight_data; 615 }; 616 617 struct dmub_cmd_abm_set_level_data { 618 uint32_t level; 619 }; 620 621 struct dmub_rb_cmd_abm_set_level { 622 struct dmub_cmd_header header; 623 struct dmub_cmd_abm_set_level_data abm_set_level_data; 624 }; 625 626 struct dmub_cmd_abm_set_ambient_level_data { 627 uint32_t ambient_lux; 628 }; 629 630 struct dmub_rb_cmd_abm_set_ambient_level { 631 struct dmub_cmd_header header; 632 struct dmub_cmd_abm_set_ambient_level_data abm_set_ambient_level_data; 633 }; 634 635 struct dmub_cmd_abm_set_pwm_frac_data { 636 uint32_t fractional_pwm; 637 }; 638 639 struct dmub_rb_cmd_abm_set_pwm_frac { 640 struct dmub_cmd_header header; 641 struct dmub_cmd_abm_set_pwm_frac_data abm_set_pwm_frac_data; 642 }; 643 644 struct dmub_cmd_abm_init_config_data { 645 union dmub_addr src; 646 uint16_t bytes; 647 }; 648 649 struct dmub_rb_cmd_abm_init_config { 650 struct dmub_cmd_header header; 651 struct dmub_cmd_abm_init_config_data abm_init_config_data; 652 }; 653 654 union dmub_rb_cmd { 655 struct dmub_rb_cmd_lock_hw lock_hw; 656 struct dmub_rb_cmd_read_modify_write read_modify_write; 657 struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq; 658 struct dmub_rb_cmd_burst_write burst_write; 659 struct dmub_rb_cmd_reg_wait reg_wait; 660 struct dmub_rb_cmd_common cmd_common; 661 struct dmub_rb_cmd_digx_encoder_control digx_encoder_control; 662 struct dmub_rb_cmd_set_pixel_clock set_pixel_clock; 663 struct dmub_rb_cmd_enable_disp_power_gating enable_disp_power_gating; 664 struct dmub_rb_cmd_dpphy_init dpphy_init; 665 struct dmub_rb_cmd_dig1_transmitter_control dig1_transmitter_control; 666 struct dmub_rb_cmd_psr_set_version psr_set_version; 667 struct dmub_rb_cmd_psr_copy_settings psr_copy_settings; 668 struct dmub_rb_cmd_psr_enable psr_enable; 669 struct dmub_rb_cmd_psr_set_level psr_set_level; 670 struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa; 671 struct dmub_rb_cmd_abm_set_pipe abm_set_pipe; 672 struct dmub_rb_cmd_abm_set_backlight abm_set_backlight; 673 struct dmub_rb_cmd_abm_set_level abm_set_level; 674 struct dmub_rb_cmd_abm_set_ambient_level abm_set_ambient_level; 675 struct dmub_rb_cmd_abm_set_pwm_frac abm_set_pwm_frac; 676 struct dmub_rb_cmd_abm_init_config abm_init_config; 677 }; 678 679 #pragma pack(pop) 680 681 682 //============================================================================== 683 //</DMUB_CMD>=================================================================== 684 //============================================================================== 685 //< DMUB_RB>==================================================================== 686 //============================================================================== 687 688 #if defined(__cplusplus) 689 extern "C" { 690 #endif 691 692 struct dmub_rb_init_params { 693 void *ctx; 694 void *base_address; 695 uint32_t capacity; 696 uint32_t read_ptr; 697 uint32_t write_ptr; 698 }; 699 700 struct dmub_rb { 701 void *base_address; 702 uint32_t data_count; 703 uint32_t rptr; 704 uint32_t wrpt; 705 uint32_t capacity; 706 707 void *ctx; 708 void *dmub; 709 }; 710 711 712 static inline bool dmub_rb_empty(struct dmub_rb *rb) 713 { 714 return (rb->wrpt == rb->rptr); 715 } 716 717 static inline bool dmub_rb_full(struct dmub_rb *rb) 718 { 719 uint32_t data_count; 720 721 if (rb->wrpt >= rb->rptr) 722 data_count = rb->wrpt - rb->rptr; 723 else 724 data_count = rb->capacity - (rb->rptr - rb->wrpt); 725 726 return (data_count == (rb->capacity - DMUB_RB_CMD_SIZE)); 727 } 728 729 static inline bool dmub_rb_push_front(struct dmub_rb *rb, 730 const union dmub_rb_cmd *cmd) 731 { 732 uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t); 733 const uint64_t *src = (const uint64_t *)cmd; 734 int i; 735 736 if (dmub_rb_full(rb)) 737 return false; 738 739 // copying data 740 for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) 741 *dst++ = *src++; 742 743 rb->wrpt += DMUB_RB_CMD_SIZE; 744 745 if (rb->wrpt >= rb->capacity) 746 rb->wrpt %= rb->capacity; 747 748 return true; 749 } 750 751 static inline bool dmub_rb_front(struct dmub_rb *rb, 752 union dmub_rb_cmd *cmd) 753 { 754 uint8_t *rd_ptr = (uint8_t *)rb->base_address + rb->rptr; 755 756 if (dmub_rb_empty(rb)) 757 return false; 758 759 dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE); 760 761 return true; 762 } 763 764 static inline bool dmub_rb_pop_front(struct dmub_rb *rb) 765 { 766 if (dmub_rb_empty(rb)) 767 return false; 768 769 rb->rptr += DMUB_RB_CMD_SIZE; 770 771 if (rb->rptr >= rb->capacity) 772 rb->rptr %= rb->capacity; 773 774 return true; 775 } 776 777 static inline void dmub_rb_flush_pending(const struct dmub_rb *rb) 778 { 779 uint32_t rptr = rb->rptr; 780 uint32_t wptr = rb->wrpt; 781 782 while (rptr != wptr) { 783 uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t); 784 //uint64_t volatile *p = (uint64_t volatile *)data; 785 uint64_t temp; 786 int i; 787 788 for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++) 789 temp = *data++; 790 791 rptr += DMUB_RB_CMD_SIZE; 792 if (rptr >= rb->capacity) 793 rptr %= rb->capacity; 794 } 795 } 796 797 static inline void dmub_rb_init(struct dmub_rb *rb, 798 struct dmub_rb_init_params *init_params) 799 { 800 rb->base_address = init_params->base_address; 801 rb->capacity = init_params->capacity; 802 rb->rptr = init_params->read_ptr; 803 rb->wrpt = init_params->write_ptr; 804 } 805 806 #if defined(__cplusplus) 807 } 808 #endif 809 810 //============================================================================== 811 //</DMUB_RB>==================================================================== 812 //============================================================================== 813 814 #endif /* _DMUB_CMD_H_ */ 815