// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_H_

#include <zircon/assert.h>

#include <limits>

#include <hwreg/bitfields.h>

#include "src/graphics/display/drivers/intel-i915/hardware-common.h"

namespace registers {

// Graphics & Memory Controller Hub Graphics Control - GGC_0_0_0_PCI
class GmchGfxControl : public hwreg::RegisterBase<GmchGfxControl, uint16_t> {
 public:
  static constexpr uint32_t kAddr = 0x50;  // Address for the mirror

  DEF_FIELD(15, 8, gfx_mode_select);
  DEF_FIELD(7, 6, gtt_size);

  inline uint32_t gtt_mappable_mem_size() { return gtt_size() ? 1 << (20 + gtt_size()) : 0; }

  inline uint32_t dsm_size() {
    if (gfx_mode_select() <= 0x10) {
      return gfx_mode_select() * 32 * 1024 * 1024;
    } else if (gfx_mode_select() == 0x20) {
      return 1024 * 1024 * 1024;
    } else if (gfx_mode_select() == 0x30) {
      return 1536 * 1024 * 1024;
    } else if (gfx_mode_select() == 0x40) {
      return 2048 * 1024 * 1024u;
    } else if (0xf0 <= gfx_mode_select() && gfx_mode_select() < 0xff) {
      return (gfx_mode_select() - 0xef) * 4 * 1024 * 1024;
    } else {
      return 0;
    }
  }

  static auto Get() { return hwreg::RegisterAddr<GmchGfxControl>(0); }
};

// Base Data of Stolen Memory - BDSM_0_0_0_PCI
class BaseDsm : public hwreg::RegisterBase<BaseDsm, uint32_t> {
 public:
  static constexpr uint32_t kAddr = 0x5c;  // Address for the mirror

  DEF_FIELD(31, 20, base_phys_addr);
  static constexpr uint32_t base_phys_addr_shift = 20;
  DEF_RSVDZ_FIELD(19, 1);
  DEF_BIT(0, lock);

  static auto Get() { return hwreg::RegisterAddr<BaseDsm>(0); }
};

// DFSM (Display Fuse)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 1 pages 432-434
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 497-499
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 495-497
class DisplayFuses : public hwreg::RegisterBase<DisplayFuses, uint32_t> {
 public:
  enum class CoreClockLimit : int {
    k675Mhz = 0,
    k540Mhz = 1,
    k450Mhz = 2,
    k337_5Mhz = 3,
  };

  // The registers names here use "_enabled" / "_disabled" prefixes
  // inconsistently in order to reflect the semantics used in the hardware.

  // Not on Tiger Lake.
  DEF_BIT(31, graphics_disabled);

  DEF_BIT(30, pipe_a_disabled);
  DEF_BIT(28, pipe_c_disabled);
  // FBC (Frame Buffer Compression) and DPST (Display Power Savings Technology).
  DEF_BIT(27, power_management_disabled);

  // Tiger Lake: All combo PHY ports disabled.
  // Kaby Lake and Skylake: DDIA eDP support disabled.
  DEF_BIT(26, edp_disabled);

  // Not on Tiger Lake.
  DEF_FIELD(24, 23, core_clock_limit_bits);
  CoreClockLimit GetCoreClockLimit() const {
    return static_cast<CoreClockLimit>(core_clock_limit_bits());
  }

  // Only Tiger Lake.
  DEF_BIT(22, pipe_d_disabled);

  DEF_BIT(21, pipe_b_disabled);
  // Display capture is called WD (Wireless Display) in Intel docs.
  DEF_BIT(20, display_capture_disabled);

  // Only Tiger Lake.
  DEF_BIT(16, isolated_decode_disabled);
  DEF_FIELD(15, 8, audio_codec_id_low);
  DEF_BIT(7, display_stream_compression_disabled);

  DEF_BIT(6, remote_screen_blanking_enabled);
  DEF_BIT(0, audio_codec_disabled);

