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