blob: 27c137eba48e7fa6d2b82941ea2426e6e3a4c62b [file] [log] [blame]
// Copyright 2018 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.
#pragma once
#include <lib/zx/bti.h>
#include <zircon/compiler.h>
#include <ddk/protocol/platform/device.h>
#include <ddk/protocol/platform-device-lib.h>
#include <zircon/assert.h>
#include <ddktl/device.h>
#include <lib/mmio/mmio.h>
#include <fbl/unique_ptr.h>
#include <optional>
#include "common.h"
#include "registers-ovl.h"
namespace mt8167s_display {
// [Ovl] --> [Clr] --> [Clr Correction] --> [AAL] --> [Gamma] --> [Dither] --> [RDMA] --> [DSI]
//
// Overlay class is the first element in the display subsystem. It is responsible
// for fetching pixels from memory, perform blending (up to 4 layers), support RGB and UYVY
// swapping, fixed color conversion coefficient (T601, T709, JPEG), alpha blending and flipping
// (veritical, horizontal, 180-degree flip). The supported memory source formats are as follows:
// RGB565, RGB888, ARGB8888, PARGB8888, XRGB, YUV422
// Single Ovl object will manage all four layers
//
constexpr uint32_t kMaxLayer = 4;
class Ovl {
public:
// Contructor
Ovl(uint32_t height, uint32_t width)
: height_(height), width_(width) {
ZX_ASSERT(height_ < kMaxHeight);
ZX_ASSERT(width_ < kMaxWidth);
}
// Init
zx_status_t Init(zx_device_t* parent);
// Stops the overlay engine and resets the active layers
void Reset();
// Configure the corresponding layer. Should only be called after Stop has been called
zx_status_t Config(uint8_t layer, OvlConfig &cfg);
// Start OVL engine. This will enable interrupts (VSync) and the Overalay engine itself
void Start();
// Stop OVL engine. This will place the Overlay engine in Idle mode and safely stop all
// transactions that may be happening. This function should be called before configuring
// the Overlay engine with new parameters
void Stop();
void Restart() {
Stop();
Start();
}
// Clears all IRQ sources
void ClearIrq() {
ovl_mmio_->Write32(0x0, OVL_INTSTA);
}
// Returns true if interrupt was not spurious
bool IsValidIrq() {
return ovl_mmio_->Read32(OVL_INTSTA) != 0;
}
// Return true if the input layer is active
bool IsLayerActive(uint8_t layer) {
return ((active_layers_ & (1 << layer)) != 0);
}
// Clears the active layer
void ClearLayer(uint8_t layer) {
active_layers_ &= static_cast<uint8_t>(~(1 << layer));
}
// Returns the layer handle which is the physical address of the VMO backed image
zx_paddr_t GetLayerHandle(uint8_t layer) {
return layer_handle_[layer];
}
// Prints the relevant status registers in the Overlay Engine
void PrintStatusRegisters() {
DISP_INFO("STA = 0x%x, INTSTA = 0x%x, FLOW_CTRL_DBG = 0x%x\n",
ovl_mmio_->Read32(OVL_STA),
ovl_mmio_->Read32(OVL_INTSTA),
ovl_mmio_->Read32(OVL_FLOW_CTRL_DBG));
}
// Return true is Overlay Engine is Idle
bool IsIdle() {
if ((ovl_mmio_->Read32(OVL_FLOW_CTRL_DBG) & (0x3ff)) != (OVL_IDLE) &&
(ovl_mmio_->Read32(OVL_FLOW_CTRL_DBG) & (0x3ff)) != (OVL_IDLE2)) {
return false;
} else {
return true;
}
}
void PrintRegisters();
private:
// Overlay support ARGB, RGB and YUV formats only
bool IsSupportedFormat(zx_pixel_format_t format);
// Return format as expected by OVL register
uint32_t GetFormat(zx_pixel_format_t format);
// BYTE_SWAP: Determines the need for swapping bytes based on format
bool ByteSwapNeeded(zx_pixel_format_t format);
// get Bytes per Pixel.
// TODO(payam): ZX_PIXEL_FORMAT_BYTES returns 4 for x888. We need three
uint32_t GetBytesPerPixel(zx_pixel_format_t format);
fbl::unique_ptr<ddk::MmioBuffer> ovl_mmio_;
pdev_protocol_t pdev_ = {nullptr, nullptr};
zx::bti bti_;
const uint32_t height_; // Display height
const uint32_t width_; // Display width
uint8_t active_layers_ = 0;
zx_paddr_t layer_handle_[kMaxLayer] = {};
bool initialized_ = false;
};
} // namespace mt8167s_display