| // 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_DISPLAY_DP_DISPLAY_H_ |
| #define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_DISPLAY_DP_DISPLAY_H_ |
| |
| #include <lib/inspect/cpp/inspect.h> |
| #include <lib/zx/result.h> |
| #include <zircon/compiler.h> |
| #include <zircon/types.h> |
| |
| #include <cstdint> |
| #include <optional> |
| |
| #include <fbl/vector.h> |
| |
| #include "src/graphics/display/drivers/intel-display/ddi-physical-layer.h" |
| #include "src/graphics/display/drivers/intel-display/display-device.h" |
| #include "src/graphics/display/drivers/intel-display/dp-aux-channel.h" |
| #include "src/graphics/display/drivers/intel-display/dp-capabilities.h" |
| #include "src/graphics/display/drivers/intel-display/dpcd.h" |
| #include "src/graphics/display/drivers/intel-display/pch-engine.h" |
| #include "src/graphics/display/lib/api-types/cpp/display-id.h" |
| #include "src/graphics/display/lib/api-types/cpp/display-timing.h" |
| #include "src/graphics/display/lib/edid/edid.h" |
| |
| namespace intel_display { |
| |
| class DpDisplay final : public DisplayDevice { |
| public: |
| DpDisplay(Controller* controller, display::DisplayId id, DdiId ddi_id, |
| DpAuxChannel* dp_aux_channel, PchEngine* pch_engine, DdiReference ddi_reference, |
| inspect::Node* parent_node); |
| |
| DpDisplay(const DpDisplay&) = delete; |
| DpDisplay(DpDisplay&&) = delete; |
| DpDisplay& operator=(const DpDisplay&) = delete; |
| DpDisplay& operator=(DpDisplay&&) = delete; |
| |
| ~DpDisplay() override; |
| |
| // Gets the backlight brightness as a coefficient on the maximum brightness, |
| // between the minimum brightness and 1. |
| double GetBacklightBrightness(); |
| |
| // DisplayDevice overrides: |
| bool Query() final; |
| bool InitWithDdiPllConfig(const DdiPllConfig& pll_config) final; |
| |
| AddedDisplayInfo CreateAddedDisplayInfo() override; |
| std::optional<display::DisplayTiming> GetDisplayTiming(display::ModeId mode_id) const override; |
| |
| uint8_t lane_count() const { return dp_lane_count_; } |
| uint32_t link_rate_mhz() const { return dp_link_rate_mhz_; } |
| |
| private: |
| // DisplayDevice overrides: |
| bool InitDdi() final; |
| bool DdiModeset(const display::DisplayTiming& mode) final; |
| bool PipeConfigPreamble(const display::DisplayTiming& mode, PipeId pipe_id, |
| TranscoderId transcoder_id) final; |
| bool PipeConfigEpilogue(const display::DisplayTiming& mode, PipeId pipe_id, |
| TranscoderId transcoder_id) final; |
| DdiPllConfig ComputeDdiPllConfig(int32_t pixel_clock_khz) final; |
| int32_t LoadPixelRateForTranscoderKhz(TranscoderId transcoder_id) final; |
| |
| bool CheckPixelRate(int64_t pixel_rate_hz) final; |
| |
| // Returns true if the eDP panel is powered on. |
| // |
| // This method performs any configuration and power sequencing needed to get |
| // the eDP panel powered on, which may include waiting for a significant |
| // amount of time. |
| // |
| // This method returns fairly quickly if the panel is already configured and |
| // powered on. It is almost idempotent, modulo the panel changing power |
| // states independently. |
| bool EnsureEdpPanelIsPoweredOn(); |
| |
| bool DpcdWrite(uint32_t addr, const uint8_t* buf, size_t size); |
| bool DpcdRead(uint32_t addr, uint8_t* buf, size_t size); |
| bool DpcdRequestLinkTraining(const dpcd::TrainingPatternSet& tp_set, |
| const dpcd::TrainingLaneSet lanes[]); |
| bool DpcdUpdateLinkTraining(const dpcd::TrainingLaneSet lanes[]); |
| template <uint32_t addr, typename T> |
| bool DpcdReadPairedRegs(hwreg::RegisterBase<T, typename T::ValueType>* status); |
| bool DpcdHandleAdjustRequest(dpcd::TrainingLaneSet* training, dpcd::AdjustRequestLane* adjust); |
| |
| bool ProgramDpModeTigerLake(); |
| |
| bool DoLinkTraining(); |
| |
| // TODO(https://fxbug.dev/42065767): Move voltage swing configuration logic to a |
| // DDI-specific class. |
| void ConfigureVoltageSwingKabyLake(size_t phy_config_index); |
| void ConfigureVoltageSwingTigerLake(size_t phy_config_index); |
| void ConfigureVoltageSwingTypeCTigerLake(size_t phy_config_index); |
| void ConfigureVoltageSwingComboTigerLake(size_t phy_config_index); |
| |
| bool LinkTrainingSetupKabyLake(); |
| bool LinkTrainingSetupTigerLake(); |
| |
| // For locking Clock Recovery Circuit of the DisplayPort receiver |
| bool LinkTrainingStage1(dpcd::TrainingPatternSet* tp_set, dpcd::TrainingLaneSet* lanes); |
| // For optimizing equalization, determining symbol boundary, and achieving inter-lane alignment |
| bool LinkTrainingStage2(dpcd::TrainingPatternSet* tp_set, dpcd::TrainingLaneSet* lanes); |
| |
| bool SetBacklightOn(bool on); |
| bool InitBacklightHw() override; |
| |
| bool IsBacklightOn(); |
| // Sets the backlight brightness with |val| as a coefficient on the maximum |
| // brightness. |val| must be in [0, 1]. If the panel has a minimum fractional |
| // brightness, then |val| will be clamped to [min, 1]. |
| bool SetBacklightBrightness(double val); |
| |
| bool HandleHotplug(bool long_pulse) override; |
| bool HasBacklight() override; |
| zx::result<> SetBacklightState(bool power, double brightness) override; |
| zx::result<fuchsia_hardware_backlight::wire::State> GetBacklightState() override; |
| |
| void SetLinkRate(uint32_t value); |
| |
| // The object referenced by this pointer must outlive the DpDisplay. |
| DpAuxChannel* dp_aux_channel_; // weak |
| |
| // Used by eDP displays. |
| PchEngine* pch_engine_; |
| |
| // Contains a value only if successfully initialized via Query(). |
| std::optional<DpCapabilities> capabilities_; |
| |
| // The current lane count and link rate. 0 if invalid/uninitialized. |
| uint8_t dp_lane_count_ = 0; |
| |
| // The current per-lane link rate configuration. Use SetLinkRate to mutate the value which also |
| // updates the related inspect properties. |
| // |
| // These values can be initialized by: |
| // 1. InitWithDdiPllConfig based on an the current DPLL state |
| // 2. Init, which selects the highest supported link rate |
| // |
| // The lane count is always initialized to the maximum value that the device can support in |
| // Query(). |
| uint32_t dp_link_rate_mhz_ = 0; |
| std::optional<uint8_t> dp_link_rate_table_idx_; |
| |
| // The backlight brightness coefficient, in the range [min brightness, 1]. |
| double backlight_brightness_ = 1.0f; |
| |
| // Initialized in `Query()`. |
| std::optional<edid::Edid> edid_; |
| |
| // Initialized in `Query()`. |
| // The timing parameter at index `k` corresponds to ModeId `k+1`. |
| fbl::Vector<display::DisplayTiming> timings_; |
| |
| // Debug |
| inspect::Node inspect_node_; |
| inspect::Node dp_capabilities_node_; |
| inspect::UintProperty dp_lane_count_inspect_; |
| inspect::UintProperty dp_link_rate_mhz_inspect_; |
| }; |
| |
| } // namespace intel_display |
| |
| #endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_DISPLAY_DP_DISPLAY_H_ |