  static auto Get() { return hwreg::RegisterAddr<DisplayFuses>(0x51000); }
};

// DSSM (Display Strap State)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 1 pages 825-827
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 545-546
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 545-546
//
// This register is based on the Tiger Lake definition.
class DisplayStraps : public hwreg::RegisterBase<DisplayStraps, uint32_t> {
 public:
  // Documented values for the `reference_frequency_select` field.
  enum class ReferenceFrequencySelectTigerLake : uint8_t {
    k24Mhz = 0b00,
    k19_2Mhz = 0b01,
    k38_4Mhz = 0b10,
  };

  // Possible values for the `audio_io_location` field.
  enum class AudioIoLocationTigerLake {
    kSouth = 0,
    kNorth = 1,
  };

  // This field has a non-trivial representation and should be accessed via the
  // `reference_frequency_khz()` helper.
  DEF_ENUM_FIELD(ReferenceFrequencySelectTigerLake, 31, 29, reference_frequency_select_tiger_lake);

  // If true, the maximum supported display width is 5120 pixels.
  //
  // The display width is the result of combinining the widths of all the pipes
  // that make up the display. If this field is true, the hardware cannot drive
  // displays above 5k, under any configuration.
  //
  // This field is reserved on Kaby Lake and Skylake.
  DEF_BIT(6, display_width_at_most_5120_pixels_tiger_lake);

  // If true, the Audio I/O flop is bypassed.
  //
  // This is enabled on dies where the path to I/O is unsuitably long.
  //
  // This field is reserved on Kaby Lake and Skylake.
  DEF_BIT(5, audio_io_flop_bypassed_tiger_lake);

  // The location where PCH audio is connected to the CPU die.
  //
  // This field is reserved on Kaby Lake and Skylake.
  DEF_ENUM_FIELD(AudioIoLocationTigerLake, 4, 4, audio_io_location_tiger_lake);

  // The WD (Wireless Display; display capture) behavior on page faults.
  //
  // If this field is true, the display capture functionality continues writing
  // data after a page fault. If this field is false, page faults result stop
  // display capture.
  //
  // This field is reserved on Kaby Lake and Skylake.
  DEF_BIT(3, continue_writes_on_display_capture_fault_tiger_lake);

  // If true, some LCPLL (LC-tank PLL) output frequencies are not available.
  //
  // This field is reserved on Tiger Lake.
  DEF_BIT(2, lcpll_frequencies_disabled);

  // True for SoC (System-on-Chip) parts, false for non-SoC parts.
  //
  // This field is reserved on Kaby Lake and Skylake.
  DEF_BIT(1, is_system_on_chip_tiger_lake);

  // If true, (DisplayPort) DDI A was present during system initialization.
  //
  // This field is reserved on Kaby Lake and Skylake.
  DEF_BIT(0, ddi_a_present);

  // The frequency of the display reference clock, in kHz.
  //
  // This frequency is used to compute the frequency multipliers for all the
  // programmable clocks in the display engine.
  //
  // Returns 0 if the field has an undocumented value.
  int32_t reference_frequency_khz_tiger_lake() const {
    const ReferenceFrequencySelectTigerLake frequency_select =
        reference_frequency_select_tiger_lake();
    switch (frequency_select) {
      case ReferenceFrequencySelectTigerLake::k19_2Mhz:
        return 19'200;
      case ReferenceFrequencySelectTigerLake::k24Mhz:
        return 24'000;
      case ReferenceFrequencySelectTigerLake::k38_4Mhz:
        return 38'400;
    }
    return 0;  // The field is set to an undocumented value.
  }

  static auto Get() { return hwreg::RegisterAddr<DisplayStraps>(0x51004); }
};

// DISPLAY_INT_CTL (Display Interrupt Control)
//
// Controls whether display interrupts propagate to the PCI device interrupt,
// and summarizes the pending display interrupts.
//
// This register is referred to as MASTER_INT_CTL (Master Interrupt Control) in
// the documentation for Kaby Lake and Skylake.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 1 pages 1054-1055
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 pages 9-11
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 pages 10-12
class DisplayInterruptControl : public hwreg::RegisterBase<DisplayInterruptControl, uint32_t> {
 public:
  // If true, display engine interrupts propagate to the next level.
  //
  // On Tiger Lake and DG1, display engine interrupts propagate to the graphics
  // interrupt dispatcher, which is controlled by the GraphicsPrimaryInterrupt
  // register.
  //
  // On Kaby Lake and Skylake, display engine interrupts propagate directly to
  // the PCI device interrupt.
  //
  // The driver sets this bit when it is ready to process display interrupts.
  DEF_BIT(31, interrupts_enabled);

