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 <zircon/compiler.h> 8 #include <ddk/protocol/platform/device.h> 9 #include <ddk/protocol/platform-device-lib.h> 10 #include <ddktl/mmio.h> 11 #include <lib/zx/interrupt.h> 12 #include <lib/zx/bti.h> 13 #include <threads.h> 14 #include "common.h" 15 #include <optional> 16 17 namespace astro_display { 18 19 struct RdmaTable { 20 uint32_t reg; 21 uint32_t val; 22 }; 23 24 enum { 25 IDX_CFG_W0, 26 IDX_CTRL_STAT, 27 IDX_MAX, 28 }; 29 30 struct RdmaChannelContainer { 31 zx_paddr_t phys_offset; // offset into physical address 32 uint8_t* virt_offset; // offset into virtual address (vmar buf) 33 bool active; // indicated whether channel is being used or not 34 }; 35 36 constexpr uint32_t kRdmaTableMaxSize = IDX_MAX; 37 38 // RDMA Channels used by OSD. Three channels should be more than enough 39 constexpr uint8_t kMaxRdmaChannels = 3; 40 constexpr uint8_t kMaxRetries = 100; 41 // spread channels 512B apart (make sure it's greater than a cache line size) 42 constexpr size_t kChannelBaseOffset = 512; 43 44 class Osd { 45 public: Osd(uint32_t fb_width,uint32_t fb_height,uint32_t display_width,uint32_t display_height)46 Osd(uint32_t fb_width, uint32_t fb_height, uint32_t display_width, uint32_t display_height) 47 : fb_width_(fb_width), fb_height_(fb_height), 48 display_width_(display_width), display_height_(display_height) {} 49 50 zx_status_t Init(zx_device_t* parent); 51 void HwInit(); 52 zx_status_t Configure(); 53 void Disable(); 54 // This function will apply configuration when VSYNC interrupt occurs using RDMA 55 void FlipOnVsync(uint8_t idx); 56 void Dump(); 57 void Release(); 58 59 private: 60 void DefaultSetup(); 61 // this function sets up scaling based on framebuffer and actual display 62 // dimensions. The scaling IP and registers and undocumented. 63 void EnableScaling(bool enable); 64 void Enable(); 65 zx_status_t SetupRdma(); 66 void ResetRdmaTable(); 67 void SetRdmaTableValue(uint32_t channel, uint32_t idx, uint32_t val); 68 void FlushRdmaTable(uint32_t channel); 69 int GetNextAvailableRdmaChannel(); 70 int RdmaThread(); 71 72 std::optional<ddk::MmioBuffer> vpu_mmio_; 73 pdev_protocol_t pdev_ = {nullptr, nullptr}; 74 zx::bti bti_; 75 76 // RDMA IRQ handle and thread 77 zx::interrupt rdma_irq_; 78 thrd_t rdma_thread_; 79 80 // use a single vmo for all channels 81 zx::vmo rdma_vmo_; 82 zx_handle_t rdma_pmt_; 83 zx_paddr_t rdma_phys_; 84 uint8_t* rdma_vbuf_; 85 86 // container that holds channel specific properties 87 RdmaChannelContainer rdma_chnl_container_[kMaxRdmaChannels]; 88 89 // Framebuffer dimension 90 uint32_t fb_width_; 91 uint32_t fb_height_; 92 // Actual display dimension 93 uint32_t display_width_; 94 uint32_t display_height_; 95 96 bool initialized_ = false; 97 }; 98 99 } // namespace astro_display 100