| // 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_POWER_H_ |
| #define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_POWER_H_ |
| |
| #include <lib/mmio/mmio.h> |
| |
| #include <unordered_map> |
| |
| #include "src/graphics/display/drivers/intel-i915/registers-ddi.h" |
| #include "src/graphics/display/drivers/intel-i915/registers-pipe.h" |
| |
| namespace i915 { |
| |
| class Power; |
| class PowerTest; |
| class Controller; |
| |
| enum class PowerWellId { |
| PG1 = 0, |
| PG2 = 1, |
| PG3 = 2, |
| PG4 = 3, |
| PG5 = 4, |
| }; |
| |
| struct PowerWellInfo { |
| // Name of power well. For debug purpose only. |
| const char* name = ""; |
| |
| // The power well is always turned on and driver should not modify its power |
| // status. |
| bool always_on = false; |
| |
| // Index of the power well's state bit in the PWR_WELL_CTL register. |
| size_t state_bit_index; |
| // Index of the power well's request bit in the PWR_WELL_CTL register. |
| size_t request_bit_index; |
| // Index of the the status of fuse distribution to this power well in the |
| // FUSE_STATUS register. |
| size_t fuse_dist_bit_index; |
| |
| // The parent power well this power well depends on. If the power well doesn't |
| // depend on any other power well, the value of |parent| will be the power |
| // well itself. |
| PowerWellId parent; |
| }; |
| using PowerWellInfoMap = std::unordered_map<PowerWellId, PowerWellInfo>; |
| |
| class PowerWellRef { |
| public: |
| PowerWellRef(); |
| ~PowerWellRef(); |
| |
| PowerWellRef(Power* power, PowerWellId power_well); |
| |
| // Copying is not allowed. |
| PowerWellRef(const PowerWellRef&) = delete; |
| PowerWellRef& operator=(const PowerWellRef&) = delete; |
| |
| PowerWellRef(PowerWellRef&& o); |
| PowerWellRef& operator=(PowerWellRef&& o); |
| |
| private: |
| Power* power_ = nullptr; |
| PowerWellId power_well_; |
| }; |
| |
| class Power { |
| public: |
| explicit Power(fdf::MmioBuffer* mmio_space, const PowerWellInfoMap* power_well_info); |
| virtual ~Power() = default; |
| |
| // Copying and moving are not allowed. |
| Power(const Power&) = delete; |
| Power& operator=(const Power&) = delete; |
| Power(Power&&) = delete; |
| Power& operator=(Power&&) = delete; |
| |
| static std::unique_ptr<Power> New(fdf::MmioBuffer* mmio_space, uint16_t device_id); |
| |
| virtual PowerWellRef GetCdClockPowerWellRef() = 0; |
| virtual PowerWellRef GetPipePowerWellRef(PipeId pipe_id) = 0; |
| virtual PowerWellRef GetDdiPowerWellRef(DdiId ddi_id) = 0; |
| |
| // TODO(https://fxbug.dev/42182480): Support Thunderbolt. Currently the API assumes all |
| // Type-C DDIs use USB-C IO. |
| virtual bool GetDdiIoPowerState(DdiId ddi_id) = 0; |
| virtual void SetDdiIoPowerState(DdiId ddi_id, bool enable) = 0; |
| |
| // TODO(https://fxbug.dev/42182480): Support Thunderbolt. Currently the API assumes all |
| // Type-C DDIs use USB-C IO. |
| virtual bool GetAuxIoPowerState(DdiId ddi_id) = 0; |
| virtual void SetAuxIoPowerState(DdiId ddi_id, bool enable) = 0; |
| |
| virtual void Resume() = 0; |
| |
| protected: |
| const fdf::MmioBuffer* mmio_space() const { return mmio_space_; } |
| const PowerWellInfoMap* power_well_info_map() const { return power_well_info_map_; } |
| const std::unordered_map<PowerWellId, size_t>& ref_count() const { return ref_count_; } |
| |
| private: |
| void IncRefCount(PowerWellId power_well); |
| void DecRefCount(PowerWellId power_well); |
| |
| virtual void SetPowerWell(PowerWellId power_well, bool enable) = 0; |
| |
| fdf::MmioBuffer* mmio_space_; |
| std::unordered_map<PowerWellId, size_t> ref_count_; |
| const PowerWellInfoMap* power_well_info_map_ = nullptr; |
| |
| friend PowerWellRef; |
| }; |
| |
| } // namespace i915 |
| |
| #endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_POWER_H_ |