// 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_DPLL_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_DPLL_H_

#include <zircon/assert.h>

#include <cstdint>
#include <limits>

#include <hwreg/bitfields.h>

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

namespace registers {

// DPLL_CTRL1 (Display PLL Control 1?)
//
// Some of this register's reserved fields are not MBZ (must be zero). So, the
// register can only be updated safely via read-modify-write operations.
//
// This register is not documented on Tiger Lake or DG1.
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 528-531
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 526-529
class DisplayPllControl1 : public hwreg::RegisterBase<DisplayPllControl1, uint32_t> {
 public:
  DEF_RSVDZ_FIELD(31, 28);

  // Documented values for the `pll_display_port_ddi_frequency_select` fields.
  enum class DisplayPortDdiFrequencySelect : int {
    k2700Mhz = 0b000,  // DP HBR2. Lane clock 5.4 GHz. VCO 8100, divider 6.
    k1350Mhz = 0b001,  // DP HBR1. Lane clock 2.7 GHz. VCO 8100, divider 3.
    k810Mhz = 0b010,   // DP RBR. Lane clock 1.62 GHz. VCO 8100, divider 10.
    k1620Mhz = 0b011,  // eDP rate 5. Lane clock 3.24 GHz. VCO 8100, divider 5.
    k1080Mhz = 0b100,  // eDP rate 2. Lane clock 2.16 GHz. VCO 8640, divider 8.
    k2160Mhz = 0b101,  // eDP rate 6. Lane clock 4.32 GHz. VCO 8640, divider 4.

    // TODO(https://fxbug.dev/42062082): Figure out modeling for invalid values.
  };

  DEF_BIT(23, pll3_uses_hdmi_configuration_mode);
  DEF_BIT(22, pll3_spread_spectrum_clocking_enabled);
  DEF_ENUM_FIELD(DisplayPortDdiFrequencySelect, 21, 19, pll3_display_port_ddi_frequency_select);
  DEF_BIT(18, pll3_programming_enabled);

  DEF_BIT(17, pll2_uses_hdmi_configuration_mode);
  DEF_BIT(16, pll2_spread_spectrum_clocking_enabled);
  DEF_ENUM_FIELD(DisplayPortDdiFrequencySelect, 15, 13, pll2_display_port_ddi_frequency_select);
  DEF_BIT(12, pll2_programming_enabled);

  DEF_BIT(11, pll1_uses_hdmi_configuration_mode);
  DEF_BIT(10, pll1_spread_spectrum_clocking_enabled);
  DEF_ENUM_FIELD(DisplayPortDdiFrequencySelect, 9, 7, pll1_display_port_ddi_frequency_select);
  DEF_BIT(6, pll1_programming_enabled);

  DEF_ENUM_FIELD(DisplayPortDdiFrequencySelect, 3, 1, pll0_display_port_ddi_frequency_select);
  DEF_BIT(0, pll0_programming_enabled);

  // If true, the Display PLL is configured for HDMI operation.
  //
  // If this field is true, the PLL uses the configuration in the DPLL*_CFGCR*
  // registers. The PLL will generate AFE (Analog Front-End) clock frequencies
  // suitable for use with DDIs that serve HDMI connections. HDMI operation does
  // not support SSC (Spread Spectrum Clocking).
  //
  // If this field is false, the PLL is configured for DisplayPort operation,
  // which uses the frequency and SSC configuration in this register. The PLL's
  // AFE clock output frequencies will be suitable for use with DDIs that serve
  // DisplayPort connections.
  //
  // This helper always returns false on DPLL0. The underlying field does not
  // exist for Display PLL0, because PLL0 does not support HDMI operation.
  bool pll_uses_hdmi_configuration_mode(i915::PllId pll_id) const {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    if (pll_id == i915::PllId::DPLL_0) {
      return false;  // DPLL 0 does not support HDMI operation.
    }

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6 + 5;
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index, bit_index).get());
  }

  // See `pll_uses_hdmi_configuration_mode()` for details.
  DisplayPllControl1& set_pll_uses_hdmi_configuration_mode(i915::PllId pll_id, bool hdmi_mode) {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    if (pll_id == i915::PllId::DPLL_0) {
      ZX_DEBUG_ASSERT(!hdmi_mode);
      return *this;
    }

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6 + 5;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index, bit_index).set(hdmi_mode ? 1 : 0);
    return *this;
  }

  // If true, the Display PLL uses SSC (Spread Spectrum Clocking).
  //
  // This helper always return false for DPLL (Display PLL) 0. The underlying
  // field does not exist for DPLL0. DPLL0 does not support SSC, because it must
  // deliver a constant frequency to the core display clock.
  bool pll_spread_spectrum_clocking_enabled(i915::PllId pll_id) const {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    if (pll_id == i915::PllId::DPLL_0) {
      return false;  // DPLL 0 does not support SSC (Spread Spectrum Clocking).
    }

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6 + 4;
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index, bit_index).get());
  }

  // See `pll_spread_spectrum_clocking_enabled()` for details.
  DisplayPllControl1& set_pll_spread_spectrum_clocking_enabled(i915::PllId pll_id,
                                                               bool ssc_enabled) {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    if (pll_id == i915::PllId::DPLL_0) {
      ZX_DEBUG_ASSERT(!ssc_enabled);
      return *this;
    }

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6 + 4;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index, bit_index).set(ssc_enabled ? 1 : 0);
    return *this;
  }

  // The Display PLL's DDI clock frequency, when operating in DisplayPort mode.
  //
  // This field sets the AFE (Analog Front-End) clock for the DPLL (Display
  // PLL), when the DPLL is operating in DisplayPort Mode. The AFE clock
  // dictates the frequency of the DDIs that use this DPLL As their clocking
  // source.
  //
  // When a DDI serves a DisplayPort connection, it pushes bits on both clock
  // edges (rising and falling). So, the AFE clock frequency (which becomes the
  // DDI's clock frequency) must be set to half the DisplayPort bit rate. For
  // example, a 2,700 MHz frequency would be used for the HBR2 link rate, which
  // is 5.4 Gbit/s.
  //
  // This field is ignored if the DPLL is not operating in DisplayPort mode.
  //
  // The frequency of DPLL0 indirectly impacts the CDCLK (core display clock)
  // frequency. The PLL's VCO (voltage-controlled oscillator) frequency will be
  // either 8,640 Mhz or 8,100 MHz, subject to the constraint that the
  // DisplayPort frequency must evenly divide the VCO frequency.
  //
  // This helper returns 0 if the field is set to an undocumented value.
  int16_t pll_display_port_ddi_frequency_mhz(i915::PllId pll_id) const {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6 + 1;
    const int raw_frequency_select = static_cast<int>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index + 2, bit_index).get());

    const auto frequency_select = static_cast<DisplayPortDdiFrequencySelect>(raw_frequency_select);
    switch (frequency_select) {
      case DisplayPortDdiFrequencySelect::k2700Mhz:
        return 2'700;
      case DisplayPortDdiFrequencySelect::k1350Mhz:
        return 1'350;
      case DisplayPortDdiFrequencySelect::k810Mhz:
        return 810;
      case DisplayPortDdiFrequencySelect::k1620Mhz:
        return 1'620;
      case DisplayPortDdiFrequencySelect::k1080Mhz:
        return 1'080;
      case DisplayPortDdiFrequencySelect::k2160Mhz:
        return 2'160;
    }
    return 0;  // The field is set to an undocumented value.
  }

  // See `pll_display_port_ddi_frequency_mhz()` for details.
  DisplayPllControl1& set_pll_display_port_ddi_frequency_mhz(i915::PllId pll_id,
                                                             int16_t ddi_frequency_mhz) {
    DisplayPortDdiFrequencySelect frequency_select;
    switch (ddi_frequency_mhz) {
      case 2'700:
        frequency_select = DisplayPortDdiFrequencySelect::k2700Mhz;
        break;
      case 1'350:
        frequency_select = DisplayPortDdiFrequencySelect::k1350Mhz;
        break;
      case 810:
        frequency_select = DisplayPortDdiFrequencySelect::k810Mhz;
        break;
      case 1'620:
        frequency_select = DisplayPortDdiFrequencySelect::k1620Mhz;
        break;
      case 1'080:
        frequency_select = DisplayPortDdiFrequencySelect::k1080Mhz;
        break;
      case 2'160:
        frequency_select = DisplayPortDdiFrequencySelect::k2160Mhz;
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Invalid DDI clock frequency: %d Mhz", ddi_frequency_mhz);
        frequency_select = DisplayPortDdiFrequencySelect::k2700Mhz;
    }

    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6 + 1;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index + 2, bit_index)
        .set(static_cast<uint32_t>(frequency_select));
    return *this;
  }

  // If true, the Display PLL uses the configuration in this register.
  bool pll_programming_enabled(i915::PllId pll_id) const {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6;
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index, bit_index).get());
  }

  // See `pll_programming_enabled()` for details.
  DisplayPllControl1& set_pll_programming_enabled(i915::PllId pll_id, bool programming_enabled) {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    const int bit_index = dpll_index * 6;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index, bit_index)
        .set(programming_enabled ? 1 : 0);
    return *this;
  }

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

