linux/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
<<
>>
Prefs
   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#if defined(_TEST_HARNESS) || defined(FPGA_USB4)
  30#include "dmub_fw_types.h"
  31#include "include_legacy/atomfirmware.h"
  32
  33#if defined(_TEST_HARNESS)
  34#include <string.h>
  35#endif
  36#else
  37
  38#include <asm/byteorder.h>
  39#include <linux/types.h>
  40#include <linux/string.h>
  41#include <linux/delay.h>
  42#include <stdarg.h>
  43
  44#include "atomfirmware.h"
  45
  46#endif // defined(_TEST_HARNESS) || defined(FPGA_USB4)
  47
  48/* Firmware versioning. */
  49#ifdef DMUB_EXPOSE_VERSION
  50#define DMUB_FW_VERSION_GIT_HASH 0x23db9b126
  51#define DMUB_FW_VERSION_MAJOR 0
  52#define DMUB_FW_VERSION_MINOR 0
  53#define DMUB_FW_VERSION_REVISION 62
  54#define DMUB_FW_VERSION_TEST 0
  55#define DMUB_FW_VERSION_VBIOS 0
  56#define DMUB_FW_VERSION_HOTFIX 0
  57#define DMUB_FW_VERSION_UCODE (((DMUB_FW_VERSION_MAJOR & 0xFF) << 24) | \
  58                ((DMUB_FW_VERSION_MINOR & 0xFF) << 16) | \
  59                ((DMUB_FW_VERSION_REVISION & 0xFF) << 8) | \
  60                ((DMUB_FW_VERSION_TEST & 0x1) << 7) | \
  61                ((DMUB_FW_VERSION_VBIOS & 0x1) << 6) | \
  62                (DMUB_FW_VERSION_HOTFIX & 0x3F))
  63
  64#endif
  65
  66//<DMUB_TYPES>==================================================================
  67/* Basic type definitions. */
  68
  69#define __forceinline inline
  70
  71/**
  72 * Flag from driver to indicate that ABM should be disabled gradually
  73 * by slowly reversing all backlight programming and pixel compensation.
  74 */
  75#define SET_ABM_PIPE_GRADUALLY_DISABLE           0
  76
  77/**
  78 * Flag from driver to indicate that ABM should be disabled immediately
  79 * and undo all backlight programming and pixel compensation.
  80 */
  81#define SET_ABM_PIPE_IMMEDIATELY_DISABLE         255
  82
  83/**
  84 * Flag from driver to indicate that ABM should be disabled immediately
  85 * and keep the current backlight programming and pixel compensation.
  86 */
  87#define SET_ABM_PIPE_IMMEDIATE_KEEP_GAIN_DISABLE 254
  88
  89/**
  90 * Flag from driver to set the current ABM pipe index or ABM operating level.
  91 */
  92#define SET_ABM_PIPE_NORMAL                      1
  93
  94/**
  95 * Number of ambient light levels in ABM algorithm.
  96 */
  97#define NUM_AMBI_LEVEL                  5
  98
  99/**
 100 * Number of operating/aggression levels in ABM algorithm.
 101 */
 102#define NUM_AGGR_LEVEL                  4
 103
 104/**
 105 * Number of segments in the gamma curve.
 106 */
 107#define NUM_POWER_FN_SEGS               8
 108
 109/**
 110 * Number of segments in the backlight curve.
 111 */
 112#define NUM_BL_CURVE_SEGS               16
 113
 114/* Maximum number of streams on any ASIC. */
 115#define DMUB_MAX_STREAMS 6
 116
 117/* Maximum number of planes on any ASIC. */
 118#define DMUB_MAX_PLANES 6
 119
 120/* Trace buffer offset for entry */
 121#define TRACE_BUFFER_ENTRY_OFFSET  16
 122
 123/**
 124 * ABM backlight control version legacy
 125 */
 126#define DMUB_CMD_ABM_SET_BACKLIGHT_VERSION_UNKNOWN 0x0
 127
 128/**
 129 * ABM backlight control version with multi edp support
 130 */
 131#define DMUB_CMD_ABM_SET_BACKLIGHT_VERSION_1 0x1
 132
 133/**
 134 * Physical framebuffer address location, 64-bit.
 135 */
 136#ifndef PHYSICAL_ADDRESS_LOC
 137#define PHYSICAL_ADDRESS_LOC union large_integer
 138#endif
 139
 140/**
 141 * OS/FW agnostic memcpy
 142 */
 143#ifndef dmub_memcpy
 144#define dmub_memcpy(dest, source, bytes) memcpy((dest), (source), (bytes))
 145#endif
 146
 147/**
 148 * OS/FW agnostic memset
 149 */
 150#ifndef dmub_memset
 151#define dmub_memset(dest, val, bytes) memset((dest), (val), (bytes))
 152#endif
 153
 154#if defined(__cplusplus)
 155extern "C" {
 156#endif
 157
 158/**
 159 * OS/FW agnostic udelay
 160 */
 161#ifndef dmub_udelay
 162#define dmub_udelay(microseconds) udelay(microseconds)
 163#endif
 164
 165/**
 166 * union dmub_addr - DMUB physical/virtual 64-bit address.
 167 */
 168union dmub_addr {
 169        struct {
 170                uint32_t low_part; /**< Lower 32 bits */
 171                uint32_t high_part; /**< Upper 32 bits */
 172        } u; /*<< Low/high bit access */
 173        uint64_t quad_part; /*<< 64 bit address */
 174};
 175
 176/**
 177 * Flags that can be set by driver to change some PSR behaviour.
 178 */
 179union dmub_psr_debug_flags {
 180        /**
 181         * Debug flags.
 182         */
 183        struct {
 184                /**
 185                 * Enable visual confirm in FW.
 186                 */
 187                uint32_t visual_confirm : 1;
 188                /**
 189                 * Use HW Lock Mgr object to do HW locking in FW.
 190                 */
 191                uint32_t use_hw_lock_mgr : 1;
 192
 193                /**
 194                 * Unused.
 195                 * TODO: Remove.
 196                 */
 197                uint32_t log_line_nums : 1;
 198        } bitfields;
 199
 200        /**
 201         * Union for debug flags.
 202         */
 203        uint32_t u32All;
 204};
 205
 206/**
 207 * DMUB feature capabilities.
 208 * After DMUB init, driver will query FW capabilities prior to enabling certain features.
 209 */
 210struct dmub_feature_caps {
 211        /**
 212         * Max PSR version supported by FW.
 213         */
 214        uint8_t psr;
 215        uint8_t reserved[7];
 216};
 217
 218#if defined(__cplusplus)
 219}
 220#endif
 221
 222//==============================================================================
 223//</DMUB_TYPES>=================================================================
 224//==============================================================================
 225//< DMUB_META>==================================================================
 226//==============================================================================
 227#pragma pack(push, 1)
 228
 229/* Magic value for identifying dmub_fw_meta_info */
 230#define DMUB_FW_META_MAGIC 0x444D5542
 231
 232/* Offset from the end of the file to the dmub_fw_meta_info */
 233#define DMUB_FW_META_OFFSET 0x24
 234
 235/**
 236 * struct dmub_fw_meta_info - metadata associated with fw binary
 237 *
 238 * NOTE: This should be considered a stable API. Fields should
 239 *       not be repurposed or reordered. New fields should be
 240 *       added instead to extend the structure.
 241 *
 242 * @magic_value: magic value identifying DMUB firmware meta info
 243 * @fw_region_size: size of the firmware state region
 244 * @trace_buffer_size: size of the tracebuffer region
 245 * @fw_version: the firmware version information
 246 * @dal_fw: 1 if the firmware is DAL
 247 */
 248struct dmub_fw_meta_info {
 249        uint32_t magic_value; /**< magic value identifying DMUB firmware meta info */
 250        uint32_t fw_region_size; /**< size of the firmware state region */
 251        uint32_t trace_buffer_size; /**< size of the tracebuffer region */
 252        uint32_t fw_version; /**< the firmware version information */
 253        uint8_t dal_fw; /**< 1 if the firmware is DAL */
 254        uint8_t reserved[3]; /**< padding bits */
 255};
 256
 257/**
 258 * union dmub_fw_meta - ensures that dmub_fw_meta_info remains 64 bytes
 259 */
 260union dmub_fw_meta {
 261        struct dmub_fw_meta_info info; /**< metadata info */
 262        uint8_t reserved[64]; /**< padding bits */
 263};
 264
 265#pragma pack(pop)
 266
 267//==============================================================================
 268//< DMUB Trace Buffer>================================================================
 269//==============================================================================
 270/**
 271 * dmub_trace_code_t - firmware trace code, 32-bits
 272 */
 273typedef uint32_t dmub_trace_code_t;
 274
 275/**
 276 * struct dmcub_trace_buf_entry - Firmware trace entry
 277 */
 278struct dmcub_trace_buf_entry {
 279        dmub_trace_code_t trace_code; /**< trace code for the event */
 280        uint32_t tick_count; /**< the tick count at time of trace */
 281        uint32_t param0; /**< trace defined parameter 0 */
 282        uint32_t param1; /**< trace defined parameter 1 */
 283};
 284
 285//==============================================================================
 286//< DMUB_STATUS>================================================================
 287//==============================================================================
 288
 289/**
 290 * DMCUB scratch registers can be used to determine firmware status.
 291 * Current scratch register usage is as follows:
 292 *
 293 * SCRATCH0: FW Boot Status register
 294 * SCRATCH15: FW Boot Options register
 295 */
 296
 297/**
 298 * union dmub_fw_boot_status - Status bit definitions for SCRATCH0.
 299 */
 300union dmub_fw_boot_status {
 301        struct {
 302                uint32_t dal_fw : 1; /**< 1 if DAL FW */
 303                uint32_t mailbox_rdy : 1; /**< 1 if mailbox ready */
 304                uint32_t optimized_init_done : 1; /**< 1 if optimized init done */
 305                uint32_t restore_required : 1; /**< 1 if driver should call restore */
 306        } bits; /**< status bits */
 307        uint32_t all; /**< 32-bit access to status bits */
 308};
 309
 310/**
 311 * enum dmub_fw_boot_status_bit - Enum bit definitions for SCRATCH0.
 312 */
 313enum dmub_fw_boot_status_bit {
 314        DMUB_FW_BOOT_STATUS_BIT_DAL_FIRMWARE = (1 << 0), /**< 1 if DAL FW */
 315        DMUB_FW_BOOT_STATUS_BIT_MAILBOX_READY = (1 << 1), /**< 1 if mailbox ready */
 316        DMUB_FW_BOOT_STATUS_BIT_OPTIMIZED_INIT_DONE = (1 << 2), /**< 1 if init done */
 317        DMUB_FW_BOOT_STATUS_BIT_RESTORE_REQUIRED = (1 << 3), /**< 1 if driver should call restore */
 318};
 319
 320/**
 321 * union dmub_fw_boot_options - Boot option definitions for SCRATCH15
 322 */
 323union dmub_fw_boot_options {
 324        struct {
 325                uint32_t pemu_env : 1; /**< 1 if PEMU */
 326                uint32_t fpga_env : 1; /**< 1 if FPGA */
 327                uint32_t optimized_init : 1; /**< 1 if optimized init */
 328                uint32_t skip_phy_access : 1; /**< 1 if PHY access should be skipped */
 329                uint32_t disable_clk_gate: 1; /**< 1 if clock gating should be disabled */
 330                uint32_t skip_phy_init_panel_sequence: 1; /**< 1 to skip panel init seq */
 331                uint32_t reserved : 26; /**< reserved */
 332        } bits; /**< boot bits */
 333        uint32_t all; /**< 32-bit access to bits */
 334};
 335
 336enum dmub_fw_boot_options_bit {
 337        DMUB_FW_BOOT_OPTION_BIT_PEMU_ENV = (1 << 0), /**< 1 if PEMU */
 338        DMUB_FW_BOOT_OPTION_BIT_FPGA_ENV = (1 << 1), /**< 1 if FPGA */
 339        DMUB_FW_BOOT_OPTION_BIT_OPTIMIZED_INIT_DONE = (1 << 2), /**< 1 if optimized init done */
 340};
 341
 342//==============================================================================
 343//</DMUB_STATUS>================================================================
 344//==============================================================================
 345//< DMUB_VBIOS>=================================================================
 346//==============================================================================
 347
 348/*
 349 * enum dmub_cmd_vbios_type - VBIOS commands.
 350 *
 351 * Command IDs should be treated as stable ABI.
 352 * Do not reuse or modify IDs.
 353 */
 354enum dmub_cmd_vbios_type {
 355        /**
 356         * Configures the DIG encoder.
 357         */
 358        DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL = 0,
 359        /**
 360         * Controls the PHY.
 361         */
 362        DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL = 1,
 363        /**
 364         * Sets the pixel clock/symbol clock.
 365         */
 366        DMUB_CMD__VBIOS_SET_PIXEL_CLOCK = 2,
 367        /**
 368         * Enables or disables power gating.
 369         */
 370        DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING = 3,
 371        DMUB_CMD__VBIOS_LVTMA_CONTROL = 15,
 372};
 373
 374//==============================================================================
 375//</DMUB_VBIOS>=================================================================
 376//==============================================================================
 377//< DMUB_GPINT>=================================================================
 378//==============================================================================
 379
 380/**
 381 * The shifts and masks below may alternatively be used to format and read
 382 * the command register bits.
 383 */
 384
 385#define DMUB_GPINT_DATA_PARAM_MASK 0xFFFF
 386#define DMUB_GPINT_DATA_PARAM_SHIFT 0
 387
 388#define DMUB_GPINT_DATA_COMMAND_CODE_MASK 0xFFF
 389#define DMUB_GPINT_DATA_COMMAND_CODE_SHIFT 16
 390
 391#define DMUB_GPINT_DATA_STATUS_MASK 0xF
 392#define DMUB_GPINT_DATA_STATUS_SHIFT 28
 393
 394/**
 395 * Command responses.
 396 */
 397
 398/**
 399 * Return response for DMUB_GPINT__STOP_FW command.
 400 */
 401#define DMUB_GPINT__STOP_FW_RESPONSE 0xDEADDEAD
 402
 403/**
 404 * union dmub_gpint_data_register - Format for sending a command via the GPINT.
 405 */
 406union dmub_gpint_data_register {
 407        struct {
 408                uint32_t param : 16; /**< 16-bit parameter */
 409                uint32_t command_code : 12; /**< GPINT command */
 410                uint32_t status : 4; /**< Command status bit */
 411        } bits; /**< GPINT bit access */
 412        uint32_t all; /**< GPINT  32-bit access */
 413};
 414
 415/*
 416 * enum dmub_gpint_command - GPINT command to DMCUB FW
 417 *
 418 * Command IDs should be treated as stable ABI.
 419 * Do not reuse or modify IDs.
 420 */
 421enum dmub_gpint_command {
 422        /**
 423         * Invalid command, ignored.
 424         */
 425        DMUB_GPINT__INVALID_COMMAND = 0,
 426        /**
 427         * DESC: Queries the firmware version.
 428         * RETURN: Firmware version.
 429         */
 430        DMUB_GPINT__GET_FW_VERSION = 1,
 431        /**
 432         * DESC: Halts the firmware.
 433         * RETURN: DMUB_GPINT__STOP_FW_RESPONSE (0xDEADDEAD) when halted
 434         */
 435        DMUB_GPINT__STOP_FW = 2,
 436        /**
 437         * DESC: Get PSR state from FW.
 438         * RETURN: PSR state enum. This enum may need to be converted to the legacy PSR state value.
 439         */
 440        DMUB_GPINT__GET_PSR_STATE = 7,
 441        /**
 442         * DESC: Notifies DMCUB of the currently active streams.
 443         * ARGS: Stream mask, 1 bit per active stream index.
 444         */
 445        DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK = 8,
 446        /**
 447         * DESC: Start PSR residency counter. Stop PSR resdiency counter and get value.
 448         * ARGS: We can measure residency from various points. The argument will specify the residency mode.
 449         *       By default, it is measured from after we powerdown the PHY, to just before we powerup the PHY.
 450         * RETURN: PSR residency in milli-percent.
 451         */
 452        DMUB_GPINT__PSR_RESIDENCY = 9,
 453};
 454
 455//==============================================================================
 456//</DMUB_GPINT>=================================================================
 457//==============================================================================
 458//< DMUB_CMD>===================================================================
 459//==============================================================================
 460
 461/**
 462 * Size in bytes of each DMUB command.
 463 */
 464#define DMUB_RB_CMD_SIZE 64
 465
 466/**
 467 * Maximum number of items in the DMUB ringbuffer.
 468 */
 469#define DMUB_RB_MAX_ENTRY 128
 470
 471/**
 472 * Ringbuffer size in bytes.
 473 */
 474#define DMUB_RB_SIZE (DMUB_RB_CMD_SIZE * DMUB_RB_MAX_ENTRY)
 475
 476/**
 477 * REG_SET mask for reg offload.
 478 */
 479#define REG_SET_MASK 0xFFFF
 480
 481/*
 482 * enum dmub_cmd_type - DMUB inbox command.
 483 *
 484 * Command IDs should be treated as stable ABI.
 485 * Do not reuse or modify IDs.
 486 */
 487enum dmub_cmd_type {
 488        /**
 489         * Invalid command.
 490         */
 491        DMUB_CMD__NULL = 0,
 492        /**
 493         * Read modify write register sequence offload.
 494         */
 495        DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE = 1,
 496        /**
 497         * Field update register sequence offload.
 498         */
 499        DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ = 2,
 500        /**
 501         * Burst write sequence offload.
 502         */
 503        DMUB_CMD__REG_SEQ_BURST_WRITE = 3,
 504        /**
 505         * Reg wait sequence offload.
 506         */
 507        DMUB_CMD__REG_REG_WAIT = 4,
 508        /**
 509         * Workaround to avoid HUBP underflow during NV12 playback.
 510         */
 511        DMUB_CMD__PLAT_54186_WA = 5,
 512        /**
 513         * Command type used to query FW feature caps.
 514         */
 515        DMUB_CMD__QUERY_FEATURE_CAPS = 6,
 516        /**
 517         * Command type used for all PSR commands.
 518         */
 519        DMUB_CMD__PSR = 64,
 520        /**
 521         * Command type used for all MALL commands.
 522         */
 523        DMUB_CMD__MALL = 65,
 524        /**
 525         * Command type used for all ABM commands.
 526         */
 527        DMUB_CMD__ABM = 66,
 528        /**
 529         * Command type used for HW locking in FW.
 530         */
 531        DMUB_CMD__HW_LOCK = 69,
 532        /**
 533         * Command type used to access DP AUX.
 534         */
 535        DMUB_CMD__DP_AUX_ACCESS = 70,
 536        /**
 537         * Command type used for OUTBOX1 notification enable
 538         */
 539        DMUB_CMD__OUTBOX1_ENABLE = 71,
 540        /**
 541         * Command type used for all VBIOS interface commands.
 542         */
 543        DMUB_CMD__VBIOS = 128,
 544};
 545
 546/**
 547 * enum dmub_out_cmd_type - DMUB outbox commands.
 548 */
 549enum dmub_out_cmd_type {
 550        /**
 551         * Invalid outbox command, ignored.
 552         */
 553        DMUB_OUT_CMD__NULL = 0,
 554        /**
 555         * Command type used for DP AUX Reply data notification
 556         */
 557        DMUB_OUT_CMD__DP_AUX_REPLY = 1,
 558        /**
 559         * Command type used for DP HPD event notification
 560         */
 561        DMUB_OUT_CMD__DP_HPD_NOTIFY = 2,
 562};
 563
 564#pragma pack(push, 1)
 565
 566/**
 567 * struct dmub_cmd_header - Common command header fields.
 568 */
 569struct dmub_cmd_header {
 570        unsigned int type : 8; /**< command type */
 571        unsigned int sub_type : 8; /**< command sub type */
 572        unsigned int ret_status : 1; /**< 1 if returned data, 0 otherwise */
 573        unsigned int reserved0 : 7; /**< reserved bits */
 574        unsigned int payload_bytes : 6;  /* payload excluding header - up to 60 bytes */
 575        unsigned int reserved1 : 2; /**< reserved bits */
 576};
 577
 578/*
 579 * struct dmub_cmd_read_modify_write_sequence - Read modify write
 580 *
 581 * 60 payload bytes can hold up to 5 sets of read modify writes,
 582 * each take 3 dwords.
 583 *
 584 * number of sequences = header.payload_bytes / sizeof(struct dmub_cmd_read_modify_write_sequence)
 585 *
 586 * modify_mask = 0xffff'ffff means all fields are going to be updated.  in this case
 587 * command parser will skip the read and we can use modify_mask = 0xffff'ffff as reg write
 588 */
 589struct dmub_cmd_read_modify_write_sequence {
 590        uint32_t addr; /**< register address */
 591        uint32_t modify_mask; /**< modify mask */
 592        uint32_t modify_value; /**< modify value */
 593};
 594
 595/**
 596 * Maximum number of ops in read modify write sequence.
 597 */
 598#define DMUB_READ_MODIFY_WRITE_SEQ__MAX 5
 599
 600/**
 601 * struct dmub_cmd_read_modify_write_sequence - Read modify write command.
 602 */
 603struct dmub_rb_cmd_read_modify_write {
 604        struct dmub_cmd_header header;  /**< command header */
 605        /**
 606         * Read modify write sequence.
 607         */
 608        struct dmub_cmd_read_modify_write_sequence seq[DMUB_READ_MODIFY_WRITE_SEQ__MAX];
 609};
 610
 611/*
 612 * Update a register with specified masks and values sequeunce
 613 *
 614 * 60 payload bytes can hold address + up to 7 sets of mask/value combo, each take 2 dword
 615 *
 616 * number of field update sequence = (header.payload_bytes - sizeof(addr)) / sizeof(struct read_modify_write_sequence)
 617 *
 618 *
 619 * USE CASE:
 620 *   1. auto-increment register where additional read would update pointer and produce wrong result
 621 *   2. toggle a bit without read in the middle
 622 */
 623
 624struct dmub_cmd_reg_field_update_sequence {
 625        uint32_t modify_mask; /**< 0xffff'ffff to skip initial read */
 626        uint32_t modify_value; /**< value to update with */
 627};
 628
 629/**
 630 * Maximum number of ops in field update sequence.
 631 */
 632#define DMUB_REG_FIELD_UPDATE_SEQ__MAX 7
 633
 634/**
 635 * struct dmub_rb_cmd_reg_field_update_sequence - Field update command.
 636 */
 637struct dmub_rb_cmd_reg_field_update_sequence {
 638        struct dmub_cmd_header header; /**< command header */
 639        uint32_t addr; /**< register address */
 640        /**
 641         * Field update sequence.
 642         */
 643        struct dmub_cmd_reg_field_update_sequence seq[DMUB_REG_FIELD_UPDATE_SEQ__MAX];
 644};
 645
 646
 647/**
 648 * Maximum number of burst write values.
 649 */
 650#define DMUB_BURST_WRITE_VALUES__MAX  14
 651
 652/*
 653 * struct dmub_rb_cmd_burst_write - Burst write
 654 *
 655 * support use case such as writing out LUTs.
 656 *
 657 * 60 payload bytes can hold up to 14 values to write to given address
 658 *
 659 * number of payload = header.payload_bytes / sizeof(struct read_modify_write_sequence)
 660 */
 661struct dmub_rb_cmd_burst_write {
 662        struct dmub_cmd_header header; /**< command header */
 663        uint32_t addr; /**< register start address */
 664        /**
 665         * Burst write register values.
 666         */
 667        uint32_t write_values[DMUB_BURST_WRITE_VALUES__MAX];
 668};
 669
 670/**
 671 * struct dmub_rb_cmd_common - Common command header
 672 */
 673struct dmub_rb_cmd_common {
 674        struct dmub_cmd_header header; /**< command header */
 675        /**
 676         * Padding to RB_CMD_SIZE
 677         */
 678        uint8_t cmd_buffer[DMUB_RB_CMD_SIZE - sizeof(struct dmub_cmd_header)];
 679};
 680
 681/**
 682 * struct dmub_cmd_reg_wait_data - Register wait data
 683 */
 684struct dmub_cmd_reg_wait_data {
 685        uint32_t addr; /**< Register address */
 686        uint32_t mask; /**< Mask for register bits */
 687        uint32_t condition_field_value; /**< Value to wait for */
 688        uint32_t time_out_us; /**< Time out for reg wait in microseconds */
 689};
 690
 691/**
 692 * struct dmub_rb_cmd_reg_wait - Register wait command
 693 */
 694struct dmub_rb_cmd_reg_wait {
 695        struct dmub_cmd_header header; /**< Command header */
 696        struct dmub_cmd_reg_wait_data reg_wait; /**< Register wait data */
 697};
 698
 699/**
 700 * struct dmub_cmd_PLAT_54186_wa - Underflow workaround
 701 *
 702 * Reprograms surface parameters to avoid underflow.
 703 */
 704struct dmub_cmd_PLAT_54186_wa {
 705        uint32_t DCSURF_SURFACE_CONTROL; /**< reg value */
 706        uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH; /**< reg value */
 707        uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS; /**< reg value */
 708        uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_HIGH_C; /**< reg value */
 709        uint32_t DCSURF_PRIMARY_SURFACE_ADDRESS_C; /**< reg value */
 710        struct {
 711                uint8_t hubp_inst : 4; /**< HUBP instance */
 712                uint8_t tmz_surface : 1; /**< TMZ enable or disable */
 713                uint8_t immediate :1; /**< Immediate flip */
 714                uint8_t vmid : 4; /**< VMID */
 715                uint8_t grph_stereo : 1; /**< 1 if stereo */
 716                uint32_t reserved : 21; /**< Reserved */
 717        } flip_params; /**< Pageflip parameters */
 718        uint32_t reserved[9]; /**< Reserved bits */
 719};
 720
 721/**
 722 * struct dmub_rb_cmd_PLAT_54186_wa - Underflow workaround command
 723 */
 724struct dmub_rb_cmd_PLAT_54186_wa {
 725        struct dmub_cmd_header header; /**< Command header */
 726        struct dmub_cmd_PLAT_54186_wa flip; /**< Flip data */
 727};
 728
 729/**
 730 * struct dmub_rb_cmd_mall - MALL command data.
 731 */
 732struct dmub_rb_cmd_mall {
 733        struct dmub_cmd_header header; /**< Common command header */
 734        union dmub_addr cursor_copy_src; /**< Cursor copy address */
 735        union dmub_addr cursor_copy_dst; /**< Cursor copy destination */
 736        uint32_t tmr_delay; /**< Timer delay */
 737        uint32_t tmr_scale; /**< Timer scale */
 738        uint16_t cursor_width; /**< Cursor width in pixels */
 739        uint16_t cursor_pitch; /**< Cursor pitch in pixels */
 740        uint16_t cursor_height; /**< Cursor height in pixels */
 741        uint8_t cursor_bpp; /**< Cursor bits per pixel */
 742        uint8_t debug_bits; /**< Debug bits */
 743
 744        uint8_t reserved1; /**< Reserved bits */
 745        uint8_t reserved2; /**< Reserved bits */
 746};
 747
 748/**
 749 * struct dmub_cmd_digx_encoder_control_data - Encoder control data.
 750 */
 751struct dmub_cmd_digx_encoder_control_data {
 752        union dig_encoder_control_parameters_v1_5 dig; /**< payload */
 753};
 754
 755/**
 756 * struct dmub_rb_cmd_digx_encoder_control - Encoder control command.
 757 */
 758struct dmub_rb_cmd_digx_encoder_control {
 759        struct dmub_cmd_header header;  /**< header */
 760        struct dmub_cmd_digx_encoder_control_data encoder_control; /**< payload */
 761};
 762
 763/**
 764 * struct dmub_cmd_set_pixel_clock_data - Set pixel clock data.
 765 */
 766struct dmub_cmd_set_pixel_clock_data {
 767        struct set_pixel_clock_parameter_v1_7 clk; /**< payload */
 768};
 769
 770/**
 771 * struct dmub_cmd_set_pixel_clock_data - Set pixel clock command.
 772 */
 773struct dmub_rb_cmd_set_pixel_clock {
 774        struct dmub_cmd_header header; /**< header */
 775        struct dmub_cmd_set_pixel_clock_data pixel_clock; /**< payload */
 776};
 777
 778/**
 779 * struct dmub_cmd_enable_disp_power_gating_data - Display power gating.
 780 */
 781struct dmub_cmd_enable_disp_power_gating_data {
 782        struct enable_disp_power_gating_parameters_v2_1 pwr; /**< payload */
 783};
 784
 785/**
 786 * struct dmub_rb_cmd_enable_disp_power_gating - Display power command.
 787 */
 788struct dmub_rb_cmd_enable_disp_power_gating {
 789        struct dmub_cmd_header header; /**< header */
 790        struct dmub_cmd_enable_disp_power_gating_data power_gating;  /**< payload */
 791};
 792
 793/**
 794 * struct dmub_dig_transmitter_control_data_v1_7 - Transmitter control.
 795 */
 796struct dmub_dig_transmitter_control_data_v1_7 {
 797        uint8_t phyid; /**< 0=UNIPHYA, 1=UNIPHYB, 2=UNIPHYC, 3=UNIPHYD, 4=UNIPHYE, 5=UNIPHYF */
 798        uint8_t action; /**< Defined as ATOM_TRANSMITER_ACTION_xxx */
 799        union {
 800                uint8_t digmode; /**< enum atom_encode_mode_def */
 801                uint8_t dplaneset; /**< DP voltage swing and pre-emphasis value, "DP_LANE_SET__xDB_y_zV" */
 802        } mode_laneset;
 803        uint8_t lanenum; /**< Number of lanes */
 804        union {
 805                uint32_t symclk_10khz; /**< Symbol Clock in 10Khz */
 806        } symclk_units;
 807        uint8_t hpdsel; /**< =1: HPD1, =2: HPD2, ..., =6: HPD6, =0: HPD is not assigned */
 808        uint8_t digfe_sel; /**< DIG front-end selection, bit0 means DIG0 FE is enabled */
 809        uint8_t connobj_id; /**< Connector Object Id defined in ObjectId.h */
 810        uint8_t reserved0; /**< For future use */
 811        uint8_t reserved1; /**< For future use */
 812        uint8_t reserved2[3]; /**< For future use */
 813        uint32_t reserved3[11]; /**< For future use */
 814};
 815
 816/**
 817 * union dmub_cmd_dig1_transmitter_control_data - Transmitter control data.
 818 */
 819union dmub_cmd_dig1_transmitter_control_data {
 820        struct dig_transmitter_control_parameters_v1_6 dig; /**< payload */
 821        struct dmub_dig_transmitter_control_data_v1_7 dig_v1_7;  /**< payload 1.7 */
 822};
 823
 824/**
 825 * struct dmub_rb_cmd_dig1_transmitter_control - Transmitter control command.
 826 */
 827struct dmub_rb_cmd_dig1_transmitter_control {
 828        struct dmub_cmd_header header; /**< header */
 829        union dmub_cmd_dig1_transmitter_control_data transmitter_control; /**< payload */
 830};
 831
 832/**
 833 * struct dmub_rb_cmd_dpphy_init - DPPHY init.
 834 */
 835struct dmub_rb_cmd_dpphy_init {
 836        struct dmub_cmd_header header; /**< header */
 837        uint8_t reserved[60]; /**< reserved bits */
 838};
 839
 840/**
 841 * enum dp_aux_request_action - DP AUX request command listing.
 842 *
 843 * 4 AUX request command bits are shifted to high nibble.
 844 */
 845enum dp_aux_request_action {
 846        /** I2C-over-AUX write request */
 847        DP_AUX_REQ_ACTION_I2C_WRITE             = 0x00,
 848        /** I2C-over-AUX read request */
 849        DP_AUX_REQ_ACTION_I2C_READ              = 0x10,
 850        /** I2C-over-AUX write status request */
 851        DP_AUX_REQ_ACTION_I2C_STATUS_REQ        = 0x20,
 852        /** I2C-over-AUX write request with MOT=1 */
 853        DP_AUX_REQ_ACTION_I2C_WRITE_MOT         = 0x40,
 854        /** I2C-over-AUX read request with MOT=1 */
 855        DP_AUX_REQ_ACTION_I2C_READ_MOT          = 0x50,
 856        /** I2C-over-AUX write status request with MOT=1 */
 857        DP_AUX_REQ_ACTION_I2C_STATUS_REQ_MOT    = 0x60,
 858        /** Native AUX write request */
 859        DP_AUX_REQ_ACTION_DPCD_WRITE            = 0x80,
 860        /** Native AUX read request */
 861        DP_AUX_REQ_ACTION_DPCD_READ             = 0x90
 862};
 863
 864/**
 865 * enum aux_return_code_type - DP AUX process return code listing.
 866 */
 867enum aux_return_code_type {
 868        /** AUX process succeeded */
 869        AUX_RET_SUCCESS = 0,
 870        /** AUX process failed with unknown reason */
 871        AUX_RET_ERROR_UNKNOWN,
 872        /** AUX process completed with invalid reply */
 873        AUX_RET_ERROR_INVALID_REPLY,
 874        /** AUX process timed out */
 875        AUX_RET_ERROR_TIMEOUT,
 876        /** HPD was low during AUX process */
 877        AUX_RET_ERROR_HPD_DISCON,
 878        /** Failed to acquire AUX engine */
 879        AUX_RET_ERROR_ENGINE_ACQUIRE,
 880        /** AUX request not supported */
 881        AUX_RET_ERROR_INVALID_OPERATION,
 882        /** AUX process not available */
 883        AUX_RET_ERROR_PROTOCOL_ERROR,
 884};
 885
 886/**
 887 * enum aux_channel_type - DP AUX channel type listing.
 888 */
 889enum aux_channel_type {
 890        /** AUX thru Legacy DP AUX */
 891        AUX_CHANNEL_LEGACY_DDC,
 892        /** AUX thru DPIA DP tunneling */
 893        AUX_CHANNEL_DPIA
 894};
 895
 896/**
 897 * struct aux_transaction_parameters - DP AUX request transaction data
 898 */
 899struct aux_transaction_parameters {
 900        uint8_t is_i2c_over_aux; /**< 0=native AUX, 1=I2C-over-AUX */
 901        uint8_t action; /**< enum dp_aux_request_action */
 902        uint8_t length; /**< DP AUX request data length */
 903        uint8_t reserved; /**< For future use */
 904        uint32_t address; /**< DP AUX address */
 905        uint8_t data[16]; /**< DP AUX write data */
 906};
 907
 908/**
 909 * Data passed from driver to FW in a DMUB_CMD__DP_AUX_ACCESS command.
 910 */
 911struct dmub_cmd_dp_aux_control_data {
 912        uint8_t instance; /**< AUX instance or DPIA instance */
 913        uint8_t manual_acq_rel_enable; /**< manual control for acquiring or releasing AUX channel */
 914        uint8_t sw_crc_enabled; /**< Use software CRC for tunneling packet instead of hardware CRC */
 915        uint8_t reserved0; /**< For future use */
 916        uint16_t timeout; /**< timeout time in us */
 917        uint16_t reserved1; /**< For future use */
 918        enum aux_channel_type type; /**< enum aux_channel_type */
 919        struct aux_transaction_parameters dpaux; /**< struct aux_transaction_parameters */
 920};
 921
 922/**
 923 * Definition of a DMUB_CMD__DP_AUX_ACCESS command.
 924 */
 925struct dmub_rb_cmd_dp_aux_access {
 926        /**
 927         * Command header.
 928         */
 929        struct dmub_cmd_header header;
 930        /**
 931         * Data passed from driver to FW in a DMUB_CMD__DP_AUX_ACCESS command.
 932         */
 933        struct dmub_cmd_dp_aux_control_data aux_control;
 934};
 935
 936/**
 937 * Definition of a DMUB_CMD__OUTBOX1_ENABLE command.
 938 */
 939struct dmub_rb_cmd_outbox1_enable {
 940        /**
 941         * Command header.
 942         */
 943        struct dmub_cmd_header header;
 944        /**
 945         *  enable: 0x0 -> disable outbox1 notification (default value)
 946         *                      0x1 -> enable outbox1 notification
 947         */
 948        uint32_t enable;
 949};
 950
 951/* DP AUX Reply command - OutBox Cmd */
 952/**
 953 * Data passed to driver from FW in a DMUB_OUT_CMD__DP_AUX_REPLY command.
 954 */
 955struct aux_reply_data {
 956        /**
 957         * Aux cmd
 958         */
 959        uint8_t command;
 960        /**
 961         * Aux reply data length (max: 16 bytes)
 962         */
 963        uint8_t length;
 964        /**
 965         * Alignment only
 966         */
 967        uint8_t pad[2];
 968        /**
 969         * Aux reply data
 970         */
 971        uint8_t data[16];
 972};
 973
 974/**
 975 * Control Data passed to driver from FW in a DMUB_OUT_CMD__DP_AUX_REPLY command.
 976 */
 977struct aux_reply_control_data {
 978        /**
 979         * Reserved for future use
 980         */
 981        uint32_t handle;
 982        /**
 983         * Aux Instance
 984         */
 985        uint8_t instance;
 986        /**
 987         * Aux transaction result: definition in enum aux_return_code_type
 988         */
 989        uint8_t result;
 990        /**
 991         * Alignment only
 992         */
 993        uint16_t pad;
 994};
 995
 996/**
 997 * Definition of a DMUB_OUT_CMD__DP_AUX_REPLY command.
 998 */
 999struct dmub_rb_cmd_dp_aux_reply {
1000        /**
1001         * Command header.
1002         */
1003        struct dmub_cmd_header header;
1004        /**
1005         * Control Data passed to driver from FW in a DMUB_OUT_CMD__DP_AUX_REPLY command.
1006         */
1007        struct aux_reply_control_data control;
1008        /**
1009         * Data passed to driver from FW in a DMUB_OUT_CMD__DP_AUX_REPLY command.
1010         */
1011        struct aux_reply_data reply_data;
1012};
1013
1014/* DP HPD Notify command - OutBox Cmd */
1015/**
1016 * DP HPD Type
1017 */
1018enum dp_hpd_type {
1019        /**
1020         * Normal DP HPD
1021         */
1022        DP_HPD = 0,
1023        /**
1024         * DP HPD short pulse
1025         */
1026        DP_IRQ
1027};
1028
1029/**
1030 * DP HPD Status
1031 */
1032enum dp_hpd_status {
1033        /**
1034         * DP_HPD status low
1035         */
1036        DP_HPD_UNPLUG = 0,
1037        /**
1038         * DP_HPD status high
1039         */
1040        DP_HPD_PLUG
1041};
1042
1043/**
1044 * Data passed to driver from FW in a DMUB_OUT_CMD__DP_HPD_NOTIFY command.
1045 */
1046struct dp_hpd_data {
1047        /**
1048         * DP HPD instance
1049         */
1050        uint8_t instance;
1051        /**
1052         * HPD type
1053         */
1054        uint8_t hpd_type;
1055        /**
1056         * HPD status: only for type: DP_HPD to indicate status
1057         */
1058        uint8_t hpd_status;
1059        /**
1060         * Alignment only
1061         */
1062        uint8_t pad;
1063};
1064
1065/**
1066 * Definition of a DMUB_OUT_CMD__DP_HPD_NOTIFY command.
1067 */
1068struct dmub_rb_cmd_dp_hpd_notify {
1069        /**
1070         * Command header.
1071         */
1072        struct dmub_cmd_header header;
1073        /**
1074         * Data passed to driver from FW in a DMUB_OUT_CMD__DP_HPD_NOTIFY command.
1075         */
1076        struct dp_hpd_data hpd_data;
1077};
1078
1079/*
1080 * Command IDs should be treated as stable ABI.
1081 * Do not reuse or modify IDs.
1082 */
1083
1084/**
1085 * PSR command sub-types.
1086 */
1087enum dmub_cmd_psr_type {
1088        /**
1089         * Set PSR version support.
1090         */
1091        DMUB_CMD__PSR_SET_VERSION               = 0,
1092        /**
1093         * Copy driver-calculated parameters to PSR state.
1094         */
1095        DMUB_CMD__PSR_COPY_SETTINGS             = 1,
1096        /**
1097         * Enable PSR.
1098         */
1099        DMUB_CMD__PSR_ENABLE                    = 2,
1100
1101        /**
1102         * Disable PSR.
1103         */
1104        DMUB_CMD__PSR_DISABLE                   = 3,
1105
1106        /**
1107         * Set PSR level.
1108         * PSR level is a 16-bit value dicated by driver that
1109         * will enable/disable different functionality.
1110         */
1111        DMUB_CMD__PSR_SET_LEVEL                 = 4,
1112
1113        /**
1114         * Forces PSR enabled until an explicit PSR disable call.
1115         */
1116        DMUB_CMD__PSR_FORCE_STATIC              = 5,
1117};
1118
1119/**
1120 * PSR versions.
1121 */
1122enum psr_version {
1123        /**
1124         * PSR version 1.
1125         */
1126        PSR_VERSION_1                           = 0,
1127        /**
1128         * PSR not supported.
1129         */
1130        PSR_VERSION_UNSUPPORTED                 = 0xFFFFFFFF,
1131};
1132
1133/**
1134 * enum dmub_cmd_mall_type - MALL commands
1135 */
1136enum dmub_cmd_mall_type {
1137        /**
1138         * Allows display refresh from MALL.
1139         */
1140        DMUB_CMD__MALL_ACTION_ALLOW = 0,
1141        /**
1142         * Disallows display refresh from MALL.
1143         */
1144        DMUB_CMD__MALL_ACTION_DISALLOW = 1,
1145        /**
1146         * Cursor copy for MALL.
1147         */
1148        DMUB_CMD__MALL_ACTION_COPY_CURSOR = 2,
1149        /**
1150         * Controls DF requests.
1151         */
1152        DMUB_CMD__MALL_ACTION_NO_DF_REQ = 3,
1153};
1154
1155
1156/**
1157 * Data passed from driver to FW in a DMUB_CMD__PSR_COPY_SETTINGS command.
1158 */
1159struct dmub_cmd_psr_copy_settings_data {
1160        /**
1161         * Flags that can be set by driver to change some PSR behaviour.
1162         */
1163        union dmub_psr_debug_flags debug;
1164        /**
1165         * 16-bit value dicated by driver that will enable/disable different functionality.
1166         */
1167        uint16_t psr_level;
1168        /**
1169         * DPP HW instance.
1170         */
1171        uint8_t dpp_inst;
1172        /**
1173         * MPCC HW instance.
1174         * Not used in dmub fw,
1175         * dmub fw will get active opp by reading odm registers.
1176         */
1177        uint8_t mpcc_inst;
1178        /**
1179         * OPP HW instance.
1180         * Not used in dmub fw,
1181         * dmub fw will get active opp by reading odm registers.
1182         */
1183        uint8_t opp_inst;
1184        /**
1185         * OTG HW instance.
1186         */
1187        uint8_t otg_inst;
1188        /**
1189         * DIG FE HW instance.
1190         */
1191        uint8_t digfe_inst;
1192        /**
1193         * DIG BE HW instance.
1194         */
1195        uint8_t digbe_inst;
1196        /**
1197         * DP PHY HW instance.
1198         */
1199        uint8_t dpphy_inst;
1200        /**
1201         * AUX HW instance.
1202         */
1203        uint8_t aux_inst;
1204        /**
1205         * Determines if SMU optimzations are enabled/disabled.
1206         */
1207        uint8_t smu_optimizations_en;
1208        /**
1209         * Unused.
1210         * TODO: Remove.
1211         */
1212        uint8_t frame_delay;
1213        /**
1214         * If RFB setup time is greater than the total VBLANK time,
1215         * it is not possible for the sink to capture the video frame
1216         * in the same frame the SDP is sent. In this case,
1217         * the frame capture indication bit should be set and an extra
1218         * static frame should be transmitted to the sink.
1219         */
1220        uint8_t frame_cap_ind;
1221        /**
1222         * Explicit padding to 4 byte boundary.
1223         */
1224        uint8_t pad[2];
1225        /**
1226         * Multi-display optimizations are implemented on certain ASICs.
1227         */
1228        uint8_t multi_disp_optimizations_en;
1229        /**
1230         * The last possible line SDP may be transmitted without violating
1231         * the RFB setup time or entering the active video frame.
1232         */
1233        uint16_t init_sdp_deadline;
1234        /**
1235         * Explicit padding to 4 byte boundary.
1236         */
1237        uint16_t pad2;
1238        /**
1239         * Length of each horizontal line in us.
1240         */
1241        uint32_t line_time_in_us;
1242        /**
1243         * FEC enable status in driver
1244         */
1245        uint8_t fec_enable_status;
1246        /**
1247         * FEC re-enable delay when PSR exit.
1248         * unit is 100us, range form 0~255(0xFF).
1249         */
1250        uint8_t fec_enable_delay_in100us;
1251        /**
1252         * Explicit padding to 4 byte boundary.
1253         */
1254        uint8_t pad3[2];
1255};
1256
1257/**
1258 * Definition of a DMUB_CMD__PSR_COPY_SETTINGS command.
1259 */
1260struct dmub_rb_cmd_psr_copy_settings {
1261        /**
1262         * Command header.
1263         */
1264        struct dmub_cmd_header header;
1265        /**
1266         * Data passed from driver to FW in a DMUB_CMD__PSR_COPY_SETTINGS command.
1267         */
1268        struct dmub_cmd_psr_copy_settings_data psr_copy_settings_data;
1269};
1270
1271/**
1272 * Data passed from driver to FW in a DMUB_CMD__PSR_SET_LEVEL command.
1273 */
1274struct dmub_cmd_psr_set_level_data {
1275        /**
1276         * 16-bit value dicated by driver that will enable/disable different functionality.
1277         */
1278        uint16_t psr_level;
1279        /**
1280         * Explicit padding to 4 byte boundary.
1281         */
1282        uint8_t pad[2];
1283};
1284
1285/**
1286 * Definition of a DMUB_CMD__PSR_SET_LEVEL command.
1287 */
1288struct dmub_rb_cmd_psr_set_level {
1289        /**
1290         * Command header.
1291         */
1292        struct dmub_cmd_header header;
1293        /**
1294         * Definition of a DMUB_CMD__PSR_SET_LEVEL command.
1295         */
1296        struct dmub_cmd_psr_set_level_data psr_set_level_data;
1297};
1298
1299/**
1300 * Definition of a DMUB_CMD__PSR_ENABLE command.
1301 * PSR enable/disable is controlled using the sub_type.
1302 */
1303struct dmub_rb_cmd_psr_enable {
1304        /**
1305         * Command header.
1306         */
1307        struct dmub_cmd_header header;
1308};
1309
1310/**
1311 * Data passed from driver to FW in a DMUB_CMD__PSR_SET_VERSION command.
1312 */
1313struct dmub_cmd_psr_set_version_data {
1314        /**
1315         * PSR version that FW should implement.
1316         */
1317        enum psr_version version;
1318};
1319
1320/**
1321 * Definition of a DMUB_CMD__PSR_SET_VERSION command.
1322 */
1323struct dmub_rb_cmd_psr_set_version {
1324        /**
1325         * Command header.
1326         */
1327        struct dmub_cmd_header header;
1328        /**
1329         * Data passed from driver to FW in a DMUB_CMD__PSR_SET_VERSION command.
1330         */
1331        struct dmub_cmd_psr_set_version_data psr_set_version_data;
1332};
1333
1334/**
1335 * Definition of a DMUB_CMD__PSR_FORCE_STATIC command.
1336 */
1337struct dmub_rb_cmd_psr_force_static {
1338        /**
1339         * Command header.
1340         */
1341        struct dmub_cmd_header header;
1342};
1343
1344/**
1345 * Set of HW components that can be locked.
1346 */
1347union dmub_hw_lock_flags {
1348        /**
1349         * Set of HW components that can be locked.
1350         */
1351        struct {
1352                /**
1353                 * Lock/unlock OTG master update lock.
1354                 */
1355                uint8_t lock_pipe   : 1;
1356                /**
1357                 * Lock/unlock cursor.
1358                 */
1359                uint8_t lock_cursor : 1;
1360                /**
1361                 * Lock/unlock global update lock.
1362                 */
1363                uint8_t lock_dig    : 1;
1364                /**
1365                 * Triple buffer lock requires additional hw programming to usual OTG master lock.
1366                 */
1367                uint8_t triple_buffer_lock : 1;
1368        } bits;
1369
1370        /**
1371         * Union for HW Lock flags.
1372         */
1373        uint8_t u8All;
1374};
1375
1376/**
1377 * Instances of HW to be locked.
1378 */
1379struct dmub_hw_lock_inst_flags {
1380        /**
1381         * OTG HW instance for OTG master update lock.
1382         */
1383        uint8_t otg_inst;
1384        /**
1385         * OPP instance for cursor lock.
1386         */
1387        uint8_t opp_inst;
1388        /**
1389         * OTG HW instance for global update lock.
1390         * TODO: Remove, and re-use otg_inst.
1391         */
1392        uint8_t dig_inst;
1393        /**
1394         * Explicit pad to 4 byte boundary.
1395         */
1396        uint8_t pad;
1397};
1398
1399/**
1400 * Clients that can acquire the HW Lock Manager.
1401 */
1402enum hw_lock_client {
1403        /**
1404         * Driver is the client of HW Lock Manager.
1405         */
1406        HW_LOCK_CLIENT_DRIVER = 0,
1407        /**
1408         * FW is the client of HW Lock Manager.
1409         */
1410        HW_LOCK_CLIENT_FW,
1411        /**
1412         * Invalid client.
1413         */
1414        HW_LOCK_CLIENT_INVALID = 0xFFFFFFFF,
1415};
1416
1417/**
1418 * Data passed to HW Lock Mgr in a DMUB_CMD__HW_LOCK command.
1419 */
1420struct dmub_cmd_lock_hw_data {
1421        /**
1422         * Specifies the client accessing HW Lock Manager.
1423         */
1424        enum hw_lock_client client;
1425        /**
1426         * HW instances to be locked.
1427         */
1428        struct dmub_hw_lock_inst_flags inst_flags;
1429        /**
1430         * Which components to be locked.
1431         */
1432        union dmub_hw_lock_flags hw_locks;
1433        /**
1434         * Specifies lock/unlock.
1435         */
1436        uint8_t lock;
1437        /**
1438         * HW can be unlocked separately from releasing the HW Lock Mgr.
1439         * This flag is set if the client wishes to release the object.
1440         */
1441        uint8_t should_release;
1442        /**
1443         * Explicit padding to 4 byte boundary.
1444         */
1445        uint8_t pad;
1446};
1447
1448/**
1449 * Definition of a DMUB_CMD__HW_LOCK command.
1450 * Command is used by driver and FW.
1451 */
1452struct dmub_rb_cmd_lock_hw {
1453        /**
1454         * Command header.
1455         */
1456        struct dmub_cmd_header header;
1457        /**
1458         * Data passed to HW Lock Mgr in a DMUB_CMD__HW_LOCK command.
1459         */
1460        struct dmub_cmd_lock_hw_data lock_hw_data;
1461};
1462
1463/**
1464 * ABM command sub-types.
1465 */
1466enum dmub_cmd_abm_type {
1467        /**
1468         * Initialize parameters for ABM algorithm.
1469         * Data is passed through an indirect buffer.
1470         */
1471        DMUB_CMD__ABM_INIT_CONFIG       = 0,
1472        /**
1473         * Set OTG and panel HW instance.
1474         */
1475        DMUB_CMD__ABM_SET_PIPE          = 1,
1476        /**
1477         * Set user requested backklight level.
1478         */
1479        DMUB_CMD__ABM_SET_BACKLIGHT     = 2,
1480        /**
1481         * Set ABM operating/aggression level.
1482         */
1483        DMUB_CMD__ABM_SET_LEVEL         = 3,
1484        /**
1485         * Set ambient light level.
1486         */
1487        DMUB_CMD__ABM_SET_AMBIENT_LEVEL = 4,
1488        /**
1489         * Enable/disable fractional duty cycle for backlight PWM.
1490         */
1491        DMUB_CMD__ABM_SET_PWM_FRAC      = 5,
1492};
1493
1494/**
1495 * Parameters for ABM2.4 algorithm. Passed from driver to FW via an indirect buffer.
1496 * Requirements:
1497 *  - Padded explicitly to 32-bit boundary.
1498 *  - Must ensure this structure matches the one on driver-side,
1499 *    otherwise it won't be aligned.
1500 */
1501struct abm_config_table {
1502        /**
1503         * Gamma curve thresholds, used for crgb conversion.
1504         */
1505        uint16_t crgb_thresh[NUM_POWER_FN_SEGS];                 // 0B
1506        /**
1507         * Gamma curve offsets, used for crgb conversion.
1508         */
1509        uint16_t crgb_offset[NUM_POWER_FN_SEGS];                 // 16B
1510        /**
1511         * Gamma curve slopes, used for crgb conversion.
1512         */
1513        uint16_t crgb_slope[NUM_POWER_FN_SEGS];                  // 32B
1514        /**
1515         * Custom backlight curve thresholds.
1516         */
1517        uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS];        // 48B
1518        /**
1519         * Custom backlight curve offsets.
1520         */
1521        uint16_t backlight_offsets[NUM_BL_CURVE_SEGS];           // 78B
1522        /**
1523         * Ambient light thresholds.
1524         */
1525        uint16_t ambient_thresholds_lux[NUM_AMBI_LEVEL];         // 112B
1526        /**
1527         * Minimum programmable backlight.
1528         */
1529        uint16_t min_abm_backlight;                              // 122B
1530        /**
1531         * Minimum reduction values.
1532         */
1533        uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];   // 124B
1534        /**
1535         * Maximum reduction values.
1536         */
1537        uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];   // 144B
1538        /**
1539         * Bright positive gain.
1540         */
1541        uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; // 164B
1542        /**
1543         * Dark negative gain.
1544         */
1545        uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL];   // 184B
1546        /**
1547         * Hybrid factor.
1548         */
1549        uint8_t hybrid_factor[NUM_AGGR_LEVEL];                   // 204B
1550        /**
1551         * Contrast factor.
1552         */
1553        uint8_t contrast_factor[NUM_AGGR_LEVEL];                 // 208B
1554        /**
1555         * Deviation gain.
1556         */
1557        uint8_t deviation_gain[NUM_AGGR_LEVEL];                  // 212B
1558        /**
1559         * Minimum knee.
1560         */
1561        uint8_t min_knee[NUM_AGGR_LEVEL];                        // 216B
1562        /**
1563         * Maximum knee.
1564         */
1565        uint8_t max_knee[NUM_AGGR_LEVEL];                        // 220B
1566        /**
1567         * Unused.
1568         */
1569        uint8_t iir_curve[NUM_AMBI_LEVEL];                       // 224B
1570        /**
1571         * Explicit padding to 4 byte boundary.
1572         */
1573        uint8_t pad3[3];                                         // 229B
1574        /**
1575         * Backlight ramp reduction.
1576         */
1577        uint16_t blRampReduction[NUM_AGGR_LEVEL];                // 232B
1578        /**
1579         * Backlight ramp start.
1580         */
1581        uint16_t blRampStart[NUM_AGGR_LEVEL];                    // 240B
1582};
1583
1584/**
1585 * Data passed from driver to FW in a DMUB_CMD__ABM_SET_PIPE command.
1586 */
1587struct dmub_cmd_abm_set_pipe_data {
1588        /**
1589         * OTG HW instance.
1590         */
1591        uint8_t otg_inst;
1592
1593        /**
1594         * Panel Control HW instance.
1595         */
1596        uint8_t panel_inst;
1597
1598        /**
1599         * Controls how ABM will interpret a set pipe or set level command.
1600         */
1601        uint8_t set_pipe_option;
1602
1603        /**
1604         * Unused.
1605         * TODO: Remove.
1606         */
1607        uint8_t ramping_boundary;
1608};
1609
1610/**
1611 * Definition of a DMUB_CMD__ABM_SET_PIPE command.
1612 */
1613struct dmub_rb_cmd_abm_set_pipe {
1614        /**
1615         * Command header.
1616         */
1617        struct dmub_cmd_header header;
1618
1619        /**
1620         * Data passed from driver to FW in a DMUB_CMD__ABM_SET_PIPE command.
1621         */
1622        struct dmub_cmd_abm_set_pipe_data abm_set_pipe_data;
1623};
1624
1625/**
1626 * Data passed from driver to FW in a DMUB_CMD__ABM_SET_BACKLIGHT command.
1627 */
1628struct dmub_cmd_abm_set_backlight_data {
1629        /**
1630         * Number of frames to ramp to backlight user level.
1631         */
1632        uint32_t frame_ramp;
1633
1634        /**
1635         * Requested backlight level from user.
1636         */
1637        uint32_t backlight_user_level;
1638
1639        /**
1640         * Backlight data version.
1641         */
1642        uint8_t version;
1643
1644        /**
1645         * Panel Control HW instance mask.
1646         * Bit 0 is Panel Control HW instance 0.
1647         * Bit 1 is Panel Control HW instance 1.
1648         */
1649        uint8_t panel_mask;
1650
1651        /**
1652         * Explicit padding to 4 byte boundary.
1653         */
1654        uint8_t pad[2];
1655};
1656
1657/**
1658 * Definition of a DMUB_CMD__ABM_SET_BACKLIGHT command.
1659 */
1660struct dmub_rb_cmd_abm_set_backlight {
1661        /**
1662         * Command header.
1663         */
1664        struct dmub_cmd_header header;
1665
1666        /**
1667         * Data passed from driver to FW in a DMUB_CMD__ABM_SET_BACKLIGHT command.
1668         */
1669        struct dmub_cmd_abm_set_backlight_data abm_set_backlight_data;
1670};
1671
1672/**
1673 * Data passed from driver to FW in a DMUB_CMD__ABM_SET_LEVEL command.
1674 */
1675struct dmub_cmd_abm_set_level_data {
1676        /**
1677         * Set current ABM operating/aggression level.
1678         */
1679        uint32_t level;
1680};
1681
1682/**
1683 * Definition of a DMUB_CMD__ABM_SET_LEVEL command.
1684 */
1685struct dmub_rb_cmd_abm_set_level {
1686        /**
1687         * Command header.
1688         */
1689        struct dmub_cmd_header header;
1690
1691        /**
1692         * Data passed from driver to FW in a DMUB_CMD__ABM_SET_LEVEL command.
1693         */
1694        struct dmub_cmd_abm_set_level_data abm_set_level_data;
1695};
1696
1697/**
1698 * Data passed from driver to FW in a DMUB_CMD__ABM_SET_AMBIENT_LEVEL command.
1699 */
1700struct dmub_cmd_abm_set_ambient_level_data {
1701        /**
1702         * Ambient light sensor reading from OS.
1703         */
1704        uint32_t ambient_lux;
1705};
1706
1707/**
1708 * Definition of a DMUB_CMD__ABM_SET_AMBIENT_LEVEL command.
1709 */
1710struct dmub_rb_cmd_abm_set_ambient_level {
1711        /**
1712         * Command header.
1713         */
1714        struct dmub_cmd_header header;
1715
1716        /**
1717         * Data passed from driver to FW in a DMUB_CMD__ABM_SET_AMBIENT_LEVEL command.
1718         */
1719        struct dmub_cmd_abm_set_ambient_level_data abm_set_ambient_level_data;
1720};
1721
1722/**
1723 * Data passed from driver to FW in a DMUB_CMD__ABM_SET_PWM_FRAC command.
1724 */
1725struct dmub_cmd_abm_set_pwm_frac_data {
1726        /**
1727         * Enable/disable fractional duty cycle for backlight PWM.
1728         * TODO: Convert to uint8_t.
1729         */
1730        uint32_t fractional_pwm;
1731};
1732
1733/**
1734 * Definition of a DMUB_CMD__ABM_SET_PWM_FRAC command.
1735 */
1736struct dmub_rb_cmd_abm_set_pwm_frac {
1737        /**
1738         * Command header.
1739         */
1740        struct dmub_cmd_header header;
1741
1742        /**
1743         * Data passed from driver to FW in a DMUB_CMD__ABM_SET_PWM_FRAC command.
1744         */
1745        struct dmub_cmd_abm_set_pwm_frac_data abm_set_pwm_frac_data;
1746};
1747
1748/**
1749 * Data passed from driver to FW in a DMUB_CMD__ABM_INIT_CONFIG command.
1750 */
1751struct dmub_cmd_abm_init_config_data {
1752        /**
1753         * Location of indirect buffer used to pass init data to ABM.
1754         */
1755        union dmub_addr src;
1756
1757        /**
1758         * Indirect buffer length.
1759         */
1760        uint16_t bytes;
1761};
1762
1763/**
1764 * Definition of a DMUB_CMD__ABM_INIT_CONFIG command.
1765 */
1766struct dmub_rb_cmd_abm_init_config {
1767        /**
1768         * Command header.
1769         */
1770        struct dmub_cmd_header header;
1771
1772        /**
1773         * Data passed from driver to FW in a DMUB_CMD__ABM_INIT_CONFIG command.
1774         */
1775        struct dmub_cmd_abm_init_config_data abm_init_config_data;
1776};
1777
1778/**
1779 * Data passed from driver to FW in a DMUB_CMD__QUERY_FEATURE_CAPS command.
1780 */
1781struct dmub_cmd_query_feature_caps_data {
1782        /**
1783         * DMUB feature capabilities.
1784         * After DMUB init, driver will query FW capabilities prior to enabling certain features.
1785         */
1786        struct dmub_feature_caps feature_caps;
1787};
1788
1789/**
1790 * Definition of a DMUB_CMD__QUERY_FEATURE_CAPS command.
1791 */
1792struct dmub_rb_cmd_query_feature_caps {
1793        /**
1794         * Command header.
1795         */
1796        struct dmub_cmd_header header;
1797        /**
1798         * Data passed from driver to FW in a DMUB_CMD__QUERY_FEATURE_CAPS command.
1799         */
1800        struct dmub_cmd_query_feature_caps_data query_feature_caps_data;
1801};
1802
1803struct dmub_optc_state {
1804        uint32_t v_total_max;
1805        uint32_t v_total_min;
1806        uint32_t v_total_mid;
1807        uint32_t v_total_mid_frame_num;
1808        uint32_t tg_inst;
1809        uint32_t enable_manual_trigger;
1810        uint32_t clear_force_vsync;
1811};
1812
1813struct dmub_rb_cmd_drr_update {
1814                struct dmub_cmd_header header;
1815                struct dmub_optc_state dmub_optc_state_req;
1816};
1817
1818/**
1819 * Data passed from driver to FW in a DMUB_CMD__VBIOS_LVTMA_CONTROL command.
1820 */
1821struct dmub_cmd_lvtma_control_data {
1822        uint8_t uc_pwr_action; /**< LVTMA_ACTION */
1823        uint8_t reserved_0[3]; /**< For future use */
1824        uint8_t panel_inst; /**< LVTMA control instance */
1825        uint8_t reserved_1[3]; /**< For future use */
1826};
1827
1828/**
1829 * Definition of a DMUB_CMD__VBIOS_LVTMA_CONTROL command.
1830 */
1831struct dmub_rb_cmd_lvtma_control {
1832        /**
1833         * Command header.
1834         */
1835        struct dmub_cmd_header header;
1836        /**
1837         * Data passed from driver to FW in a DMUB_CMD__VBIOS_LVTMA_CONTROL command.
1838         */
1839        struct dmub_cmd_lvtma_control_data data;
1840};
1841
1842/**
1843 * union dmub_rb_cmd - DMUB inbox command.
1844 */
1845union dmub_rb_cmd {
1846        struct dmub_rb_cmd_lock_hw lock_hw;
1847        /**
1848         * Elements shared with all commands.
1849         */
1850        struct dmub_rb_cmd_common cmd_common;
1851        /**
1852         * Definition of a DMUB_CMD__REG_SEQ_READ_MODIFY_WRITE command.
1853         */
1854        struct dmub_rb_cmd_read_modify_write read_modify_write;
1855        /**
1856         * Definition of a DMUB_CMD__REG_SEQ_FIELD_UPDATE_SEQ command.
1857         */
1858        struct dmub_rb_cmd_reg_field_update_sequence reg_field_update_seq;
1859        /**
1860         * Definition of a DMUB_CMD__REG_SEQ_BURST_WRITE command.
1861         */
1862        struct dmub_rb_cmd_burst_write burst_write;
1863        /**
1864         * Definition of a DMUB_CMD__REG_REG_WAIT command.
1865         */
1866        struct dmub_rb_cmd_reg_wait reg_wait;
1867        /**
1868         * Definition of a DMUB_CMD__VBIOS_DIGX_ENCODER_CONTROL command.
1869         */
1870        struct dmub_rb_cmd_digx_encoder_control digx_encoder_control;
1871        /**
1872         * Definition of a DMUB_CMD__VBIOS_SET_PIXEL_CLOCK command.
1873         */
1874        struct dmub_rb_cmd_set_pixel_clock set_pixel_clock;
1875        /**
1876         * Definition of a DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING command.
1877         */
1878        struct dmub_rb_cmd_enable_disp_power_gating enable_disp_power_gating;
1879        /**
1880         * Definition of a DMUB_CMD__VBIOS_DPPHY_INIT command.
1881         */
1882        struct dmub_rb_cmd_dpphy_init dpphy_init;
1883        /**
1884         * Definition of a DMUB_CMD__VBIOS_DIG1_TRANSMITTER_CONTROL command.
1885         */
1886        struct dmub_rb_cmd_dig1_transmitter_control dig1_transmitter_control;
1887        /**
1888         * Definition of a DMUB_CMD__PSR_SET_VERSION command.
1889         */
1890        struct dmub_rb_cmd_psr_set_version psr_set_version;
1891        /**
1892         * Definition of a DMUB_CMD__PSR_COPY_SETTINGS command.
1893         */
1894        struct dmub_rb_cmd_psr_copy_settings psr_copy_settings;
1895        /**
1896         * Definition of a DMUB_CMD__PSR_ENABLE command.
1897         */
1898        struct dmub_rb_cmd_psr_enable psr_enable;
1899        /**
1900         * Definition of a DMUB_CMD__PSR_SET_LEVEL command.
1901         */
1902        struct dmub_rb_cmd_psr_set_level psr_set_level;
1903        /**
1904         * Definition of a DMUB_CMD__PSR_FORCE_STATIC command.
1905         */
1906        struct dmub_rb_cmd_psr_force_static psr_force_static;
1907        /**
1908         * Definition of a DMUB_CMD__PLAT_54186_WA command.
1909         */
1910        struct dmub_rb_cmd_PLAT_54186_wa PLAT_54186_wa;
1911        /**
1912         * Definition of a DMUB_CMD__MALL command.
1913         */
1914        struct dmub_rb_cmd_mall mall;
1915        /**
1916         * Definition of a DMUB_CMD__ABM_SET_PIPE command.
1917         */
1918        struct dmub_rb_cmd_abm_set_pipe abm_set_pipe;
1919
1920        /**
1921         * Definition of a DMUB_CMD__ABM_SET_BACKLIGHT command.
1922         */
1923        struct dmub_rb_cmd_abm_set_backlight abm_set_backlight;
1924
1925        /**
1926         * Definition of a DMUB_CMD__ABM_SET_LEVEL command.
1927         */
1928        struct dmub_rb_cmd_abm_set_level abm_set_level;
1929
1930        /**
1931         * Definition of a DMUB_CMD__ABM_SET_AMBIENT_LEVEL command.
1932         */
1933        struct dmub_rb_cmd_abm_set_ambient_level abm_set_ambient_level;
1934
1935        /**
1936         * Definition of a DMUB_CMD__ABM_SET_PWM_FRAC command.
1937         */
1938        struct dmub_rb_cmd_abm_set_pwm_frac abm_set_pwm_frac;
1939
1940        /**
1941         * Definition of a DMUB_CMD__ABM_INIT_CONFIG command.
1942         */
1943        struct dmub_rb_cmd_abm_init_config abm_init_config;
1944
1945        /**
1946         * Definition of a DMUB_CMD__DP_AUX_ACCESS command.
1947         */
1948        struct dmub_rb_cmd_dp_aux_access dp_aux_access;
1949
1950        /**
1951         * Definition of a DMUB_CMD__OUTBOX1_ENABLE command.
1952         */
1953        struct dmub_rb_cmd_outbox1_enable outbox1_enable;
1954
1955        /**
1956         * Definition of a DMUB_CMD__QUERY_FEATURE_CAPS command.
1957         */
1958        struct dmub_rb_cmd_query_feature_caps query_feature_caps;
1959        struct dmub_rb_cmd_drr_update drr_update;
1960        /**
1961         * Definition of a DMUB_CMD__VBIOS_LVTMA_CONTROL command.
1962         */
1963        struct dmub_rb_cmd_lvtma_control lvtma_control;
1964};
1965
1966/**
1967 * union dmub_rb_out_cmd - Outbox command
1968 */
1969union dmub_rb_out_cmd {
1970        /**
1971         * Parameters common to every command.
1972         */
1973        struct dmub_rb_cmd_common cmd_common;
1974        /**
1975         * AUX reply command.
1976         */
1977        struct dmub_rb_cmd_dp_aux_reply dp_aux_reply;
1978        /**
1979         * HPD notify command.
1980         */
1981        struct dmub_rb_cmd_dp_hpd_notify dp_hpd_notify;
1982};
1983#pragma pack(pop)
1984
1985
1986//==============================================================================
1987//</DMUB_CMD>===================================================================
1988//==============================================================================
1989//< DMUB_RB>====================================================================
1990//==============================================================================
1991
1992#if defined(__cplusplus)
1993extern "C" {
1994#endif
1995
1996/**
1997 * struct dmub_rb_init_params - Initialization params for DMUB ringbuffer
1998 */
1999struct dmub_rb_init_params {
2000        void *ctx; /**< Caller provided context pointer */
2001        void *base_address; /**< CPU base address for ring's data */
2002        uint32_t capacity; /**< Ringbuffer capacity in bytes */
2003        uint32_t read_ptr; /**< Initial read pointer for consumer in bytes */
2004        uint32_t write_ptr; /**< Initial write pointer for producer in bytes */
2005};
2006
2007/**
2008 * struct dmub_rb - Inbox or outbox DMUB ringbuffer
2009 */
2010struct dmub_rb {
2011        void *base_address; /**< CPU address for the ring's data */
2012        uint32_t rptr; /**< Read pointer for consumer in bytes */
2013        uint32_t wrpt; /**< Write pointer for producer in bytes */
2014        uint32_t capacity; /**< Ringbuffer capacity in bytes */
2015
2016        void *ctx; /**< Caller provided context pointer */
2017        void *dmub; /**< Pointer to the DMUB interface */
2018};
2019
2020/**
2021 * @brief Checks if the ringbuffer is empty.
2022 *
2023 * @param rb DMUB Ringbuffer
2024 * @return true if empty
2025 * @return false otherwise
2026 */
2027static inline bool dmub_rb_empty(struct dmub_rb *rb)
2028{
2029        return (rb->wrpt == rb->rptr);
2030}
2031
2032/**
2033 * @brief Checks if the ringbuffer is full
2034 *
2035 * @param rb DMUB Ringbuffer
2036 * @return true if full
2037 * @return false otherwise
2038 */
2039static inline bool dmub_rb_full(struct dmub_rb *rb)
2040{
2041        uint32_t data_count;
2042
2043        if (rb->wrpt >= rb->rptr)
2044                data_count = rb->wrpt - rb->rptr;
2045        else
2046                data_count = rb->capacity - (rb->rptr - rb->wrpt);
2047
2048        return (data_count == (rb->capacity - DMUB_RB_CMD_SIZE));
2049}
2050
2051/**
2052 * @brief Pushes a command into the ringbuffer
2053 *
2054 * @param rb DMUB ringbuffer
2055 * @param cmd The command to push
2056 * @return true if the ringbuffer was not full
2057 * @return false otherwise
2058 */
2059static inline bool dmub_rb_push_front(struct dmub_rb *rb,
2060                                      const union dmub_rb_cmd *cmd)
2061{
2062        uint64_t volatile *dst = (uint64_t volatile *)(rb->base_address) + rb->wrpt / sizeof(uint64_t);
2063        const uint64_t *src = (const uint64_t *)cmd;
2064        uint8_t i;
2065
2066        if (dmub_rb_full(rb))
2067                return false;
2068
2069        // copying data
2070        for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
2071                *dst++ = *src++;
2072
2073        rb->wrpt += DMUB_RB_CMD_SIZE;
2074
2075        if (rb->wrpt >= rb->capacity)
2076                rb->wrpt %= rb->capacity;
2077
2078        return true;
2079}
2080
2081/**
2082 * @brief Pushes a command into the DMUB outbox ringbuffer
2083 *
2084 * @param rb DMUB outbox ringbuffer
2085 * @param cmd Outbox command
2086 * @return true if not full
2087 * @return false otherwise
2088 */
2089static inline bool dmub_rb_out_push_front(struct dmub_rb *rb,
2090                                      const union dmub_rb_out_cmd *cmd)
2091{
2092        uint8_t *dst = (uint8_t *)(rb->base_address) + rb->wrpt;
2093        const uint8_t *src = (uint8_t *)cmd;
2094
2095        if (dmub_rb_full(rb))
2096                return false;
2097
2098        dmub_memcpy(dst, src, DMUB_RB_CMD_SIZE);
2099
2100        rb->wrpt += DMUB_RB_CMD_SIZE;
2101
2102        if (rb->wrpt >= rb->capacity)
2103                rb->wrpt %= rb->capacity;
2104
2105        return true;
2106}
2107
2108/**
2109 * @brief Returns the next unprocessed command in the ringbuffer.
2110 *
2111 * @param rb DMUB ringbuffer
2112 * @param cmd The command to return
2113 * @return true if not empty
2114 * @return false otherwise
2115 */
2116static inline bool dmub_rb_front(struct dmub_rb *rb,
2117                                 union dmub_rb_cmd  **cmd)
2118{
2119        uint8_t *rb_cmd = (uint8_t *)(rb->base_address) + rb->rptr;
2120
2121        if (dmub_rb_empty(rb))
2122                return false;
2123
2124        *cmd = (union dmub_rb_cmd *)rb_cmd;
2125
2126        return true;
2127}
2128
2129/**
2130 * @brief Returns the next unprocessed command in the outbox.
2131 *
2132 * @param rb DMUB outbox ringbuffer
2133 * @param cmd The outbox command to return
2134 * @return true if not empty
2135 * @return false otherwise
2136 */
2137static inline bool dmub_rb_out_front(struct dmub_rb *rb,
2138                                 union dmub_rb_out_cmd  *cmd)
2139{
2140        const uint64_t volatile *src = (const uint64_t volatile *)(rb->base_address) + rb->rptr / sizeof(uint64_t);
2141        uint64_t *dst = (uint64_t *)cmd;
2142        uint8_t i;
2143
2144        if (dmub_rb_empty(rb))
2145                return false;
2146
2147        // copying data
2148        for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
2149                *dst++ = *src++;
2150
2151        return true;
2152}
2153
2154/**
2155 * @brief Removes the front entry in the ringbuffer.
2156 *
2157 * @param rb DMUB ringbuffer
2158 * @return true if the command was removed
2159 * @return false if there were no commands
2160 */
2161static inline bool dmub_rb_pop_front(struct dmub_rb *rb)
2162{
2163        if (dmub_rb_empty(rb))
2164                return false;
2165
2166        rb->rptr += DMUB_RB_CMD_SIZE;
2167
2168        if (rb->rptr >= rb->capacity)
2169                rb->rptr %= rb->capacity;
2170
2171        return true;
2172}
2173
2174/**
2175 * @brief Flushes commands in the ringbuffer to framebuffer memory.
2176 *
2177 * Avoids a race condition where DMCUB accesses memory while
2178 * there are still writes in flight to framebuffer.
2179 *
2180 * @param rb DMUB ringbuffer
2181 */
2182static inline void dmub_rb_flush_pending(const struct dmub_rb *rb)
2183{
2184        uint32_t rptr = rb->rptr;
2185        uint32_t wptr = rb->wrpt;
2186
2187        while (rptr != wptr) {
2188                uint64_t volatile *data = (uint64_t volatile *)rb->base_address + rptr / sizeof(uint64_t);
2189                uint8_t i;
2190
2191                for (i = 0; i < DMUB_RB_CMD_SIZE / sizeof(uint64_t); i++)
2192                        *data++;
2193
2194                rptr += DMUB_RB_CMD_SIZE;
2195                if (rptr >= rb->capacity)
2196                        rptr %= rb->capacity;
2197        }
2198}
2199
2200/**
2201 * @brief Initializes a DMCUB ringbuffer
2202 *
2203 * @param rb DMUB ringbuffer
2204 * @param init_params initial configuration for the ringbuffer
2205 */
2206static inline void dmub_rb_init(struct dmub_rb *rb,
2207                                struct dmub_rb_init_params *init_params)
2208{
2209        rb->base_address = init_params->base_address;
2210        rb->capacity = init_params->capacity;
2211        rb->rptr = init_params->read_ptr;
2212        rb->wrpt = init_params->write_ptr;
2213}
2214
2215/**
2216 * @brief Copies output data from in/out commands into the given command.
2217 *
2218 * @param rb DMUB ringbuffer
2219 * @param cmd Command to copy data into
2220 */
2221static inline void dmub_rb_get_return_data(struct dmub_rb *rb,
2222                                           union dmub_rb_cmd *cmd)
2223{
2224        // Copy rb entry back into command
2225        uint8_t *rd_ptr = (rb->rptr == 0) ?
2226                (uint8_t *)rb->base_address + rb->capacity - DMUB_RB_CMD_SIZE :
2227                (uint8_t *)rb->base_address + rb->rptr - DMUB_RB_CMD_SIZE;
2228
2229        dmub_memcpy(cmd, rd_ptr, DMUB_RB_CMD_SIZE);
2230}
2231
2232#if defined(__cplusplus)
2233}
2234#endif
2235
2236//==============================================================================
2237//</DMUB_RB>====================================================================
2238//==============================================================================
2239
2240#endif /* _DMUB_CMD_H_ */
2241