  // True if there are pending interrupts from the PCU (Power Control Unit).
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(30, pcu_pending_kaby_lake);

  // True if there are pending interrupts from the audio codec.
  DEF_BIT(24, audio_codec_pending);

  // True if there are pending interrupts from the PCH display engine.
  //
  // If this bit is set, the {{PCH interrupts register}} must be checked.
  DEF_BIT(23, pch_engine_pending);

  // True if there are pending miscellaneous display engine interrupts.
  DEF_BIT(22, misc_display_pending);

  // True if there are pending hotplug interrupts from the main display engine.
  //
  // This field only reflects hotplug events from the main / north display
  // engine. Hotplug interrupts from the PCH / south display engine are recorded
  // in the `pch_engine_pending` bit.
  //
  // This bit is not documented on Kaby Lake and Skylake, where the display
  // engine does not handle hot plug for any port.
  DEF_BIT(21, display_hot_plug_pending_tiger_lake);

  // True if there are pending port interrupts.
  DEF_BIT(20, port_pending);

  // True if there are pending Pipe D interrupts.
  //
  // This field is not documented on Kaby Lake and Skylake. The underlying bit
  // is reserved but not documented as MBZ (Must Be Zero).
  DEF_BIT(19, pipe_d_pending_tiger_lake);

  // True if there are pending Pipe C interrupts.
  DEF_BIT(18, pipe_c_pending);

  // True if there are pending Pipe B interrupts.
  DEF_BIT(17, pipe_b_pending);

  // True if there are pending Pipe A interrupts.
  DEF_BIT(16, pipe_a_pending);

  // True if there are pending VEBox (video encoding box) interrupts.
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(6, video_encoding_box_pending_kaby_lake);

  // True if there are pending GTPM (GPU power management) interrupts.
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(4, gpu_power_pending_kaby_lake);

  // True if there are pending VCS (Video Command Streamer) 2 interrupts.
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(3, video_command_streamer_2_pending_kaby_lake);

  // True if there are pending VCS (Video Command Streamer) 1 interrupts.
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(2, video_command_streamer_1_pending_kaby_lake);

  // True if there are pending blitter interrupts.
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(1, blitter_pending_kaby_lake);

  // True if there are pending render interrupts.
  //
  // This is not documented on Tiger Lake. However, it has good read semantics.
  // The underlying bit is reserved and documented as MBZ (must be zero), so
  // reading it will always report that no interrupts are pending.
  DEF_BIT(0, render_pending_kaby_lake);

  static auto Get() { return hwreg::RegisterAddr<DisplayInterruptControl>(0x44200); }
};

// GFX_MSTR_INTR (Graphics Primary Interrupt)
//
// Controls whether top-level graphics interrupts propagate to the PCI device
// interrupt, and summarizes the pending graphics-level interrupts.
//
// This register is not documented on Kaby Lake or Skylake. On those platforms,
// the display engine interrupts covered by DisplayInterruptControl propagate
// directly to the PCI device interrupt.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 1 pages 1054-1055
class GraphicsPrimaryInterrupt : public hwreg::RegisterBase<GraphicsPrimaryInterrupt, uint32_t> {
 public:
  // If true, graphics interrupts propagate to the PCI device interrupt.
  //
  // The driver sets this bit when it is ready to process graphics interrupts.
  DEF_BIT(31, interrupts_enabled);

  // True if an interrupt from the display engine is pending.
  DEF_BIT(16, display_interrupt_pending);

  // True if a GPU interrupt is pending.
  DEF_BIT(1, gt1_interrupt_pending);

  // True if a GPU interrupt is pending.
  DEF_BIT(0, gt0_interrupt_pending);