// DPLL_CTRL2 (Display PLL Control 2?)
//
// This register controls which DPLL (Display PLL) is used as a clock source by
// each DDI.
//
// Some of this register's reserved fields are not MBZ (must be zero). So, the
// register can only be updated safely via read-modify-write operations.
//
// The Tiger Lake equivalent of this register is `DdiClockConfiguration`
// (DPCLKA_CFGCR0).
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 532-534
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 530-532
class DisplayPllDdiMapKabyLake : public hwreg::RegisterBase<DisplayPllDdiMapKabyLake, uint32_t> {
 public:
  DEF_RSVDZ_FIELD(31, 24);

  DEF_BIT(19, ddi_e_clock_disabled);
  DEF_BIT(18, ddi_d_clock_disabled);
  DEF_BIT(17, ddi_c_clock_disabled);
  DEF_BIT(16, ddi_b_clock_disabled);
  DEF_BIT(15, ddi_a_clock_disabled);

  DEF_FIELD(14, 13, ddi_e_clock_display_pll_index);
  DEF_BIT(12, ddi_e_clock_programming_enabled);

  DEF_FIELD(11, 10, ddi_d_clock_display_pll_index);
  DEF_BIT(9, ddi_d_clock_programming_enabled);

  DEF_FIELD(8, 7, ddi_c_clock_display_pll_index);
  DEF_BIT(6, ddi_c_clock_programming_enabled);

  DEF_FIELD(5, 4, ddi_b_clock_display_pll_index);
  DEF_BIT(3, ddi_b_clock_programming_enabled);

  DEF_FIELD(2, 1, ddi_a_clock_display_pll_index);
  DEF_BIT(0, ddi_a_clock_programming_enabled);

  // If true, the DDI's clock is disabled. This is accomplished by gating.
  bool ddi_clock_disabled(i915::DdiId ddi_id) const {
    ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_ASSERT(ddi_id <= i915::DdiId::DDI_E);

    const int ddi_index = ddi_id - i915::DdiId::DDI_A;
    const int bit_index = 15 + ddi_index;
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index, bit_index).get());
  }

  // See `ddi_clock_disabled()` for details.
  DisplayPllDdiMapKabyLake& set_ddi_clock_disabled(i915::DdiId ddi_id, bool clock_disabled) {
    ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_ASSERT(ddi_id <= i915::DdiId::DDI_E);

    const int ddi_index = ddi_id - i915::DdiId::DDI_A;
    const int bit_index = 15 + ddi_index;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index, bit_index).set(clock_disabled ? 1 : 0);
    return *this;
  }

  // The DPLL (Display PLL) used as a clock source for a DDI.
  i915::PllId ddi_clock_display_pll(i915::DdiId ddi_id) const {
    ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_ASSERT(ddi_id <= i915::DdiId::DDI_E);

    const int ddi_index = ddi_id - i915::DdiId::DDI_A;
    const int bit_index = ddi_index * 3 + 1;
    const uint32_t dpll_index = static_cast<int>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index + 1, bit_index).get());
    // The cast result is DPLL0-3 because `dpll_index` comes from a 2-bit field.
    return static_cast<i915::PllId>(dpll_index);
  }

  // See `ddi_clock_display_pll()` for details.
  DisplayPllDdiMapKabyLake& set_ddi_clock_display_pll(i915::DdiId ddi_id, i915::PllId pll_id) {
    ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_ASSERT(ddi_id <= i915::DdiId::DDI_E);
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_0);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int ddi_index = ddi_id - i915::DdiId::DDI_A;
    const int bit_index = ddi_index * 3 + 1;
    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index + 1, bit_index).set(dpll_index);
    return *this;
  }

  // If true, the DDI uses the clock configuration in this register.
  bool ddi_clock_programming_enabled(i915::DdiId ddi_id) const {
    ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_ASSERT(ddi_id <= i915::DdiId::DDI_E);

    const int ddi_index = ddi_id - i915::DdiId::DDI_A;
    const int bit_index = ddi_index * 3;
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), bit_index, bit_index).get());
  }

  // See `ddi_clock_programming_enabled()` for details.
  DisplayPllDdiMapKabyLake& set_ddi_clock_programming_enabled(i915::DdiId ddi_id,
                                                              bool programming_enabled) {
    ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A);
    ZX_ASSERT(ddi_id <= i915::DdiId::DDI_E);

    const int ddi_index = ddi_id - i915::DdiId::DDI_A;
    const int bit_index = ddi_index * 3;
    hwreg::BitfieldRef<uint32_t>(reg_value_ptr(), bit_index, bit_index)
        .set(programming_enabled ? 1 : 0);
    return *this;
  }

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

