1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <lib/zx/bti.h> 8 #include <zircon/compiler.h> 9 #include <ddk/protocol/platform/device.h> 10 #include <ddk/protocol/platform-device-lib.h> 11 #include <zircon/assert.h> 12 #include <ddktl/device.h> 13 #include <ddktl/mmio.h> 14 #include <fbl/unique_ptr.h> 15 #include <optional> 16 #include "common.h" 17 #include "registers-ovl.h" 18 19 namespace mt8167s_display { 20 21 // [Ovl] --> [Clr] --> [Clr Correction] --> [AAL] --> [Gamma] --> [Dither] --> [RDMA] --> [DSI] 22 23 // 24 // Overlay class is the first element in the display subsystem. It is responsible 25 // for fetching pixels from memory, perform blending (up to 4 layers), support RGB and UYVY 26 // swapping, fixed color conversion coefficient (T601, T709, JPEG), alpha blending and flipping 27 // (veritical, horizontal, 180-degree flip). The supported memory source formats are as follows: 28 // RGB565, RGB888, ARGB8888, PARGB8888, XRGB, YUV422 29 // Single Ovl object will manage all four layers 30 // 31 32 constexpr uint16_t kMaxWidth = 4095; 33 constexpr uint16_t kMaxHeight = 4095; 34 constexpr uint32_t kMaxLayer = 4; 35 36 class Ovl { 37 public: 38 // Contructor Ovl(uint32_t height,uint32_t width,uint32_t pitch,uint32_t x,uint32_t y)39 Ovl(uint32_t height, uint32_t width, uint32_t pitch, uint32_t x, uint32_t y) 40 : height_(height), width_(width), pitch_(pitch), x_(x), y_(y) { 41 ZX_DEBUG_ASSERT(height_ < kMaxHeight); 42 ZX_DEBUG_ASSERT(width_ < kMaxWidth); 43 } 44 45 // Init 46 zx_status_t Init(zx_device_t* parent); 47 48 // Stops the overlay engine and resets the active layers 49 void Reset(); 50 51 // Configure the corresponding layer. Should only be called after Stop has been called 52 zx_status_t Config(uint8_t layer, OvlConfig &cfg); 53 54 // Start OVL engine. This will enable interrupts (VSync) and the Overalay engine itself 55 void Start(); 56 57 // Stop OVL engine. This will place the Overlay engine in Idle mode and safely stop all 58 // transactions that may be happening. This function should be called before configuring 59 // the Overlay engine with new parameters 60 void Stop(); 61 Restart()62 void Restart() { 63 Stop(); 64 Start(); 65 } 66 67 // Clears all IRQ sources ClearIrq()68 void ClearIrq() { 69 ovl_mmio_->Write32(0x0, OVL_INTSTA); 70 } 71 72 // Returns true if interrupt was not spurious IsValidIrq()73 bool IsValidIrq() { 74 return ovl_mmio_->Read32(OVL_INTSTA) != 0; 75 } 76 77 // Return true if the input layer is active IsLayerActive(uint8_t layer)78 bool IsLayerActive(uint8_t layer) { 79 return ((active_layers_ & (1 << layer)) != 0); 80 } 81 82 // Clears the active layer ClearLayer(uint8_t layer)83 void ClearLayer(uint8_t layer) { 84 active_layers_ &= static_cast<uint8_t>(~(1 << layer)); 85 } 86 87 // Returns the layer handle which is the physical address of the VMO backed image GetLayerHandle(uint8_t layer)88 zx_paddr_t GetLayerHandle(uint8_t layer) { 89 return layer_handle_[layer]; 90 } 91 92 // Prints the relevant status registers in the Overlay Engine PrintStatusRegisters()93 void PrintStatusRegisters() { 94 DISP_INFO("STA = 0x%x, INTSTA = 0x%x, FLOW_CTRL_DBG = 0x%x\n", 95 ovl_mmio_->Read32(OVL_STA), 96 ovl_mmio_->Read32(OVL_INTSTA), 97 ovl_mmio_->Read32(OVL_FLOW_CTRL_DBG)); 98 } 99 100 // Return true is Overlay Engine is Idle IsIdle()101 bool IsIdle() { 102 return (ovl_mmio_->Read32(OVL_FLOW_CTRL_DBG) & (OVL_IDLE)) == (OVL_IDLE); 103 } 104 105 // Dumps all relevant Overlay Registers 106 void Dump(); 107 108 private: 109 110 // Overlay support ARGB, RGB and YUV formats only 111 bool IsSupportedFormat(zx_pixel_format_t format); 112 113 // Return format as expected by OVL register 114 uint32_t GetFormat(zx_pixel_format_t format); 115 116 // BYTE_SWAP: Determines the need for swapping bytes based on format 117 bool ByteSwapNeeded(zx_pixel_format_t format); 118 119 // get Bytes per Pixel. 120 // TODO(payam): ZX_PIXEL_FORMAT_BYTES returns 4 for x888. We need three 121 uint32_t GetBytesPerPixel(zx_pixel_format_t format); 122 123 fbl::unique_ptr<ddk::MmioBuffer> ovl_mmio_; 124 pdev_protocol_t pdev_ = {nullptr, nullptr}; 125 zx::bti bti_; 126 127 const uint32_t height_; // height of buffer 128 const uint32_t width_; // width of buffer 129 const uint32_t pitch_; // i.e. stride 130 const uint32_t x_; // x-offset for the actual start of image in buffer 131 const uint32_t y_; // y-offset for the actual start of image in buffer 132 133 bool initialized_ = false; 134 135 uint8_t active_layers_ = 0; 136 zx_paddr_t layer_handle_[kMaxLayer] = {}; 137 }; 138 139 } // namespace mt8167s_display