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 <unistd.h> 8 9 #include <zircon/compiler.h> 10 #include <zircon/pixelformat.h> 11 #include <zircon/thread_annotations.h> 12 #include <lib/zx/interrupt.h> 13 #include <lib/zx/bti.h> 14 15 #include <ddk/driver.h> 16 #include <ddk/protocol/platform/device.h> 17 #include <ddk/protocol/gpio.h> 18 #include <ddk/protocol/amlogiccanvas.h> 19 #include <ddk/debug.h> 20 21 #include <ddktl/protocol/display/controller.h> 22 #include <ddktl/device.h> 23 24 #include <fbl/auto_lock.h> 25 #include <fbl/mutex.h> 26 #include <fbl/unique_ptr.h> 27 28 #include <bitmap/raw-bitmap.h> 29 #include <bitmap/storage.h> 30 #include "vpu.h" 31 #include "osd.h" 32 #include "astro-clock.h" 33 #include "aml-dsi-host.h" 34 #include "common.h" 35 36 namespace astro_display { 37 38 class AstroDisplay; 39 40 constexpr uint8_t kMaxImportedImages = 255; 41 using ImportedImageBitmap = bitmap::RawBitmapGeneric<bitmap::FixedStorage<kMaxImportedImages>>; 42 43 // AstroDisplay will implement only a few subset of Device. 44 using DeviceType = ddk::Device<AstroDisplay, ddk::Unbindable>; 45 46 class AstroDisplay : public DeviceType, 47 public ddk::DisplayControllerImplProtocol<AstroDisplay, ddk::base_protocol> { 48 public: AstroDisplay(zx_device_t * parent,uint32_t width,uint32_t height)49 AstroDisplay(zx_device_t* parent, uint32_t width, uint32_t height) 50 : DeviceType(parent), width_(width), height_(height) {} 51 52 // This function is called from the c-bind function upon driver matching 53 zx_status_t Bind(); 54 55 // Required functions needed to implement Display Controller Protocol 56 void DisplayControllerImplSetDisplayControllerInterface( 57 const display_controller_interface_t* intf); 58 zx_status_t DisplayControllerImplImportVmoImage(image_t* image, zx::vmo vmo, size_t offset); 59 void DisplayControllerImplReleaseImage(image_t* image); 60 uint32_t DisplayControllerImplCheckConfiguration(const display_config_t** display_configs, 61 size_t display_count, 62 uint32_t** layer_cfg_results, 63 size_t* layer_cfg_result_count); 64 void DisplayControllerImplApplyConfiguration(const display_config_t** display_config, 65 size_t display_count); 66 uint32_t DisplayControllerImplComputeLinearStride(uint32_t width, zx_pixel_format_t format); 67 zx_status_t DisplayControllerImplAllocateVmo(uint64_t size, zx::vmo* vmo_out); 68 69 // Required functions for DeviceType 70 void DdkUnbind(); 71 void DdkRelease(); 72 73 void Dump(); 74 75 private: 76 zx_status_t SetupDisplayInterface(); 77 int VSyncThread(); 78 void CopyDisplaySettings(); 79 void PopulateAddedDisplayArgs(added_display_args_t* args); 80 void PopulatePanelType() TA_REQ(display_lock_); 81 82 // Zircon handles 83 zx::bti bti_; 84 zx::interrupt inth_; 85 86 // Thread handles 87 thrd_t vsync_thread_; 88 89 // Protocol handles used in by this driver 90 pdev_protocol_t pdev_ = {}; 91 gpio_protocol_t gpio_ = {}; 92 amlogic_canvas_protocol_t canvas_ = {}; 93 94 // Board Info 95 pdev_board_info_t board_info_; 96 97 // Interrupts 98 zx::interrupt vsync_irq_; 99 100 // Locks used by the display driver 101 fbl::Mutex display_lock_; // general display state (i.e. display_id) 102 fbl::Mutex image_lock_; // used for accessing imported_images_ 103 104 // TODO(stevensd): This can race if this is changed right after 105 // vsync but before the interrupt is handled. 106 uint8_t current_image_ TA_GUARDED(display_lock_);; 107 bool current_image_valid_ TA_GUARDED(display_lock_);; 108 109 // display dimensions and format 110 uint32_t width_; 111 uint32_t height_; 112 uint32_t stride_; 113 zx_pixel_format_t format_; 114 115 const DisplaySetting* init_disp_table_ = nullptr; 116 117 // This flag is used to skip all driver initializations for older 118 // boards that we don't support. Those boards will depend on U-Boot 119 // to set things up 120 bool skip_disp_init_ TA_GUARDED(display_lock_); 121 122 // board revision and panel type detected by the display driver 123 uint8_t panel_type_ TA_GUARDED(display_lock_); 124 125 // Display structure used by various layers of display controller 126 DisplaySetting disp_setting_; 127 128 // Display controller related data 129 ddk::DisplayControllerInterfaceClient dc_intf_ TA_GUARDED(display_lock_); 130 131 // Simple hashtable 132 ImportedImageBitmap imported_images_ TA_GUARDED(image_lock_);; 133 134 // Objects 135 fbl::unique_ptr<astro_display::Vpu> vpu_; 136 fbl::unique_ptr<astro_display::Osd> osd_; 137 fbl::unique_ptr<astro_display::AstroDisplayClock> clock_; 138 fbl::unique_ptr<astro_display::AmlDsiHost> dsi_host_; 139 }; 140 141 } // namespace astro_display 142