// DPLL_CFGCR1 (Display PLL Configuration and Control Register 1?)
//
// When the DPLL (Display PLL) operates in HDMI mode, this register configures
// the frequency of the DCO (Digitally-Controlled Oscillator) in the DPLL. This
// influences the frequency that the DPLL outputs to connected DDIs.
//
// This register's reserved fields are all MBZ (must be zero). So, this register
// can be safely written without reading it first.
//
// The Tiger Lake equivalent of this register is
// `DisplayPllDcoFrequencyTigerLake` (DPLL_CFGCR0).
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 page 525
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 530-532
class DisplayPllDcoFrequencyKabyLake
    : public hwreg::RegisterBase<DisplayPllDcoFrequencyKabyLake, uint32_t> {
 public:
  // Kaby Lake and Skylake display engines support a single reference frequency.
  static constexpr int32_t kReferenceFrequencyKhz = 24'000;

  // The number of fractional bits in the DCO frequency multiplier.
  //
  // The DCO frequency multiplier is a fixed-point (as opposed to
  // floating-point) number. This constant represents the position of the base-2
  // equivalent of the decimal point.
  static constexpr int kMultiplierPrecisionBits = 15;

  // If true, the circuits for generating HDMI frequencies are enabled.
  //
  // This must be set when the DPLL operates in HDMI mode.
  DEF_BIT(31, frequency_programming_enabled);

  DEF_RSVDZ_FIELD(30, 24);

  // These fields have a non-trivial representation. They should be used via the
  // `dco_frequency_multiplier()` and `set_dco_frequency_multiplier()` helpers.
  DEF_FIELD(23, 9, dco_frequency_multiplier_fraction);
  DEF_FIELD(8, 0, dco_frequency_multiplier_integer);

  // The frequency multiplier for the DCO (Digitally Controlled Oscillator).
  //
  // The return value has `kMultiplierPrecisionBits` fractional bits.
  //
  // The multiplier is relative to the display engine reference frequency. On
  // Kaby Lake, this reference frequency is always `kReferenceFrequencyHz`.
  int32_t dco_frequency_multiplier() const {
    return static_cast<int32_t>(
        (static_cast<int32_t>(dco_frequency_multiplier_integer()) << kMultiplierPrecisionBits) |
        static_cast<int32_t>(dco_frequency_multiplier_fraction()));
  }

  // See `dco_frequency_multiplier()` for details.
  DisplayPllDcoFrequencyKabyLake& set_dco_frequency_multiplier(int32_t multiplier) {
    ZX_ASSERT(multiplier > 0);
    ZX_ASSERT(multiplier < (1 << 24));

    return set_dco_frequency_multiplier_fraction(multiplier & ((1 << kMultiplierPrecisionBits) - 1))
        .set_dco_frequency_multiplier_integer(multiplier >> kMultiplierPrecisionBits);
  }

  // The currently configured DCO (Digitally Controlled Oscillator) frequency.
  //
  // This is a convenience method on top of the `dco_frequency_multiplier`
  // fields.
  int32_t dco_frequency_khz() const {
    // The formulas in the PRM use truncating division when converting from a
    // frequency to a DCO multiplier. Rounding up below aims to re-constitue an
    // original frequency that is round-tripped through the conversion.
    return static_cast<int32_t>(((int64_t{dco_frequency_multiplier()} * kReferenceFrequencyKhz) +
                                 (1 << kMultiplierPrecisionBits) - 1) >>
                                kMultiplierPrecisionBits);
  }

  // The currently configured DCO (Digitally Controlled Oscillator) frequency.
  //
  // This is a convenience method on top of the `dco_frequency_multiplier`
  // fields.
  DisplayPllDcoFrequencyKabyLake& set_dco_frequency_khz(int frequency_khz) {
    // The formulas in the PRM use truncating division.
    return set_dco_frequency_multiplier(static_cast<int32_t>(
        (int64_t{frequency_khz} << kMultiplierPrecisionBits) / kReferenceFrequencyKhz));
  }

  static auto GetForDpll(i915::PllId pll_id) {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_1);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    return hwreg::RegisterAddr<DisplayPllDcoFrequencyKabyLake>(0x6c040 + (dpll_index - 1) * 8);
  }
};

