// 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_
