blob: 94690b5e50b9180340f93fb9922a343bac0cfb9c [file] [log] [blame] [edit]
// Copyright 2025 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_CAPABILITIES_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_DISPLAY_DP_CAPABILITIES_H_
#include <lib/fpromise/result.h>
#include <lib/inspect/cpp/inspect.h>
#include <zircon/compiler.h>
#include <zircon/types.h>
#include <array>
#include <cstdint>
#include <optional>
#include <vector>
#include "src/graphics/display/drivers/intel-display/dp-aux-channel.h"
#include "src/graphics/display/drivers/intel-display/dpcd.h"
namespace intel_display {
// DpCapabilities is a utility for reading and storing DisplayPort capabilities
// supported by the display based on a copy of read-only DPCD capability
// registers. Drivers can also use PublishToInspect() to publish the data to
// inspect.
class DpCapabilities final {
public:
// Initializes the DPCD capability array with all zeros and the EDP DPCD capabilities as
// non-present.
DpCapabilities();
// Allow copy.
DpCapabilities(const DpCapabilities&) = default;
DpCapabilities& operator=(const DpCapabilities&) = default;
// Allow move.
DpCapabilities(DpCapabilities&&) = default;
DpCapabilities& operator=(DpCapabilities&&) = default;
// Read and parse DPCD capabilities. Clears any previously initialized content
static fpromise::result<DpCapabilities> Read(DpAuxChannel* dp_aux_channel);
// Publish the capabilities fields to inspect node `caps_node`.
void PublishToInspect(inspect::Node* caps_node) const;
// Get the cached value of a DPCD register using its DPCD address.
uint8_t dpcd_at(dpcd::Register address) const {
ZX_ASSERT(address < dpcd::DPCD_SUPPORTED_LINK_RATE_START);
return dpcd_[address - dpcd::DPCD_CAP_START];
}
// Get the cached value of a EDP DPCD register using its address. Asserts if the eDP capabilities
// are not available.
uint8_t edp_dpcd_at(dpcd::EdpRegister address) const {
ZX_ASSERT(edp_dpcd_.has_value());
ZX_ASSERT(address < dpcd::DPCD_EDP_RESERVED);
ZX_ASSERT(address >= dpcd::DPCD_EDP_CAP_START);
return edp_dpcd_->bytes[address - dpcd::DPCD_EDP_CAP_START];
}
template <typename T, dpcd::Register A>
T dpcd_reg() const {
T reg;
reg.set_reg_value(dpcd_at(A));
return reg;
}
// Asserts if eDP capabilities are not available.
template <typename T, dpcd::EdpRegister A>
T edp_dpcd_reg() const {
T reg;
reg.set_reg_value(edp_dpcd_at(A));
return reg;
}
dpcd::Revision dpcd_revision() const {
return static_cast<dpcd::Revision>(dpcd_[dpcd::DPCD_REV]);
}
std::optional<dpcd::EdpRevision> edp_revision() const {
if (edp_dpcd_) {
return edp_dpcd_->revision;
}
return std::nullopt;
}
// Total number of stream sinks within this Sink device.
size_t sink_count() const { return sink_count_.count(); }
// Maximum number of DisplayPort lanes.
uint8_t max_lane_count() const { return max_lane_count_.lane_count_set(); }
// True for SST mode displays that support the Enhanced Framing symbol sequence (see DP v1.4a
// Section 2.2.1.2).
bool enhanced_frame_capability() const { return max_lane_count_.enhanced_frame_enabled(); }
// True for eDP displays that support the `backlight_enable` bit in the
// dpcd::DPCD_EDP_DISPLAY_CTRL register (see dpcd.h).
bool backlight_aux_power() const { return edp_dpcd_ && edp_dpcd_->backlight_aux_power; }
// True for eDP displays that support backlight adjustment through the
// dpcd::DPCD_EDP_BACKLIGHT_BRIGHTNESS_[MSB|LSB] registers.
bool backlight_aux_brightness() const { return edp_dpcd_ && edp_dpcd_->backlight_aux_brightness; }
// The list of supported link rates in ascending order, measured in units of Mbps/lane.
const std::vector<uint32_t>& supported_link_rates_mbps() const {
return supported_link_rates_mbps_;
}
// True if the contents of vector returned by `supported_link_rates_mbps()` was populated using
// the "Link Rate Table" method. If true, the link rate must be selected by writing the vector
// index to the DPCD LINK_RATE_SET register. Otherwise, the selected link rate must be programmed
// using the DPCD LINK_BW_SET register.
bool use_link_rate_table() const { return use_link_rate_table_; }
private:
// DpCapabilities that are only present in eDP displays.
struct Edp {
Edp();
std::array<uint8_t, dpcd::DPCD_EDP_RESERVED - dpcd::DPCD_EDP_CAP_START> bytes;
dpcd::EdpRevision revision;
bool backlight_aux_power = false;
bool backlight_aux_brightness = false;
};
bool ProcessEdp(DpAuxChannel* dp_aux_channel);
bool ProcessSupportedLinkRates(DpAuxChannel* dp_aux_channel);
std::array<uint8_t, dpcd::DPCD_SUPPORTED_LINK_RATE_START - dpcd::DPCD_CAP_START> dpcd_;
dpcd::SinkCount sink_count_;
dpcd::LaneCount max_lane_count_;
std::vector<uint32_t> supported_link_rates_mbps_;
bool use_link_rate_table_ = false;
std::optional<Edp> edp_dpcd_;
};
} // namespace intel_display
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_DISPLAY_DP_CAPABILITIES_H_