// DPLL_CFGCR2 (Display PLL Configuration and Control Register 2?)
//
// When the DPLL (Display PLL) operates in HDMI mode, this register configures
// the frequency dividers between the DCO (Digitally-Controlled Oscillator) in
// the DPLL and the DPLL's AFE (Analog Front-End) clock output, which goes to
// connected DDIs. The frequency output by the DPLL to DDIs, also called AFE
// clock frequency, is the DCO frequency configured in DPLL_CFGCR1 divided by
// the product of all the dividers (P * Q * K, also documented as P0 * P1 * P2)
// in this register.
//
// Unfortunately, Intel's documentation refers to the DCO frequency dividers
// both as (P0, P1, P2) and as (P, Q, K). Fortunately, both variations use short
// names, so we can use both variations in our names below. This facilitates
// checking our code against documents that use either naming variation.
//
// This register's reserved fields are all MBZ (must be zero). So, this register
// can be safely written without reading it first.
//
// The Tiger Lake equivalent of this register is DPLL_CFGCR1.
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 page 526-527
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 524-525
class DisplayPllDcoDividersKabyLake
    : public hwreg::RegisterBase<DisplayPllDcoDividersKabyLake, uint32_t> {
 public:
  // Possible values for the `k_p2_divider_select` field.
  enum class KP2DividerSelect {
    k5 = 0b00,
    k2 = 0b01,  // The preferred value
    k3 = 0b10,
    k1 = 0b11,
  };

  // Documented values for the `p_p0_divider_select` field.
  enum class PP0DividerSelect {
    k1 = 0b000,
    k2 = 0b001,
    k3 = 0b010,
    k7 = 0b100,
  };

  // Possible values for the `center_frequency_select` field.
  enum class CenterFrequencySelect {
    k9600Mhz = 0b00,
    k9000Mhz = 0b01,
    k8400Mhz = 0b11,
  };

  DEF_RSVDZ_FIELD(31, 16);

  // This field has a non-trivial representation and should be accessed via the
  // `q_p1_divider() and `set_q_p1_divider()` helpers.
  DEF_FIELD(15, 8, q_p1_divider_select);

  // This field has a non-trivial representation and should be accessed via the
  // `q_p1_divider() and `set_q_p1_divider()` helpers.
  DEF_BIT(7, q_p1_divider_select_enabled);

  // This field has a non-trivial representation and should be accessed via the
  // `k_p2_divider() and `set_k_p2_divider()` helpers.
  DEF_ENUM_FIELD(KP2DividerSelect, 6, 5, k_p2_divider_select);

  // This field has a non-trivial representation and should be accessed via the
  // `k_p2_divider() and `set_k_p2_divider()` helpers.
  DEF_ENUM_FIELD(PP0DividerSelect, 4, 2, p_p0_divider_select);

  // This field has a non-trivial representation and should be accessed via the
  // `center_frequency_mhz()` and `set_center_frequency_mhz()` helpers.
  DEF_ENUM_FIELD(CenterFrequencySelect, 1, 0, center_frequency_select);

  // The K (P2) divider.
  //
  // The preferred value is 2. If the K divider is not 2, this constrains both
  // the Q (P1) divider and the P (P0) divider.
  uint8_t k_p2_divider() const {
    switch (k_p2_divider_select()) {
      case KP2DividerSelect::k5:
        return 5;
      case KP2DividerSelect::k2:
        return 2;
      case KP2DividerSelect::k3:
        return 3;
      case KP2DividerSelect::k1:
        return 1;
    }
    // This will never happen. `k_p2_divider_select()` is a 2-bit field.
    ZX_DEBUG_ASSERT(false);
    return 0;
  }

  // The value of the Q (P1) divider.
  //
  // This field must not be zero. Any other value (1-255) is acceptable.
  //
  // The Q divider must be 1 (disabled) if the K divider is not 2. This
  // requirement is also stated as ensuring a 50% duty cycle for this divider.
  uint8_t q_p1_divider() const {
    if (!q_p1_divider_select_enabled()) {
      return 1;
    }
    ValueType value = q_p1_divider_select();
    ZX_DEBUG_ASSERT_MSG(value <= std::numeric_limits<uint8_t>::max(), "%u overflows uint8_t",
                        value);
    return static_cast<uint8_t>(value);
  }

  // See `q_p1_divider()` for details.
  DisplayPllDcoDividersKabyLake& set_q_p1_divider(uint8_t q_p1_divider) {
    ZX_ASSERT(q_p1_divider > 0);
    return set_q_p1_divider_select_enabled(q_p1_divider != 1).set_q_p1_divider_select(q_p1_divider);
  }

  // See `k_p2_divider()` for details.
  DisplayPllDcoDividersKabyLake& set_k_p2_divider(uint8_t k_p2_divider) {
    KP2DividerSelect k_p2_divider_select;
    switch (k_p2_divider) {
      case 5:
        k_p2_divider_select = KP2DividerSelect::k5;
        break;
      case 2:
        k_p2_divider_select = KP2DividerSelect::k2;
        break;
      case 3:
        k_p2_divider_select = KP2DividerSelect::k3;
        break;
      case 1:
        k_p2_divider_select = KP2DividerSelect::k1;
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Invalid K (P2) divider: %d", k_p2_divider);
        k_p2_divider_select = KP2DividerSelect::k2;
    };
    return set_k_p2_divider_select(k_p2_divider_select);
  }

  // The P (P0) divider.
  //
  // The P (P0) divider can only be 1 if the Q (P1) divider is also 1.
  //
  // This helper returns 0 if the field is set to an undocumented value.
  uint8_t p_p0_divider() const {
    switch (p_p0_divider_select()) {
      case PP0DividerSelect::k1:
        return 1;
      case PP0DividerSelect::k2:
        return 2;
      case PP0DividerSelect::k3:
        return 3;
      case PP0DividerSelect::k7:
        return 7;
    }
    return 0;  // The field is set to an undocumented value.
  }

  // See `p_p0_divider()` for details.
  DisplayPllDcoDividersKabyLake& set_p_p0_divider(uint8_t p_p0_divider) {
    PP0DividerSelect p_p0_divider_select;
    switch (p_p0_divider) {
      case 1:
        p_p0_divider_select = PP0DividerSelect::k1;
        break;
      case 2:
        p_p0_divider_select = PP0DividerSelect::k2;
        break;
      case 3:
        p_p0_divider_select = PP0DividerSelect::k3;
        break;
      case 7:
        p_p0_divider_select = PP0DividerSelect::k7;
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Invalid P (P0) divider: %d", p_p0_divider);
        p_p0_divider_select = PP0DividerSelect::k2;
    };
    return set_p_p0_divider_select(p_p0_divider_select);
  }

  // The center frquency for the DPLL's DCO, in Mhz.
  //
  // The DCO frequency configured in the DisplayPllDcoFrequencyKabyLake register must be
  // within [-6%, +1%] of the selected center frequency.
  //
  // This helper returns 0 if the field is set to an undocumented value.
  int16_t center_frequency_mhz() const {
    switch (center_frequency_select()) {
      case CenterFrequencySelect::k8400Mhz:
        return 8'400;
      case CenterFrequencySelect::k9000Mhz:
        return 9'000;
      case CenterFrequencySelect::k9600Mhz:
        return 9'600;
    }
    return 0;  // The field is set to an undocumented value.
  }

  // See `center_frequency_mhz()` for details.
  DisplayPllDcoDividersKabyLake& set_center_frequency_mhz(int16_t center_frequency_mhz) {
    CenterFrequencySelect center_frequency_select;
    switch (center_frequency_mhz) {
      case 8'400:
        center_frequency_select = CenterFrequencySelect::k8400Mhz;
        break;
      case 9'000:
        center_frequency_select = CenterFrequencySelect::k9000Mhz;
        break;
      case 9'600:
        center_frequency_select = CenterFrequencySelect::k9600Mhz;
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Invalid DCO center frequency: %d Mhz", center_frequency_mhz);
        center_frequency_select = CenterFrequencySelect::k9000Mhz;
    }
    return set_center_frequency_select(center_frequency_select);
  }

  static auto GetForDpll(i915::PllId pll_id) {
    ZX_ASSERT(pll_id >= i915::PllId::DPLL_1);
    ZX_ASSERT(pll_id <= i915::PllId::DPLL_3);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    return hwreg::RegisterAddr<DisplayPllDcoDividersKabyLake>(0x6c044 + (dpll_index - 1) * 8);
  }
};