  static auto Get() { return hwreg::RegisterAddr<GraphicsPrimaryInterrupt>(0x190010); }
};

// PWR_WELL_CTL
//
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 690-693
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 2 pages 1063-1065
class PowerWellControl : public hwreg::RegisterBase<PowerWellControl, uint32_t> {
 public:
  hwreg::BitfieldRef<uint32_t> power_request(size_t index) {
    ZX_DEBUG_ASSERT(index & 1);
    ZX_DEBUG_ASSERT_MSG(index <= std::numeric_limits<uint32_t>::max(), "%zu overflows uint32_t",
                        index);
    const uint32_t i = static_cast<uint32_t>(index);
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), i, i);
  }

  hwreg::BitfieldRef<uint32_t> power_state(size_t index) {
    ZX_DEBUG_ASSERT((index & 1) == 0);
    ZX_DEBUG_ASSERT_MSG(index <= std::numeric_limits<uint32_t>::max(), "%zu overflows uint32_t",
                        index);
    const uint32_t i = static_cast<uint32_t>(index);
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), i, i);
  }

  hwreg::BitfieldRef<uint32_t> ddi_io_power_request_skylake(i915::DdiId ddi_id) {
    int bit =
        2 + ((ddi_id == i915::DdiId::DDI_A || ddi_id == i915::DdiId::DDI_E) ? 0 : ddi_id * 2) + 1;
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit);
  }

  hwreg::BitfieldRef<uint32_t> ddi_io_power_state_skylake(i915::DdiId ddi_id) {
    int bit = 2 + ((ddi_id == i915::DdiId::DDI_A || ddi_id == i915::DdiId::DDI_E) ? 0 : ddi_id * 2);
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit);
  }

  // Misc IO Power Request (on Skylake / Kaby Lake only)
  // This field requests power for Miscellaneous IO to enable (1) or disable (0).
  // This includes all AUX channels, audio pins, and utility pin.
  hwreg::BitfieldRef<uint32_t> misc_io_power_request_skylake() {
    int bit = kMiscIoBitsOffset + 1;
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit);
  }

  // Misc IO Power State (on Skylake / Kaby Lake only):
  // Enabled (1) or disabled (0).
  hwreg::BitfieldRef<uint32_t> misc_io_power_state_skylake() {
    int bit = kMiscIoBitsOffset;
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit);
  }

  static auto Get() {
    // The address below is for PWR_WELL_CTL2, which is provided for driver use.
    // By contrast, PWR_WELL_CTL1 is intended for BIOS use.
    return hwreg::RegisterAddr<PowerWellControl>(0x45404);
  }

 private:
  constexpr static size_t kMiscIoBitsOffset = 0;
};

// PWR_WELL_CTL_AUX2 (Power Well Control AUX2)
// Control display power for AUX IO for each DDI / Transport.
// This register is only available on Tiger Lake.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 1072-1077
class PowerWellControlAux : public hwreg::RegisterBase<PowerWellControlAux, uint32_t> {
 public:
  DEF_BIT(29, power_on_request_thunderbolt_6);
  DEF_BIT(28, powered_on_thunderbolt_6);

  DEF_BIT(27, power_on_request_thunderbolt_5);
  DEF_BIT(26, powered_on_thunderbolt_5);

  DEF_BIT(25, power_on_request_thunderbolt_4);
  DEF_BIT(24, powered_on_thunderbolt_4);

  DEF_BIT(23, power_on_request_thunderbolt_3);
  DEF_BIT(22, powered_on_thunderbolt_3);

  DEF_BIT(21, power_on_request_thunderbolt_2);
  DEF_BIT(20, powered_on_thunderbolt_2);

  DEF_BIT(19, power_on_request_thunderbolt_1);
  DEF_BIT(18, powered_on_thunderbolt_1);

  DEF_BIT(17, power_on_request_usb_c_6);
  DEF_BIT(16, powered_on_usb_c_6);

  DEF_BIT(15, power_on_request_usb_c_5);
  DEF_BIT(14, powered_on_usb_c_5);

  DEF_BIT(13, power_on_request_usb_c_4);
  DEF_BIT(12, powered_on_usb_c_4);

  DEF_BIT(11, power_on_request_usb_c_3);
  DEF_BIT(10, powered_on_usb_c_3);

  DEF_BIT(9, power_on_request_usb_c_2);
  DEF_BIT(8, powered_on_usb_c_2);

  DEF_BIT(7, power_on_request_usb_c_1);
  DEF_BIT(6, powered_on_usb_c_1);

