1 // Copyright 2017 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 <ddk/device.h>
8 #include <ddk/mmio-buffer.h>
9 #include <ddk/protocol/platform/device.h>
10 #include <zircon/listnode.h>
11 #include <zircon/types.h>
12 #include <threads.h>
13 #include "edid.h"
14 
15 #define DW_DSI_READ32(a)        readl(dsi->mmio.vaddr + a)
16 #define DW_DSI_WRITE32(a, v)    writel(v, dsi->mmio.vaddr + a)
17 
18 #define DW_DSI_MASK(start, count) (((1 << (count)) - 1) << (start))
19 
20 #define DW_DSI_SET_BITS32(dest, value, count, start) \
21             DW_DSI_WRITE32(dest, (DW_DSI_READ32(dest) & ~DW_DSI_MASK(start, count)) | \
22                                 (((value) << (start)) & DW_DSI_MASK(start, count)))
23 #define DW_DSI_SET_MASK(mask, start, count, value) \
24                         ((mask & ~DW_DSI_MASK(start, count)) | \
25                                 (((value) << (start)) & DW_DSI_MASK(start, count)))
26 
27 #define DW_DSI_VERSION                  0x0     /* contains the vers of the DSI host controller */
28 #define DW_DSI_PWR_UP                   0x4     /* controls the power up of the core */
29 #define DW_DSI_CLKMGR_CFG               0x8     /* configs the factor for internal dividers */
30 #define DW_DSI_DPI_VCID                 0xc     /* configs the Virt Chan ID for DPI traffic */
31 #define DW_DSI_DPI_COLOR_CODING         0x10    /* configs DPI color coding */
32 #define DW_DSI_DPI_CFG_POL              0x14    /* configs the polarity of DPI signals */
33 #define DW_DSI_DPI_LP_CMD_TIM           0x18    /* configs the timing for lp cmds (in vid mode) */
34 #define DW_DSI_DBI_VCID                 0x1c    /* configs Virtual Channel ID for DBI traffic */
35 #define DW_DSI_DBI_CFG                  0x20    /* configs the bit width of pixels for DBI */
36 #define DW_DSI_DBI_PARTITIONING_EN      0x24    /* host partition DBI traffic automatically */
37 #define DW_DSI_DBI_CMDSIZE              0x28    /* cmd size for auto partitioning of DBI */
38 #define DW_DSI_PCKHDL_CFG               0x2c    /* how EoTp, BTA, CRC and ECC are to be used */
39 #define DW_DSI_GEN_VCID                 0x30    /* Virtual Channel ID of READ responses to store */
40 #define DW_DSI_MODE_CFG                 0x34    /* mode of op between Video or Command Mode */
41 #define DW_DSI_VID_MODE_CFG             0x38    /* Video mode operation config */
42 #define DW_DSI_VID_PKT_SIZE             0x3c    /* video packet size */
43 #define DW_DSI_VID_NUM_CHUNKS           0x40    /* number of chunks to use  */
44 #define DW_DSI_VID_NULL_SIZE            0x44    /* configs the size of null packets */
45 #define DW_DSI_VID_HSA_TIME             0x48    /* configs the video HSA time */
46 #define DW_DSI_VID_HBP_TIME             0x4c    /* configs the video HBP time */
47 #define DW_DSI_VID_HLINE_TIME           0x50    /* configs the overall time for each video line */
48 #define DW_DSI_VID_VSA_LINES            0x54    /* configs the VSA period */
49 #define DW_DSI_VID_VBP_LINES            0x58    /* configs the VBP period */
50 #define DW_DSI_VID_VFP_LINES            0x5c    /* configs the VFP period */
51 #define DW_DSI_VID_VACTIVE_LINES        0x60    /* configs the vertical resolution of video */
52 #define DW_DSI_EDPI_CMD_SIZE            0x64    /* configs the size of eDPI packets */
53 #define DW_DSI_CMD_MODE_CFG             0x68    /* command mode operation config */
54 #define DW_DSI_GEN_HDR                  0x6c    /* header for new packets */
55 #define DW_DSI_GEN_PLD_DATA             0x70    /* payload for packets sent using the Gen i/f */
56 #define DW_DSI_CMD_PKT_STATUS           0x74    /* info about FIFOs related to DBI and Gen i/f */
57 #define DW_DSI_TO_CNT_CFG               0x78    /* counters that trig timeout errors */
58 #define DW_DSI_HS_RD_TO_CNT             0x7c    /* Peri Resp timeout after HS Rd operations */
59 #define DW_DSI_LP_RD_TO_CNT             0x80    /* Peri Resp timeout after LP Rd operations */
60 #define DW_DSI_HS_WR_TO_CNT             0x84    /* Peri Resp timeout after HS Wr operations */
61 #define DW_DSI_LP_WR_TO_CNT             0x88    /* Peri Resp timeout after LP Wr operations */
62 #define DW_DSI_BTA_TO_CNT               0x8c    /* Peri Resp timeout after Bus Turnaround comp */
63 #define DW_DSI_SDF_3D                   0x90    /* 3D cntrl info for VSS packets in video mode. */
64 #define DW_DSI_LPCLK_CTRL               0x94    /* non continuous clock in the clock lane. */
65 #define DW_DSI_PHY_TMR_LPCLK_CFG        0x98    /* time for the clock lane  */
66 #define DW_DSI_PHY_TMR_CFG              0x9c    /* time for the data lanes  */
67 #define DW_DSI_PHY_RSTZ                 0xa0    /* controls resets and the PLL of the D-PHY. */
68 #define DW_DSI_PHY_IF_CFG               0xa4    /* number of active lanes  */
69 #define DW_DSI_PHY_ULPS_CTRL            0xa8    /* entering and leaving ULPS in the D- PHY. */
70 #define DW_DSI_PHY_TX_TRIGGERS          0xac    /* pins that activate triggers in the D-PHY */
71 #define DW_DSI_PHY_STATUS               0xb0    /* contains info about the status of the D- PHY */
72 #define DW_DSI_PHY_TST_CTRL0            0xb4    /* controls clock and clear pins of the D-PHY */
73 #define DW_DSI_PHY_TST_CTRL1            0xb8    /* controls data and enable pins of the D-PHY */
74 #define DW_DSI_INT_ST0                  0xbc    /* status of intr from ack and D-PHY */
75 #define DW_DSI_INT_ST1                  0xc0    /* status of intr related to timeout, ECC, etc */
76 #define DW_DSI_INT_MSK0                 0xc4    /* masks interrupts that affect the INT_ST0 reg */
77 #define DW_DSI_INT_MSK1                 0xc8    /* masks interrupts that affect the INT_ST1 reg */
78 #define DW_DSI_PHY_CAL                  0xcc    /* controls the skew calibration of D-PHY. */
79 #define DW_DSI_INT_FORCE0               0xd8    /* forces that affect the INT_ST0 register. */
80 #define DW_DSI_INT_FORCE1               0xdc    /* forces interrupts that affect the INT_ST1 reg */
81 #define DW_DSI_DSC_PARAMETER            0xf0    /* configs Display Stream Compression */
82 #define DW_DSI_PHY_TMR_RD_CFG           0xf4    /* PHY related times for ops in lane byte clock */
83 #define DW_DSI_VID_SHADOW_CTRL          0x100   /* controls dpi shadow feature */
84 #define DW_DSI_DPI_VCID_ACT             0x10c   /* val used for DPI_VCID. */
85 #define DW_DSI_DPI_COLOR_CODING_ACT     0x110   /* val used for DPI_COLOR_CODING. */
86 #define DW_DSI_DPI_LP_CMD_TIM_ACT       0x118   /* val used for DPI_LP_CMD_TIM. */
87 #define DW_DSI_VID_MODE_CFG_ACT         0x138   /* val used for VID_MODE_CFG.*/
88 #define DW_DSI_VID_PKT_SIZE_ACT         0x13c   /* val used for VID_PKT_SIZE.*/
89 #define DW_DSI_VID_NUM_CHUNKS_ACT       0x140   /* val used for VID_NUM_CHUNKS.*/
90 #define DW_DSI_VID_NULL_SIZE_ACT        0x144   /* val used for VID_NULL_SIZE.*/
91 #define DW_DSI_VID_HSA_TIME_ACT         0x148   /* val used for VID_HSA_TIME.*/
92 #define DW_DSI_VID_HBP_TIME_ACT         0x14c   /* val used for VID_HBP_TIME.*/
93 #define DW_DSI_VID_HLINE_TIME_ACT       0x150   /* val used for VID_HLINE_TIME.*/
94 #define DW_DSI_VID_VSA_LINES_ACT        0x154   /* val used for VID_VSA_LINES.*/
95 #define DW_DSI_VID_VBP_LINES_ACT        0x158   /* val used for VID_VBP_LINES.*/
96 #define DW_DSI_VID_VFP_LINES_ACT        0x15c   /* val used for VID_VFP_LINES.*/
97 #define DW_DSI_VID_VACTIVE_LINES_ACT    0x160   /* val used for VID_VACTIVE_LINES.*/
98 #define DW_DSI_SDF_3D_ACT               0x190   /* val used for SDF_3D.*/
99 
100 
101 /* Bit DPI_CFG_POL Definitions */
102 #define DW_DSI_DPI_CFG_POL_DATAEN_START      (0)
103 #define DW_DSI_DPI_CFG_POL_VSYNC_START       (1)
104 #define DW_DSI_DPI_CFG_POL_HSYNC_START       (2)
105 #define DW_DSI_DPI_CFG_POL_SHUTD_START       (3)
106 #define DW_DSI_DPI_CFG_POL_COLORM_START      (4)
107 
108 /* Bit VID_MODE_CFG Definitions */
109 #define DW_DSI_VID_MODE_CFG_LP_CMD_START      (15)
110 #define DW_DSI_VID_MODE_CFG_LP_CMD_BITS       (1)
111 #define DW_DSI_VID_MODE_CFG_FRAME_ACK_START      (14)
112 #define DW_DSI_VID_MODE_CFG_FRAME_ACK_BITS       (1)
113 #define DW_DSI_VID_MODE_CFG_LP_ALL_START       (8)
114 #define DW_DSI_VID_MODE_CFG_LP_ALL_BITS        (6)
115 #define DW_DSI_VID_MODE_CFG_LP_VSA     (1 << 8)
116 #define DW_DSI_VID_MODE_CFG_LP_VBP     (1 << 9)
117 #define DW_DSI_VID_MODE_CFG_LP_VFP     (1 << 10)
118 #define DW_DSI_VID_MODE_CFG_LP_VACT    (1 << 11)
119 #define DW_DSI_VID_MODE_CFG_LP_HBP     (1 << 12)
120 #define DW_DSI_VID_MODE_CFG_LP_HFP     (1 << 13)
121 #define DW_DSI_VID_MODE_CFG_ALL_LP (DW_DSI_VID_MODE_CFG_LP_VSA | \
122                                     DW_DSI_VID_MODE_CFG_LP_VBP  | \
123                                     DW_DSI_VID_MODE_CFG_LP_VFP  | \
124                                     DW_DSI_VID_MODE_CFG_LP_VACT | \
125                                     DW_DSI_VID_MODE_CFG_LP_HBP  |\
126                                     DW_DSI_VID_MODE_CFG_LP_HFP)
127 #define DW_DSI_VID_MODE_CFG_MODE_START       (0)
128 #define DW_DSI_VID_MODE_CFG_MODE_BITS        (2)
129 
130 /* Bit VID_PKT_SIZE Definitions */
131 #define DW_DSI_VID_PKT_SIZE_START          0
132 #define DW_DSI_VID_PKT_SIZE_BITS           14
133 
134 /* Bit PHY_RSTZ Definitions */
135 #define DW_DSI_PHY_RSTZ_SHUTDOWN   (0)
136 #define DW_DSI_PHY_RSTZ_ENABLE     (0x7)
137 
138 /* Bit HY_STATUS Definitions */
139 #define DW_DSI_PHY_STATUS_PHY_LOCKED   (1 << 0)
140 #define DW_DSI_PHY_STATUS_L0STOP       (1 << 4)
141 #define DW_DSI_PHY_STATUS_LxSTOP(x)    (((x + 2) << 1) + 1)
142 #define DW_DSI_PHY_STATUS_ALLSTOP      (0xA90)
143 #define DW_DSI_PHY_STATUS_
144 #define DW_DSI_PHY_TST_CTRL0_TSTCLK (1 << 1)
145 #define DW_DSI_PHY_TST_CTRL0_TSTCLR (0 << 0)
146 #define DW_DSI_PHY_TST_CTRL1_TESTEN (1 << 16)
147 
148 
149 #define DS_NUM_LANES                        4
150 #define DSI_COLOR_CODE_24BITS               0x5
151 #define DSI_CFG_POL_ACTIVE_HIGH             0
152 #define DSI_CFG_POL_ACTIVE_LOW              1
153 #define DSI_NON_BURST_SYNC_PULSES           0
154 
155 #define LANE_BYTE_CLOCK (108000000ULL)
156 #define ROUND(x, y)     ((x) / (y) + \
157                 ((x) % (y) * 10 / (y) >= 5 ? 1 : 0))
158 #define ROUND1(x, y)    ((x) / (y) + ((x) % (y)  ? 1 : 0))
159 
160 typedef enum {
161     GPIO_MUX,
162     GPIO_PD,
163     GPIO_INT,
164     GPIO_COUNT,
165 } hdmi_gpio_if_t;
166 
167 typedef struct {
168     zx_device_t* zdev;
169     i2c_protocol_t i2c_main;
170     i2c_protocol_t i2c_cec;
171     i2c_protocol_t i2c_edid;
172 } adv7533_i2c_t;
173 
174 
175 typedef struct {
176     zx_device_t* zxdev;
177     gpio_protocol_t gpios[GPIO_COUNT];
178 } hdmi_gpio_t;
179 
180 
181 typedef struct {
182     zx_device_t*                        zxdev;
183     pdev_protocol_t          pdev;
184     zx_device_t*                        parent;
185     mmio_buffer_t                       mmio;
186 
187     adv7533_i2c_t                       i2c_dev;        // ADV7533 I2C device
188     hdmi_gpio_t                         hdmi_gpio;      // ADV7533-related GPIOs
189 
190     char                                write_buf[64];  // scratch buffer used for the i2c driver
191 
192     detailed_timing_t*                  std_raw_dtd;
193     disp_timing_t*                      std_disp_timing;
194     detailed_timing_t*                  raw_dtd;
195     disp_timing_t*                      disp_timing;
196 } dsi_t;
197 
198 static zx_status_t dsi_mipi_init(dsi_t* dsi);
199