// DPLL_CFGCR0 (Display PLL Configuration and Control Register 0?)
//
// This register configures the frequency of the DCO (Digitally-Controlled
// Oscillator) in the DPLL. This influences the frequency that the DPLL outputs
// to connected DDIs.
//
// This register's reserved fields are all MBZ (must be zero). So, this register
// can be safely written without reading it first.
//
// The Kaby Lake and Skylake equivalent of this register is
// `DisplayPllDcoFrequencyKabyLake` (DPLL_CFGCR1).
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 1 page 650 and
//             IHD-OS-TGL-Vol 14-12.21 pages 32 and 62.
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 1 page 614
// Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 1 pages 471-472
class DisplayPllDcoFrequencyTigerLake
    : public hwreg::RegisterBase<DisplayPllDcoFrequencyTigerLake, uint32_t> {
 public:
  // The number of fractional bits in the DCO frequency multiplier.
  //
  // The DCO frequency multiplier is a fixed-point (as opposed to
  // floating-point) number. This constant represents the position of the base-2
  // equivalent of the decimal point.
  static constexpr int kMultiplierPrecisionBits = 15;

  DEF_RSVDZ_FIELD(31, 26);

  // Enables SSC (Spread Spectrum Clocking) on Ice Lake display engines.
  //
  // On Tiger Lake, SSC is configured in the `DisplayPllSpreadSpectrumClocking`
  // (DPLL_SSC) register. The SSC entries in IHD-OS-TGL-Vol 14-12.21 pages 8 and
  // 47 suggest that this change landed late / unintentionally.
  DEF_BIT(25, spread_spectrum_clocking_enabled_ice_lake);

  // These fields have a non-trivial representation. They should be used via the
  // `dco_frequency_multiplier()` and `set_dco_frequency_multiplier()`
  // helpers.
  DEF_FIELD(24, 10, dco_frequency_multiplier_fraction);
  DEF_FIELD(9, 0, dco_frequency_multiplier_integer);

  // The frequency multiplier for the DCO (Digitally Controlled Oscillator).
  //
  // The return value has `kMultiplierPrecisionBits` fractional bits.
  //
  // `tiger_lake_38mhz_workaround` must be true iff targeting a Tiger Lake
  // display engine with a 38.4 MHz reference. clock.
  //
  // The multiplier is relative to the display engine reference frequency. On
  // Tiger Lake, there are multiple possible values for this reference
  // frequency.
  int32_t dco_frequency_multiplier(bool tiger_lake_38mhz_workaround) const {
    const int32_t raw_integer_multiplier = static_cast<int32_t>(dco_frequency_multiplier_integer());
    const int32_t raw_fractional_multiplier =
        static_cast<int32_t>(dco_frequency_multiplier_fraction());
    const int32_t adjusted_fractional_multiplier = raw_fractional_multiplier
                                                   << (tiger_lake_38mhz_workaround ? 1 : 0);

    // `integer_multiplier` and `raw_fractional_multiplier` do not have any
    // overlapping bits. However, `adjusted_fractional_multiplier` may overlap
    // by 1 bit, in case of incorrect configuration.
    return (raw_integer_multiplier << kMultiplierPrecisionBits) + adjusted_fractional_multiplier;
  }

  // See `dco_frequency_multiplier()` for details.
  DisplayPllDcoFrequencyTigerLake& set_dco_frequency_multiplier(int32_t multiplier,
                                                                bool tiger_lake_38mhz_workaround) {
    ZX_ASSERT(multiplier > 0);
    ZX_ASSERT(multiplier < (1 << 25));

    const int32_t raw_integer_multiplier = multiplier >> kMultiplierPrecisionBits;
    const int32_t raw_fractional_multiplier = multiplier & ((1 << kMultiplierPrecisionBits) - 1);
    const int32_t adjusted_fractional_multiplier =
        raw_fractional_multiplier >> (tiger_lake_38mhz_workaround ? 1 : 0);
    return set_dco_frequency_multiplier_fraction(adjusted_fractional_multiplier)
        .set_dco_frequency_multiplier_integer(raw_integer_multiplier);
  }

  // The currently configured DCO (Digitally Controlled Oscillator) frequency.
  //
  // `reference_frequency_khz` is the frequency of the display engine's
  // reference clock, which can be read from the `DisplayStraps` (DSSM)
  // register.
  //
  // This is a convenience method on top of the `dco_frequency_multiplier`
  // fields.
  int32_t dco_frequency_khz(int32_t reference_frequency_khz) const {
    const bool tiger_lake_38mhz_workaround = reference_frequency_khz == 38'400;
    const int32_t pll_reference_khz = PllReferenceFrequencyKhz(reference_frequency_khz);

    // The formulas in the PRM use truncating division when converting from a
    // frequency to a DCO multiplier. Rounding up below aims to re-constitue an
    // original frequency that is round-tripped through the conversion.
    return static_cast<int32_t>(
        ((int64_t{dco_frequency_multiplier(tiger_lake_38mhz_workaround)} * pll_reference_khz) +
         (1 << kMultiplierPrecisionBits) - 1) >>
        kMultiplierPrecisionBits);
  }

  // The currently configured DCO (Digitally Controlled Oscillator) frequency.
  //
  // `reference_frequency_khz` is the frequency of the display engine's
  // reference clock, which can be read from the `DisplayStraps` (DSSM)
  // register.
  //
  // This is a convenience method on top of the `dco_frequency_multiplier`
  // fields.
  DisplayPllDcoFrequencyTigerLake& set_dco_frequency_khz(int32_t frequency_khz,
                                                         int32_t reference_frequency_khz) {
    const bool tiger_lake_38mhz_workaround = reference_frequency_khz == 38'400;
    const int32_t pll_reference_khz = PllReferenceFrequencyKhz(reference_frequency_khz);

    // The formulas in the PRM use truncating division.
    const int32_t frequency_multiplier = static_cast<int32_t>(
        (int64_t{frequency_khz} << kMultiplierPrecisionBits) / pll_reference_khz);
    return set_dco_frequency_multiplier(frequency_multiplier, tiger_lake_38mhz_workaround);
  }

  static auto GetForDpll(i915::PllId pll_id) {
    ZX_ASSERT_MSG(pll_id >= i915::PllId::DPLL_0, "Unsupported DPLL %d", pll_id);

    // TODO(https://fxbug.dev/42061706): Allow DPLL 4, once we support it.
    ZX_ASSERT_MSG(pll_id <= i915::PllId::DPLL_2, "Unsupported DPLL %d", pll_id);

    // The MMIO addresses vary across Tiger Lake, DG1, and Ice Lake.
    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    static constexpr uint32_t kMmioAddresses[] = {0x164284, 0x16428c, 0x16429c, 0, 0x164294};
    return hwreg::RegisterAddr<DisplayPllDcoFrequencyTigerLake>(kMmioAddresses[dpll_index]);
  }

 private:
  // Computes the PLL reference frequency from the display reference frequency.
  static int32_t PllReferenceFrequencyKhz(int32_t reference_frequency_khz) {
    ZX_ASSERT(reference_frequency_khz > 0);
    if (reference_frequency_khz == 38'400) {
      // The DPLL uses a 19.2Mhz reference frequency if the display reference is
      // 38.4 MHz. This is documented in IHD-OS-TGL-Vol 12-1.22-Rev2.0 section
      // "Formula for HDMI Mode DPLL Programming", page 180.
      return 19'200;
    }
    return reference_frequency_khz;
  }
};

