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 <assert.h>
8#include <stdint.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <ddk/device.h>
13#include <ddk/io-buffer.h>
14#include <ddk/protocol/platform-device.h>
15#include <zircon/listnode.h>
16#include <zircon/types.h>
17#include <threads.h>
18#include "vpu.h"
19#include "dwc-hdmi.h"
20
21__BEGIN_CDECLS
22
23#define DISPLAY_MASK(start, count) (((1 << (count)) - 1) << (start))
24#define DISPLAY_SET_MASK(mask, start, count, value) \
25                        ((mask & ~DISPLAY_MASK(start, count)) | \
26                                (((value) << (start)) & DISPLAY_MASK(start, count)))
27
28#define READ32_PRESET_REG(a)             readl((uint8_t*)io_buffer_virt(&display->mmio_preset) + a)
29#define WRITE32_PRESET_REG(a, v)         writel(v, (uint8_t*)io_buffer_virt(&display->mmio_preset) + a)
30
31#define READ32_HDMITX_REG(a)             readl((uint8_t*)io_buffer_virt(&display->mmio_hdmitx) + a)
32#define WRITE32_HDMITX_REG(a, v)         writel(v, (uint8_t*)io_buffer_virt(&display->mmio_hdmitx) + a)
33
34#define READ32_HHI_REG(a)                readl((uint8_t*)io_buffer_virt(&display->mmio_hiu) + a)
35#define WRITE32_HHI_REG(a, v)            writel(v, (uint8_t*)io_buffer_virt(&display->mmio_hiu) + a)
36
37#define READ32_VPU_REG(a)                readl((uint8_t*)io_buffer_virt(&display->mmio_vpu) + a)
38#define WRITE32_VPU_REG(a, v)            writel(v, (uint8_t*)io_buffer_virt(&display->mmio_vpu) + a)
39
40#define READ32_HDMITX_SEC_REG(a)         readl((uint8_t*)io_buffer_virt(&display->mmio_hdmitx_sec) + a)
41#define WRITE32_HDMITX_SEC_REG(a, v)     writel(v, (uint8_t*)io_buffer_virt(&display->mmio_hdmitx_sec) + a)
42
43#define READ32_CBUS_REG(a)              readl((uint8_t*)io_buffer_virt(&display->mmio_cbus) + 0x400 + a)
44#define WRITE32_CBUS_REG(a, v)          writel(v, (uint8_t*)io_buffer_virt(&display->mmio_cbus) + 0x400+ a)
45
46#define SET_BIT32(x, dest, value, count, start) \
47            WRITE32_##x##_REG(dest, (READ32_##x##_REG(dest) & ~DISPLAY_MASK(start, count)) | \
48                                (((value) << (start)) & DISPLAY_MASK(start, count)))
49
50#define WRITE32_REG(x, a, v)    WRITE32_##x##_REG(a, v)
51#define READ32_REG(x, a)        READ32_##x##_REG(a)
52
53#define SEC_OFFSET           (0x1UL << 24)
54#define TOP_OFFSET_MASK      (0x0UL << 24)
55#define TOP_SEC_OFFSET_MASK  ((TOP_OFFSET_MASK) | (SEC_OFFSET))
56#define DWC_OFFSET_MASK      (0x10UL << 24)
57#define DWC_SEC_OFFSET_MASK  ((DWC_OFFSET_MASK) | (SEC_OFFSET))
58
59#define DMC_CAV_LUT_DATAL           (0x12 << 2)
60#define DMC_CAV_LUT_DATAH           (0x13 << 2)
61#define DMC_CAV_LUT_ADDR             (0x14 << 2)
62
63#define DMC_CAV_ADDR_LMASK       0x1fffffff
64#define DMC_CAV_WIDTH_LMASK      0x7
65#define DMC_CAV_WIDTH_LWID       3
66#define DMC_CAV_WIDTH_LBIT       29
67
68#define DMC_CAV_WIDTH_HMASK      0x1ff
69#define DMC_CAV_WIDTH_HBIT       0
70#define DMC_CAV_HEIGHT_MASK      0x1fff
71#define DMC_CAV_HEIGHT_BIT       9
72
73#define DMC_CAV_LUT_ADDR_INDEX_MASK  0x7
74#define DMC_CAV_LUT_ADDR_RD_EN       (1 << 8)
75#define DMC_CAV_LUT_ADDR_WR_EN       (2 << 8)
76
77
78// P RESET
79#define PRESET_REGISTER                                 (0x400)
80#define PRESET0_REGISTER                                (0x404)
81#define PRESET2_REGISTER                                (0x40C)
82
83// HDMITX ADDRESS and DATA PORTS
84#define HDMITX_ADDR_PORT                                (0x00)
85#define HDMITX_DATA_PORT                                (0x04)
86#define HDMITX_CTRL_PORT                                (0x08)
87
88
89// HDMI TOP
90#define HDMITX_TOP_SW_RESET                             (TOP_OFFSET_MASK + 0x000)
91#define HDMITX_TOP_CLK_CNTL                             (TOP_OFFSET_MASK + 0x001)
92#define HDMITX_TOP_HPD_FILTER                           (TOP_OFFSET_MASK + 0x002)
93#define HDMITX_TOP_INTR_MASKN                           (TOP_OFFSET_MASK + 0x003)
94#define HDMITX_TOP_INTR_STAT                            (TOP_OFFSET_MASK + 0x004)
95#define HDMITX_TOP_INTR_STAT_CLR                        (TOP_OFFSET_MASK + 0x005)
96#define HDMITX_TOP_BIST_CNTL                            (TOP_OFFSET_MASK + 0x006)
97#define HDMITX_TOP_SHIFT_PTTN_012                       (TOP_OFFSET_MASK + 0x007)
98#define HDMITX_TOP_SHIFT_PTTN_345                       (TOP_OFFSET_MASK + 0x008)
99#define HDMITX_TOP_SHIFT_PTTN_67                        (TOP_OFFSET_MASK + 0x009)
100#define HDMITX_TOP_TMDS_CLK_PTTN_01                     (TOP_OFFSET_MASK + 0x00A)
101#define HDMITX_TOP_TMDS_CLK_PTTN_23                     (TOP_OFFSET_MASK + 0x00B)
102#define HDMITX_TOP_TMDS_CLK_PTTN_CNTL                   (TOP_OFFSET_MASK + 0x00C)
103#define HDMITX_TOP_REVOCMEM_STAT                        (TOP_OFFSET_MASK + 0x00D)
104#define HDMITX_TOP_STAT0                                (TOP_OFFSET_MASK + 0x00E)
105#define HDMITX_TOP_SKP_CNTL_STAT                        (TOP_SEC_OFFSET_MASK + 0x010)
106#define HDMITX_TOP_NONCE_0                              (TOP_SEC_OFFSET_MASK + 0x011)
107#define HDMITX_TOP_NONCE_1                              (TOP_SEC_OFFSET_MASK + 0x012)
108#define HDMITX_TOP_NONCE_2                              (TOP_SEC_OFFSET_MASK + 0x013)
109#define HDMITX_TOP_NONCE_3                              (TOP_SEC_OFFSET_MASK + 0x014)
110#define HDMITX_TOP_PKF_0                                (TOP_SEC_OFFSET_MASK + 0x015)
111#define HDMITX_TOP_PKF_1                                (TOP_SEC_OFFSET_MASK + 0x016)
112#define HDMITX_TOP_PKF_2                                (TOP_SEC_OFFSET_MASK + 0x017)
113#define HDMITX_TOP_PKF_3                                (TOP_SEC_OFFSET_MASK + 0x018)
114#define HDMITX_TOP_DUK_0                                (TOP_SEC_OFFSET_MASK + 0x019)
115#define HDMITX_TOP_DUK_1                                (TOP_SEC_OFFSET_MASK + 0x01A)
116#define HDMITX_TOP_DUK_2                                (TOP_SEC_OFFSET_MASK + 0x01B)
117#define HDMITX_TOP_DUK_3                                (TOP_SEC_OFFSET_MASK + 0x01C)
118#define HDMITX_TOP_INFILTER                             (TOP_OFFSET_MASK + 0x01D)
119#define HDMITX_TOP_NSEC_SCRATCH                         (TOP_OFFSET_MASK + 0x01E)
120#define HDMITX_TOP_SEC_SCRATCH                          (TOP_SEC_OFFSET_MASK + 0x01F)
121#define HDMITX_TOP_DONT_TOUCH0                          (TOP_OFFSET_MASK + 0x0FE)
122#define HDMITX_TOP_DONT_TOUCH1                          (TOP_OFFSET_MASK + 0x0FF)
123
124
125
126
127#define PAD_PULL_UP_EN_REG1                             (0x49 << 2)
128#define PAD_PULL_UP_REG1                                (0x3d << 2)
129#define P_PREG_PAD_GPIO1_EN_N                           (0x0f << 2)
130#define PERIPHS_PIN_MUX_6                               (0x32 << 2)
131
132struct reg_val_pair {
133    uint32_t    reg;
134    uint32_t    val;
135};
136
137static const struct reg_val_pair ENC_LUT_GEN[] = {
138    {VPU_ENCP_VIDEO_EN, 0,},
139    {VPU_ENCI_VIDEO_EN, 0,},
140    {VPU_ENCP_VIDEO_MODE, 0x4040,},
141    {VPU_ENCP_VIDEO_MODE_ADV, 0x18,},
142    {VPU_VPU_VIU_VENC_MUX_CTRL, 0xA},
143    {VPU_ENCP_VIDEO_VSO_BEGIN, 16},
144    {VPU_ENCP_VIDEO_VSO_END, 32},
145    {VPU_ENCI_VIDEO_EN, 0},
146    {VPU_ENCP_VIDEO_EN, 1},
147    { 0xFFFFFFFF, 0},
148};
149
150struct cea_timing {
151    bool                interlace_mode;
152    uint32_t            pfreq;
153    uint8_t             ln;
154    uint8_t             pixel_repeat;
155    uint8_t             venc_pixel_repeat;
156
157    uint32_t            hfreq;
158    uint32_t            hactive;
159    uint32_t            htotal;
160    uint32_t            hblank;
161    uint32_t            hfront;
162    uint32_t            hsync;
163    uint32_t            hback;
164    bool                hpol;
165
166    uint32_t            vfreq;
167    uint32_t            vactive;
168    uint32_t            vtotal;
169    uint32_t            vblank0;    // in case of interlace
170    uint32_t            vblank1;    // vblank0 + 1 for interlace
171    uint32_t            vfront;
172    uint32_t            vsync;
173    uint32_t            vback;
174    bool                vpol;
175};
176
177#define VID_PLL_DIV_1      0
178#define VID_PLL_DIV_2      1
179#define VID_PLL_DIV_3      2
180#define VID_PLL_DIV_3p5    3
181#define VID_PLL_DIV_3p75   4
182#define VID_PLL_DIV_4      5
183#define VID_PLL_DIV_5      6
184#define VID_PLL_DIV_6      7
185#define VID_PLL_DIV_6p25   8
186#define VID_PLL_DIV_7      9
187#define VID_PLL_DIV_7p5    10
188#define VID_PLL_DIV_12     11
189#define VID_PLL_DIV_14     12
190#define VID_PLL_DIV_15     13
191#define VID_PLL_DIV_2p5    14
192
193enum viu_type {
194    VIU_ENCL = 0,
195    VIU_ENCI,
196    VIU_ENCP,
197    VIU_ENCT,
198};
199
200struct pll_param {
201    uint32_t mode;
202    uint32_t viu_channel;
203    uint32_t viu_type;
204    uint32_t hpll_clk_out;
205    uint32_t od1;
206    uint32_t od2;
207    uint32_t od3;
208    uint32_t vid_pll_div;
209    uint32_t vid_clk_div;
210    uint32_t hdmi_tx_pixel_div;
211    uint32_t encp_div;
212    uint32_t enci_div;
213};
214
215struct hdmi_param {
216    uint16_t                        vic;
217    uint8_t                         aspect_ratio;
218    uint8_t                         colorimetry;
219    uint8_t                         phy_mode;
220    struct pll_param                pll_p_24b;
221    struct cea_timing               timings;
222    bool                            is4K;
223};
224
225#define HDMI_COLOR_DEPTH_24B    4
226#define HDMI_COLOR_DEPTH_30B    5
227#define HDMI_COLOR_DEPTH_36B    6
228#define HDMI_COLOR_DEPTH_48B    7
229
230#define HDMI_COLOR_FORMAT_RGB   0
231#define HDMI_COLOR_FORMAT_444   1
232
233#define HDMI_ASPECT_RATIO_NONE  0
234#define HDMI_ASPECT_RATIO_4x3   1
235#define HDMI_ASPECT_RATIO_16x9  2
236
237#define HDMI_COLORIMETRY_ITU601  1
238#define HDMI_COLORIMETRY_ITU709  2
239
240/* VIC lookup */
241 #define VIC_720x480p_60Hz_4x3                  2
242 #define VIC_720x480p_60Hz_16x9                 3
243 #define VIC_1280x720p_60Hz_16x9                4
244 #define VIC_1920x1080i_60Hz_16x9               5
245 #define VIC_720x480i_60Hz_4x3                  6
246 #define VIC_720x480i_60Hz_16x9                 7
247 #define VIC_720x240p_60Hz_4x3                  8
248 #define VIC_720x240p_60Hz_16x9                 9
249 #define VIC_2880x480i_60Hz_4x3                 10
250 #define VIC_2880x480i_60Hz_16x9                11
251 #define VIC_2880x240p_60Hz_4x3                 12
252 #define VIC_2880x240p_60Hz_16x9                13
253 #define VIC_1440x480p_60Hz_4x3                 14
254 #define VIC_1440x480p_60Hz_16x9                15
255 #define VIC_1920x1080p_60Hz_16x9               16
256 #define VIC_720x576p_50Hz_4x3                  17
257 #define VIC_720x576p_50Hz_16x9                 18
258 #define VIC_1280x720p_50Hz_16x9                19
259 #define VIC_1920x1080i_50Hz_16x9               20
260 #define VIC_720x576i_50Hz_4x3                  21
261 #define VIC_720x576i_50Hz_16x9                 22
262 #define VIC_720x288p_50Hz_4x3                  23
263 #define VIC_720x288p_50Hz_16x9                 24
264 #define VIC_2880x576i_50Hz_4x3                 25
265 #define VIC_2880x576i_50Hz_16x9                26
266 #define VIC_2880x288p_50Hz_4x3                 27
267 #define VIC_2880x288p_50Hz_16x9                28
268 #define VIC_1440x576p_50Hz_4x3                 29
269 #define VIC_1440x576p_50Hz_16x9                30
270 #define VIC_1920x1080p_50Hz_16x9               31
271 #define VIC_1920x1080p_24Hz_16x9               32
272 #define VIC_1920x1080p_25Hz_16x9               33
273 #define VIC_1920x1080p_30Hz_16x9               34
274 #define VIC_2880x480p_60Hz_4x3                 35
275 #define VIC_2880x480p_60Hz_16x9                36
276 #define VIC_2880x576p_50Hz_4x3                 37
277 #define VIC_2880x576p_50Hz_16x9                38
278 #define VIC_1920x1080i_1250_50Hz_16x9          39
279 #define VIC_1920x1080i_100Hz_16x9              40
280 #define VIC_1280x720p_100Hz_16x9               41
281 #define VIC_720x576p_100Hz_4x3                 42
282 #define VIC_720x576p_100Hz_16x9                43
283 #define VIC_720x576i_100Hz_4x3                 44
284 #define VIC_720x576i_100Hz_16x9                45
285 #define VIC_1920x1080i_120Hz_16x9              46
286 #define VIC_1280x720p_120Hz_16x9               47
287 #define VIC_720x480p_120Hz_4x3                 48
288 #define VIC_720x480p_120Hz_16x9                49
289 #define VIC_720x480i_120Hz_4x3                 50
290 #define VIC_720x480i_120Hz_16x9                51
291 #define VIC_720x576p_200Hz_4x3                 52
292 #define VIC_720x576p_200Hz_16x9                53
293 #define VIC_720x576i_200Hz_4x3                 54
294 #define VIC_720x576i_200Hz_16x9                55
295 #define VIC_720x480p_240Hz_4x3                 56
296 #define VIC_720x480p_240Hz_16x9                57
297 #define VIC_720x480i_240Hz_4x3                 58
298 #define VIC_720x480i_240Hz_16x9                59
299 #define VIC_1280x720p_24Hz_16x9                60
300 #define VIC_1280x720p_25Hz_16x9                61
301 #define VIC_1280x720p_30Hz_16x9                62
302 #define VIC_1920x1080p_120Hz_16x9              63
303 #define VIC_1920x1080p_100Hz_16x9              64
304 #define VESA_OFFSET                            300
305 #define VIC_VESA_640x480p_60Hz_4x3             300
306 #define VIC_VESA_1280x800p_60Hz_16x9           301
307 #define VIC_VESA_1280x1024p_60Hz_5x4           302
308 #define VIC_VESA_1920x1200p_60Hz_8x5           303
309 #define VIC_VESA_800x600p_60Hz                 304
310 #define VIC_VESA_1024x768p_60Hz                305
311
312struct vim2_display;  // fwd decl
313
314void hdmitx_writereg(const struct vim2_display* display, uint32_t addr, uint32_t data);
315uint32_t hdmitx_readreg(const struct vim2_display* display, uint32_t addr);
316void init_hdmi_hardware(struct vim2_display* display);
317void dump_regs(struct vim2_display* display);
318void init_hdmi_interface(struct vim2_display* display, const struct hdmi_param* p);
319void hdmi_test(struct vim2_display* display, uint32_t width);
320zx_status_t configure_pll(struct vim2_display* display, const struct hdmi_param* p,
321    const struct pll_param* pll);
322void hdmi_shutdown(struct vim2_display* display);
323
324__END_CDECLS
325