  DEF_BIT(5, power_on_request_c);
  DEF_BIT(4, powered_on_c);

  DEF_BIT(3, power_on_request_b);
  DEF_BIT(2, powered_on_b);

  DEF_BIT(1, power_on_request_a);
  DEF_BIT(0, powered_on_a);

  SelfType& set_power_on_request_combo_or_usb_c(i915::DdiId ddi_id, bool enabled) {
    ZX_DEBUG_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_DEBUG_ASSERT(ddi_id <= i915::DdiId::DDI_TC_6);
    const uint32_t bit = ddi_id * 2 + 1;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit).set(enabled);
    return *this;
  }

  bool powered_on_combo_or_usb_c(i915::DdiId ddi_id) const {
    ZX_DEBUG_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_DEBUG_ASSERT(ddi_id <= i915::DdiId::DDI_TC_6);
    const uint32_t bit = ddi_id * 2;
    return hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit, bit).get();
  }

  SelfType& set_power_on_request_thunderbolt(i915::DdiId ddi_id, bool enabled) {
    ZX_DEBUG_ASSERT(ddi_id >= i915::DdiId::DDI_TC_1);
    ZX_DEBUG_ASSERT(ddi_id <= i915::DdiId::DDI_TC_6);
    // The request_thunderbolt_* bits start from bit 19.
    const uint32_t bit = (ddi_id - i915::DdiId::DDI_TC_1) * 2 + 19;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit).set(enabled);
    return *this;
  }

  bool powered_on_thunderbolt(i915::DdiId ddi_id) const {
    ZX_DEBUG_ASSERT(ddi_id >= i915::DdiId::DDI_TC_1);
    ZX_DEBUG_ASSERT(ddi_id <= i915::DdiId::DDI_TC_6);
    // The state_thunderbolt_* bits start from bit 18.
    const uint32_t bit = (ddi_id - i915::DdiId::DDI_TC_1) * 2 + 18;
    return hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit, bit).get();
  }

  static auto Get() {
    // The address below is for PWR_WELL_CTL_AUX2, which is provided for driver
    // use. By contrast, PWR_WELL_CTL_AUX1 is intended for BIOS use.
    return hwreg::RegisterAddr<PowerWellControlAux>(0x45444);
  }
};

// PWR_WELL_CTL_DDI
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 2 pages 1072-1075
class PowerWellControlDdi2 : public hwreg::RegisterBase<PowerWellControlDdi2, uint32_t> {
 public:
  hwreg::BitfieldRef<uint32_t> ddi_io_power_request_tiger_lake(i915::DdiId ddi_id) {
    // DDI A-C: bits 1/3/5. DDI TC1-6: bits 7/9/11/13/15/17.
    int bit = ddi_id * 2 + 1;
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit);
  }

  hwreg::BitfieldRef<uint32_t> ddi_io_power_state_tiger_lake(i915::DdiId ddi_id) {
    int bit = ddi_id * 2;  // DDI A-C: bits 0/2/4. DDI TC1-6: bits 6/8/10/12/14/16.
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit, bit);
  }

  static auto Get() {
    // The address below is for PWR_WELL_CTL_DDI2, which is provided for driver
    // use. By contrast, PWR_WELL_CTL_DDI1 is intended for BIOS use.
    return hwreg::RegisterAddr<PowerWellControlDdi2>(0x45454);
  }
};

// FUSE_STATUS
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 1 pages 990-991
class FuseStatus : public hwreg::RegisterBase<FuseStatus, uint32_t> {
 public:
  DEF_BIT(31, fuse_download_status);
  DEF_BIT(27, pg0_dist_status);
  DEF_BIT(26, pg1_dist_status);
  DEF_BIT(25, pg2_dist_status);
  DEF_BIT(24, pg3_dist_status);  // Only for Icy lake or higher gen
  DEF_BIT(23, pg4_dist_status);  // Only for Icy lake or higher gen
  DEF_BIT(22, pg5_dist_status);  // Only for Tiger lake or higher gen

  uint32_t dist_status(uint32_t index) {
    ZX_DEBUG_ASSERT(index >= 0 && index <= 31);
    return hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), index, index).get();
  }

  static auto Get() { return hwreg::RegisterAddr<FuseStatus>(0x42000); }
};