// DPLL_CFGCR1 (Display PLL Configuration and Control Register 1?)
//
// This register configures the frequency dividers between the DCO
// (Digitally-Controlled Oscillator) in the DPLL and the DPLL's AFE (Analog
// Front-End) clock output, which goes to connected DDIs. The frequency output
// by the DPLL to DDIs, also called AFE clock frequency, is the DCO frequency
// configured in DPLL_CFGCR1 divided by the product of all the dividers (P * Q *
// K, also documented as P0 * P1 * P2) in this register.
//
// Unfortunately, Intel's documentation refers to the DCO frequency dividers
// both as (P0, P1, P2) and as (P, Q, K). Fortunately, both variations use short
// names, so we can use both variations in our names below. This facilitates
// checking our code against documents that use either naming variation.
//
// This register's reserved fields are all MBZ (must be zero). So, this register
// can be safely written without reading it first.
//
// The Kaby Lake and Skylake equivalent of this register is
// `DisplayPllDcoDividersTigerLake` (DPLL_CFGCR2).
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 1 pages 651-652
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 1 pages 615-616
// Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 1 pages 473-474
class DisplayPllDcoDividersTigerLake
    : public hwreg::RegisterBase<DisplayPllDcoDividersTigerLake, uint32_t> {
 public:
  DEF_RSVDZ_FIELD(31, 18);

  // This field has a non-trivial representation and should be accessed via the
  // `q_p1_divider() and `set_q_p1_divider()` helpers.
  DEF_FIELD(17, 10, q_p1_divider_select);

  // This field has a non-trivial representation and should be accessed via the
  // `q_p1_divider() and `set_q_p1_divider()` helpers.
  DEF_BIT(9, q_p1_divider_select_enabled);

  // The value of the Q (P1) divider.
  //
  // This field must not be zero. Any other value (1-255) is acceptable.
  //
  // The Q divider must be 1 (disabled) if the K divider is not 2. This
  // requirement is also stated as ensuring a 50% duty cycle for this divider.
  uint8_t q_p1_divider() const {
    if (!q_p1_divider_select_enabled()) {
      return 1;
    }
    ValueType value = q_p1_divider_select();
    ZX_DEBUG_ASSERT_MSG(value <= std::numeric_limits<uint8_t>::max(), "%u overflows uint8_t",
                        value);
    return static_cast<uint8_t>(value);
  }

  // See `q_p1_divider()` for details.
  DisplayPllDcoDividersTigerLake& set_q_p1_divider(uint8_t q_p1_divider) {
    ZX_ASSERT(q_p1_divider > 0);
    return set_q_p1_divider_select_enabled(q_p1_divider != 1).set_q_p1_divider_select(q_p1_divider);
  }

  // Possible values for the `k_p2_divider_select` field.
  enum class KP2DividerSelect {
    k1 = 0b001,
    k2 = 0b010,
    k3 = 0b100,
  };

  // This field has a non-trivial representation and should be accessed via the
  // `k_p2_divider() and `set_k_p2_divider()` helpers.
  DEF_ENUM_FIELD(KP2DividerSelect, 8, 6, k_p2_divider_select);

  // The K (P2) divider.
  //
  // The preferred value is 2. If the K divider is not 2, this constrains both
  // the Q (P1) divider and the P (P0) divider.
  //
  // This helper returns 0 if the field is set to an undocumented value.
  uint8_t k_p2_divider() const {
    switch (k_p2_divider_select()) {
      case KP2DividerSelect::k1:
        return 1;
      case KP2DividerSelect::k2:
        return 2;
      case KP2DividerSelect::k3:
        return 3;
    }
    return 0;  // The field is set to an undocumented value.
  }

  // See `k_p2_divider()` for details.
  DisplayPllDcoDividersTigerLake& set_k_p2_divider(uint8_t k_p2_divider) {
    KP2DividerSelect k_p2_divider_select;
    switch (k_p2_divider) {
      case 1:
        k_p2_divider_select = KP2DividerSelect::k1;
        break;
      case 2:
        k_p2_divider_select = KP2DividerSelect::k2;
        break;
      case 3:
        k_p2_divider_select = KP2DividerSelect::k3;
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Invalid K (P2) divider: %d", k_p2_divider);
        k_p2_divider_select = KP2DividerSelect::k2;
    };
    return set_k_p2_divider_select(k_p2_divider_select);
  }

  // Documented values for the `p_p0_divider_select` field.
  enum class PP0DividerSelect {
    k2 = 0b0001,
    k3 = 0b0010,
    k5 = 0b0100,
    k7 = 0b1000,
  };

  // This field has a non-trivial representation and should be accessed via the
  // `k_p2_divider() and `set_k_p2_divider()` helpers.
  DEF_ENUM_FIELD(PP0DividerSelect, 5, 2, p_p0_divider_select);

  // The P (P0) divider.
  //
  // The P (P0) divider can only be 1 if the Q (P1) divider is also 1.
  //
  // This helper returns 0 if the field is set to an undocumented value.
  uint8_t p_p0_divider() const {
    switch (p_p0_divider_select()) {
      case PP0DividerSelect::k2:
        return 2;
      case PP0DividerSelect::k3:
        return 3;
      case PP0DividerSelect::k5:
        return 5;
      case PP0DividerSelect::k7:
        return 7;
    }
    return 0;  // The field is set to an undocumented value.
  }

  // See `p_p0_divider()` for details.
  DisplayPllDcoDividersTigerLake& set_p_p0_divider(uint8_t p_p0_divider) {
    PP0DividerSelect p_p0_divider_select;
    switch (p_p0_divider) {
      case 2:
        p_p0_divider_select = PP0DividerSelect::k2;
        break;
      case 3:
        p_p0_divider_select = PP0DividerSelect::k3;
        break;
      case 5:
        p_p0_divider_select = PP0DividerSelect::k5;
        break;
      case 7:
        p_p0_divider_select = PP0DividerSelect::k7;
        break;
      default:
        ZX_DEBUG_ASSERT_MSG(false, "Invalid P (P0) divider: %d", p_p0_divider);
        p_p0_divider_select = PP0DividerSelect::k2;
    };
    return set_p_p0_divider_select(p_p0_divider_select);
  }

  // Possible values for the `reference_clock_select` field.
  enum class ReferenceClockSelect {
    kDisplayReference = 0b00,
    kUnfilteredGenlock = 0b01,
    kInvalid = 0b10,
    kFilteredGenlock = 0b11,
  };

  // The reference clock source for the DCO.
  //
  // In most cases, this should be set to `kDisplayReference`, the XTAL (crystal
  // oscillator) that serves as the display engine reference frequency. The
  // display controller sets this for genlocked transcoders.
  DEF_ENUM_FIELD(ReferenceClockSelect, 1, 0, reference_clock_select);

  static auto GetForDpll(i915::PllId pll_id) {
    ZX_ASSERT_MSG(pll_id >= i915::PllId::DPLL_0, "Unsupported DPLL %d", pll_id);

    // TODO(https://fxbug.dev/42061706): Allow DPLL 4, once we support it.
    ZX_ASSERT_MSG(pll_id <= i915::PllId::DPLL_2, "Unsupported DPLL %d", pll_id);

    // The MMIO addresses vary across Tiger Lake, DG1, and Ice Lake.
    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    static constexpr uint32_t kMmioAddresses[] = {0x164288, 0x164290, 0x1642a0, 0, 0x164298};
    return hwreg::RegisterAddr<DisplayPllDcoDividersTigerLake>(kMmioAddresses[dpll_index]);
  }
};

// DPLL_DIV0 (Display PLL frequency Divider?)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 1 pages 653-654
class DisplayPllDivider : public hwreg::RegisterBase<DisplayPllDivider, uint32_t> {
 public:
  DEF_FIELD(31, 30, true_lock_criteria_select);
  DEF_FIELD(29, 28, early_lock_criteria_select);
  DEF_FIELD(27, 25, automatic_frequency_calibration_start_point_select);

  DEF_BIT(24, feedback_clock_retiming_enabled);

  // Both loop filter coefficients are shifted right by this value.
  DEF_FIELD(23, 21, loop_filter_gain_control);

  // The loop filter's integral coefficient = 2 ^ (-field value).
  //
  // The maximum allowed value is 11.
  DEF_FIELD(20, 16, loop_filter_integral_coefficient_exponent);

  // The loop filter's proportional coefficient = 2 ^ (1 - value).
  DEF_FIELD(15, 12, loop_filter_proportional_coefficient_exponent);

  // The pre-division feedback loop divider. Only 2 and 4 are valid dividers.
  DEF_FIELD(11, 8, feedback_pre_divider);

  // The post-division feedback loop divider. Also known as the M2 coefficient.
  DEF_FIELD(7, 0, feedback_post_divider);

  // Number of consecutive cycles of low phase error for early -> true lock.
  //
  // If the phase error is below the threshold for this many cycles after the
  // early lock indicator, the PLL asserts the (external) PLL locked signal.
  int8_t true_lock_criteria_cycles() const {
    // The cast is lossless because the underlying field is 2-bits.
    return static_cast<int8_t>((true_lock_criteria_select() + 1) * 16);
  }

