blob: eec2c3260a17ffe504c909a68d13f00147feef2f [file] [log] [blame]
// Copyright 2019 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_CAMERA_DRIVERS_ISP_MODULES_DMA_MGR_H_
#define SRC_CAMERA_DRIVERS_ISP_MODULES_DMA_MGR_H_
#include <fuchsia/camera/common/c/fidl.h>
#include <fuchsia/sysmem/c/fidl.h>
#include <lib/fit/function.h>
#include <lib/fzl/vmo-pool.h>
#include <deque>
#include "../mali-009/pingpong_regs.h"
#include "dma-format.h"
namespace camera {
class DmaManager {
public:
enum class Stream : bool { FullResolution = false, Downscaled };
DmaManager(Stream stream_type, ddk::MmioView isp_mmio_local)
: isp_mmio_local_(isp_mmio_local), stream_type_(stream_type) {}
// Initialize the format and buffers of the DMA Writer. Calling this
// function enables the DMA's streaming functions.
// |buffer_collection| contains the vmos that the DMA will write to, and
// the image format that dictates the DMA's configuration.
// |frame_available_callback| will be called when the DMA is done writing
// to a buffer.
// A note on making multiple Start() calls:
// The way to transition the DMA manager to another format is to call Start()
// with a different buffer collection. However, doing so will remove all
// knowledge of the locked status of frames of the previous BufferCollection.
// This has the following effects:
// - Frames that are currently being written will be dropped. Calls to
// On*FrameWritten()
// will only relate to frames written in the new BufferCollection.
// TODO(CAM-54): Provide a way to dump the previous set of write locked
// buffers.
// - ReleaseFrame calls with currently used indices (relating to the old
// BufferCollection)
// will return errors.
zx_status_t Start(
fuchsia_sysmem_BufferCollectionInfo buffer_collection,
fit::function<void(fuchsia_camera_common_FrameAvailableEvent)>
frame_available_callback);
static zx_status_t Create(const zx::bti& bti, ddk::MmioView isp_mmio_local,
Stream stream_type,
std::unique_ptr<DmaManager>* out);
// Updates the dma writer with the address of a free buffer from the pool.
void OnNewFrame();
// This should be called when the appropriate "y-DMA write done" interrupt
// is triggered.
void OnPrimaryFrameWritten();
// This should be called when the appropriate "uv-DMA write done" interrupt
// is triggered (if a secondary channel is used).
void OnSecondaryFrameWritten();
// Signal that all consumers are done with this frame.
zx_status_t ReleaseFrame(uint32_t buffer_index);
private:
bool enabled_ = false;
ddk::MmioView isp_mmio_local_;
fzl::VmoPool buffers_;
std::deque<fzl::VmoPool::Buffer> write_locked_buffers_;
std::optional<DmaFormat> current_format_;
Stream stream_type_;
fit::function<void(fuchsia_camera_common_FrameAvailableEvent)>
frame_available_callback_;
zx::bti bti_;
bool primary_frame_written_ = false, secondary_frame_written_ = false;
// Get the Registers used by the DMA Writer.
auto GetPrimaryMisc();
auto GetUvMisc();
auto GetPrimaryBank0();
auto GetUvBank0();
auto GetPrimaryActiveDim();
auto GetUvActiveDim();
auto GetPrimaryLineOffset();
auto GetUvLineOffset();
// Writes the dma format to the registers
void WriteFormat();
// Releases the write lock on the frame and calls the
// frame_available_callback.
void OnFrameWritten();
};
} // namespace camera
#endif // SRC_CAMERA_DRIVERS_ISP_MODULES_DMA_MGR_H_