// AUD_EDID_DATA
class AudEdidData : public hwreg::RegisterBase<AudEdidData, uint32_t> {
 public:
  DEF_FIELD(31, 0, data);

  static auto Get(int transcoder_id) {
    if (transcoder_id == 0) {
      return hwreg::RegisterAddr<AudEdidData>(0x65050);
    } else if (transcoder_id == 1) {
      return hwreg::RegisterAddr<AudEdidData>(0x65150);
    } else {  // transcoder_id == 2.
      ZX_DEBUG_ASSERT(transcoder_id == 2);
      return hwreg::RegisterAddr<AudEdidData>(0x65250);
    }
  }
};

// AUD_DIP_ELD_CTRL_ST
class AudioDipEldControlStatus : public hwreg::RegisterBase<AudioDipEldControlStatus, uint32_t> {
 public:
  DEF_FIELD(30, 29, dip_port_select);
  DEF_FIELD(24, 21, dip_type_enable_status);
  DEF_FIELD(20, 18, dip_buffer_index);
  DEF_FIELD(17, 16, dip_transmission_frequency);
  DEF_FIELD(14, 10, eld_buffer_size);
  DEF_FIELD(9, 5, eld_access_address);
  DEF_BIT(4, eld_ack);
  DEF_FIELD(3, 0, dip_access_address);
  static auto Get() { return hwreg::RegisterAddr<AudioDipEldControlStatus>(0x650B4); }
};

// AUD_PIN_ELD_CP_VLD
class AudioPinEldCPReadyStatus : public hwreg::RegisterBase<AudioPinEldCPReadyStatus, uint32_t> {
 public:
  DEF_BIT(11, audio_inactive_c);
  DEF_BIT(10, audio_enable_c);
  DEF_BIT(9, cp_ready_c);
  DEF_BIT(8, eld_valid_c);

  DEF_BIT(7, audio_inactive_b);
  DEF_BIT(6, audio_enable_b);
  DEF_BIT(5, cp_ready_b);
  DEF_BIT(4, eld_valid_b);

  DEF_BIT(3, audio_inactive_a);
  DEF_BIT(2, audio_enable_a);
  DEF_BIT(1, cp_ready_a);
  DEF_BIT(0, eld_valid_a);

  static auto Get() { return hwreg::RegisterAddr<AudioPinEldCPReadyStatus>(0x650C0); }
};

// CDCLK_CTL (CD Clock Control)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 1 pages 220-222
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 328-329
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 325-326
class CdClockCtl : public hwreg::RegisterBase<CdClockCtl, uint32_t> {
 public:
  DEF_FIELD(27, 26, skl_cd_freq_select);
  static constexpr uint32_t kFreqSelect4XX = 0;
  static constexpr uint32_t kFreqSelect540 = 1;
  static constexpr uint32_t kFreqSelect3XX = 2;
  static constexpr uint32_t kFreqSelect6XX = 3;

  DEF_FIELD(23, 22, icl_cd2x_divider_select);
  static constexpr uint32_t kCd2xDivider1 = 0;
  static constexpr uint32_t kCd2xDivider2 = 1;

  DEF_FIELD(21, 19, icl_cd2x_pipe_select);

  DEF_FIELD(10, 0, cd_freq_decimal);
  // This returns binary representation of CD clock frequency (MHz) in
  // U10.1 format (cd_freq_decimal field). To calculate its value, we first
  // round the frequency to 0.5MHz and then minus it by one.
  static constexpr uint32_t FreqDecimal(uint32_t khz) {
    // Truncate the frequency to 0.25MHz for rounding.
    uint32_t mhz_4x_trunc = khz / 250;
    // Round the frequency to 0.5 MHz.
    uint32_t mhz_2x_round = (mhz_4x_trunc + 1) / 2;
    // Return rounded value minus 1 (0x2 in U10.1 format).
    return mhz_2x_round - 2;
  }

  static auto Get() { return hwreg::RegisterAddr<CdClockCtl>(0x46000); }
};

