| // 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_DDI_PHY_TIGER_LAKE_H_ |
| #define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_DDI_PHY_TIGER_LAKE_H_ |
| |
| // Most fields in the PHY (Physical Layer) configuration registers are not |
| // sufficiently documented to be configured by driver authors. Plausible |
| // explanations are that the fields are only intended for DMC (display |
| // microcontroller) usage, or that their default values are the only supported |
| // values for correct hardware operation. The register definitions below expand |
| // abbreviations in register and field names when we have guesses that we are |
| // reasonably confident in. |
| // |
| // The "spare" fields are considered reserved, as opposed to free for driver |
| // use. This assumption is supported by the PORT_TX_DW5 descriptions, where the |
| // "Disable 2tap" field (referenced in the initialization sequence) is marked as |
| // "ospare2". |
| // |
| // Some reserved fields are documented as MBZ (must be zero) on Tiger Lake and |
| // DG1, but PBC (preserve bit content) on Ice Lake. These fields are currently |
| // described as MBZ. |
| |
| #include <lib/ddk/debug.h> |
| #include <zircon/assert.h> |
| |
| #include <cstdint> |
| |
| #include <hwreg/bitfields.h> |
| |
| #include "src/graphics/display/drivers/intel-i915/hardware-common.h" |
| |
| namespace registers { |
| |
| // PHY_MISC (Miscellaneous Physical layer settings?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 664 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 663-664 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 page 361 |
| class PhyMisc : public hwreg::RegisterBase<PhyMisc, uint32_t> { |
| public: |
| // Undocumented semantics. |
| // |
| // This is likely a communication channel from the display engine driver to |
| // the PHY logic. |
| DEF_FIELD(31, 28, display_engine_to_io); |
| |
| // Undocumented semantics. |
| // |
| // This is likely a communication channel from the PHY logic to the display |
| // engine driver. |
| DEF_FIELD(27, 24, io_to_display_engine); |
| |
| // If true, the compensation resistors are powered down. |
| // |
| // The display engine driver sets this field, and the PHY logic acts on it. |
| // This must be set to false before the DDI is enabled. |
| DEF_BIT(23, compensation_resistors_powered_down); |
| |
| DEF_RSVDZ_FIELD(19, 0); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A); |
| ZX_ASSERT(ddi_id <= i915::DdiId::DDI_C); |
| |
| const int ddi_index = ddi_id - i915::DdiId::DDI_A; |
| return hwreg::RegisterAddr<PhyMisc>(0x64c00 + 4 * ddi_index); |
| } |
| }; |
| |
| // Undocumented register PORT_CL_DW0 / PHY Common Lane config double-word 0? |
| // |
| // This definition is currently only used as a host for MmioAddressForDdi(). |
| class PortCommonLane0 : public hwreg::RegisterBase<PortCommonLane0, uint32_t> { |
| public: |
| // Returns the base address of the PORT_CL_ configuration registers for a i915::DdiId. |
| static constexpr uint32_t MmioAddressForDdi(i915::DdiId ddi_id) { |
| ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A); |
| ZX_ASSERT(ddi_id <= i915::DdiId::DDI_C); |
| const int ddi_index = ddi_id - i915::DdiId::DDI_A; |
| // `kMmioAddress` can be static in C++20. |
| constexpr uint32_t kMmioAddress[] = {0x162000, 0x6c000, 0x160000}; |
| return kMmioAddress[ddi_index]; |
| } |
| }; |
| |
| // PORT_CL_DW5 (PHY Common Lane config double-word 5?) |
| // |
| // "Common Lane" functionality is centralized across all lanes in a PHY, and |
| // placed in a single power gate. |
| // |
| // All the bits in this register are documented, so it is safe to update this |
| // register without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 885-886 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 897-898 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 553-554 |
| class PortCommonLane5 : public hwreg::RegisterBase<PortCommonLane5, uint32_t> { |
| public: |
| // Undocumented semantics. |
| DEF_FIELD(31, 24, force); |
| |
| DEF_RSVDZ_BIT(23); |
| |
| DEF_BIT(22, fuse_valid_reset); |
| DEF_BIT(21, fuse_valid_override); |
| DEF_BIT(20, fuse_repull); |
| DEF_FIELD(19, 16, common_register_interface_clock_count_max); |
| DEF_RSVDZ_BIT(15); |
| |
| // IOSF PD (Intel On-chip System Fabric Presence Detection) count. |
| DEF_FIELD(14, 13, onchip_system_fabric_presence_detection_count); |
| DEF_RSVDZ_BIT(12); |
| DEF_FIELD(11, 9, onchip_system_fabric_clock_divider_select); |
| |
| // If true, all transmitters are programmed by writes to group addresses. |
| DEF_BIT(8, downlink_broadcast_enable); |
| |
| DEF_RSVDZ_BIT(7); |
| DEF_BIT(6, port_staggering_enabled); |
| DEF_BIT(5, power_gate_staggering_control_disabled); |
| DEF_BIT(4, common_lane_power_down_enabled); |
| DEF_BIT(3, common_register_interface_clock_select); |
| DEF_BIT(2, phy_power_ack_override); |
| DEF_FIELD(1, 0, suspend_clock_config); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCommonLane5>(PortCommonLane0::MmioAddressForDdi(ddi_id) + 5 * 4); |
| } |
| }; |
| |
| // PORT_CL_DW10 (PHY Common Lane config double-word 10?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 887-889 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 899-901 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 555-556 |
| class PortCommonLaneMainLinkPower |
| : public hwreg::RegisterBase<PortCommonLaneMainLinkPower, uint32_t> { |
| public: |
| // Possible values for the `terminating_resistor_override` field. |
| enum class TerminatingResistorOverride { |
| k150Ohms = 0, |
| k100Ohms = 1, |
| }; |
| |
| DEF_RSVDZ_FIELD(31, 27); |
| |
| DEF_FIELD(26, 25, power_gate_sequential_delay_override); |
| |
| // If false, `power_gate_sequential_delay_override` is ignored. |
| DEF_BIT(24, power_gate_sequential_delay_override_valid); |
| |
| // HPVG (High Voltage Power Gate) for the MIPI DSI operating mode. |
| // |
| // On Ice Lake display engines with one common lane for all IOs, this bit |
| // controls the HVPG (High-Voltage Power Gate) for DSI0 (MIPI A). |
| // |
| // On display engines without MIPI DSI support, this bit is ignored. |
| DEF_BIT(23, high_voltage_power_gate_control); |
| |
| // Unused (Common Register Interface spare bit) on most display engines. |
| // |
| // On Ice Lake display engines with one common lane for all IOs, this bit |
| // controls the HVPG (High-Voltage Power Gate) for DSI1 (MIPI C). |
| DEF_BIT(22, high_voltage_power_gate_control_dsi_c); |
| |
| // CRI (Common Register Interface) spare bits. |
| DEF_FIELD(21, 16, common_register_interface_ret); |
| |
| DEF_RSVDZ_FIELD(15, 12); |
| |
| // If true, the DDI's main link lane 3 is powered down. |
| // |
| // Some `power_down_lane*` field combinations are not supported. The |
| // `set_powered_up_lanes()` helper is guaranteed to set valid combinations. |
| DEF_BIT(7, power_down_lane3); |
| |
| // If true, the DDI's main link lane 2 is powered down. |
| // |
| // Some `power_down_lane*` field combinations are not supported. The |
| // `set_powered_up_lanes()` helper is guaranteed to set valid combinations. |
| DEF_BIT(6, power_down_lane2); |
| |
| // If true, the DDI's main link lane 1 is powered down. |
| // |
| // Some `power_down_lane*` field combinations are not supported. The |
| // `set_powered_up_lanes()` helper is guaranteed to set valid combinations. |
| DEF_BIT(5, power_down_lane1); |
| |
| // If true, the DDI's main link lane 0 is powered down. |
| // |
| // Some `power_down_lane*` field combinations are not supported. The |
| // `set_powered_up_lanes()` helper is guaranteed to set valid combinations. |
| DEF_BIT(4, power_down_lane0); |
| |
| // If false, `edp_power_optimized_mode_enabled` is ignored. |
| // |
| // Some `power_down_lane*` field combinations are not supported. The |
| // `set_powered_up_lanes()` helper is guaranteed to set valid combinations. |
| DEF_BIT(3, edp_power_optimized_mode_valid); |
| |
| // If true, enables a eDP (embedded DisplayPort) power-optimized mode. |
| // |
| // This field is ignored if `edp_power_optimized_mode_valid` is false. Setting |
| // this to true must be accompanied by a specific voltage swing configuration. |
| DEF_BIT(2, edp_power_optimized_mode_enabled); |
| |
| // If false, `terminating_resistor_override` is ignored. |
| DEF_BIT(1, terminating_resistor_override_valid); |
| |
| // Overrides the terminating resisor value. |
| DEF_ENUM_FIELD(TerminatingResistorOverride, 0, 0, terminating_resistor_override); |
| |
| // Powers up/down DDI main link lanes. |
| // |
| // `active_lane_count` must be a 1/2/4 for DisplayPort connections, and 4 for |
| // HDMI connections. DSI connections are not currently supported. |
| PortCommonLaneMainLinkPower& set_powered_up_lanes(int active_lane_count) { |
| ZX_ASSERT(active_lane_count >= 1); |
| ZX_ASSERT(active_lane_count <= 4); |
| return set_power_down_lane0(false) |
| .set_power_down_lane1(active_lane_count <= 1) |
| .set_power_down_lane2(active_lane_count <= 2) |
| .set_power_down_lane3(active_lane_count <= 3); |
| } |
| |
| // Powers up/down DDI main link lanes for a reverse connection. |
| // |
| // `active_lane_count` must be a 1/2/4 for DisplayPort connections, and 4 for |
| // HDMI connections. DSI connections are not currently supported. |
| PortCommonLaneMainLinkPower& set_powered_up_lanes_reversed(int active_lane_count) { |
| ZX_ASSERT(active_lane_count >= 1); |
| ZX_ASSERT(active_lane_count <= 4); |
| return set_power_down_lane3(false) |
| .set_power_down_lane2(active_lane_count <= 1) |
| .set_power_down_lane1(active_lane_count <= 2) |
| .set_power_down_lane0(active_lane_count <= 3); |
| } |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCommonLaneMainLinkPower>( |
| PortCommonLane0::MmioAddressForDdi(ddi_id) + 10 * 4); |
| } |
| }; |
| |
| // PORT_CL_DW12 (PHY Common Lane config double-word 12?) |
| // |
| // All the bits in this register are documented, so it is safe to update this |
| // register without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 890-891 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 902-903 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 557-559 |
| class PortCommonLaneMiscPower : public hwreg::RegisterBase<PortCommonLaneMiscPower, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 30); |
| DEF_BIT(29, mipi_lane_enabled); |
| DEF_RSVDZ_BIT(28); |
| |
| // If false, `mipi_mode_override` is ignored. |
| DEF_BIT(27, mipi_mode_override_valid); |
| DEF_BIT(26, mipi_mode_override); |
| DEF_RSVDZ_FIELD(25, 12); |
| |
| // Overrides the power request signal for the AUX channel. |
| // |
| // Ignored if `aux_power_request_override_valid` is false. |
| DEF_BIT(11, aux_power_request_override); |
| |
| // If false, `aux_power_request_override` is ignored. |
| DEF_BIT(10, aux_power_request_override_valid); |
| |
| DEF_RSVDZ_FIELD(9, 7); |
| DEF_BIT(6, aux_phy_status); // Read-only. |
| DEF_RSVDZ_BIT(5); |
| DEF_BIT(4, aux_power_acknowledged); // Read-only. |
| |
| DEF_RSVDZ_FIELD(3, 1); |
| |
| // If true, the AUX lane will eventually be powered up. |
| DEF_BIT(0, aux_lane_enabled); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCommonLaneMiscPower>(PortCommonLane0::MmioAddressForDdi(ddi_id) + |
| 12 * 4); |
| } |
| }; |
| |
| // PORT_CL_DW15 (PHY Common Lane config double-word 15?) |
| // |
| // This register reports the state of powering various domains inside the PHY. |
| // All fields are read-only. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 892-893 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 904-905 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 560-561 |
| class PortCommonLanePowerStatus : public hwreg::RegisterBase<PortCommonLanePowerStatus, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 30); |
| |
| DEF_BIT(29, high_voltage_power_gate_power_acknowledged); |
| DEF_BIT(28, high_voltage_power_gate_enabled); |
| DEF_BIT(27, mipi_power_acknowledged); |
| |
| DEF_RSVDZ_FIELD(26, 22); |
| |
| DEF_BIT(21, aux_power_requested); |
| DEF_RSVDZ_FIELD(20, 18); |
| DEF_BIT(17, aux_power_acknowledged); |
| |
| DEF_RSVDZ_FIELD(16, 0); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCommonLanePowerStatus>( |
| PortCommonLane0::MmioAddressForDdi(ddi_id) + 15 * 4); |
| } |
| }; |
| |
| // PORT_CL_DW16 (PHY Common Lane config double-word 16?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 894-895 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 906-907 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 562-563 |
| class PortCommonLane16 : public hwreg::RegisterBase<PortCommonLane16, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 16); |
| |
| DEF_BIT(15, ddi_b_hd_port_select_override_valid); |
| DEF_BIT(14, ddi_b_hd_port_select_override); |
| DEF_BIT(13, ddi_c_hd_port_select_override_valid); |
| DEF_BIT(12, ddi_c_hd_port_select_override); |
| DEF_BIT(11, ddi_d_hd_port_select_override_valid); |
| DEF_BIT(10, ddi_d_hd_port_select_override); |
| |
| DEF_RSVDZ_FIELD(9, 8); |
| |
| // If true, forces powering down the compensation source in the PHY. |
| DEF_BIT(3, compensators_power_down_override); |
| |
| // If false, `compensators_power_down_override` is ignored. |
| DEF_BIT(2, compensators_power_down_override_valid); |
| |
| // If true, force-wakes the CRI (Common Register Interface) domain. |
| DEF_BIT(1, common_register_interface_wake_override); |
| |
| // If false, `common_register_interface_wake_override` is ignored. |
| DEF_BIT(0, common_register_interface_wake_override_valid); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCommonLane16>(PortCommonLane0::MmioAddressForDdi(ddi_id) + |
| 16 * 4); |
| } |
| }; |
| |
| // PORT_COMP_DW0 (PHY process variation Compensation config double-word 0?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 896 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 908 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 page 564 |
| class PortCompensation0 : public hwreg::RegisterBase<PortCompensation0, uint32_t> { |
| public: |
| // If true, the PHY's compensation resistors are initialized. |
| DEF_BIT(31, initialized); |
| |
| DEF_FIELD(30, 29, transmitter_slew_control); |
| DEF_FIELD(28, 27, transmitter_drive_switch_on); |
| DEF_BIT(26, transmitter_drive_switch_control); |
| |
| DEF_BIT(23, process_monitor_clock_select); |
| |
| DEF_RSVDZ_FIELD(22, 20); |
| |
| // Programmable counter driving the frequency of compensation updates. |
| DEF_FIELD(19, 8, periodic_counter); |
| |
| DEF_RSVDZ_FIELD(7, 0); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCompensation0>(MmioAddressForDdi(ddi_id) + 0 * 4); |
| } |
| |
| // Returns the base address of the PORT_COMP configuration registers. |
| static constexpr uint32_t MmioAddressForDdi(i915::DdiId ddi_id) { |
| ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A); |
| ZX_ASSERT(ddi_id <= i915::DdiId::DDI_C); |
| const int ddi_index = ddi_id - i915::DdiId::DDI_A; |
| // `kMmioAddress` can be static in C++20. |
| constexpr uint32_t kMmioAddress[] = {0x162100, 0x6c100, 0x160100}; |
| return kMmioAddress[ddi_index]; |
| } |
| }; |
| |
| // PORT_COMP_DW1 (PHY process variation Compensation config double-word 1?) |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 897-898 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 909-910 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 565-566 |
| class PortCompensation1 : public hwreg::RegisterBase<PortCompensation1, uint32_t> { |
| public: |
| DEF_BIT(31, low_dropout_regulator_bypass); |
| DEF_BIT(30, frequency_compensation_override_valid); |
| DEF_BIT(29, frequency_compensation_capacity_ratio); |
| DEF_BIT(28, frequency_compensation_bias_select); |
| DEF_FIELD(27, 26, frequency_compensation_input_select_overload); |
| DEF_BIT(25, frequency_compensation_polarity_select); |
| DEF_BIT(24, resistance_compensation_enabled); |
| |
| // TODO(https://fxbug.dev/42065922): Add helpers for reading and writing the fields |
| // below, which are spread across PortCompensation1, |
| // PortCompensationNominalVoltageReferences, and |
| // PortCompensationLowVoltageReferences. |
| DEF_FIELD(23, 22, positive_nominal_voltage_reference_high_value_bits98); |
| DEF_FIELD(21, 20, positive_nominal_voltage_reference_low_value_bits98); |
| DEF_FIELD(19, 18, negative_nominal_voltage_reference_high_value_bits98); |
| DEF_FIELD(17, 16, negative_nominal_voltage_reference_low_value_bits98); |
| |
| DEF_FIELD(15, 14, positive_high_voltage_reference_high_value_bits98); |
| DEF_FIELD(13, 12, positive_high_voltage_reference_low_value_bits98); |
| DEF_FIELD(11, 10, negative_high_voltage_reference_high_value_bits98); |
| DEF_FIELD(9, 8, negative_high_voltage_reference_low_value_bits98); |
| |
| DEF_FIELD(7, 6, positive_low_voltage_reference_high_value_bits98); |
| DEF_FIELD(5, 4, positive_low_voltage_reference_low_value_bits98); |
| DEF_FIELD(3, 2, negative_low_voltage_reference_high_value_bits98); |
| DEF_FIELD(1, 0, negative_low_voltage_reference_low_value_bits98); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCompensation1>(PortCompensation0::MmioAddressForDdi(ddi_id) + |
| 1 * 4); |
| } |
| }; |
| |
| // PORT_COMP_DW3 (PHY process variation Compensation config double-word 3?) |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 899-900 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 909-910 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 567-568 |
| class PortCompensationStatus : public hwreg::RegisterBase<PortCompensationStatus, uint32_t> { |
| public: |
| // Documented values for the `process_select` field. |
| enum class ProcessSelect { |
| kDot0 = 0b000, |
| kDot1 = 0b001, |
| kDot4 = 0b010, |
| }; |
| |
| // Documented values for the `voltage_select` field. |
| enum class VoltageSelect { |
| k850mv = 0b00, |
| k950mv = 0b01, |
| k1050mv = 0b10, |
| }; |
| |
| DEF_RSVDZ_FIELD(31, 29); |
| |
| // Process variation reported by the procmon (process monitor). |
| // |
| // The process monitor is a circuit that detects process skew (effects of |
| // manufacturing variation) for the chip area that hosts the display engine. |
| // The skew is characterized as slow, nominal, or fast. |
| // |
| // Sources: |
| // * "Synergies Between Delay Test and Post-silicon Speed Path Validation: |
| // A Tutorial Introduction," 2021 IEEE European Test Symposium (ETS) |
| // * "Use of Process monitors in Post silicon validation to reduce TTM," |
| // 2017 IEEE 35th VLSI Test Symposium (VTS) |
| DEF_ENUM_FIELD(ProcessSelect, 28, 26, process_select); |
| |
| // The port's operating voltage. |
| DEF_ENUM_FIELD(VoltageSelect, 25, 24, voltage_select); |
| |
| DEF_BIT(23, pll_ddi_power_acknowledged); |
| DEF_BIT(22, first_compensation_done); |
| DEF_BIT(21, process_monitor_done); |
| |
| DEF_BIT(20, current_compensation_code_maxout); |
| DEF_BIT(19, current_compensation_code_minout); |
| DEF_RSVDZ_FIELD(18, 15); |
| DEF_FIELD(14, 8, current_compensation_code); |
| |
| DEF_BIT(7, mipi_low_power_data_negative_code_maxout); |
| DEF_BIT(6, mipi_low_power_data_negative_code_minout); |
| |
| // LPDn (negative Data pin in Low-Power mode) compensation value. |
| DEF_FIELD(5, 0, mipi_low_power_data_negative_code); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCompensationStatus>( |
| PortCompensation0::MmioAddressForDdi(ddi_id) + 3 * 4); |
| } |
| }; |
| |
| // PORT_COMP_DW8 (PHY process variation Compensation config double-word 8?) |
| // |
| // All the bits in this register are documented, so it is safe to update this |
| // register without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 901 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 914 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 569-570 |
| class PortCompensationSource : public hwreg::RegisterBase<PortCompensationSource, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 25); |
| |
| // Must be true for PHYs that serve as compensation sources. |
| DEF_BIT(24, generate_internal_references); |
| |
| DEF_RSVDZ_FIELD(23, 15); |
| |
| // If true, periodic ICOMP (current compensation) value updates are disabled. |
| DEF_BIT(14, periodic_current_compensation_disabled); |
| |
| DEF_RSVDZ_FIELD(13, 0); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCompensationSource>( |
| PortCompensation0::MmioAddressForDdi(ddi_id) + 8 * 4); |
| } |
| }; |
| |
| // PORT_COMP_DW9 (PHY process variation Compensation config double-word 9?) |
| // |
| // This register stores the low bits of {negative, positive} {low, high} |
| // reference values for nominal voltage transistors. The high bits are in |
| // PORT_COMP_DW1. |
| // |
| // All the bits in this register are documented, so it is safe to update this |
| // register without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 902 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 915 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 page 571 |
| class PortCompensationNominalVoltageReferences |
| : public hwreg::RegisterBase<PortCompensationNominalVoltageReferences, uint32_t> { |
| public: |
| // The high bits for all these values are in PORT_COMP_DW1. |
| |
| DEF_FIELD(31, 24, negative_nominal_voltage_reference_low_value_bits70); |
| DEF_FIELD(23, 16, negative_nominal_voltage_reference_high_value_bits70); |
| DEF_FIELD(15, 8, positive_nominal_voltage_reference_low_value_bits70); |
| DEF_FIELD(7, 0, positive_nominal_voltage_reference_high_value_bits70); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCompensationNominalVoltageReferences>( |
| PortCompensation0::MmioAddressForDdi(ddi_id) + 9 * 4); |
| } |
| }; |
| |
| // PORT_COMP_DW10 (PHY process variation Compensation config double-word 10?) |
| // |
| // This register stores the low bits of {negative, positive} {low, high} |
| // reference values for LVT (low voltage transistors). The high bits are in |
| // PORT_COMP_DW1. |
| // |
| // All the bits in this register are documented, so it is safe to update this |
| // register without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 903 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 916 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 page 572 |
| class PortCompensationLowVoltageReferences |
| : public hwreg::RegisterBase<PortCompensationLowVoltageReferences, uint32_t> { |
| public: |
| // The high bits for all these values are in PORT_COMP_DW1. |
| |
| DEF_FIELD(31, 24, negative_low_voltage_reference_low_value_bits70); |
| DEF_FIELD(23, 16, negative_low_voltage_reference_high_value_bits70); |
| DEF_FIELD(15, 8, positive_low_voltage_reference_low_value_bits70); |
| DEF_FIELD(7, 0, positive_low_voltage_reference_high_value_bits70); |
| |
| static auto GetForDdi(i915::DdiId ddi_id) { |
| return hwreg::RegisterAddr<PortCompensationLowVoltageReferences>( |
| PortCompensation0::MmioAddressForDdi(ddi_id) + 10 * 4); |
| } |
| }; |
| |
| // Identifies a pair of pins used in voltage differential transmission. |
| // |
| // The lane usage is documented in the "Mode Set" > "Sequences for MIPI DSI" > |
| // "DSI Transcoder Enable Sequence" section of the display engine PRMs. |
| // Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 page 127 |
| // Ice Lake: IHD-OS-ICLLP-Vol 12-1.22-Rev2.0 page 129 |
| enum class PortLane { |
| kAux = 0x3, // DisplayPort AUX channel. DSI Data lane 0. |
| kAll = 0x6, // Virtual pair that routes writes to all non-AUX lanes. |
| kMainLinkLane0 = 0x8, // 1st DisplayPort main link lane. DSI Data lane 1. |
| kMainLinkLane1 = 0x9, // 2nd DisplayPort main link lane. DSI Data lane 2. |
| kMainLinkLane2 = 0xa, // 3rd DisplayPort main link lane. DSI Clock lane. |
| kMainLinkLane3 = 0xb, // 4th DisplayPort main link lane. DSI Data lane 3. |
| }; |
| |
| // PORT_PCS_DW1 (Physical Coding Sublayer config double-word 1?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 903-907 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 917-921 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 573-575 |
| class PortPhysicalCoding1 : public hwreg::RegisterBase<PortPhysicalCoding1, uint32_t> { |
| public: |
| // Possible values for the `duty_cycle_correction_schedule_select` field. |
| enum class DutyCycleCorrectionScheduleSelect { |
| kOnce = 0b00, |
| kEvery100Microseconds = 0b01, |
| kEvery1000Microseconds = 0b10, |
| kContinuously = 0b11, |
| }; |
| |
| DEF_RSVDZ_FIELD(31, 29); |
| |
| DEF_BIT(28, common_mode_keeper_enabled_while_power_gated); |
| |
| // If true, the pins are power-gated (powered off). |
| DEF_BIT(27, power_gate_powered_down); |
| |
| // Enables the common mode voltage keeper circuit. |
| // |
| // The common keeper preserves the common-mode voltage between the pair of |
| // pins during low power modes. |
| DEF_BIT(26, common_mode_keeper_enabled); |
| DEF_FIELD(25, 24, common_mode_keeper_bias_control); |
| |
| DEF_RSVDZ_FIELD(23, 22); |
| |
| // Selects how often DCC (Duty Cycle Correction) is performed. |
| DEF_ENUM_FIELD(DutyCycleCorrectionScheduleSelect, 21, 20, duty_cycle_correction_schedule_select); |
| |
| // If true, the DCC (Duty Cycle Correction) calibration is bypassed. |
| // |
| // Setting this to true also bypasses DFx (design for debug/test) receiver |
| // calibration. The two bypasses share a signal in the PCS (Physical Coding |
| // Sublayer). |
| DEF_BIT(19, duty_cycle_correction_calibration_bypassed); |
| |
| // If true, DCC calibration will be performed on the next power up. |
| // |
| // Setting this to true forces a DCC (Duty Cycle Correction) calibration the |
| // next time the DL (downlink) is woken up after a power down event. |
| DEF_BIT(18, duty_cycle_correction_calibration_on_wake); |
| |
| // If true, forces a transmitter DCC (Duty Cycle Correction) calibration. |
| // |
| // This field should only be used (set to true) after the boot-time |
| // initialization completes. |
| DEF_BIT(17, force_transmitter_duty_cycle_correction_calibration); |
| |
| DEF_RSVDZ_FIELD(15, 14); |
| |
| DEF_FIELD(13, 12, transmitter_high); |
| |
| DEF_RSVDZ_FIELD(11, 10); |
| |
| DEF_FIELD(9, 8, clock_request); |
| |
| // If true, the lane's symbol clock is the TBC (Transmitter Buffer Clock). |
| DEF_BIT(7, use_transmitter_buffer_clock_as_symbol_clock); |
| |
| // If false, `transmitter_fifo_reset_main_override` is ignored. |
| DEF_BIT(6, transmitter_fifo_reset_main_override_valid); |
| |
| // Reset Main override for the transmitter's FIFO. |
| // |
| // Ignored if `transmitter_fifo_reset_main_override_valid` is false |
| DEF_BIT(5, transmitter_fifo_reset_main_override); |
| |
| DEF_BIT(4, transmitter_deemphasis_value); |
| |
| DEF_FIELD(3, 2, latency_optimization_value); |
| |
| // If true, `soft_lane_reset` is read by the circuitry. |
| DEF_BIT(1, soft_lane_reset_valid); |
| |
| // If false, requests that the lanes controlled by this register are reset. |
| // |
| // This field is only used if `soft_lane_reset_valid` is true. |
| DEF_BIT(0, soft_lane_reset); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortPhysicalCoding1>(MmioAddressForDdiLane(ddi_id, lane) + 1 * 4); |
| } |
| |
| // Returns the base address of lane's PORT_PCS_ configuration registers. |
| static constexpr uint32_t MmioAddressForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A); |
| ZX_ASSERT(ddi_id <= i915::DdiId::DDI_C); |
| const int ddi_index = ddi_id - i915::DdiId::DDI_A; |
| // `kMmioAddress` can be static in C++20. |
| constexpr uint32_t kMmioAddress[] = {0x162000, 0x6c000, 0x160000}; |
| return kMmioAddress[ddi_index] | (static_cast<uint32_t>(lane) << 8); |
| } |
| }; |
| |
| // PORT_PCS_DW9 (Physical Coding Sublayer config double-word 9?) |
| // |
| // All reserved bits in this register are MBZ (must be zero). So, the register |
| // can be safely updated without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 908-910 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 922-925 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 576-579 |
| class PortPhysicalCoding9 : public hwreg::RegisterBase<PortPhysicalCoding9, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 28); |
| |
| DEF_FIELD(27, 16, strong_cm_count_overload); |
| |
| DEF_RSVDZ_FIELD(15, 11); |
| |
| DEF_FIELD(10, 8, stagger_multiplier); |
| |
| DEF_RSVDZ_FIELD(7, 6); |
| |
| DEF_BIT(5, stagger_override_valid); |
| DEF_FIELD(4, 0, stagger_override); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortPhysicalCoding9>( |
| PortPhysicalCoding1::MmioAddressForDdiLane(ddi_id, lane) + 9 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW0 (Transmitter analog front-end config double-word 0?) |
| // |
| // This register controls transmitter equalization in the Combo PHY's AFE |
| // (Analog Front-End). |
| // |
| // All reserved bits in this register are MBZ (must be zero). So, the register |
| // can be safely updated without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 929-931 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 945-948 |
| class PortTransmitterMipiEqualization |
| : public hwreg::RegisterBase<PortTransmitterMipiEqualization, uint32_t> { |
| public: |
| // Selects the equalization level for MIPI DSI transmission. |
| // |
| // This bit is ignored unless `mipi_equalization_override` is true. |
| // |
| // Low level equalization is 3.5 dB. High level equalization is 7 dB. |
| DEF_BIT(31, mipi_equalization_is_high); |
| |
| // If true, lane equalization for MIPI DSI transmission is enabled. |
| // |
| // This bit is ignored unless `mipi_equalization_override` is true. |
| DEF_BIT(30, mipi_equalization_enabled); |
| |
| // Transmitter equalization tap C+1 (post-cursor) coefficient. |
| // |
| // The PRM advises against changing this field. The default value is 0xb. |
| DEF_FIELD(29, 24, post_cursor_coefficient); |
| |
| // If true, the equalization logic is driven by fields in this register. |
| // |
| // If this field is false, the equalization logic is driven by PPI (PHY |
| // Protocol Interface, in the MIPI D-PHY specification) Transmitter |
| // Equalization pins (TxEqActiveHS, TxEqLevelHS). |
| DEF_BIT(23, mipi_equalization_override); |
| |
| DEF_RSVDZ_FIELD(22, 6); |
| |
| // Transmitter equalization tap C (cursor) coefficient. |
| // |
| // The PRM advises against changing this field. The default value is 0x34. |
| DEF_FIELD(5, 0, cursor_coefficient); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterMipiEqualization>( |
| MmioAddressForDdiLane(ddi_id, lane) + 0 * 4); |
| } |
| |
| // Returns the base address of lane's PORT_TX_ configuration registers. |
| static constexpr uint32_t MmioAddressForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| ZX_ASSERT(ddi_id >= i915::DdiId::DDI_A); |
| ZX_ASSERT(ddi_id <= i915::DdiId::DDI_C); |
| const int ddi_index = ddi_id - i915::DdiId::DDI_A; |
| // `kMmioAddress` can be static in C++20. |
| constexpr uint32_t kMmioAddress[] = {0x162080, 0x6c080, 0x160080}; |
| return kMmioAddress[ddi_index] | (static_cast<uint32_t>(lane) << 8); |
| } |
| }; |
| |
| using PortTransmitter0 = PortTransmitterMipiEqualization; |
| |
| // PORT_TX_DW1 (Transmitter analog front-end config double-word 1?) |
| // |
| // All reserved bits in this register are MBZ (must be zero). So, the register |
| // can be safely updated without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 932-934 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 949-952 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 page 614 |
| class PortTransmitter1 : public hwreg::RegisterBase<PortTransmitter1, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 8); |
| |
| // ICOMP (current configuration) reference configuration. |
| // |
| // This configuration bit is routed from the COMP (compensation) registers to |
| // the TX (Transmitter analog front-end) registers. |
| DEF_BIT(7, output_current_compensation_reference_config); |
| |
| // Sets the transmitter's current intensity boost ratio. |
| DEF_FIELD(6, 5, output_current_reference_control); |
| |
| // Configures the MIPI DSI HSTX (high-speed transmission mode) slew. |
| DEF_FIELD(4, 3, mipi_high_speed_transmission_slew_rate_control); |
| |
| // Enables the LDO feedback path for low reference voltage. |
| DEF_BIT(2, low_reference_voltage_low_dropout_regulator_feedback_enabled); |
| |
| // Enables the LDO feedback path for high reference voltage. |
| DEF_BIT(1, high_reference_voltage_low_dropout_regulator_feedback_enabled); |
| |
| // Enables the LDO feedback path for nominal reference voltage. |
| DEF_BIT(0, nominal_reference_voltage_low_dropout_regulator_feedback_enabled); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitter1>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 1 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW2 (Transmitter analog front-end config double-word 2?) |
| // |
| // All reserved bits in this register are MBZ (must be zero). So, the register |
| // can be safely updated without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 935-937 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 953-956 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 615-617 |
| class PortTransmitterVoltageSwing |
| : public hwreg::RegisterBase<PortTransmitterVoltageSwing, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 16); |
| |
| // This field must be combined with `voltage_swing_select_bits20`. The helpers |
| // `voltage_swing_select()` and `set_voltage_swing_select()` handle that. |
| DEF_BIT(15, voltage_swing_select_bit3); |
| |
| DEF_BIT(14, weak_common_mode_select); |
| |
| // This field must be combined with `voltage_swing_select_bits3`. The helpers |
| // `voltage_swing_select()` and `set_voltage_swing_select()` handle that. |
| DEF_FIELD(13, 11, voltage_swing_select_bits20); |
| |
| DEF_FIELD(10, 8, force_latency_optimized_fifo); |
| |
| // Applied to RCOMP (resistance compensation) code. |
| // |
| // This field adjusts the RCOMP code to get the desired output termination |
| // resistance. This field is also named the (voltage) swing scalar. |
| DEF_FIELD(7, 0, resistance_compensation_code_scalar); |
| |
| // Configures the signal's peak-to-peak voltage differences. |
| // |
| // There is an undocumented mapping between (transition and non-transition) |
| // peak-to-peak voltage differences and values in this field. Intel's |
| // documentation has tables mapping voltage swing and pre-emphasis levels to |
| // field values. |
| int8_t voltage_swing_select() const { |
| return static_cast<int8_t>((static_cast<int8_t>(voltage_swing_select_bit3()) << 3) | |
| static_cast<int8_t>(voltage_swing_select_bits20())); |
| } |
| |
| // See `voltage_swing_select()` for details. |
| PortTransmitterVoltageSwing& set_voltage_swing_select(int voltage_swing_select) { |
| ZX_DEBUG_ASSERT(voltage_swing_select >= 0); |
| ZX_DEBUG_ASSERT(voltage_swing_select <= 0b1111); |
| return set_voltage_swing_select_bits20(static_cast<uint32_t>(voltage_swing_select & 7)) |
| .set_voltage_swing_select_bit3(static_cast<uint32_t>((voltage_swing_select >> 3) & 1)); |
| } |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterVoltageSwing>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 2 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW4 (Transmitter analog front-end config double-word 4?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 938-940 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 957-960 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 618-620 |
| class PortTransmitterEqualization |
| : public hwreg::RegisterBase<PortTransmitterEqualization, uint32_t> { |
| public: |
| DEF_BIT(31, load_generation_select); |
| |
| DEF_BIT(23, bs_comp_override); |
| |
| DEF_FIELD(22, 18, termination_resistance_limit); |
| |
| // Equalization tap C+1 (post-cursor) coefficient. |
| DEF_FIELD(17, 12, post_cursor_coefficient1); |
| |
| // Equalization tap C+2 (post-cursor) coefficient. |
| DEF_FIELD(11, 6, post_cursor_coefficient2); |
| |
| // Equalization tap C (cursor) coefficient. |
| DEF_FIELD(5, 0, cursor_coefficient); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterEqualization>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 4 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW5 (Transmitter analog front-end config double-word 5?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 941-944 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 961-964 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 621-624 |
| class PortTransmitterVoltage : public hwreg::RegisterBase<PortTransmitterVoltage, uint32_t> { |
| public: |
| // While true, the lane's voltage parameters cannot be reconfigured. |
| // |
| // This field must be set to false briefly for the parameters in the PORT_TX* |
| // registers to be picked up, then set back to true. |
| DEF_BIT(31, training_enabled); |
| |
| DEF_BIT(30, two_tap_equalization_disabled); |
| DEF_BIT(29, three_tap_equalization_disabled); |
| |
| DEF_BIT(26, cursor_programming_disabled); |
| DEF_BIT(25, coefficient_polarity_disabled); |
| |
| DEF_RSVDZ_FIELD(23, 21); |
| |
| DEF_FIELD(20, 18, scaling_mode_select); |
| DEF_FIELD(17, 16, decode_timer_select); |
| DEF_FIELD(15, 11, cr_scaling_coefficient); |
| |
| DEF_FIELD(5, 3, terminating_resistor_select); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterVoltage>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 5 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW6 (Transmitter analog front-end config double-word 6?) |
| // |
| // All reserved bits in this register are MBZ (must be zero). So, the register |
| // can be safely updated without reading it first. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 945-947 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 965-968 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 page 625 |
| class PortTransmitterLowDropoutRegulator |
| : public hwreg::RegisterBase<PortTransmitterLowDropoutRegulator, uint32_t> { |
| public: |
| DEF_RSVDZ_FIELD(31, 8); |
| |
| DEF_BIT(7, function_override_enabled); |
| |
| // This field should be replicated from CRI (Common Register Interface). |
| DEF_FIELD(6, 1, low_dropout_reference_select); |
| |
| // This field should be replicated from CRI (Common Register Interface). |
| DEF_BIT(0, low_dropout_bypass); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterLowDropoutRegulator>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 6 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW7 (Transmitter analog front-end config double-word 7?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 948-950 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 969-971 |
| // Ice Lake: IHD-OS-ICLLP-Vol 2c-1.22-Rev2.0 Part 2 pages 626-628 |
| class PortTransmitterNScalar : public hwreg::RegisterBase<PortTransmitterNScalar, uint32_t> { |
| public: |
| DEF_FIELD(30, 24, n_scalar); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterNScalar>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 7 * 4); |
| } |
| }; |
| |
| // PORT_TX_DW8 (Transmitter analog front-end config double-word 8?) |
| // |
| // This register has bits that are reserved but not MBZ (must be zero). So, it |
| // can only be safely updated via read-modify-write operations. |
| // |
| // This register is not documented on Kaby Lake or Skylake. |
| // |
| // Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 951-953 |
| // DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 972-975 |
| class PortTransmitterDutyCycleCorrection |
| : public hwreg::RegisterBase<PortTransmitterDutyCycleCorrection, uint32_t> { |
| public: |
| // Possible values for `duty_cycle_correction_clock_divider_select`. |
| enum class ClockDividerSelect { |
| k2 = 0b01, |
| k4 = 0b10, |
| k8 = 0b11, |
| }; |
| |
| DEF_BIT(31, output_duty_cycle_correction_clock_select); |
| DEF_ENUM_FIELD(ClockDividerSelect, 30, 29, output_duty_cycle_correction_clock_divider_select); |
| |
| // Ignored if `output_duty_cycle_correction_code_override_valid` is false. |
| DEF_FIELD(28, 24, output_duty_cycle_correction_code_override); |
| |
| // If false, `output_duty_cycle_correction_code_override` is ignored. |
| DEF_BIT(23, output_duty_cycle_correction_code_override_valid); |
| |
| DEF_BIT(22, output_duty_cycle_correction_fuse_enabled); |
| DEF_FIELD(20, 16, output_duty_cycle_correction_lower_limit); |
| |
| DEF_FIELD(14, 13, input_duty_cycle_correction_thermal_bits43); |
| DEF_FIELD(12, 8, input_duty_cycle_correction_code); |
| DEF_FIELD(7, 5, input_duty_cycle_correction_thermal_bits20); |
| |
| DEF_FIELD(4, 0, output_duty_cycle_correction_upper_limit); |
| |
| static auto GetForDdiLane(i915::DdiId ddi_id, PortLane lane) { |
| return hwreg::RegisterAddr<PortTransmitterDutyCycleCorrection>( |
| PortTransmitter0::MmioAddressForDdiLane(ddi_id, lane) + 8 * 4); |
| } |
| }; |
| |
| } // namespace registers |
| |
| #endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_DDI_PHY_TIGER_LAKE_H_ |