blob: c1070b519c61812579d4b0da5336045b1ec3594b [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_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_