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 "edid.h" 8 #include <assert.h> 9 #include <ddk/debug.h> 10 #include <ddk/protocol/amlogiccanvas.h> 11 #include <ddk/protocol/display/controller.h> 12 #include <ddk/protocol/gpio.h> 13 #include <ddktl/mmio.h> 14 #include <stdint.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <zircon/listnode.h> 19 #include <zircon/pixelformat.h> 20 21 #include <optional> 22 23 #include "vim-audio.h" 24 #include "vpu.h" 25 26 __BEGIN_CDECLS 27 28 #define DISP_ERROR(fmt, ...) zxlogf(ERROR, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__) 29 #define DISP_INFO(fmt, ...) zxlogf(INFO, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__) 30 #define DISP_SPEW(fmt, ...) zxlogf(SPEW, "[%s %d]" fmt, __func__, __LINE__, ##__VA_ARGS__) 31 #define DISP_TRACE zxlogf(INFO, "[%s %d]\n", __func__, __LINE__) 32 33 #define NUM_CANVAS_ENTRIES 256 34 #define CANVAS_BYTE_STRIDE 32 35 36 // From uBoot source 37 #define VFIFO2VD_TO_HDMI_LATENCY 2 38 #define EDID_BUF_SIZE 256 39 40 #define MAX_RDMA_CHANNELS 3 41 42 // Should match display_irqs table in board driver 43 enum { 44 IRQ_VSYNC, 45 IRQ_RDMA, 46 }; 47 48 49 // MMIO indices (based on vim2_display_mmios) 50 enum { 51 MMIO_PRESET = 0, 52 MMIO_HDMITX, 53 MMIO_HIU, 54 MMIO_VPU, 55 MMIO_HDMTX_SEC, 56 MMIO_DMC, 57 MMIO_CBUS, 58 MMIO_AUD_OUT, 59 MMIO_COUNT // Must be the final entry 60 }; 61 62 // BTI indices (based on vim2_display_btis) 63 enum { 64 BTI_DISPLAY = 0, 65 BTI_AUDIO, 66 BTI_COUNT // Must be the final entry 67 }; 68 69 typedef struct vim2_display { 70 zx_device_t* zxdev; 71 pdev_protocol_t pdev; 72 zx_device_t* parent; 73 zx_device_t* mydevice; 74 zx_handle_t bti; 75 zx_handle_t inth; 76 77 gpio_protocol_t gpio; 78 amlogic_canvas_protocol_t canvas; 79 80 thrd_t main_thread; 81 thrd_t vsync_thread; 82 83 // RDMA IRQ thread 84 thrd_t rdma_thread; 85 86 // Lock for general display state, in particular display_id. 87 mtx_t display_lock; 88 // Lock for imported images. 89 mtx_t image_lock; 90 mtx_t i2c_lock; 91 92 // TODO(stevensd): This can race if this is changed right after 93 // vsync but before the interrupt is handled. 94 bool current_image_valid; 95 uint8_t current_image; 96 bool vd1_image_valid; 97 uint32_t vd1_image; 98 99 std::optional<ddk::MmioBuffer> mmio_preset; 100 std::optional<ddk::MmioBuffer> mmio_hdmitx; 101 std::optional<ddk::MmioBuffer> mmio_hiu; 102 std::optional<ddk::MmioBuffer> mmio_vpu; 103 std::optional<ddk::MmioBuffer> mmio_hdmitx_sec; 104 std::optional<ddk::MmioBuffer> mmio_dmc; 105 std::optional<ddk::MmioBuffer> mmio_cbus; 106 107 zx_handle_t vsync_interrupt; 108 zx_handle_t rdma_interrupt; 109 RdmaContainer rdma_container; 110 111 bool display_attached; 112 // The current display id (if display_attached), or the next display id 113 uint64_t display_id; 114 const char* manufacturer_name; 115 char monitor_name[14]; 116 char monitor_serial[14]; 117 118 uint8_t input_color_format; 119 uint8_t output_color_format; 120 uint8_t color_depth; 121 122 struct hdmi_param* p; 123 display_mode_t cur_display_mode; 124 125 display_controller_interface_t dc_intf; 126 list_node_t imported_images; 127 128 // A reference to the object which controls the VIM2 DAIs used to feed audio 129 // into the HDMI stream. 130 vim2_audio_t* audio; 131 uint32_t audio_format_count; 132 } vim2_display_t; 133 134 void disable_vd(vim2_display_t* display, uint32_t vd_index); 135 void configure_vd(vim2_display_t* display, uint32_t vd_index); 136 void flip_vd(vim2_display_t* display, uint32_t vd_index, uint32_t index); 137 138 void disable_osd(vim2_display_t* display, uint32_t osd_index); 139 zx_status_t configure_osd(vim2_display_t* display, uint32_t osd_index); 140 void flip_osd(vim2_display_t* display, uint32_t osd_index, uint8_t idx); 141 void osd_debug_dump_register_all(vim2_display_t* display); 142 void osd_dump(vim2_display_t* display); 143 void release_osd(vim2_display_t* display); 144 zx_status_t setup_rdma(vim2_display_t* display); 145 int rdma_thread(void *arg); 146 zx_status_t get_preferred_res(vim2_display_t* display, uint16_t edid_buf_size); 147 struct hdmi_param** get_supported_formats(void); 148 149 // TODO(johngro) : eliminate the need for these hooks if/when we start to 150 // support composite device drivers and can separate the DAI driver from the 151 // HDMI driver (which is currently playing the role of codec driver) 152 // 153 // TODO(johngro) : add any info needed to properly set up the audio info-frame. 154 zx_status_t vim2_display_configure_audio_mode(const vim2_display_t* display, 155 uint32_t N, 156 uint32_t CTS, 157 uint32_t frame_rate, 158 uint32_t bits_per_sample); 159 void vim2_display_disable_audio(const vim2_display_t* display); 160 161 __END_CDECLS 162