blob: 10d3b589f2fa4aaf59efb201a1a53dca3dcc9d04 [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_GTT_H_
#define SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_GTT_H_
#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <lib/device-protocol/pci.h>
#include <lib/mmio/mmio.h>
#include <lib/zx/bti.h>
#include <lib/zx/vmo.h>
#include <memory>
#include <fbl/vector.h>
#include <hwreg/mmio.h>
#include <region-alloc/region-alloc.h>
namespace i915 {
// The offset into the MMIO space (at BAR 0) where the GTT is stored.
constexpr uint32_t GTT_BASE_OFFSET = 0x800000;
class Gtt;
class GttRegion {
public:
virtual ~GttRegion() = default;
GttRegion(const GttRegion&) = delete;
GttRegion& operator=(const GttRegion&) = delete;
// This is the same as stride in units of bytes.
virtual uint64_t bytes_per_row() const = 0;
virtual uint64_t base() const = 0;
protected:
GttRegion() = default;
};
class GttRegionImpl : public GttRegion {
public:
GttRegionImpl(Gtt* gtt, RegionAllocator::Region::UPtr region);
~GttRegionImpl() override;
void SetRotation(uint32_t rotation, const image_metadata_t& image_metadata);
zx_status_t PopulateRegion(zx_handle_t vmo, uint64_t page_offset, uint64_t length,
bool writable = false);
void ClearRegion();
uint64_t base() const override { return region_->base; }
uint64_t size() const { return region_->size; }
uint64_t bytes_per_row() const override { return bytes_per_row_; }
void set_bytes_per_row(uint64_t bytes_per_row) { bytes_per_row_ = bytes_per_row; }
private:
RegionAllocator::Region::UPtr region_;
Gtt* gtt_;
fbl::Vector<zx::pmt> pmts_;
uint32_t mapped_end_ = 0;
// The region's current vmo. The region does not own the vmo handle; it
// is up to the owner of the region to determine when the vmo should be
// closed.
zx_handle_t vmo_ = ZX_HANDLE_INVALID;
bool is_rotated_ = false;
// Populated immediately after construction. Only valid for images (not arbitrary GTT regions).
size_t bytes_per_row_ = 0;
};
class Gtt {
public:
Gtt();
~Gtt();
// Copying and moving are not allowed.
Gtt(const Gtt&) = delete;
Gtt& operator=(const Gtt&) = delete;
Gtt(Gtt&&) = delete;
Gtt& operator=(Gtt&&) = delete;
// Initialize the GTT using the given parameters.
//
// |pci|: The PCI protocol implementation
// |buffer|: The MMIO region that stores the GTT. The contents of the GTT must start at offset 0.
// |fb_offset|: The offset to the end of the bootloader framebuffer in GTT-mapped memory.
zx_status_t Init(const ddk::Pci& pci, fdf::MmioBuffer buffer, uint32_t fb_offset);
zx_status_t AllocRegion(uint32_t length, uint32_t align_pow2,
std::unique_ptr<GttRegionImpl>* region_out);
void SetupForMexec(uintptr_t stolen_fb, uint32_t length);
uint64_t size() const { return gfx_mem_size_; }
private:
friend class GttRegionImpl;
std::optional<fdf::MmioBuffer> buffer_;
uint64_t gfx_mem_size_;
RegionAllocator region_allocator_;
zx::vmo scratch_buffer_;
zx::bti bti_;
zx::pmt scratch_buffer_pmt_;
zx_paddr_t scratch_buffer_paddr_ = 0;
uint64_t min_contiguity_;
};
} // namespace i915
#endif // SRC_GRAPHICS_DISPLAY_DRIVERS_INTEL_I915_GTT_H_