blob: d0248c9102e1fd6497d259f75c352261980f81b7 [file] [log] [blame]
// 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_PCH_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_PCH_H_
// The registers in this file should only be accessed from the PchEngine class.
#include <cstdint>
#include <hwreg/bitfields.h>
namespace registers {
// NDE_RSTWRN_OPT (North Display Reset Warn Options)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 134
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 141
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 440
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 436
//
// This register has at least 1 bit that is reserved but not MBZ. The only safe
// way to modify it is via quick read-modify-write operations.
class DisplayResetOptions : public hwreg::RegisterBase<DisplayResetOptions, uint32_t> {
public:
// If true, the North Display Engine will notify PCH display engine when it is
// reset, and will wait for the PCH display engine to acknowledge the reset.
//
// The display engine initialization sequence involves setting this to true.
DEF_BIT(4, pch_reset_handshake);
static auto Get() { return hwreg::RegisterAddr<DisplayResetOptions>(0x46408); }
};
// SBLC_PWM_CTL1 (South / PCH Backlight Control 1)
//
// Not directly documented for DG1, but mentioned in IHD-OS-DG1-Vol 12-2.21
// "Backlight Enabling Sequence" page 349.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 1154
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 787
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 772
class PchBacklightControl : public hwreg::RegisterBase<PchBacklightControl, uint32_t> {
public:
// Enables the PWM counter logic. When disabled, the PWM is always inactive.
DEF_BIT(31, pwm_counter_enabled);
DEF_RSVDZ_BIT(30);
// Inverts whether the backlight PWM active duty drives the PWM pin high/low.
//
// When 0 (default), the backlight PWM pin is driven high when the PWM is in
// active duty, and the pin is driven low when the PWM is inactive.
//
// When 1 (inverted), the backlight PWM pin is driven low when the PWM is in
// active duty, and the pin is driven high when the PWM is inactive.
DEF_BIT(29, pwm_polarity_inverted);
DEF_RSVDZ_FIELD(28, 0);
static auto Get() { return hwreg::RegisterAddr<PchBacklightControl>(0xc8250); }
// Tiger Lake has another instance for a 2nd backlight at 0xc8350.
};
// SBLC_PWM_CTL2 (South / PCH Backlight Control 2)
//
// Does not exist on DG1 or Tiger Lake. The MMIO address is recycled for the new
// SLBC_PWM_FREQ register. The PWM frequency and duty cycle are specified in the
// SLBC_PWM_FREQ and SLBC_PWM_DUTY registers.
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 788
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 773
class PchBacklightFreqDuty : public hwreg::RegisterBase<PchBacklightFreqDuty, uint32_t> {
public:
// Based on the frequency of the clock and desired PWM frequency.
//
// PWM frequency = RAWCLK_FREQ / (freq_divider * backlight_pwm_multiplier)
// backlight_pwm_multiplier is 16 or 128, based on SCHICKEN_1.
DEF_FIELD(31, 16, freq_divider);
// Must be <= `freq_divider`.
// 0 = 0% PWM duty cycle. `freq_divider` = 100% PWM duty cycle.
DEF_FIELD(15, 0, duty_cycle);
static auto Get() { return hwreg::RegisterAddr<PchBacklightFreqDuty>(0xc8254); }
};
// SLBC_PWM_FREQ (South / PCH Backlight PWM Frequency)
//
// Does not exist on Kaby Lake and Skylake. PWM frequency and duty cycle are
// specified in the SBLC_PWM_CTL2 register.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 1156
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 1205
class PchBacklightFreq : public hwreg::RegisterBase<PchBacklightFreq, uint32_t> {
public:
// (Reference clock frequency from RAWCLK_FREQ) / (Desired PWM frequency).
DEF_FIELD(31, 0, divider);
static auto Get() { return hwreg::RegisterAddr<PchBacklightFreq>(0xc8254); }
// Tiger Lake has another instance for a 2nd backlight at 0xc8354.
};
// SBLC_PWM_DUTY (South / PCH Backlight PWM Duty Cycle)
//
// Does not exist on Kaby Lake and Skylake. PWM frequency and duty cycle are
// specified in the SBLC_PWM_CTL2 register.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 1155
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 1205
class PchBacklightDuty : public hwreg::RegisterBase<PchBacklightDuty, uint32_t> {
public:
// Specified a scale from 0 (0%) to SBLC_PWM_FREQ (100%).
// Must not exceed SBLC_PWM_FREQ.
DEF_FIELD(31, 0, value);
static auto Get() { return hwreg::RegisterAddr<PchBacklightDuty>(0xc8258); }
// Tiger Lake has another instance for a 2nd backlight at 0xc8358.
};
// SCHICKEN_1 (South / PCH Display Engine Chicken 1)
//
// This register is not explicitly documented, but the Kaby Lake PRMs have clues
// that reveal its name and address.
// * IHD-OS-KBL-Vol 2c-1.17 Part 2 page 788 mentions the SCHICKEN_1 name, and
// that bit 0 selects between a multiplier of 16 and 128 for SBLC_PWM_CTL2
// backlight modulation and duty cycle.
// * IHD-OS-KBL-Vol 12-1.17 "Backlight Enabling Sequence" page 197 states that
// a granularity of 16 or 128 is set in bit 0 of the 0xC2000 register.
//
// The name is a reference to "chicken bits", which are configuration bits that
// create the option to reverse (chicken out of) risky design changes (fixes or
// new features). The risk can be due to the complexity of the feature, or due
// to having to make changes late in the design cycle. More details in
// "Formal Verification - An Essential Toolkit for Modern VLSI Design".
class PchChicken1 : public hwreg::RegisterBase<PchChicken1, uint32_t> {
public:
// All bits must be set to 1 on DG1.
//
// Setting the bits to 1 compensates for the fact that DG1's HPD signals are
// inverted (0 = connected, 1 = disconnected). This issue is not mentioned in
// other PRMs.
//
// DG1: IHD-OS-DG1-Vol 12-2.21 "Hotplug Board Inversion" page 352 and
// IHD-OS-DG1-Vol 2c-2.21 Part 2 page 1259
DEF_FIELD(18, 15, hpd_invert_bits);
// Set on S0ix entry and cleared on S0ix exit.
//
// This bit works around an issue bug where the PCH display engine's clock
// is not stopped when entering the S0ix state. This issue is mentioned in the
// PRMs listed below.
//
// Lakefield: IHD-OS-LKF-Vol 14-4.21 page 15
// Tiger Lake: IHD-OS-TGL-Vol 14-12.21 page 18 and page 50
// Ice Lake: IHD-OS-ICLLP-Vol 14-1.20 page 33
// Not mentioned in DG1, Kaby Lake, or Skylake.
DEF_BIT(7, pch_display_clock_disable);
// Toggles shared IO pins between multi-chip genlock and backlight 2.
//
// Lake Field: IHD-OS-LKF-Vol 12-4.21 page 50
// DG1: IHD-OS-DG1-Vol 12-2.21 page 349
// Kaby Lake and Skylake don't support multi-chip genlock.
DEF_BIT(2, genlock_instead_of_backlight);
// Multiplier for the backlight PWM frequency and duty cycle.
//
// This multiplier applies to SBLC_PWM_CTL1 and SBLC_PWM_CTL2. It is not
// present on DG1, where the PWM frequency and duty cycle are specified as
// 32-bit values in the SBLC_PWM_FREQ and SBLC_PWM_DUTY registers.
//
// The multiplier can be 16 (0) or 128 (1).
//
// Kaby Lake: IHD-OS-KBL-Vol 12-1.17 "Backlight Enabling Sequence" page 197
// Skylake: IHD-OS-SKL-Vol 12-05.16 "Backlight Enabling Sequence" page 189
// Does not exist on DG1.
DEF_BIT(0, backlight_pwm_multiplier);
static auto Get() { return hwreg::RegisterAddr<PchChicken1>(0xc2000); }
};
// RAWCLK_FREQ (Rawclk frequency)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 1083-1084
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 1131-1132
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 712
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 705
class PchRawClock : public hwreg::RegisterBase<PchRawClock, uint32_t> {
public:
// The raw clock frequency in MHz. Complex representation used by DG1.
//
// Raw clock frequency = integral frequency + fractional frequency
// Integral frequency = `integer` + 1
// Fractional frequency = `fraction_numerator` / (`fraction_denominator` + 1)
//
// `fraction_denominator` must be zero if `fraction_numerator` is zero.
// Only `fraction_numerator` values 0-2 are documented as supported.
//
// All these fields must be zero on Kaby Lake and Skylake.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 1083-1084
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 1131-1132
DEF_FIELD(29, 26, fraction_denominator);
DEF_FIELD(25, 16, integer);
DEF_FIELD(13, 11, fraction_numerator);
// The raw clock frequency in MHz.
//
// This must be set to 24MHz on Kaby Lake and Skylake. Must be zero on Tiger
// Lake and DG1.
//
// Kaby Lake: IHD-OS-KBL-Vol 12-1.17 page 195
// Skylake: IHD-OS-SKL-Vol 12-05.16 page 188
DEF_FIELD(9, 0, mhz);
static auto Get() { return hwreg::RegisterAddr<PchRawClock>(0xc6204); }
};
// PP_CONTROL (Panel Power Control)
//
// The Tiger Lake PRMS do not include a description for this register. However,
// IHD-OS-TGL-Vol 14-12.21 pages 29 and 56 mention the register name and
// address. Experiments on Tiger Lake (device ID 0x9a49) suggest that this
// register has the same semantics as in DG1.
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 961-962
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 pages 986-987
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 pages 626-627
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 pages 620-621
class PchPanelPowerControl : public hwreg::RegisterBase<PchPanelPowerControl, uint32_t> {
public:
// eDP T12 - Required delay from panel power disable to power enable.
//
// Value = (desired_delay / 100ms) + 1.
// Zero means no delay, and also stops a current delay.
//
// Must be zero on Kaby Lake and Skylake.
DEF_FIELD(8, 4, power_cycle_delay);
// If true, the eDP port's VDD is on even if the panel power sequence hasn't
// been completed. Intended for panels that need VDD for DP AUX transactions.
//
// This setting overrides all power sequencing logic. So, we (the display
// driver) must enforce the eDP T12 power delay. In other words, we must make
// sure that that the delay between setting `force` to false and setting it
// back to true is at least T12. Additional documentation sources:
// * Kaby Lake - IHD-OS-KBL-Vol 16-1.17 page 20
// * Skyake - IHD-OS-SKL-Vol 16-05.16 page 9
//
// The Intel documentation references the T4 delay from the SPWG Notebook
// Panel Specification 3.8, Section 5.9 "Panel Power Sequence", page 26. The
// T4 delay there is equivalent to the T12 delay in the eDP Standard version
// 1.4b (revised on December 31, 2020), Section 11 "Power Sequencing", pages
// 249 and 251.
DEF_BIT(3, vdd_always_on);
// If true, the backlight is on when the panel is in the powered on state.
DEF_BIT(2, backlight_enabled);
// If true, panel runs power down sequence when reset is detected.
//
// Recommended for preserving the panel's lifetime.
DEF_BIT(1, power_down_on_reset);
// If true, the panel will eventually be powered on. This may initiate a panel
// power on sequence, which would require waiting for an ongoing power off
// sequence to complete, and then honoring the T12 delay.
//
// If false, the panel will eventually be powered off. This may initiate a
// power off sequence, which would require waiting for an ongoing power on
// sequence to complete, and then honoring the TXX delay.
//
// The panel power on sequence must not be initiated until all panel delays
// are set correctly.
DEF_BIT(0, power_state_target);
static auto Get() { return hwreg::RegisterAddr<PchPanelPowerControl>(0xc7204); }
// Tiger Lake has another instance for a 2nd panel at 0xc7304.
};
// PP_DIVISOR (Panel Power Cycle Delay and Reference Divisor)
//
// On Tiger Lake and DG1, the T12 value is stored in PP_CONTROL, and there is no
// documented register for setting the panel clock divisor.
//
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 629
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 623
class PchPanelPowerClockDelay : public hwreg::RegisterBase<PchPanelPowerClockDelay, uint32_t> {
public:
// Divider that generates the panel power clock from the PCH raw clock.
//
// Value = divider / 2 - 1. 0 is not a valid value.
//
// Intel's PRMs state that the panel clock must always be 10 kHz. This results
// in a 100us period, which is assumed to be the base unit for all panel
// timings.
DEF_FIELD(31, 8, clock_divider);
// eDP T12 - Required delay from panel power disable to power enable.
//
// Value = (desired_delay / 100ms) + 1.
// Zero means no delay, and also stops a current delay.
//
// This field is stored in PP_CONTROL on DG1.
DEF_FIELD(4, 0, power_cycle_delay);
static auto Get() { return hwreg::RegisterAddr<PchPanelPowerClockDelay>(0xc7210); }
};
// PP_OFF_DELAYS (Panel Power Off Sequencing Delays)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 963
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 988
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 629
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 623
class PchPanelPowerOffDelays : public hwreg::RegisterBase<PchPanelPowerOffDelays, uint32_t> {
public:
DEF_RSVDZ_FIELD(31, 29);
// eDP T10 - Minimum delay from valid video data end to panel power disabled.
// eDP T10 = register value * 100us.
DEF_FIELD(28, 16, video_end_to_power_off_delay);
DEF_RSVDZ_FIELD(15, 13);
// eDP T9 - Minimum delay from backlight disabled to valid video data end.
// eDP T9 = register value * 100us.
DEF_FIELD(12, 0, backlight_off_to_video_end_delay);
static auto Get() { return hwreg::RegisterAddr<PchPanelPowerOffDelays>(0xc720c); }
// Tiger Lake has another instance for a 2nd panel at 0xc730c.
};
// PP_ON_DELAYS (Panel Power On Sequencing Delays)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 page 964
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 989
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 page 630
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 624
class PchPanelPowerOnDelays : public hwreg::RegisterBase<PchPanelPowerOnDelays, uint32_t> {
public:
DEF_RSVDZ_FIELD(31, 29);
// eDP T3 - Expected delay from enabling panel power to HPD and AUX ready.
// eDP T3 = register value * 100us.
DEF_FIELD(28, 16, power_on_to_hpd_aux_ready_delay);
DEF_RSVDZ_FIELD(15, 13);
// Minimum delay from power on until the backlight can be enabled.
// The PCH will not enable the backlight until T3 and this delay have passed.
// Delay = register value * 100us.
//
// This seems to match eDP T2 - the minimum delay from enabling panel
// power to Automatic Black Video Generation, where the panel renders black
// video instead of noise when it gets an invalid video signal.
DEF_FIELD(12, 0, power_on_to_backlight_on_delay);
static auto Get() { return hwreg::RegisterAddr<PchPanelPowerOnDelays>(0xc7208); }
// Tiger Lake has another instance for a 2nd panel at 0xc7308.
};
// PP_STATUS (Panel Power Status)
//
// Tiger Lake: IHD-OS-TGL-Vol 2c-1.22-Rev2.0 Part 2 pages 965-966
// DG1: IHD-OS-DG1-Vol 2c-2.21 Part 2 page 990
// Kaby Lake: IHD-OS-KBL-Vol 2c-1.17 Part 2 pages 631-632
// Skylake: IHD-OS-SKL-Vol 2c-05.16 Part 2 page 625
class PchPanelPowerStatus : public hwreg::RegisterBase<PchPanelPowerStatus, uint32_t> {
public:
enum class Transition : int {
kNone = 0, // Not in a power sequence.
kPoweringUp = 1, // Powering up, or waiting for T12 delay.
kPoweringDown = 2, // Powering down.
kInvalid = 3, // Reserved value.
};
// If true, the panel is powered up. It may be powering down.
// If false, the panel is powered down. A T12 delay may be in effect.
DEF_BIT(31, panel_on);
DEF_RSVDZ_BIT(30);
DEF_FIELD(29, 28, power_transition_bits);
Transition PowerTransition() const { return static_cast<Transition>(power_transition_bits()); }
// If true, a T12 delay (power down to power up) is in effect.
DEF_BIT(27, power_cycle_delay_active);
DEF_RSVDZ_FIELD(26, 4);
static auto Get() { return hwreg::RegisterAddr<PchPanelPowerStatus>(0xc7200); }
// Tiger Lake has another instance for a 2nd panel at 0xc7300.
};
} // namespace registers
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_REGISTERS_PCH_H_