// CDCLK_PLL_ENABLE on ICL+
class IclCdClkPllEnable : public hwreg::RegisterBase<IclCdClkPllEnable, uint32_t> {
 public:
  DEF_BIT(31, pll_enable);
  DEF_BIT(30, pll_lock);
  DEF_FIELD(7, 0, pll_ratio);

  static auto Get() { return hwreg::RegisterAddr<IclCdClkPllEnable>(0x46070); }
};

// DBUF_CTL (DBUF Slice Control)
//
// Some of the register's reserved are not documented as MBZ (must be zero). So,
// this register can only be safely updated using read-modify-write operations.
//
// The "Data Buffer" expansion for the DBUF acronym is implicitly documented in
// the "Shared Functions" > "Data Buffer" section of the display engine PRMs
// (Vol 12 for all recent display engines), which lists all the DBUF-related
// registers.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 1 pages 331-332
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 1 pages 309-310
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 430-431
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 426-427
class DataBufferControl : public hwreg::RegisterBase<DataBufferControl, uint32_t> {
 public:
  // The eventual state that `powered_on` will reach.
  //
  // If true, the DBUF (Data Buffer) slice will eventually power on. If false,
  // the DBUF slice will eventually power off.
  //
  // The first DBUF slice must be powered on before using the display engine.
  // Powering it on is a step in the "Sequences to Initialize Display".
  DEF_BIT(31, powered_on_target);

  // If true, the DBUF (Data Buffer) slice is powered on.
  DEF_BIT(30, powered_on);

  // Maximum number of clock cycles until the tracker state is serviced.
  //
  // This field is not documented on Kaby Lake and Skylake. The underlying bits
  // are documented as reserved MBZ (must be zero).
  DEF_FIELD(23, 19, maximum_tracker_state_delay_tiger_lake);

  // Maximum number of clock cycles until the CC block valid state is serviced.
  //
  // This field is not documented on Kaby Lake and Skylake. The underlying bits
  // are documented as reserved MBZ (must be zero).
  DEF_FIELD(15, 12, maximum_cc_block_valid_delay);

  // DBUF (Data Buffer) slice count varies by display engine.
  //
  // `slice_index` is 0-based.
  static auto GetForSlice(int slice_index) {
    ZX_ASSERT(slice_index >= 0);
    ZX_ASSERT(slice_index < 2);

    static constexpr uint32_t kMmioAddress[] = {0x45008, 0x44fe8};
    return hwreg::RegisterAddr<DataBufferControl>(kMmioAddress[slice_index]);
  }
};

// DBUF_CTL (DBUF Slice Control 2)
//
// All reserved bits are MBZ (must be zero), so this register can be written
// safely without reading it first.
//
// This register is not documented on Kaby Lake or Skylake.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-12.21 Part 1 page 333
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 1 page 311
class DataBufferControl2 : public hwreg::RegisterBase<DataBufferControl2, uint32_t> {
 public:
  DEF_RSVDZ_FIELD(31, 13);

  // Number of time slots between servicing HPUTs.
  //
  // This field must not be set to zero.
  DEF_FIELD(12, 8, hput_service_interval);

  // Number of time slots dedicated to servicing APUTs.
  //
  // This field must not be set to zero.
  DEF_FIELD(7, 4, aput_service_time_slots);

  // Number of time slots dedicated to servicing BYPASS puts.
  //
  // This field must not be set to zero.
  DEF_FIELD(3, 0, bypass_put_service_time_slots);

  // DBUF (Data Buffer) slice count varies by display engine.
  //
  // `slice_index` is 0-based.
  static auto GetForSlice(int slice_index) {
    ZX_ASSERT(slice_index >= 0);
    ZX_ASSERT(slice_index < 2);

    static constexpr uint32_t kMmioAddress[] = {0x44ffc, 0x44fe4};
    return hwreg::RegisterAddr<DataBufferControl2>(kMmioAddress[slice_index]);
  }
};

// VGA_CONTROL
class VgaCtl : public hwreg::RegisterBase<VgaCtl, uint32_t> {
 public:
  DEF_BIT(31, vga_display_disable);

  static auto Get() { return hwreg::RegisterAddr<VgaCtl>(0x41000); }
};

}  // namespace registers

#endif  // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_H_
