1 /*
2  * Copyright 2020-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef _FSL_MIPI_DSI_H_
9 #define _FSL_MIPI_DSI_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup mipi_dsi
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*@{*/
24 #define FSL_MIPI_DSI_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
25 /*@}*/
26 
27 /* The max APB transfer size. */
28 #define FSL_DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U)
29 #define FSL_DSI_RX_MAX_PAYLOAD_BYTE (64U * 4U)
30 
31 /*! @brief MIPI DSI structure definition. */
32 typedef struct
33 {
34     DSI_HOST_Type *host;                        /*!< Pointer to HOST registers. */
35     DSI_HOST_APB_PKT_IF_Type *apb;              /*!< Pointer to APB registers. */
36     DSI_HOST_DPI_INTFC_Type *dpi;               /*!< Pointer to DPI registers. */
37     DSI_HOST_NXP_FDSOI28_DPHY_INTFC_Type *dphy; /*!< Pointer to DPHY registers. */
38 } MIPI_DSI_Type;
39 
40 /*! @brief Error codes for the MIPI DSI driver. */
41 enum
42 {
43     kStatus_DSI_Busy                = MAKE_STATUS(kStatusGroup_MIPI_DSI, 0), /*!< DSI is busy. */
44     kStatus_DSI_RxDataError         = MAKE_STATUS(kStatusGroup_MIPI_DSI, 1), /*!< Read data error. */
45     kStatus_DSI_ErrorReportReceived = MAKE_STATUS(kStatusGroup_MIPI_DSI, 2), /*!< Error report package received. */
46     kStatus_DSI_NotSupported        = MAKE_STATUS(kStatusGroup_MIPI_DSI, 3), /*!< The transfer type not supported. */
47 };
48 
49 /*! @brief MIPI DSI controller configuration. */
50 typedef struct _dsi_config
51 {
52     uint8_t numLanes;              /*!< Number of lanes. */
53     bool enableNonContinuousHsClk; /*!< In enabled, the high speed clock will enter
54                                        low power mode between transmissions. */
55     bool enableTxUlps;             /*!< Enable the TX ULPS. */
56     bool autoInsertEoTp;           /*!< Insert an EoTp short package when switching from HS to LP. */
57     uint8_t numExtraEoTp;          /*!< How many extra EoTp to send after the end of a packet. */
58     uint32_t htxTo_ByteClk;        /*!< HS TX timeout count (HTX_TO) in byte clock. */
59     uint32_t lrxHostTo_ByteClk;    /*!< LP RX host timeout count (LRX-H_TO) in byte clock. */
60     uint32_t btaTo_ByteClk;        /*!< Bus turn around timeout count (TA_TO) in byte clock. */
61 } dsi_config_t;
62 
63 /*! @brief MIPI DPI interface color coding. */
64 typedef enum _dsi_dpi_color_coding
65 {
66     kDSI_Dpi16BitConfig1 = 0U, /*!< 16-bit configuration 1. RGB565: XXXXXXXX_RRRRRGGG_GGGBBBBB. */
67     kDSI_Dpi16BitConfig2 = 1U, /*!< 16-bit configuration 2. RGB565: XXXRRRRR_XXGGGGGG_XXXBBBBB. */
68     kDSI_Dpi16BitConfig3 = 2U, /*!< 16-bit configuration 3. RGB565: XXRRRRRX_XXGGGGGG_XXBBBBBX. */
69     kDSI_Dpi18BitConfig1 = 3U, /*!< 18-bit configuration 1. RGB666: XXXXXXRR_RRRRGGGG_GGBBBBBB. */
70     kDSI_Dpi18BitConfig2 = 4U, /*!< 18-bit configuration 2. RGB666: XXRRRRRR_XXGGGGGG_XXBBBBBB. */
71     kDSI_Dpi24Bit        = 5U, /*!< 24-bit. */
72 } dsi_dpi_color_coding_t;
73 
74 /*! @brief MIPI DSI pixel packet type send through DPI interface. */
75 typedef enum _dsi_dpi_pixel_packet
76 {
77     kDSI_PixelPacket16Bit        = 0U, /*!< 16 bit RGB565. */
78     kDSI_PixelPacket18Bit        = 1U, /*!< 18 bit RGB666 packed. */
79     kDSI_PixelPacket18BitLoosely = 2U, /*!< 18 bit RGB666 loosely packed into three bytes. */
80     kDSI_PixelPacket24Bit        = 3U, /*!< 24 bit RGB888, each pixel uses three bytes. */
81 } dsi_dpi_pixel_packet_t;
82 
83 /*! @brief _dsi_dpi_polarity_flag DPI signal polarity. */
84 enum
85 {
86     kDSI_DpiVsyncActiveLow  = 0U,         /*!< VSYNC active low. */
87     kDSI_DpiHsyncActiveLow  = 0U,         /*!< HSYNC active low. */
88     kDSI_DpiVsyncActiveHigh = (1U << 0U), /*!< VSYNC active high. */
89     kDSI_DpiHsyncActiveHigh = (1U << 1U), /*!< HSYNC active high. */
90 };
91 
92 /*! @brief DPI video mode. */
93 typedef enum _dsi_dpi_video_mode
94 {
95     kDSI_DpiNonBurstWithSyncPulse = 0U, /*!< Non-Burst mode with Sync Pulses. */
96     kDSI_DpiNonBurstWithSyncEvent = 1U, /*!< Non-Burst mode with Sync Events. */
97     kDSI_DpiBurst                 = 2U, /*!< Burst mode. */
98 } dsi_dpi_video_mode_t;
99 
100 /*! @brief Behavior in BLLP (Blanking or Low-Power Interval). */
101 typedef enum _dsi_dpi_bllp_mode
102 {
103     kDSI_DpiBllpLowPower, /*!< LP mode used in BLLP periods. */
104     kDSI_DpiBllpBlanking, /*!< Blanking packets used in BLLP periods. */
105     kDSI_DpiBllpNull,     /*!< Null packets used in BLLP periods. */
106 } dsi_dpi_bllp_mode_t;
107 
108 /*! @brief MIPI DSI controller DPI interface configuration. */
109 typedef struct _dsi_dpi_config
110 {
111     uint16_t pixelPayloadSize;             /*!< Maximum number of pixels that should be sent
112                                               as one DSI packet. Recommended that the line size
113                                               (in pixels) is evenly divisible by this parameter. */
114     dsi_dpi_color_coding_t dpiColorCoding; /*!< DPI color coding. */
115     dsi_dpi_pixel_packet_t pixelPacket;    /*!< Pixel packet format. */
116 
117     dsi_dpi_video_mode_t videoMode; /*!< Video mode. */
118     dsi_dpi_bllp_mode_t bllpMode;   /*!< Behavior in BLLP. */
119 
120     uint8_t polarityFlags; /*!< OR'ed value of _dsi_dpi_polarity_flag controls signal polarity. */
121     uint16_t hfp;          /*!< Horizontal front porch, in dpi pixel clock. */
122     uint16_t hbp;          /*!< Horizontal back porch, in dpi pixel clock. */
123     uint16_t hsw;          /*!< Horizontal sync width, in dpi pixel clock. */
124     uint8_t vfp;           /*!< Number of lines in vertical front porch. */
125     uint8_t vbp;           /*!< Number of lines in vertical back porch. */
126     uint16_t panelHeight;  /*!< Line number in vertical active area. */
127 
128     uint8_t virtualChannel; /*!< Virtual channel. */
129 } dsi_dpi_config_t;
130 
131 /*! @brief MIPI DSI D-PHY configuration. */
132 typedef struct _dsi_dphy_config
133 {
134     uint32_t txHsBitClk_Hz; /*!< The generated HS TX bit clock in Hz. */
135 
136     uint8_t tClkPre_ByteClk;        /*!< TLPX + TCLK-PREPARE + TCLK-ZERO + TCLK-PRE in byte clock.
137                                          Set how long the controller
138                                          will wait after enabling clock lane for HS before
139                                          enabling data lanes for HS. */
140     uint8_t tClkPost_ByteClk;       /*!< TCLK-POST + T_CLK-TRAIL in byte clock. Set how long the controller
141                                         will wait before putting clock lane into LP mode after
142                                         data lanes detected in stop state. */
143     uint8_t tHsExit_ByteClk;        /*!< THS-EXIT in byte clock. Set how long the controller
144                                           will wait after the clock lane has been put into LP
145                                           mode before enabling clock lane for HS again. */
146     uint32_t tWakeup_EscClk;        /*!< Number of clk_esc clock periods to keep a clock
147                                          or data lane in Mark-1 state after exiting ULPS. */
148     uint8_t tHsPrepare_HalfEscClk;  /*!< THS-PREPARE in clk_esc/2. Set how long
149                                       to drive the LP-00 state before HS transmissions,
150                                       available values are 2, 3, 4, 5. */
151     uint8_t tClkPrepare_HalfEscClk; /*!< TCLK-PREPARE in clk_esc/2. Set how long
152                                      to drive the LP-00 state before HS transmissions,
153                                      available values are 2, 3. */
154     uint8_t tHsZero_ByteClk;        /*!< THS-ZERO in clk_byte. Set how long that controller
155                                       drives data lane HS-0 state before transmit
156                                       the Sync sequence. Available values are 6, 7, ..., 37. */
157     uint8_t tClkZero_ByteClk;       /*!< TCLK-ZERO in clk_byte. Set how long that controller
158                                       drives clock lane HS-0 state before transmit
159                                       the Sync sequence. Available values are 3, 4, ..., 66. */
160     uint8_t tHsTrail_ByteClk;       /*!< THS-TRAIL + 4*UI in clk_byte. Set the time
161                                        of the flipped differential state after last payload
162                                        data bit of HS transmission burst. Available values
163                                        are 0, 1, ..., 15. */
164     uint8_t tClkTrail_ByteClk;      /*!< TCLK-TRAIL + 4*UI in clk_byte. Set the time
165                                        of the flipped differential state after last payload
166                                        data bit of HS transmission burst. Available values
167                                        are 0, 1, ..., 15. */
168 } dsi_dphy_config_t;
169 
170 /*! @brief _dsi_apb_status Status of APB to packet interface. */
171 enum
172 {
173     kDSI_ApbNotIdle          = (1U << 0U), /*!< State machine not idle */
174     kDSI_ApbTxDone           = (1U << 1U), /*!< Tx packet done */
175     kDSI_ApbRxControl        = (1U << 2U), /*!< DPHY direction 0 - tx had control, 1 - rx has control */
176     kDSI_ApbTxOverflow       = (1U << 3U), /*!< TX fifo overflow */
177     kDSI_ApbTxUnderflow      = (1U << 4U), /*!< TX fifo underflow */
178     kDSI_ApbRxOverflow       = (1U << 5U), /*!< RX fifo overflow */
179     kDSI_ApbRxUnderflow      = (1U << 6U), /*!< RX fifo underflow */
180     kDSI_ApbRxHeaderReceived = (1U << 7U), /*!< RX packet header has been received */
181     kDSI_ApbRxPacketReceived = (1U << 8U), /*!< All RX packet payload data has been received */
182 };
183 
184 /*! @brief _dsi_rx_error_status Host receive error status. */
185 enum
186 {
187     kDSI_RxErrorEccOneBit   = (1U << 0U), /*!< ECC single bit error detected. */
188     kDSI_RxErrorEccMultiBit = (1U << 1U), /*!< ECC multi bit error detected. */
189     kDSI_RxErrorCrc         = (1U << 7U), /*!< CRC error detected. */
190     kDSI_RxErrorHtxTo       = (1U << 8U), /*!< High Speed forward TX timeout detected. */
191     kDSI_RxErrorLrxTo       = (1U << 9U), /*!< Reverse Low power data receive timeout detected. */
192     kDSI_RxErrorBtaTo       = (1U << 10U) /*!< BTA timeout detected. */
193 };
194 
195 /*! @brief DSI host controller status (status_out) */
196 enum _dsi_host_status
197 {
198     kDSI_HostSoTError           = (1U << 0U),  /*!< SoT error from peripheral error report. */
199     kDSI_HostSoTSyncError       = (1U << 1U),  /*!< SoT Sync error from peripheral error report. */
200     kDSI_HostEoTSyncError       = (1U << 2U),  /*!< EoT Sync error from peripheral error report. */
201     kDSI_HostEscEntryCmdError   = (1U << 3U),  /*!< Escape Mode Entry Command Error from peripheral error report. */
202     kDSI_HostLpTxSyncError      = (1U << 4U),  /*!< Low-power transmit Sync Error from peripheral error report. */
203     kDSI_HostPeriphToError      = (1U << 5U),  /*!< Peripheral timeout error from peripheral error report. */
204     kDSI_HostFalseControlError  = (1U << 6U),  /*!< False control error from peripheral error report. */
205     kDSI_HostContentionDetected = (1U << 7U),  /*!< Contention detected from peripheral error report. */
206     kDSI_HostEccErrorOneBit     = (1U << 8U),  /*!< Single bit ECC error (corrected) from peripheral error report. */
207     kDSI_HostEccErrorMultiBit   = (1U << 9U),  /*!< Multi bit ECC error (not corrected) from peripheral error report. */
208     kDSI_HostChecksumError      = (1U << 10U), /*!< Checksum error from peripheral error report. */
209     kDSI_HostInvalidDataType    = (1U << 11U), /*!< DSI data type not recognized. */
210     kDSI_HostInvalidVcId        = (1U << 12U), /*!< DSI VC ID invalid. */
211     kDSI_HostInvalidTxLength    = (1U << 13U), /*!< Invalid transmission length. */
212     kDSI_HostProtocalViolation  = (1U << 15U), /*!< DSI protocal violation. */
213     kDSI_HostResetTriggerReceived = (1U << 16U), /*!< Reset trigger received. */
214     kDSI_HostTearTriggerReceived  = (1U << 17U), /*!< Tear effect trigger receive. */
215     kDSI_HostAckTriggerReceived   = (1U << 18U), /*!< Acknowledge trigger message received. */
216 };
217 
218 /*! @brief _dsi_interrupt DSI interrupt. */
219 enum
220 {
221     kDSI_InterruptGroup1ApbNotIdle          = (1U << 0U),   /*!< State machine not idle */
222     kDSI_InterruptGroup1ApbTxDone           = (1U << 1U),   /*!< Tx packet done */
223     kDSI_InterruptGroup1ApbRxControl        = (1U << 2U),   /*!< DPHY direction 0 - tx control, 1 - rx control */
224     kDSI_InterruptGroup1ApbTxOverflow       = (1U << 3U),   /*!< TX fifo overflow */
225     kDSI_InterruptGroup1ApbTxUnderflow      = (1U << 4U),   /*!< TX fifo underflow */
226     kDSI_InterruptGroup1ApbRxOverflow       = (1U << 5U),   /*!< RX fifo overflow */
227     kDSI_InterruptGroup1ApbRxUnderflow      = (1U << 6U),   /*!< RX fifo underflow */
228     kDSI_InterruptGroup1ApbRxHeaderReceived = (1U << 7U),   /*!< RX packet header has been received */
229     kDSI_InterruptGroup1ApbRxPacketReceived = (1U << 8U),   /*!< All RX packet payload data has been received */
230     kDSI_InterruptGroup1SoTError            = (1U << 9U),   /*!< SoT error from peripheral error report. */
231     kDSI_InterruptGroup1SoTSyncError        = (1U << 10U),  /*!< SoT Sync error from peripheral error report. */
232     kDSI_InterruptGroup1EoTSyncError        = (1U << 11U),  /*!< EoT Sync error from peripheral error report. */
233     kDSI_InterruptGroup1EscEntryCmdError    = (1U << 12U),  /*!< Escape Mode Entry Command Error
234                                                                    from peripheral error report. */
235     kDSI_InterruptGroup1LpTxSyncError = (1U << 13U),        /*!< Low-power transmit Sync Error from
236                                                                    peripheral error report. */
237     kDSI_InterruptGroup1PeriphToError = (1U << 14U),        /*!< Peripheral timeout error from
238                                                                    peripheral error report. */
239     kDSI_InterruptGroup1FalseControlError  = (1U << 15U),   /*!< False control error from peripheral error report. */
240     kDSI_InterruptGroup1ContentionDetected = (1U << 16U),   /*!< Contention detected from peripheral error report. */
241     kDSI_InterruptGroup1EccErrorOneBit     = (1U << 17U),   /*!< Single bit ECC error (corrected) from
242                                                                    peripheral error report. */
243     kDSI_InterruptGroup1EccErrorMultiBit = (1U << 18U),     /*!< Multi bit ECC error (not corrected) from
244                                                                peripheral error report. */
245     kDSI_InterruptGroup1ChecksumError        = (1U << 19U), /*!< Checksum error from peripheral error report. */
246     kDSI_InterruptGroup1InvalidDataType      = (1U << 20U), /*!< DSI data type not recognized. */
247     kDSI_InterruptGroup1InvalidVcId          = (1U << 21U), /*!< DSI VC ID invalid. */
248     kDSI_InterruptGroup1InvalidTxLength      = (1U << 22U), /*!< Invalid transmission length. */
249     kDSI_InterruptGroup1ProtocalViolation    = (1U << 24U), /*!< DSI protocal violation. */
250     kDSI_InterruptGroup1ResetTriggerReceived = (1U << 25U), /*!< Reset trigger received. */
251     kDSI_InterruptGroup1TearTriggerReceived  = (1U << 26U), /*!< Tear effect trigger receive. */
252     kDSI_InterruptGroup1AckTriggerReceived   = (1U << 27U), /*!< Acknowledge trigger message received. */
253     kDSI_InterruptGroup1HtxTo                = (1U << 29U), /*!< High speed TX timeout. */
254     kDSI_InterruptGroup1LrxTo                = (1U << 30U), /*!< Low power RX timeout. */
255     kDSI_InterruptGroup1BtaTo                = (1U << 31U), /*!< Host BTA timeout. */
256     kDSI_InterruptGroup2EccOneBit            = (1U << 0U),  /*!< Sinle bit ECC error. */
257     kDSI_InterruptGroup2EccMultiBit          = (1U << 1U),  /*!< Multi bit ECC error. */
258     kDSI_InterruptGroup2CrcError             = (1U << 2U),  /*!< CRC error. */
259 };
260 
261 /*! @brief DSI TX data type. */
262 typedef enum _dsi_tx_data_type
263 {
264     kDSI_TxDataVsyncStart          = 0x01U, /*!< V Sync start. */
265     kDSI_TxDataVsyncEnd            = 0x11U, /*!< V Sync end. */
266     kDSI_TxDataHsyncStart          = 0x21U, /*!< H Sync start. */
267     kDSI_TxDataHsyncEnd            = 0x31U, /*!< H Sync end. */
268     kDSI_TxDataEoTp                = 0x08U, /*!< End of transmission packet. */
269     kDSI_TxDataCmOff               = 0x02U, /*!< Color mode off. */
270     kDSI_TxDataCmOn                = 0x12U, /*!< Color mode on. */
271     kDSI_TxDataShutDownPeriph      = 0x22U, /*!< Shut down peripheral. */
272     kDSI_TxDataTurnOnPeriph        = 0x32U, /*!< Turn on peripheral. */
273     kDSI_TxDataGenShortWrNoParam   = 0x03U, /*!< Generic Short WRITE, no parameters. */
274     kDSI_TxDataGenShortWrOneParam  = 0x13U, /*!< Generic Short WRITE, one parameter. */
275     kDSI_TxDataGenShortWrTwoParam  = 0x23U, /*!< Generic Short WRITE, two parameter. */
276     kDSI_TxDataGenShortRdNoParam   = 0x04U, /*!< Generic Short READ, no parameters. */
277     kDSI_TxDataGenShortRdOneParam  = 0x14U, /*!< Generic Short READ, one parameter. */
278     kDSI_TxDataGenShortRdTwoParam  = 0x24U, /*!< Generic Short READ, two parameter. */
279     kDSI_TxDataDcsShortWrNoParam   = 0x05U, /*!< DCS Short WRITE, no parameters. */
280     kDSI_TxDataDcsShortWrOneParam  = 0x15U, /*!< DCS Short WRITE, one parameter. */
281     kDSI_TxDataDcsShortRdNoParam   = 0x06U, /*!< DCS Short READ, no parameters. */
282     kDSI_TxDataSetMaxReturnPktSize = 0x37U, /*!< Set the Maximum Return Packet Size. */
283 
284     kDSI_TxDataNull                         = 0x09U, /*!< Null Packet, no data. */
285     kDSI_TxDataBlanking                     = 0x19U, /*!< Blanking Packet, no data. */
286     kDSI_TxDataGenLongWr                    = 0x29U, /*!< Generic long write. */
287     kDSI_TxDataDcsLongWr                    = 0x39U, /*!< DCS Long Write/write_LUT Command Packet. */
288     kDSI_TxDataLooselyPackedPixel20BitYCbCr = 0x0CU, /*!< Loosely Packed Pixel Stream, 20-bit YCbCr, 4:2:2 Format. */
289     kDSI_TxDataPackedPixel24BitYCbCr        = 0x1CU, /*!< Packed Pixel Stream, 24-bit YCbCr, 4:2:2 Format. */
290     kDSI_TxDataPackedPixel16BitYCbCr        = 0x2CU, /*!< Packed Pixel Stream, 16-bit YCbCr, 4:2:2 Format. */
291     kDSI_TxDataPackedPixel30BitRGB          = 0x0DU, /*!< Packed Pixel Stream, 30-bit RGB, 10-10-10 Format. */
292     kDSI_TxDataPackedPixel36BitRGB          = 0x1DU, /*!< Packed Pixel Stream, 36-bit RGB, 12-12-12 Format. */
293     kDSI_TxDataPackedPixel12BitYCrCb        = 0x3DU, /*!< Packed Pixel Stream, 12-bit YCbCr, 4:2:0 Format. */
294     kDSI_TxDataPackedPixel16BitRGB          = 0x0EU, /*!< Packed Pixel Stream, 16-bit RGB, 5-6-5 Format. */
295     kDSI_TxDataPackedPixel18BitRGB          = 0x1EU, /*!< Packed Pixel Stream, 18-bit RGB, 6-6-6 Format. */
296     kDSI_TxDataLooselyPackedPixel18BitRGB   = 0x2EU, /*!< Loosely Packed Pixel Stream, 18-bit RGB, 6-6-6 Format. */
297     kDSI_TxDataPackedPixel24BitRGB          = 0x3EU, /*!< Packed Pixel Stream, 24-bit RGB, 8-8-8 Format. */
298 } dsi_tx_data_type_t;
299 
300 /*! @brief DSI RX data type. */
301 typedef enum _dsi_rx_data_type
302 {
303     kDSI_RxDataAckAndErrorReport         = 0x02U, /*!< Acknowledge and Error Report */
304     kDSI_RxDataEoTp                      = 0x08U, /*!< End of Transmission packet. */
305     kDSI_RxDataGenShortRdResponseOneByte = 0x11U, /*!< Generic Short READ Response, 1 byte returned. */
306     kDSI_RxDataGenShortRdResponseTwoByte = 0x12U, /*!< Generic Short READ Response, 2 byte returned. */
307     kDSI_RxDataGenLongRdResponse         = 0x1AU, /*!< Generic Long READ Response. */
308     kDSI_RxDataDcsLongRdResponse         = 0x1CU, /*!< DCS Long READ Response. */
309     kDSI_RxDataDcsShortRdResponseOneByte = 0x21U, /*!< DCS Short READ Response, 1 byte returned. */
310     kDSI_RxDataDcsShortRdResponseTwoByte = 0x22U, /*!< DCS Short READ Response, 2 byte returned. */
311 } dsi_rx_data_type_t;
312 
313 /*! @brief _dsi_transfer_flags DSI transfer control flags. */
314 enum
315 {
316     kDSI_TransferUseHighSpeed = (1U << 0U), /*!< Use high speed mode or not. */
317     kDSI_TransferPerformBTA   = (1U << 1U), /*!< Perform BTA or not. */
318 };
319 
320 /*! @brief Structure for the data transfer. */
321 typedef struct _dsi_transfer
322 {
323     uint8_t virtualChannel;        /*!< Virtual channel. */
324     dsi_tx_data_type_t txDataType; /*!< TX data type. */
325     uint8_t flags;                 /*!< Flags to control the transfer, see _dsi_transfer_flags. */
326     const uint8_t *txData;         /*!< The TX data buffer. */
327     uint8_t *rxData;               /*!< The TX data buffer. */
328     uint16_t txDataSize;           /*!< Size of the TX data. */
329     uint16_t rxDataSize;           /*!< Size of the RX data. */
330     bool sendDscCmd;               /*!< If set to true, the DSC command is specified by @ref dscCmd, otherwise
331                                         the DSC command is included in the @ref txData. */
332     uint8_t dscCmd;                /*!< The DSC command to send, only valid when @ref sendDscCmd is true. */
333 } dsi_transfer_t;
334 
335 /*! @brief MIPI DSI transfer handle. */
336 typedef struct _dsi_handle dsi_handle_t;
337 
338 /*!
339  * @brief MIPI DSI callback for finished transfer.
340  *
341  * When transfer finished, one of these status values will be passed to the user:
342  * - @ref kStatus_Success Data transfer finished with no error.
343  * - @ref kStatus_Timeout Transfer failed because of timeout.
344  * - @ref kStatus_DSI_RxDataError RX data error, user could use @ref DSI_GetRxErrorStatus
345  *        to check the error details.
346  * - @ref kStatus_DSI_ErrorReportReceived Error Report packet received, user could use
347  *        @ref DSI_GetAndClearHostStatus to check the error report status.
348  * - @ref kStatus_Fail Transfer failed for other reasons.
349  */
350 typedef void (*dsi_callback_t)(const MIPI_DSI_Type *base, dsi_handle_t *handle, status_t status, void *userData);
351 
352 /*! @brief MIPI DSI transfer handle structure */
353 struct _dsi_handle
354 {
355     volatile bool isBusy;     /*!< MIPI DSI is busy with APB data transfer. */
356     dsi_transfer_t xfer;      /*!< Transfer information. */
357     dsi_callback_t callback;  /*!< DSI callback */
358     void *userData;           /*!< Callback parameter */
359     const MIPI_DSI_Type *dsi; /*!< Pointer to MIPI DSI peripheral. */
360 };
361 
362 /*******************************************************************************
363  * API
364  ******************************************************************************/
365 
366 #if defined(__cplusplus)
367 extern "C" {
368 #endif
369 
370 /*!
371  * @name MIPI_DSI host initialization.
372  * @{
373  */
374 
375 /*!
376  * @brief Initializes an MIPI DSI host with the user configuration.
377  *
378  * This function initializes the MIPI DSI host with the configuration, it should
379  * be called first before other MIPI DSI driver functions.
380  *
381  * @param base MIPI DSI host peripheral base address.
382  * @param config Pointer to a user-defined configuration structure.
383  */
384 void DSI_Init(const MIPI_DSI_Type *base, const dsi_config_t *config);
385 
386 /*!
387  * @brief Deinitializes an MIPI DSI host.
388  *
389  * This function should be called after all bother MIPI DSI driver functions.
390  *
391  * @param base MIPI DSI host peripheral base address.
392  */
393 void DSI_Deinit(const MIPI_DSI_Type *base);
394 
395 /*!
396  * @brief Get the default configuration to initialize the MIPI DSI host.
397  *
398  * The default value is:
399  * @code
400     config->numLanes = 4;
401     config->enableNonContinuousHsClk = false;
402     config->enableTxUlps = false;
403     config->autoInsertEoTp = true;
404     config->numExtraEoTp = 0;
405     config->htxTo_ByteClk = 0;
406     config->lrxHostTo_ByteClk = 0;
407     config->btaTo_ByteClk = 0;
408    @endcode
409  *
410  * @param config Pointer to a user-defined configuration structure.
411  */
412 void DSI_GetDefaultConfig(dsi_config_t *config);
413 
414 /*! @} */
415 
416 /*!
417  * @name DPI interface
418  * @{
419  */
420 
421 /*!
422  * @brief Configure the DPI interface core.
423  *
424  * This function sets the DPI interface configuration, it should be used in
425  * video mode.
426  *
427  * @param base MIPI DSI host peripheral base address.
428  * @param config Pointer to the DPI interface configuration.
429  * @param numLanes Lane number, should be same with the setting in @ref dsi_dpi_config_t.
430  * @param dpiPixelClkFreq_Hz The DPI pixel clock frequency in Hz.
431  * @param dsiHsBitClkFreq_Hz The DSI high speed bit clock frequency in Hz. It is
432  * the same with DPHY PLL output.
433  */
434 void DSI_SetDpiConfig(const MIPI_DSI_Type *base,
435                       const dsi_dpi_config_t *config,
436                       uint8_t numLanes,
437                       uint32_t dpiPixelClkFreq_Hz,
438                       uint32_t dsiHsBitClkFreq_Hz);
439 
440 /*! @} */
441 
442 /*!
443  * @name D-PHY configuration.
444  * @{
445  */
446 
447 /*!
448  * @brief Initializes the D-PHY
449  *
450  * This function configures the D-PHY timing and setups the D-PHY PLL based on
451  * user configuration. The configuration structure could be got by the function
452  * @ref DSI_GetDphyDefaultConfig.
453  *
454  * For some platforms there is not dedicated D-PHY PLL, indicated by the macro
455  * FSL_FEATURE_MIPI_DSI_NO_DPHY_PLL. For these platforms, the @p refClkFreq_Hz
456  * is useless.
457  *
458  * @param base MIPI DSI host peripheral base address.
459  * @param config Pointer to the D-PHY configuration.
460  * @param refClkFreq_Hz The REFCLK frequency in Hz.
461  * @return The actual D-PHY PLL output frequency. If could not configure the
462  * PLL to the target frequency, the return value is 0.
463  */
464 uint32_t DSI_InitDphy(const MIPI_DSI_Type *base, const dsi_dphy_config_t *config, uint32_t refClkFreq_Hz);
465 
466 /*!
467  * @brief Deinitializes the D-PHY
468  *
469  * Power down the D-PHY PLL and shut down D-PHY.
470  *
471  * @param base MIPI DSI host peripheral base address.
472  */
473 void DSI_DeinitDphy(const MIPI_DSI_Type *base);
474 
475 /*!
476  * @brief Get the default D-PHY configuration.
477  *
478  * Gets the default D-PHY configuration, the timing parameters are set according
479  * to D-PHY specification. User could use the configuration directly, or change
480  * some parameters according to the special device.
481  *
482  * @param config Pointer to the D-PHY configuration.
483  * @param txHsBitClk_Hz High speed bit clock in Hz.
484  * @param txEscClk_Hz Esc clock in Hz.
485  */
486 void DSI_GetDphyDefaultConfig(dsi_dphy_config_t *config, uint32_t txHsBitClk_Hz, uint32_t txEscClk_Hz);
487 
488 /*! @} */
489 
490 /*!
491  * @name Interrupts
492  * @{
493  */
494 
495 /*!
496  * @brief Enable the interrupts.
497  *
498  * The interrupts to enable are passed in as OR'ed mask value of _dsi_interrupt.
499  *
500  * @param base MIPI DSI host peripheral base address.
501  * @param intGroup1 Interrupts to enable in group 1.
502  * @param intGroup2 Interrupts to enable in group 2.
503  */
DSI_EnableInterrupts(const MIPI_DSI_Type * base,uint32_t intGroup1,uint32_t intGroup2)504 static inline void DSI_EnableInterrupts(const MIPI_DSI_Type *base, uint32_t intGroup1, uint32_t intGroup2)
505 {
506     base->apb->IRQ_MASK &= ~intGroup1;
507     base->apb->IRQ_MASK2 &= ~intGroup2;
508 }
509 
510 /*!
511  * @brief Disable the interrupts.
512  *
513  * The interrupts to disable are passed in as OR'ed mask value of _dsi_interrupt.
514  *
515  * @param base MIPI DSI host peripheral base address.
516  * @param intGroup1 Interrupts to disable in group 1.
517  * @param intGroup2 Interrupts to disable in group 2.
518  */
DSI_DisableInterrupts(const MIPI_DSI_Type * base,uint32_t intGroup1,uint32_t intGroup2)519 static inline void DSI_DisableInterrupts(const MIPI_DSI_Type *base, uint32_t intGroup1, uint32_t intGroup2)
520 {
521     base->apb->IRQ_MASK |= intGroup1;
522     base->apb->IRQ_MASK2 |= intGroup2;
523 }
524 
525 /*!
526  * @brief Get and clear the interrupt status.
527  *
528  * @param base MIPI DSI host peripheral base address.
529  * @param intGroup1 Group 1 interrupt status.
530  * @param intGroup2 Group 2 interrupt status.
531  */
DSI_GetAndClearInterruptStatus(const MIPI_DSI_Type * base,uint32_t * intGroup1,uint32_t * intGroup2)532 static inline void DSI_GetAndClearInterruptStatus(const MIPI_DSI_Type *base, uint32_t *intGroup1, uint32_t *intGroup2)
533 {
534     *intGroup2 = base->apb->IRQ_STATUS2;
535     *intGroup1 = base->apb->IRQ_STATUS;
536 }
537 
538 /*! @} */
539 
540 /*!
541  * @name MIPI DSI APB
542  * @{
543  */
544 
545 /*!
546  * @brief Configure the APB packet to send.
547  *
548  * This function configures the next APB packet transfer. After configuration,
549  * the packet transfer could be started with function @ref DSI_SendApbPacket.
550  * If the packet is long packet, Use @ref DSI_WriteApbTxPayload to fill the payload
551  * before start transfer.
552  *
553  * @param base MIPI DSI host peripheral base address.
554  * @param wordCount For long packet, this is the byte count of the payload.
555  * For short packet, this is (data1 << 8) | data0.
556  * @param virtualChannel Virtual channel.
557  * @param dataType The packet data type, (DI).
558  * @param flags The transfer control flags, see _dsi_transfer_flags.
559  */
560 void DSI_SetApbPacketControl(
561     const MIPI_DSI_Type *base, uint16_t wordCount, uint8_t virtualChannel, dsi_tx_data_type_t dataType, uint8_t flags);
562 
563 /*!
564  * @brief Fill the long APB packet payload.
565  *
566  * Write the long packet payload to TX FIFO.
567  *
568  * @param base MIPI DSI host peripheral base address.
569  * @param payload Pointer to the payload.
570  * @param payloadSize Payload size in byte.
571  */
572 void DSI_WriteApbTxPayload(const MIPI_DSI_Type *base, const uint8_t *payload, uint16_t payloadSize);
573 
574 /*!
575  * @brief Extended function to fill the payload to TX FIFO.
576  *
577  * Write the long packet payload to TX FIFO. This function could be used in two ways
578  *
579  * 1. Include the DSC command in parameter @p payload. In this case, the DSC command
580  *    is the first byte of @p payload. The parameter @p sendDscCmd is set to false,
581  *    the @p dscCmd is not used. This function is the same as @ref DSI_WriteApbTxPayload
582  *    when used in this way.
583  *
584  * 2. The DSC command in not in parameter @p payload, but specified by parameter @p dscCmd.
585  *    In this case, the parameter @p sendDscCmd is set to true, the @p dscCmd is the DSC
586  *    command to send. The @p payload is sent after @p dscCmd.
587  *
588  * @param base MIPI DSI host peripheral base address.
589  * @param payload Pointer to the payload.
590  * @param payloadSize Payload size in byte.
591  * @param sendDscCmd If set to true, the DSC command is specified by @p dscCmd,
592  *        otherwise the DSC command is included in the @p payload.
593  * @param dscCmd The DSC command to send, only used when @p sendDscCmd is true.
594  */
595 void DSI_WriteApbTxPayloadExt(
596     const MIPI_DSI_Type *base, const uint8_t *payload, uint16_t payloadSize, bool sendDscCmd, uint8_t dscCmd);
597 
598 /*!
599  * @brief Read the long APB packet payload.
600  *
601  * Read the long packet payload from RX FIFO. This function reads directly but
602  * does not check the RX FIFO status. Upper layer should make sure there are
603  * available data.
604  *
605  * @param base MIPI DSI host peripheral base address.
606  * @param payload Pointer to the payload.
607  * @param payloadSize Payload size in byte.
608  */
609 void DSI_ReadApbRxPayload(const MIPI_DSI_Type *base, uint8_t *payload, uint16_t payloadSize);
610 
611 /*!
612  * @brief Trigger the controller to send out APB packet.
613  *
614  * Send the packet set by @ref DSI_SetApbPacketControl.
615  *
616  * @param base MIPI DSI host peripheral base address.
617  */
DSI_SendApbPacket(const MIPI_DSI_Type * base)618 static inline void DSI_SendApbPacket(const MIPI_DSI_Type *base)
619 {
620     base->apb->SEND_PACKET = 0x1U;
621 }
622 
623 /*!
624  * @brief Get the APB status.
625  *
626  * The return value is OR'ed value of _dsi_apb_status.
627  *
628  * @param base MIPI DSI host peripheral base address.
629  * @return The APB status.
630  */
DSI_GetApbStatus(const MIPI_DSI_Type * base)631 static inline uint32_t DSI_GetApbStatus(const MIPI_DSI_Type *base)
632 {
633     return base->apb->PKT_STATUS;
634 }
635 
636 /*!
637  * @brief Get the error status during data transfer.
638  *
639  * The return value is OR'ed value of _dsi_rx_error_status.
640  *
641  * @param base MIPI DSI host peripheral base address.
642  * @return The error status.
643  */
DSI_GetRxErrorStatus(const MIPI_DSI_Type * base)644 static inline uint32_t DSI_GetRxErrorStatus(const MIPI_DSI_Type *base)
645 {
646     return base->host->RX_ERROR_STATUS;
647 }
648 
649 /*!
650  * @brief Get the one-bit RX ECC error position.
651  *
652  * When one-bit ECC RX error detected using @ref DSI_GetRxErrorStatus, this
653  * function could be used to get the error bit position.
654  *
655  * @code
656    uint8_t eccErrorPos;
657    uint32_t rxErrorStatus = DSI_GetRxErrorStatus(MIPI_DSI);
658    if (kDSI_RxErrorEccOneBit & rxErrorStatus)
659    {
660        eccErrorPos = DSI_GetEccRxErrorPosition(rxErrorStatus);
661    }
662    @endcode
663  *
664  * @param rxErrorStatus The error status returned by @ref DSI_GetRxErrorStatus.
665  * @return The 1-bit ECC error position.
666  */
DSI_GetEccRxErrorPosition(uint32_t rxErrorStatus)667 static inline uint8_t DSI_GetEccRxErrorPosition(uint32_t rxErrorStatus)
668 {
669     return (uint8_t)((rxErrorStatus >> 2U) & 0x1FU);
670 }
671 
672 /*!
673  * @brief Get and clear the DSI host status.
674  *
675  * The host status are returned as mask value of @ref _dsi_host_status.
676  *
677  * @param base MIPI DSI host peripheral base address.
678  * @return The DSI host status.
679  */
DSI_GetAndClearHostStatus(const MIPI_DSI_Type * base)680 static inline uint32_t DSI_GetAndClearHostStatus(const MIPI_DSI_Type *base)
681 {
682     return base->host->CFG_STATUS_OUT;
683 }
684 
685 /*!
686  * @brief Get the RX packet header.
687  *
688  * @param base MIPI DSI host peripheral base address.
689  * @return The RX packet header.
690  */
DSI_GetRxPacketHeader(const MIPI_DSI_Type * base)691 static inline uint32_t DSI_GetRxPacketHeader(const MIPI_DSI_Type *base)
692 {
693     return base->apb->PKT_RX_PKT_HEADER;
694 }
695 
696 /*!
697  * @brief Extract the RX packet type from the packet header.
698  *
699  * Extract the RX packet type from the packet header get by @ref DSI_GetRxPacketHeader.
700  *
701  * @param rxPktHeader The RX packet header get by @ref DSI_GetRxPacketHeader.
702  * @return The RX packet type.
703  */
DSI_GetRxPacketType(uint32_t rxPktHeader)704 static inline dsi_rx_data_type_t DSI_GetRxPacketType(uint32_t rxPktHeader)
705 {
706     return (dsi_rx_data_type_t)(uint8_t)((rxPktHeader >> 16U) & 0x3FU);
707 }
708 
709 /*!
710  * @brief Extract the RX packet word count from the packet header.
711  *
712  * Extract the RX packet word count from the packet header get by @ref DSI_GetRxPacketHeader.
713  *
714  * @param rxPktHeader The RX packet header get by @ref DSI_GetRxPacketHeader.
715  * @return For long packet, return the payload word count (byte). For short packet,
716  * return the (data0 << 8) | data1.
717  */
DSI_GetRxPacketWordCount(uint32_t rxPktHeader)718 static inline uint16_t DSI_GetRxPacketWordCount(uint32_t rxPktHeader)
719 {
720     return (uint16_t)(rxPktHeader & 0xFFFFU);
721 }
722 
723 /*!
724  * @brief Extract the RX packet virtual channel from the packet header.
725  *
726  * Extract the RX packet virtual channel from the packet header get by @ref DSI_GetRxPacketHeader.
727  *
728  * @param rxPktHeader The RX packet header get by @ref DSI_GetRxPacketHeader.
729  * @return The virtual channel.
730  */
DSI_GetRxPacketVirtualChannel(uint32_t rxPktHeader)731 static inline uint8_t DSI_GetRxPacketVirtualChannel(uint32_t rxPktHeader)
732 {
733     return (uint8_t)((rxPktHeader >> 22U) & 0x3U);
734 }
735 
736 /*!
737  * @brief APB data transfer using blocking method.
738  *
739  * Perform APB data transfer using blocking method. This function waits until all
740  * data send or received, or timeout happens.
741  *
742  * @param base MIPI DSI host peripheral base address.
743  * @param xfer Pointer to the transfer structure.
744  * @retval kStatus_Success Data transfer finished with no error.
745  * @retval kStatus_Timeout Transfer failed because of timeout.
746  * @retval kStatus_DSI_RxDataError RX data error, user could use @ref DSI_GetRxErrorStatus
747  * to check the error details.
748  * @retval kStatus_DSI_ErrorReportReceived Error Report packet received, user could use
749  *        @ref DSI_GetAndClearHostStatus to check the error report status.
750  * @retval kStatus_DSI_NotSupported Transfer format not supported.
751  * @retval kStatus_DSI_Fail Transfer failed for other reasons.
752  */
753 status_t DSI_TransferBlocking(const MIPI_DSI_Type *base, dsi_transfer_t *xfer);
754 
755 /*! @} */
756 
757 /*!
758  * @name Transactional
759  * @{
760  */
761 
762 /*!
763  * @brief Create the MIPI DSI handle.
764  *
765  * This function initializes the MIPI DSI handle which can be used for other transactional APIs.
766  *
767  * @param base MIPI DSI host peripheral base address.
768  * @param handle Handle pointer.
769  * @param callback Callback function.
770  * @param userData User data.
771  */
772 status_t DSI_TransferCreateHandle(const MIPI_DSI_Type *base,
773                                   dsi_handle_t *handle,
774                                   dsi_callback_t callback,
775                                   void *userData);
776 
777 /*!
778  * @brief APB data transfer using interrupt method.
779  *
780  * Perform APB data transfer using interrupt method, when transfer finished,
781  * upper layer could be informed through callback function.
782  *
783  * @param base MIPI DSI host peripheral base address.
784  * @param handle pointer to dsi_handle_t structure which stores the transfer state.
785  * @param xfer Pointer to the transfer structure.
786  *
787  * @retval kStatus_Success Data transfer started successfully.
788  * @retval kStatus_DSI_Busy Failed to start transfer because DSI is busy with pervious transfer.
789  * @retval kStatus_DSI_NotSupported Transfer format not supported.
790  */
791 status_t DSI_TransferNonBlocking(const MIPI_DSI_Type *base, dsi_handle_t *handle, dsi_transfer_t *xfer);
792 
793 /*!
794  * @brief Abort current APB data transfer.
795  *
796  * @param base MIPI DSI host peripheral base address.
797  * @param handle pointer to dsi_handle_t structure which stores the transfer state.
798  */
799 void DSI_TransferAbort(const MIPI_DSI_Type *base, dsi_handle_t *handle);
800 
801 /*!
802  * @brief Interrupt handler for the DSI.
803  *
804  * @param base MIPI DSI host peripheral base address.
805  * @param handle pointer to dsi_handle_t structure which stores the transfer state.
806  */
807 void DSI_TransferHandleIRQ(const MIPI_DSI_Type *base, dsi_handle_t *handle);
808 
809 /*! @} */
810 
811 #if defined(__cplusplus)
812 }
813 #endif
814 
815 /*! @} */
816 
817 #endif /* _FSL_MIPI_DSI_H_ */
818