  // See `true_lock_criteria_cycles()` for details.
  DisplayPllDivider& set_true_lock_criteria_cycles(int8_t cycles) {
    ZX_DEBUG_ASSERT(cycles >= 16);
    ZX_DEBUG_ASSERT(cycles <= 64);
    ZX_DEBUG_ASSERT(cycles % 16 == 0);
    // The cast is lossless because the underlying field is 2-bits.
    return set_true_lock_criteria_select(cycles / 16 - 1);
  }

  // Number of consecutive cycles of low phase error for early lock.
  //
  // Once the phase error is below the threshold for this many cycles, the PLL
  // asserts the early lock indicator.
  int8_t early_lock_criteria_cycles() const {
    // The cast is lossless because the underlying field is 2-bits.
    return static_cast<int8_t>((early_lock_criteria_select() + 1) * 16);
  }

  // See `early_lock_criteria_cycles()` for details.
  DisplayPllDivider& set_early_lock_criteria_cycles(int8_t cycles) {
    ZX_DEBUG_ASSERT(cycles >= 16);
    ZX_DEBUG_ASSERT(cycles <= 64);
    ZX_DEBUG_ASSERT(cycles % 16 == 0);
    // The cast is lossless because the underlying field is 2-bits.
    return set_early_lock_criteria_select(cycles / 16 - 1);
  }

  // The AFC (Automatic Frequency Calibration) start point.
  int16_t automatic_frequency_calibration_start_point() const {
    // `raw_point` will be a signed 8-bit integer with the 3 most significant
    // bits set to the raw field bits.
    int8_t raw_start_point =
        static_cast<int8_t>(automatic_frequency_calibration_start_point_select() << 5);

    // We use a multiplication instead of shifting left here because the left
    // shift gets flagged by UBSan. Shifting left a negative signed integer is
    // UB until C++20. Fortunately, good compilers optimize the multiplication
    // to a shift.
    return static_cast<int16_t>(511 + int16_t{raw_start_point} * 4);
  }

  // See `automatic_frequency_calibration_start_point()` for details.
  DisplayPllDivider& set_automatic_frequency_calibration_start_point(int16_t start_point) {
    ZX_DEBUG_ASSERT(start_point >= 127);
    ZX_DEBUG_ASSERT(start_point <= 895);
    ZX_DEBUG_ASSERT((start_point - 511) % 128 == 0);

    uint8_t point_select = static_cast<uint8_t>(((start_point - 511) >> 7) & 7);
    return set_automatic_frequency_calibration_start_point_select(point_select);
  }

  static auto GetForDpll(i915::PllId pll_id) {
    ZX_ASSERT_MSG(pll_id >= i915::PllId::DPLL_0, "Unsupported DPLL %d", pll_id);

    // TODO(https://fxbug.dev/42061706): Allow DPLL 4, once we support it.
    ZX_ASSERT_MSG(pll_id <= i915::PllId::DPLL_1, "Unsupported DPLL %d", pll_id);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    static constexpr uint32_t kMmioAddresses[] = {0x164b00, 0x164c00, 0, 0, 0x16e00};
    return hwreg::RegisterAddr<DisplayPllDivider>(kMmioAddresses[dpll_index]);
  }
};

// DPLL_SSC (Display PLL Spread Spectrum Clocking?)
//
// This register does not have any reserved fields. However, the documentation
// for most fields is not sufficient for us to configure them. So, we can only
// safely update this register via read-modify-write operations.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 1 pages 658-659
class DisplayPllSpreadSpectrumClocking
    : public hwreg::RegisterBase<DisplayPllSpreadSpectrumClocking, uint32_t> {
 public:
  DEF_FIELD(31, 29, reference_clock_divider);
  DEF_FIELD(28, 26, step_number_offset);

  // If true, Adaptive Gain Change is enabled for SSC injection.
  DEF_BIT(25, injection_adaptive_gain_enabled);

  // If true, SSC injection is enabled.
  DEF_BIT(24, injection_enabled);

  // SSC step size, measured in reference clock cycles.
  DEF_FIELD(23, 16, step_size_reference_clock_cycles);

  // Selects the frequency update rate for the FLL (Frequency Locked Loop).
  DEF_FIELD(15, 14, fll_frequency_update_rate);

  // SSC step number.
  DEF_FIELD(13, 11, step_number);

  // If true, SSC open loop is enabled.
  DEF_BIT(10, open_loop_enabled);

  // If true, SSC is enabled.
  DEF_BIT(9, enabled);

  // If true, FLL (Frequency Locked Loop) frequency adjustment is enabled .
  DEF_BIT(8, fll_frequency_programming_enabled);

  // Selects the guard band after bias calibration.
  DEF_FIELD(7, 6, bias_calibration_guard_band);

  // Initial DCO (Digitally-Controlled Oscillator) amplification value.
  DEF_FIELD(5, 0, dco_amplification_initial_value);

  static auto GetForDpll(i915::PllId pll_id) {
    ZX_ASSERT_MSG(pll_id >= i915::PllId::DPLL_0, "Unsupported DPLL %d", pll_id);

    // TODO(https://fxbug.dev/42061706): Allow DPLL 4, once we support it.
    ZX_ASSERT_MSG(pll_id <= i915::PllId::DPLL_1, "Unsupported DPLL %d", pll_id);

    // The MMIO addresses vary across Tiger Lake and DG1.
    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    static constexpr uint32_t kMmioAddresses[] = {0x164b10, 0x164c10, 0, 0, 0x16e10};
    return hwreg::RegisterAddr<DisplayPllSpreadSpectrumClocking>(kMmioAddresses[dpll_index]);
  }
};

// DPLL_ENABLE (DPLL Enable), LCPLL_CTL / WRPLL_CTL (LCPLL/WRPLL Control).
//
// This class describes all the PLL enablement registers, as they have similar
// layouts.
//
// On Tiger Lake, this covers all the DPLL_ENABLE (* PLL Enable) registers.
// * DPLL0_ENABLE, DPLL1_ENABLE, DPLL4_ENABLE - for DPLL0/1/4
// * TBTPLL_ENABLE - for DPLL2
// * MGPLL1_ENABLE ... MGPLL6_ENABLE - for MG and Dekel PLLs 1-6
//
// On Kaby Lake and Skylake, this covers the following registers:
// * LCPLL1_CTL / LCPLL2_CTL - LCPLL1/2 Control - for DPLL0/1
// * WRPLL1_CTL / WRPLL2_CTL - WRPLL1/2 Control - for DPLL2/3
//
// PLL enablement registers must not be changed while their corresponding PLLs
// are in use.
//
// On Kaby Lake and Skylake, all DPLLs can be used to drive DDIs. DPLL0 also
// drives the core display clocks (CDCLK, CD2XCLK). LCPLL (DPLL0, DPLL1)
// probably stands for "LC-tank PLL" and WRPLL (DPLL2, DPLL3) probably means
// "Wide-Range PLL". The distinction is historical, alluding to the LCPLLs and
// WRPLLs on Broadwell (IHD-OS-BDW-Vol 11-11.15 page 110) and Haswell
// (intel-gfx-prm-osrc-hsw-display Vol 11a dated 12/18/2013 page 191),
// which support different ranges of output frequencies.
//
// On Tiger Lake, TC (USB Type-C connector) DDI has its own PLL, called an MG
// PLL. DPLLs (Display PLLs) 0, 1, and 4 can be connected to all DDIs. DPLL2 is
// dedicated to generating the frequencies needed for TBT (Thunderbolt)
// operation, and is shared by all DDIs that operate in Thunderbolt mode.
//
// DPLL_ENABLE documentation:
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev 2.0 Part 1 pages 656-657
//
// LCPLL1_CTL and LCPLL2_CTL documentation:
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 1121, 1122
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 1110, 1111
//
// WRPLL1_CTL and WRPLL2_CTL documentation:
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 pages 1349-1350
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 pages 1321-1322
class PllEnable : public hwreg::RegisterBase<PllEnable, uint32_t> {
 public:
  // If true, the PLL will be enabled. If false, the PLL will be disabled.
  //
  // The PLL's frequency must be set before it is enabled.
  DEF_BIT(31, pll_enabled);

  // If true, the PLL is locked. If false, the PLL is not locked.
  //
  // On Tiger Lake, this field is supported on all PLL enablement registers.
  //
  // On Kaby Lake and Skylake, this field is only supported on LCPLL1, which
  // drives DPLL0. The underlying bit is reserved on all other registers. On
  // LCPLL1, this field seems redundant with the DPLL0 locked field in the
  // DPLL_STATUS register. However, PRM explicitly asks us to check this field,
  // in "Sequences to Initialize Display" sub-sections "Initialize Sequence" and
  // "Un-initialize Sequence".
  // Kaby Lake: IHD-OS-KBL-Vol 12-1.17 pages 112-113
  // Skylake: IHD-OS-SKL-Vol 12-05.16 pages 110-111
  DEF_BIT(30, pll_locked_tiger_lake_and_lcpll1);

  // If true, the PLL will eventually be powered on.
  //
  // This field is only documented for Tiger Lake.
  //
  // On Kaby Lake and Skylake, the underlying bit is reserved, and PLLs can be
  // assumed to be powered on at all times.
  DEF_BIT(27, power_on_request_tiger_lake);

  // If true, the PLL is currently powered on.
  //
  // A PLL must be powered on before it is enabled.
  //
  // This field is only documented for Tiger Lake. The underlying bit is
  // reserved on Kaby Lake and Skylake.
  DEF_BIT(26, powered_on_tiger_lake);

  static auto GetForSkylakeDpll(i915::PllId pll_id) {
    ZX_ASSERT_MSG(pll_id >= i915::PllId::DPLL_0, "Unsupported DPLL %d", pll_id);
    ZX_ASSERT_MSG(pll_id <= i915::PllId::DPLL_3, "Unsupported DPLL %d", pll_id);
    const int dpll_index = pll_id - i915::PllId::DPLL_0;

    static constexpr uint32_t kAddresses[] = {0x46010, 0x46014, 0x46040, 0x46060};
    return hwreg::RegisterAddr<PllEnable>(kAddresses[dpll_index]);
  }

  // Tiger Lake: On IHD-OS-TGL-Vol 2c-1.22-Rev 2.0, Page 656, it mentions
  // that the MG register instances are used for Type-C in general, so they
  // can control Dekel PLLs as well (for example, MGPLL1_ENABLE controls
  // Dekel PLL Type-C Port 1).
  static auto GetForTigerLakeDpll(i915::PllId pll_id) {
    if (pll_id >= i915::PllId::DPLL_TC_1 && pll_id <= i915::PllId::DPLL_TC_6) {
      // MGPLL1_ENABLE - MGPLL6_ENABLE
      const int mgpll_index = pll_id - i915::PllId::DPLL_TC_1;
      return hwreg::RegisterAddr<PllEnable>(0x46030 + 4 * mgpll_index);
    }

    ZX_ASSERT_MSG(pll_id >= i915::PllId::DPLL_0, "Unsupported DPLL %d", pll_id);

    // TODO(https://fxbug.dev/42061706): Allow DPLL 4, once we support it.
    ZX_ASSERT_MSG(pll_id <= i915::PllId::DPLL_2, "Unsupported DPLL %d", pll_id);

    const int dpll_index = pll_id - i915::PllId::DPLL_0;
    static constexpr uint32_t kPllEnableAddresses[] = {0x46010, 0x46014, 0x46020, 0, 0x46018};
    return hwreg::RegisterAddr<PllEnable>(kPllEnableAddresses[dpll_index]);
  }
};

// DPLL_STATUS
//
// This register is not documented on Tiger Lake or DG1. On those display
// engines, the DPLL_ENABLE register for each DPLL has a status field.
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 1 pages 535-537
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 1 pages 533-535
class DisplayPllStatus : public hwreg::RegisterBase<DisplayPllStatus, uint32_t> {
 public:
  DEF_BIT(28, pll3_sem_done);
  DEF_BIT(24, pll3_locked);
  DEF_BIT(20, pll2_sem_done);
  DEF_BIT(16, pll2_locked);
  DEF_BIT(12, pll1_sem_done);
  DEF_BIT(8, pll1_locked);
  DEF_BIT(4, pll0_sem_done);
  DEF_BIT(0, pll0_locked);

  // The meaning of "SEM Done" is not documented.
  //
  // Including access to these fields for logging purposes.
  bool pll_sem_done(i915::PllId display_pll) const {
    ZX_ASSERT_MSG(display_pll >= i915::PllId::DPLL_0, "Unsupported Display PLL %d", display_pll);
    ZX_ASSERT_MSG(display_pll <= i915::PllId::DPLL_3, "Unsupported Display PLL %d", display_pll);

    const int display_pll_index = display_pll - i915::PllId::DPLL_0;
    const int locked_bit_index = display_pll_index * 8 + 4;

    // The cast is lossless because the BitfieldRef references a 1-bit field.
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), locked_bit_index, locked_bit_index)
            .get());
  }

  // True if the DPLL (Display PLL) is locked onto its target frequency.
  //
  // Soon after a PLL is enabled, it will lock onto its target frequency. Soon
  // after a PLL is disabled, it will no longer be locked -- the frequency lock
  // will be lost.
  bool pll_locked(i915::PllId display_pll) const {
    ZX_ASSERT_MSG(display_pll >= i915::PllId::DPLL_0, "Unsupported Display PLL %d", display_pll);
    ZX_ASSERT_MSG(display_pll <= i915::PllId::DPLL_3, "Unsupported Display PLL %d", display_pll);

    const int display_pll_index = display_pll - i915::PllId::DPLL_0;
    const int locked_bit_index = display_pll_index * 8;

    // The cast is lossless because the BitfieldRef references a 1-bit field.
    return static_cast<bool>(
        hwreg::BitfieldRef<const uint32_t>(reg_value_ptr(), locked_bit_index, locked_bit_index)
            .get());
  }

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

}  // namespace registers

#endif  // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_DPLL_H_
