1 /*
2  * Copyright (c) 2019-2021,2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef FSL_LCDIF_H_
8 #define FSL_LCDIF_H_
9 
10 #include "fsl_common.h"
11 
12 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
13 #include "fsl_memory.h"
14 #endif
15 
16 /*!
17  * @addtogroup lcdif_driver
18  * @{
19  */
20 
21 /*******************************************************************************
22  * Definitions
23  ******************************************************************************/
24 
25 /*! @name Driver version */
26 /*! @{ */
27 #define FSL_LCDIF_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
28 /*! @} */
29 
30 /*! @brief Construct the cursor color, every element should be in the range of 0 ~ 255. */
31 #define LCDIF_MAKE_CURSOR_COLOR(r, g, b) (((r) << 16U) | ((g) << 8U) | ((b) << 0U))
32 
33 /*! @brief Construct the gamma value set to LCDIF gamma table, every element should be in the range of 0~255. */
34 #define LCDIF_MAKE_GAMMA_VALUE(r, g, b) (((r) << 16U) | ((g) << 8U) | ((b) << 0U))
35 
36 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
37 /*! @brief Construct the colour value for the background layer. */
38 #define LCDIF_MAKE_BACKGROUND_VALUE(a, r, g, b) (((a) << 24U) | ((r) << 16U) | ((g) << 8U) | ((b) << 0U))
39 #endif
40 
41 /*! @brief Calculate the aligned address for LCDIF buffer. */
42 #define LCDIF_ALIGN_ADDR(addr, align) ((((addr) / (align) * (align)) == (addr)) ? (addr) : ((addr) / (align) * (align) + (align)))
43 
44 /*! @brief The frame buffer should be 128 byte aligned. */
45 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
46 #define LCDIF_FB_ALIGN    64U
47 #define LCDIF_FB_UV_ALIGN 32U
48 #else
49 #define LCDIF_FB_ALIGN 128U
50 #endif
51 
52 /*! @brief Gamma index max value. */
53 #define LCDIF_GAMMA_INDEX_MAX 256U
54 
55 /*! @brief The cursor size is 32 x 32 */
56 #define LCDIF_CURSOR_SIZE 32U
57 
58 #ifndef LCDIF_FRAMEBUFFERCONFIG0_OUTPUT_MASK
59 #define LCDIF_FRAMEBUFFERCONFIG0_OUTPUT_MASK (1U << 8U)
60 #endif
61 
62 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
63 #define LCDIF_ADDR_CPU_2_IP(addr) (MEMORY_ConvertMemoryMapAddress((uint32_t)(addr), kMEMORY_Local2DMA))
64 #else
65 #define LCDIF_ADDR_CPU_2_IP(addr) ((uint32_t)addr)
66 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
67 
68 /*!
69  * @brief LCDIF signal polarity flags
70  */
71 enum _lcdif_polarity_flags
72 {
73     kLCDIF_VsyncActiveLow            = 0U,         /*!< VSYNC active low. */
74     kLCDIF_VsyncActiveHigh           = (1U << 0U), /*!< VSYNC active high. */
75     kLCDIF_HsyncActiveLow            = 0U,         /*!< HSYNC active low. */
76     kLCDIF_HsyncActiveHigh           = (1U << 1U), /*!< HSYNC active high. */
77     kLCDIF_DataEnableActiveLow       = 0U,         /*!< Data enable line active low. */
78     kLCDIF_DataEnableActiveHigh      = (1U << 2U), /*!< Data enable line active high. */
79     kLCDIF_DriveDataOnFallingClkEdge = 0U, /*!< Drive data on falling clock edge, capture data on rising clock edge. */
80     kLCDIF_DriveDataOnRisingClkEdge  = (1U << 3U), /*!< Drive data on falling clock edge, capture data
81                                                                          on rising clock edge. */
82 };
83 
84 /*! @brief LCDIF DPI output format. */
85 typedef enum _lcdif_output_format
86 {
87     kLCDIF_Output16BitConfig1 = 0U, /*!< 16-bit configuration 1. RGB565: XXXXXXXX_RRRRRGGG_GGGBBBBB. */
88     kLCDIF_Output16BitConfig2 = 1U, /*!< 16-bit configuration 2. RGB565: XXXRRRRR_XXGGGGGG_XXXBBBBB. */
89     kLCDIF_Output16BitConfig3 = 2U, /*!< 16-bit configuration 3. RGB565: XXRRRRRX_XXGGGGGG_XXBBBBBX. */
90     kLCDIF_Output18BitConfig1 = 3U, /*!< 18-bit configuration 1. RGB666: XXXXXXRR_RRRRGGGG_GGBBBBBB. */
91     kLCDIF_Output18BitConfig2 = 4U, /*!< 18-bit configuration 2. RGB666: XXRRRRRR_XXGGGGGG_XXBBBBBB. */
92     kLCDIF_Output24Bit        = 5U, /*!< 24-bit. */
93 } lcdif_output_format_t;
94 
95 /*! @brief Configuration for LCDIF module to work in DBI mode. */
96 typedef struct _lcdif_dpi_config
97 {
98     uint16_t panelWidth;          /*!< Display panel width, pixels per line. */
99     uint16_t panelHeight;         /*!< Display panel height, how many lines per panel. */
100     uint8_t hsw;                  /*!< HSYNC pulse width. */
101     uint8_t hfp;                  /*!< Horizontal front porch. */
102     uint8_t hbp;                  /*!< Horizontal back porch. */
103     uint8_t vsw;                  /*!< VSYNC pulse width. */
104     uint8_t vfp;                  /*!< Vrtical front porch. */
105     uint8_t vbp;                  /*!< Vertical back porch. */
106     uint32_t polarityFlags;       /*!< OR'ed value of @ref _lcdif_polarity_flags, used to contol the signal polarity. */
107     lcdif_output_format_t format; /*!< DPI output format. */
108 } lcdif_dpi_config_t;
109 
110 /*! @brief LCDIF frame buffer pixel format. */
111 typedef enum _lcdif_fb_format
112 {
113 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
114     kLCDIF_PixelFormatARGB4444      = 1,          /*!< ARGB4444, 16-bit each pixel, 4-bit each element. */
115     kLCDIF_PixelFormatARGB1555      = 2,          /*!< ARGB1555, 16-bit each pixel, 5-bit each element. */
116     kLCDIF_PixelFormatRGB565        = 3,          /*!< RGB565, 16-bit each pixel. */
117     kLCDIF_PixelFormatARGB8888      = 4,          /*!< ARGB8888, 32-bit each pixel, 8-bit each element. */
118     kLCDIF_PixelFormatRGB888        = 5,          /*!< RGB888, 24-bit each pixel, 8-bit each element. */
119     kLCDIF_PixelFormatARGB8565      = 6,          /*!< ARGB8565, 24-bit each pixel. */
120     kLCDIF_PixelFormatARGB8888Tiled = 0x1U << 3U, /*!< ARGB8888, 32-bit each pixel, 8-bit each element in tiled format,
121                                                      not supported in overlay layer 1. */
122     kLCDIF_PixelFormatYUV422Tiled = 0x2U << 3U,   /*!< YUV422, in tiled format, not supported in overlay layer 1. */
123     kLCDIF_PixelFormatYUV420Tiled =
124         0x3U << 3U, /*!< YUV420, in tiled format, need 2 plane, not supported in overlay layer 1. */
125     kLCDIF_PixelFormatRGB888Tiled =
126         0x8U
127         << 3U, /*!< RGB888, 24-bit each pixel, 8-bit each element in tiled format, not supported in overlay layer 1. */
128     kLCDIF_PixelFormatARGB8565Tiled =
129         0x9U << 3U, /*!< ARGB8565, 24-bit each pixel in tiled format, not supported in overlay layer 1. */
130 #else
131     kLCDIF_PixelFormatXRGB444  = 1, /*!< XRGB4444, deprecated, use kLCDIF_PixelFormatXRGB4444 instead. */
132     kLCDIF_PixelFormatXRGB4444 = 1, /*!< XRGB4444, 16-bit each pixel, 4-bit each element. R4G4B4 in reference manual. */
133     kLCDIF_PixelFormatXRGB1555 = 2, /*!< XRGB1555, 16-bit each pixel, 5-bit each element. R5G5B5 in reference manual. */
134     kLCDIF_PixelFormatRGB565   = 3, /*!< RGB565, 16-bit each pixel. R5G6B5 in reference manual. */
135     kLCDIF_PixelFormatXRGB8888 = 4, /*!< XRGB8888, 32-bit each pixel, 8-bit each element. R8G8B8 in reference manual. */
136 #endif
137 } lcdif_fb_format_t;
138 
139 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
140 /*! @brief LCDIF layer input pixel order. */
141 typedef enum _lcdif_layer_input_order
142 {
143     kLCDIF_PixelInputOrderARGB = 0, /*!< Input order ARGB. */
144     kLCDIF_PixelInputOrderRGBA = 1, /*!< Input order RGBA. */
145     kLCDIF_PixelInputOrderABGR = 2, /*!< Input order ABGR. */
146     kLCDIF_PixelInputOrderBGRA = 3, /*!< Input order BGRA. */
147 } lcdif_layer_input_order_t;
148 
149 /*! @brief LCDIF layer rotation or flip configuration. */
150 typedef enum _lcdif_layer_rotate_flip
151 {
152     kLCDIF_Rotate0        = 0U, /*!< Clock wise rotate 0 degree. */
153     kLCDIF_Rotate90       = 1U, /*!< Clock wise rotate 90 degree, not supported yet. */
154     kLCDIF_Rotate180      = 2U, /*!< Clock wise rotate 180 degree. */
155     kLCDIF_Rotate270      = 3U, /*!< Clock wise rotate 270 degree, not supported yet. */
156     kLCDIF_FlipHorizontal = 4U, /*!< Horizontal flip. */
157     kLCDIF_FlipVertical   = 5U, /*!< Vertical flip. */
158 } lcdif_layer_rotate_flip_t;
159 
160 /*! @brief LCDIF layer color key configuration. */
161 typedef struct _lcdif_layer_colorkey
162 {
163     bool enable;        /*!< Enable the color keying. */
164     uint32_t lowValue;  /* The low value for the color key range, in 32-bit ARGB8888 format. */
165     uint32_t highValue; /* The high value for the color key range, in 32-bit ARGB8888 format. */
166 } lcdif_layer_colorkey_t;
167 
168 /*!
169  * @brief Alpha blend alpha component mode.
170  * @anchor lcdif_layer_alpha_mode_t
171  */
172 enum
173 {
174     kLCDIF_AlphaStraight = 0U, /*!< Use straight alpha, s0_alpha' = s0_alpha. */
175     kLCDIF_AlphaInversed       /*!< Use inversed alpha, s0_alpha' = 0xFF - s0_alpha. */
176 };
177 
178 /*! @brief LCDIF layer global alpha mode for alpha blend.
179  *  @anchor lcdif_layer_global_alpha_mode_t
180  */
181 enum
182 {
183     kLCDIF_AlphaLocal = 0U, /*!< Use the alpha(or inversed alpha) component directly. */
184     kLCDIF_AlphaGlobal,     /*!< Use the global alpha instead. */
185     kLCDIF_AlphaScaled,     /*!< Multiply the alpha(or inversed alpha) component by the global alpha. */
186 };
187 
188 /*!
189  * @brief Alpha blend factor mode.
190  * @anchor lcdif_layer_alpha_factor_mode_t
191  */
192 enum
193 {
194     kLCDIF_AlphaFactorZero     = 0, /*!< Use 0 as the blending factor. */
195     kLCDIF_AlphaFactorOne      = 1, /*!< Use 1 as the blending factor. */
196     kLCDIF_AlphaFactorStraight = 2, /*!< Use the modified alpha component(As'' for source layer or Ad'' for destination
197                                        layer) as the blending factor. */
198     kLCDIF_AlphaFactorInversed = 3, /*!< Use the inversed alpha component(1-As'' for source layer or 1-Ad'' for
199                                        destination layer) as the blending factor. */
200 };
201 
202 /*! @brief LCDIF frame buffer alpha blend configuration.
203  *
204  * The alpha blending formula is C = Fs x Cs + Fd x Cd, and A = Fs x As'' + Fd x Ad''.
205  * C/A: generated final color/alpha component,
206  * Cs/Cd: original color component for source and destination layer,
207  * As''/Ad'': modified alpha component for source and destination layer, take As'' as example,
208  *            As' = As or (1 - As), chosen by srcAlphaMode
209  *            As'' = As' or Ags or (As' x Ags), chosen by srcGlobalAlphaMode, Ags configured by srcGlobalAlpha
210  * Fs/Fd: blending factor for source/destination layer, take Fs as example,
211  *        Fs = 0 or 1 or As'' or (1 - As''), chosen by srcFactorMode
212  */
213 typedef struct
214 {
215     uint32_t enable : 1;       /*!< Enables or disables alpha blend configuration. */
216     uint32_t srcAlphaMode : 1; /*!< Use the straight(As) or inversed(1-As) alpha value for modified alpha for the source
217                                   layer, see @ref lcdif_layer_alpha_mode_t. */
218     uint32_t : 1;
219     uint32_t srcGlobalAlphaMode : 2; /*!< Source layer global alpha mode, see @ref lcdif_layer_global_alpha_mode_t. */
220     uint32_t : 1;
221     uint32_t srcFactorMode : 2;      /*!< Source layer blend factor mode, see @ref lcdif_layer_alpha_factor_mode_t. */
222     uint32_t useSrcAlpha : 1;   /*!< Set to true to use source alpha for the source blending factor, otherwise use the
223                                    destination alpha. */
224     uint32_t dstAlphaMode : 1;  /*!< Use the straight(Ad) or inversed(1-Ad) alpha value for modified alpha for the
225                                    destination layer, see @ref lcdif_layer_alpha_mode_t. */
226     uint32_t
227         dstGlobalAlphaMode : 2; /*!< Destination layer global alpha mode, see @ref lcdif_layer_global_alpha_mode_t. */
228     uint32_t : 1;
229     uint32_t dstFactorMode : 2; /*!< Destination layer blend factor mode, see @ref lcdif_layer_alpha_factor_mode_t. */
230     uint32_t useDstAlpha : 1;   /*!< Set to true to use destination alpha for the destination blending factor, otherwise
231                                    use the source alpha. */
232     uint32_t srcGlobalAlpha : 8; /*!< Source layer global alpha value, 0~255. */
233     uint32_t dstGlobalAlpha : 8; /*!< Destination layer global alpha value, 0~255. */
234 } lcdif_layer_alpha_blend_config_t;
235 
236 /*! @brief LCDIF Porter Duff blend mode. Note: don't change the enum item value */
237 typedef enum _lcdif_porter_duff_blend_mode
238 {
239     kLCDIF_PorterDuffSrc = 0, /*!< Source Only */
240     kLCDIF_PorterDuffAtop,    /*!< Source Atop */
241     kLCDIF_PorterDuffOver,    /*!< Source Over */
242     kLCDIF_PorterDuffIn,      /*!< Source In. */
243     kLCDIF_PorterDuffOut,     /*!< Source Out. */
244     kLCDIF_PorterDuffDst,     /*!< Destination Only. */
245     kLCDIF_PorterDuffDstAtop, /*!< Destination Atop. */
246     kLCDIF_PorterDuffDstOver, /*!< Destination Over. */
247     kLCDIF_PorterDuffDstIn,   /*!< Destination In. */
248     kLCDIF_PorterDuffDstOut,  /*!< Destination Out. */
249     kLCDIF_PorterDuffPlus,    /*!< Clear. */
250     kLCDIF_PorterDuffXor,     /*!< XOR. */
251     kLCDIF_PorterDuffClear,   /*!< Clear. */
252     kLCDIF_PorterDuffMax,
253 } lcdif_porter_duff_blend_mode_t;
254 
255 /*! @brief LCDIF Color space convert standard between RGB and YUV when the input format is tiled YUV. */
256 typedef enum _lcdif_layer_convert_standard
257 {
258     kLCDIF_ConvertBT601 = 0x0U, /*!< Use standard BT601. */
259     kLCDIF_ConvertBT709 = 0x1U, /*!< Use standard BT709. */
260 } lcdif_layer_convert_standard_t;
261 
262 /*! @brief LCDIF frame buffer configuration.
263  *
264  * For LCDIF of DC8000 version, there are 3 layers in the pre-processing,
265  * all shares the same frame buffer configuration.
266  */
267 typedef struct _lcdif_fb_config
268 {
269     bool enable;      /*!< Enable the layer output. */
270     bool enableClear; /*!< Enable the color clear for this layer, onve enabled, the whole layer will be filled with the
271                          color configured in clearValue. */
272     uint32_t clearValue;                     /*!< The value used for layer clear. */
273     lcdif_fb_format_t format;                /*!< Frame buffer output pixel format. */
274     lcdif_layer_convert_standard_t standard; /*!< Color space convert standard, not used for overlay layer 1 since it
275                                                 does not support tile YUV input. */
276     bool enableUVSwizzle; /*!< Swizzle the U/V components, not used for overlay layer 1 since it does not support tile
277                              YUV input. */
278     lcdif_layer_input_order_t inOrder;        /*!< Color component order of the input pixel. */
279     lcdif_layer_colorkey_t colorkey;          /*!< Color key configuration. */
280     lcdif_layer_rotate_flip_t rotateFlipMode; /*!< LCDIF frame buffer rotation or flip configuration. */
281     lcdif_layer_alpha_blend_config_t alpha;   /*!< The alpha blending configuration. */
282     /* The background layer with a constant color is used, the other layers do not need to fill the whole screen. */
283     uint16_t topLeftX; /*!< The x value of thr top-left coordinate. */
284     uint16_t topLeftY; /*!< The y value of thr top-left coordinate. */
285     uint16_t width;    /*!< The width of the layer. */
286     uint16_t height;   /*!< The height of the layer. */
287 } lcdif_fb_config_t;
288 
289 /*! @brief LCDIF the layer order from bottom to top.
290  *
291  * There are 5 layers in total, apart from the background layer fixed in the bottom, and the cursor
292  * layer on top that does not participate in the color key and alpha blend, the order of the other 3 layers
293  * video/graphic layer, overlay layer 0 and 1 can be changed. During color key or alpha blend process, between
294  * 2 adjacent layers, the lower layer is considered as destination layer and the upper layer is considered
295  * as source layer. The precess is performed from bottom to top, after processing 2 layes, the generated new
296  * layer will be considered as destination layer then participate in the next process with the next upper layer.
297  */
298 typedef enum _lcdif_layer_order
299 {
300     kLCDIF_VideoOverlay0Overlay1 = 0U, /*!< In the order of video, overlay0, overlay1. */
301     kLCDIF_VideoOverlay1Overlay0 = 1U, /*!< In the order of video, overlay1, overlay0. */
302     kLCDIF_Overlay0VideoOverlay1 = 2U, /*!< In the order of overlay0, video, overlay1. */
303     kLCDIF_Overlay0Overlay1Video = 3U, /*!< In the order of overlay0, overlay1, video. */
304     kLCDIF_Overlay1VideoOverlay0 = 4U, /*!< In the order of overlay1, video, overlay0. */
305     kLCDIF_Overlay1Overlay0Video = 5U, /*!< In the order of overlay1, overlay0, video. */
306 } lcdif_layer_order_t;
307 
308 /*! @brief LCDIF the pixel source endian mode. */
309 typedef enum _lcdif_endian_mode
310 {
311     kLCDIF_NoSwap       = 0U, /*!< No swap. */
312     kLCDIF_HalfWordSwap = 1U, /*!< 16-bit boundary swap, from 0123 to 1032. */
313     kLCDIF_WordSwap     = 2U, /*!< 32-bit boundary swap, from 0123 to 3210. */
314 } lcdif_endian_mode_t;
315 
316 /*! @brief LCDIF panel configuration. */
317 typedef struct _lcdif_panel_config
318 {
319     bool enable;                /*!< Enable the frame buffer output. */
320     bool enableGamma;           /*!< Enable the gamma correction. */
321     lcdif_layer_order_t order;  /*!< Layer order. */
322     lcdif_endian_mode_t endian; /*!< Pixel source endian mode. */
323 } lcdif_panel_config_t;
324 #else
325 /*! @brief LCDIF frame buffer configuration. */
326 typedef struct _lcdif_fb_config
327 {
328     bool enable;              /*!< Enable the frame buffer output. */
329     bool enableGamma;         /*!< Enable the gamma correction. */
330     lcdif_fb_format_t format; /*!< Frame buffer pixel format. */
331 } lcdif_fb_config_t;
332 #endif
333 
334 /*! @brief LCDIF interrupt and status. */
335 enum _lcdif_interrupt
336 {
337     kLCDIF_Display0FrameDoneInterrupt =
338         LCDIF_DISPLAYINTR_DISP0_MASK, /*!< The last pixel of visible area in frame is shown. */
339 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
340     kLCDIF_Display0DbiConfigErrorInterrupt =
341         LCDIF_DISPLAYINTR_DISP0_DBI_CFG_ERROR_MASK,                          /*!< The DBI command is illegal. */
342     kLCDIF_PanelUnderflowInterrupt = LCDIF_DISPLAYINTR_PANEL_UNDERFLOW_MASK, /*!< The AXI clock and pixel clock mismatch
343                                                                                 causing data supply insufficient. */
344     kLCDIF_SoftwareResetDoneInterrupt = LCDIF_DISPLAYINTR_SOFT_RESET_DONE_MASK, /*!< A software reset has completed. */
345     kLCDIF_BusErrorInterrupt          = LCDIF_DISPLAYINTR_BUS_ERROR_MASK, /*!< An AXI bus transfer error occurrs. */
346 #endif
347 };
348 
349 /*! @brief LCDIF cursor format. */
350 typedef enum _lcdif_cursor_format
351 {
352     kLCDIF_CursorMasked   = 1, /*!< Masked format. */
353     kLCDIF_CursorARGB8888 = 2, /*!< ARGB8888. */
354 } lcdif_cursor_format_t;
355 
356 /*! @brief LCDIF cursor configuration. */
357 typedef struct _lcdif_cursor_config
358 {
359     bool enable;                  /*!< Enable the cursor or not. */
360     lcdif_cursor_format_t format; /*!< Cursor format. */
361     uint8_t hotspotOffsetX;       /*!< Offset of the hotspot to top left point, range 0 ~ 31 */
362     uint8_t hotspotOffsetY;       /*!< Offset of the hotspot to top left point, range 0 ~ 31 */
363 } lcdif_cursor_config_t;
364 
365 /*!
366  * @brief LCDIF dither configuration.
367  *
368  * 1. Decide which bit of pixel color to enhance. This is configured by the
369  * @ref lcdif_dither_config_t::redSize, @ref lcdif_dither_config_t::greenSize,
370  * and @ref lcdif_dither_config_t::blueSize. For example, setting redSize=6
371  * means it is the 6th bit starting from the MSB that we want to enhance, in other words,
372  * it is the RedColor[2]bit from RedColor[7:0]. greenSize and blueSize function
373  * in the same way.
374  *
375  * 2. Create the look-up table.
376  *  a. The Look-Up Table includes 16 entries, 4 bits for each.
377  *  b. The Look-Up Table provides a value U[3:0] through the index X[1:0] and Y[1:0].
378  *  c. The color value RedColor[3:0] is used to compare with this U[3:0].
379  *  d. If RedColor[3:0] > U[3:0], and RedColor[7:2] is not 6'b111111, then the
380  *     final color value is: NewRedColor = RedColor[7:2] + 1'b1.
381  *  e. If RedColor[3:0] <= U[3:0], then NewRedColor = RedColor[7:2].
382  */
383 typedef struct _lcdif_dither_config
384 {
385     bool enable;       /*!< Enable or not. */
386 #if !(defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000)
387     uint8_t redSize;   /*!< Red color size, valid region 4-8. */
388     uint8_t greenSize; /*!< Green color size, valid region 4-8. */
389     uint8_t blueSize;  /*!< Blue color size, valid region 4-8. */
390 #endif
391     uint32_t low;      /*!< Low part of the look up table. */
392     uint32_t high;     /*!< High part of the look up table. */
393 } lcdif_dither_config_t;
394 
395 /*! @brief LCDIF DBI command flag. */
396 enum _lcdif_dbi_cmd_flag
397 {
398     kLCDIF_DbiCmdAddress = 0U, /*!< Send address (or command). */
399     kLCDIF_DbiCmdWriteMem,     /*!< Start write memory. */
400     kLCDIF_DbiCmdData,         /*!< Send data. */
401     kLCDIF_DbiCmdReadMem,      /*!< Start read memory. */
402 };
403 
404 /*! @brief LCDIF DBI output format. */
405 typedef enum _lcdif_dbi_out_format
406 {
407     /*! 8-bit data bus width, pixel RGB332. For type A or B. 1 pixel sent in 1 cycle. */
408     kLCDIF_DbiOutD8RGB332 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(0),
409     /*! 8-bit data bus width, pixel RGB444. For type A or B. 2 pixels sent in 3 cycles. */
410     kLCDIF_DbiOutD8RGB444 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(1),
411     /*! 8-bit data bus width, pixel RGB565. For type A or B. 1 pixel sent in 2 cycles. */
412     kLCDIF_DbiOutD8RGB565 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(2),
413     /*! 8-bit data bus width, pixel RGB666. For type A or B. 1 pixel sent in 3 cycles, data bus 2 LSB not used. */
414     kLCDIF_DbiOutD8RGB666 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(3),
415     /*! 8-bit data bus width, pixel RGB888. For type A or B. 1 pixel sent in 3 cycles. */
416     kLCDIF_DbiOutD8RGB888 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(4),
417     /*! 9-bit data bus width, pixel RGB666. For type A or B. 1 pixel sent in 2 cycles. */
418     kLCDIF_DbiOutD9RGB666 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(5),
419     /*! 16-bit data bus width, pixel RGB332. For type A or B. 2 pixels sent in 1 cycle. */
420     kLCDIF_DbiOutD16RGB332 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(6),
421     /*! 16-bit data bus width, pixel RGB444. For type A or B. 1 pixel sent in 1 cycle, data bus 4 MSB not used. */
422     kLCDIF_DbiOutD16RGB444 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(7),
423     /*! 16-bit data bus width, pixel RGB565. For type A or B. 1 pixel sent in 1 cycle. */
424     kLCDIF_DbiOutD16RGB565 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(8),
425     /*! 16-bit data bus width, pixel RGB666. For type A or B. 2 pixels sent in 3 cycles. */
426     kLCDIF_DbiOutD16RGB666Option1 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(9),
427     /*! 16-bit data bus width, pixel RGB666. For type A or B. 1 pixel sent in 2 cycles. */
428     kLCDIF_DbiOutD16RGB666Option2 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(10),
429     /*! 16-bit data bus width, pixel RGB888. For type A or B. 2 pixels sent in 3 cycles. */
430     kLCDIF_DbiOutD16RGB888Option1 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(11),
431     /*! 16-bit data bus width, pixel RGB888. For type A or B. 1 pixel sent in 2 cycles. */
432     kLCDIF_DbiOutD16RGB888Option2 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(12),
433 
434 #if (defined(FSL_FEATURE_LCDIF_HAS_TYPEC) && FSL_FEATURE_LCDIF_HAS_TYPEC)
435     /*! 1-bit data bus width, pixel RGB565. For type C option 1, use extra bit to distinguish Data and Command (DC). */
436     kLCDIF_DbiOutD1RGB565Option1 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(13) | LCDIF_DBICONFIG0_DBI_TYPEC_OPT(1),
437     /*! 1-bit data bus width, pixel RGB565. For type C option 2, use extra byte to distinguish Data and Command (DC). */
438     kLCDIF_DbiOutD1RGB565Option2 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(13) | LCDIF_DBICONFIG0_DBI_TYPEC_OPT(2),
439     /*! 1-bit data bus width, pixel RGB565. For type C option 3, use extra DC line to distinguish Data and Command (DC).
440      */
441     kLCDIF_DbiOutD1RGB565Option3 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(13) | LCDIF_DBICONFIG0_DBI_TYPEC_OPT(3),
442     /*! 1-bit data bus width, pixel RGB888. For type C option 1, use extra bit to distinguish Data and Command (DC). */
443     kLCDIF_DbiOutD1RG888Option1 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(14) | LCDIF_DBICONFIG0_DBI_TYPEC_OPT(1),
444     /*! 1-bit data bus width, pixel RGB888. For type C option 2, use extra byte to distinguish Data and Command (DC). */
445     kLCDIF_DbiOutD1RG888Option2 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(14) | LCDIF_DBICONFIG0_DBI_TYPEC_OPT(2),
446     /*! 1-bit data bus width, pixel RGB888. For type C option 3, use extra DC line to distinguish Data and Command (DC).
447      */
448     kLCDIF_DbiOutD1RG888Option3 = LCDIF_DBICONFIG0_DBI_DATA_FORMAT(14) | LCDIF_DBICONFIG0_DBI_TYPEC_OPT(3),
449 #endif
450 } lcdif_dbi_out_format_t;
451 
452 /*! @brief LCDIF DBI type. */
453 typedef enum _lcdif_dbi_type
454 {
455     kLCDIF_DbiTypeA_FixedE   = 0U, /*!< Selects DBI type A fixed E mode, 68000, Motorola mode. */
456     kLCDIF_DbiTypeA_ClockedE = 1U, /*!< Selects DBI Type A Clocked E mode, 68000, Motorola mode. */
457     kLCDIF_DbiTypeB          = 2U, /*!< Selects DBI type B, 8080, Intel mode. */
458 #if (defined(FSL_FEATURE_LCDIF_HAS_TYPEC) && FSL_FEATURE_LCDIF_HAS_TYPEC)
459     kLCDIF_DbiTypeC = 3U,          /*!< Selects DBI type C, SPI mode. */
460 #endif
461 } lcdif_dbi_type_t;
462 
463 /*! @brief LCDIF DBI output swizzle. */
464 typedef enum _lcdif_dbi_out_swizzle
465 {
466     kLCDIF_DbiOutSwizzleRGB = 0U, /*!< RGB */
467     kLCDIF_DbiOutSwizzleBGR = 1U, /*!< BGR */
468 } lcdif_dbi_out_swizzle_t;
469 
470 /*! @brief LCDIF DBI configuration. */
471 typedef struct _lcdif_dbi_config
472 {
473     lcdif_dbi_out_swizzle_t swizzle; /*!< Swizzle. */
474     lcdif_dbi_out_format_t format;   /*!< Output format. */
475     uint8_t acTimeUnit;              /*!< Time unit for AC characteristics. */
476     lcdif_dbi_type_t type;           /*!< DBI type. */
477 #if (defined(FSL_FEATURE_LCDIF_HAS_DBIX_POLARITY) && FSL_FEATURE_LCDIF_HAS_DBIX_POLARITY)
478     bool reversePolarity;            /*!< Reverse the DC pin polarity. */
479 #endif
480 
481     /*! WR signal period, Cycle number = writeWRPeriod * (acTimeUnit + 1), must be no less than 3.
482      * Only for type A and type b.
483      */
484     uint16_t writeWRPeriod;
485     /*! Cycle number = writeWRAssert * (acTimeUnit + 1), only for type A and type B.
486      * With kLCDIF_DbiTypeA_FixedE: Not used.
487      * With kLCDIF_DbiTypeA_ClockedE: Time to assert E.
488      * With kLCDIF_DbiTypeB: Time to assert WRX.
489      */
490     uint8_t writeWRAssert;
491 
492     /*! Cycle number = writeCSAssert * (acTimeUnit + 1), only for type A and type B.
493      * With kLCDIF_DbiTypeA_FixedE: Time to assert CSX.
494      * With kLCDIF_DbiTypeA_ClockedE: Not used.
495      * With kLCDIF_DbiTypeB: Time to assert CSX.
496      */
497     uint8_t writeCSAssert;
498 
499     /*! Cycle number = writeWRDeassert * (acTimeUnit + 1), only for type A and type B.
500      * With kLCDIF_DbiTypeA_FixedE: Not used.
501      * With kLCDIF_DbiTypeA_ClockedE: Time to de-assert E.
502      * With kLCDIF_DbiTypeB: Time to de-assert WRX.
503      */
504     uint16_t writeWRDeassert;
505 
506     /*! Cycle number = writeCSDeassert * (acTimeUnit + 1), only for type A and type B.
507      * With kLCDIF_DbiTypeA_FixedE: Time to de-assert CSX.
508      * With kLCDIF_DbiTypeA_ClockedE: Not used.
509      * With kLCDIF_DbiTypeB: Time to de-assert CSX.
510      */
511     uint16_t writeCSDeassert;
512 
513 #if (defined(FSL_FEATURE_LCDIF_HAS_TYPEC) && FSL_FEATURE_LCDIF_HAS_TYPEC)
514     /* Type C AC configuration. */
515     uint8_t typeCTas;     /*!< How many sdaClk cycles in Tas phase, only for Type C option 3, at least 1. */
516     uint8_t typeCSCLTwrl; /*!< How many sdaClk cycles in Twrl phase, only for Type C, at least 1. */
517     uint8_t typeCSCLTwrh; /*!< How many sdaClk cycles in Twrh phase, only for Type C, at least 1. */
518 #endif
519 } lcdif_dbi_config_t;
520 
521 /*******************************************************************************
522  * API
523  ******************************************************************************/
524 
525 #if defined(__cplusplus)
526 extern "C" {
527 #endif
528 
529 /*!
530  * @name Initialization and deinitialization
531  * @{
532  */
533 
534 /*!
535  * @brief Initialize the LCDIF.
536  *
537  * This function initializes the LCDIF to work.
538  *
539  * @param base LCDIF peripheral base address.
540  *
541  * @retval kStatus_Success Initialize successfully.
542  */
543 status_t LCDIF_Init(LCDIF_Type *base);
544 
545 /*!
546  * @brief De-initialize the LCDIF.
547  *
548  * This function disables the LCDIF peripheral clock.
549  *
550  * @param base LCDIF peripheral base address.
551  */
552 void LCDIF_Deinit(LCDIF_Type *base);
553 
554 /*! @} */
555 
556 /*!
557  * @name DPI mode
558  * @{
559  */
560 
561 /*!
562  * @brief Get the default configuration for to initialize the LCDIF.
563  *
564  * The default configuration value is:
565  *
566  * @code
567    config->panelWidth = 0;
568    config->panelHeight = 0;
569    config->hsw = 0;
570    config->hfp = 0;
571    config->hbp = 0;
572    config->vsw = 0;
573    config->vfp = 0;
574    config->vbp = 0;
575    config->polarityFlags = kLCDIF_VsyncActiveLow | kLCDIF_HsyncActiveLow | kLCDIF_DataEnableActiveHigh |
576    kLCDIF_DriveDataOnFallingClkEdge; config->format = kLCDIF_Output24Bit;
577    @endcode
578  *
579  * @param config Pointer to the LCDIF configuration.
580  */
581 void LCDIF_DpiModeGetDefaultConfig(lcdif_dpi_config_t *config);
582 
583 /*!
584  * @brief Initialize the LCDIF to work in DPI mode.
585  *
586  * This function configures the LCDIF DPI display.
587  *
588  * @param base LCDIF peripheral base address.
589  * @param displayIndex Display index.
590  * @param config Pointer to the configuration structure.
591  *
592  * @retval kStatus_Success Initialize successfully.
593  * @retval kStatus_InvalidArgument Initialize failed because of invalid argument.
594  */
595 status_t LCDIF_DpiModeSetConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_dpi_config_t *config);
596 
597 /* @} */
598 
599 /*!
600  * @name DBI mode
601  * @{
602  */
603 
604 /*!
605  * @brief Initialize the LCDIF to work in DBI mode.
606  *
607  * This function configures the LCDIF DBI display.
608  *
609  * @param base LCDIF peripheral base address.
610  * @param displayIndex Display index.
611  * @param config Pointer to the configuration structure.
612  * @retval kStatus_Success Initialize successfully.
613  * @retval kStatus_InvalidArgument Initialize failed because of invalid argument.
614  */
615 status_t LCDIF_DbiModeSetConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_dbi_config_t *config);
616 
617 /*!
618  * @brief Get the default configuration to initialize the LCDIF DBI mode.
619  *
620  * The default configuration value is:
621  *
622  * @code
623    config->swizzle         = kLCDIF_DbiOutSwizzleRGB;
624    config->format          = kLCDIF_DbiOutD8RGB332;
625    config->acTimeUnit      = 0;
626    config->type            = kLCDIF_DbiTypeA_ClockedE;
627    config->reversePolarity = false;
628    config->writeWRPeriod   = 3U;
629    config->writeWRAssert   = 0U;
630    config->writeCSAssert   = 0U;
631    config->writeWRDeassert = 0U;
632    config->writeCSDeassert = 0U;
633    config->typeCTas        = 1U;
634    config->typeCSCLTwrl    = 1U;
635    config->typeCSCLTwrh    = 1U;
636    @endcode
637  *
638  * @param config Pointer to the LCDIF DBI configuration.
639  */
640 void LCDIF_DbiModeGetDefaultConfig(lcdif_dbi_config_t *config);
641 
642 /*!
643  * @brief Reset the DBI module.
644  *
645  * @param displayIndex Display index.
646  * @param base LCDIF peripheral base address.
647  */
LCDIF_DbiReset(LCDIF_Type * base,uint8_t displayIndex)648 static inline void LCDIF_DbiReset(LCDIF_Type *base, uint8_t displayIndex)
649 {
650     base->DBIIFRESET0 = LCDIF_DBIIFRESET0_DBI_IF_LEVEL_RESET_MASK;
651 }
652 
653 #if (defined(FSL_FEATURE_LCDIF_HAS_TYPEC) && FSL_FEATURE_LCDIF_HAS_TYPEC)
654 /*!
655  * @brief Check whether the FIFO is full in DBI mode type C.
656  *
657  * @param base LCDIF peripheral base address.
658  * @param displayIndex Display index.
659  * @retval true FIFO full.
660  * @retval false FIFO not full.
661  */
LCDIF_DbiIsTypeCFifoFull(LCDIF_Type * base,uint8_t displayIndex)662 static inline bool LCDIF_DbiIsTypeCFifoFull(LCDIF_Type *base, uint8_t displayIndex)
663 {
664     return (base->DCSTATUS0 & LCDIF_DCSTATUS0_DBI_TYPEC_FIFO_FULL_MASK) != 0UL;
665 }
666 #endif
667 
668 /*!
669  * @brief Select the update area in DBI mode.
670  *
671  * @param base LCDIF peripheral base address.
672  * @param displayIndex Display index.
673  * @param startX X coordinate for start pixel.
674  * @param startY Y coordinate for start pixel.
675  * @param endX X coordinate for end pixel.
676  * @param endY Y coordinate for end pixel.
677  * @param isTiled true if the pixel data is tiled.
678  */
679 void LCDIF_DbiSelectArea(LCDIF_Type *base,
680                          uint8_t displayIndex,
681                          uint16_t startX,
682                          uint16_t startY,
683                          uint16_t endX,
684                          uint16_t endY,
685                          bool isTiled);
686 
687 /*!
688  * @brief Send command to DBI port.
689  *
690  * @param base LCDIF peripheral base address.
691  * @param displayIndex Display index.
692  * @param cmd the DBI command to send.
693  */
LCDIF_DbiSendCommand(LCDIF_Type * base,uint8_t displayIndex,uint8_t cmd)694 static inline void LCDIF_DbiSendCommand(LCDIF_Type *base, uint8_t displayIndex, uint8_t cmd)
695 {
696     base->DBICMD0 = LCDIF_DBICMD0_DBI_COMMANDFLAG(kLCDIF_DbiCmdAddress) | (uint32_t)cmd;
697 }
698 
699 /*!
700  * brief Send data to DBI port.
701  *
702  * Can be used to send light weight data to panel. To send pixel data in frame buffer, use @ref LCDIF_DbiWriteMem.
703  *
704  * param base LCDIF peripheral base address.
705  * param displayIndex Display index.
706  * param data pointer to data buffer.
707  * param dataLen_Byte data buffer length in byte.
708  */
709 void LCDIF_DbiSendData(LCDIF_Type *base, uint8_t displayIndex, const uint8_t *data, uint32_t dataLen_Byte);
710 
711 /*!
712  * @brief Send command followed by data to DBI port.
713  *
714  * @param base LCDIF peripheral base address.
715  * @param displayIndex Display index.
716  * @param cmd the DBI command to send.
717  * @param data pointer to data buffer.
718  * @param dataLen_Byte data buffer length in byte.
719  */
720 void LCDIF_DbiSendCommandAndData(
721     LCDIF_Type *base, uint8_t displayIndex, uint8_t cmd, const uint8_t *data, uint32_t dataLen_Byte);
722 
723 /*!
724  * @brief Send pixel data in frame buffer to panel controller memory.
725  *
726  * This function starts sending the pixel data in frame buffer to panel controller,
727  * user can monitor interrupt @ref kLCDIF_Display0FrameDoneInterrupt to know when
728  * then data sending finished.
729  *
730  * @param base LCDIF peripheral base address.
731  * @param displayIndex Display index.
732  */
LCDIF_DbiWriteMem(LCDIF_Type * base,uint8_t displayIndex)733 static inline void LCDIF_DbiWriteMem(LCDIF_Type *base, uint8_t displayIndex)
734 {
735     base->DBICMD0 = LCDIF_DBICMD0_DBI_COMMANDFLAG(kLCDIF_DbiCmdWriteMem);
736 }
737 /* @} */
738 
739 /*!
740  * @name Frame buffer
741  * @{
742  */
743 
744 /*!
745  * @brief Configure the LCDIF frame buffer.
746  *
747  * @Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version.
748  * Apart from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API to
749  * configure the legacy video layer, and use @ref LCDIF_SetOverlayFrameBufferConfig to configure the overlay layers.
750  *
751  * @param base LCDIF peripheral base address.
752  * @param displayIndex Display index.
753  * @param config Pointer to the configuration structure.
754  */
755 void LCDIF_SetFrameBufferConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_fb_config_t *config);
756 
757 /*!
758  * @brief Get default frame buffer configuration.
759  *
760  * @Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version.
761  Apart
762  * from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API
763  * to get the default configuration for all the 3 layers.
764  *
765  * The default configuration is
766  * @code
767     config->enable = true;
768     config->enableGamma = false;
769     config->format = kLCDIF_PixelFormatRGB565;
770    @endcode
771  *
772  * @param config Pointer to the configuration structure.
773  */
774 void LCDIF_FrameBufferGetDefaultConfig(lcdif_fb_config_t *config);
775 
776 /*!
777  * @brief Set the frame buffer to LCDIF.
778  *
779  * @param base LCDIF peripheral base address.
780  * @param displayIndex Display index.
781  * @param address Frame buffer address.
782  * @note The address must be 128 bytes aligned.
783  */
LCDIF_SetFrameBufferAddr(LCDIF_Type * base,uint8_t displayIndex,uint32_t address)784 static inline void LCDIF_SetFrameBufferAddr(LCDIF_Type *base, uint8_t displayIndex, uint32_t address)
785 {
786     /* The frame buffer address and stride must be aligned. */
787     assert(0U == (address & (LCDIF_FB_ALIGN - 1U)));
788 
789     base->FRAMEBUFFERADDRESS0 = LCDIF_ADDR_CPU_2_IP(address);
790 }
791 
792 /*!
793  * @brief Set the frame buffer stride.
794  *
795  * @param base LCDIF peripheral base address.
796  * @param displayIndex Display index.
797  * @param strideBytes The stride in byte.
798  */
799 void LCDIF_SetFrameBufferStride(LCDIF_Type *base, uint8_t displayIndex, uint32_t strideBytes);
800 
801 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
802 /*!
803  * @brief Set the frame buffer to LCDIF for UV plane when the input format is YUV420.
804  *
805  * @param base LCDIF peripheral base address.
806  * @param displayIndex Display index.
807  * @param address Frame buffer address.
808  */
LCDIF_SetFrameBufferUVAddr(LCDIF_Type * base,uint8_t displayIndex,uint32_t address)809 static inline void LCDIF_SetFrameBufferUVAddr(LCDIF_Type *base, uint8_t displayIndex, uint32_t address)
810 {
811     /* The frame buffer address and stride must be 64-byte aligned. */
812     assert(0U == (address & (LCDIF_FB_ALIGN - 1U)));
813 
814     base->DCTILEUVFRAMEBUFFERADR0 = LCDIF_ADDR_CPU_2_IP(address);
815 }
816 
817 /*
818  * @brief Set the frame buffer stride for UV plane when the input format is YUV420.
819  *
820  * @param base LCDIF peripheral base address.
821  * @param displayIndex Display index.
822  * @param strideBytes The stride in byte.
823  */
LCDIF_SetFrameBufferUVStride(LCDIF_Type * base,uint8_t displayIndex,uint32_t strideBytes)824 static inline void LCDIF_SetFrameBufferUVStride(LCDIF_Type *base, uint8_t displayIndex, uint32_t strideBytes)
825 {
826     base->DCTILEUVFRAMEBUFFERSTR0 = LCDIF_ALIGN_ADDR(strideBytes, LCDIF_FB_ALIGN);
827 }
828 
829 /*!
830  * @brief Configure the video layer position.
831  *
832  * @Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version.
833  * Apart from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API to
834  * configure the legacy video layer, and use @ref LCDIF_SetOverlayLayerPosition to configure the overlay layers.
835  *
836  * @param base LCDIF peripheral base address.
837  * @param displayIndex Display index.
838  * @param topLeftX The x value of thr top-left coordinate.
839  * @param topLeftY The y value of thr top-left coordinate.
840  * @param width The width of the layer.
841  * @param height The height of the layer.
842  */
843 void LCDIF_SetFrameBufferPosition(
844     LCDIF_Type *base, uint8_t displayIndex, uint16_t topLeftX, uint16_t topLeftY, uint16_t width, uint16_t height);
845 
846 /*!
847  * @brief Configure the overlay layers for LCDIF frame buffer.
848  *
849  * @Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version.
850  * Apart from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API to
851  * configure the overlay layers, and use @ref LCDIF_SetFrameBufferConfig to configure the legacy video layer.
852  *
853  * @param base LCDIF peripheral base address.
854  * @param displayIndex Display index.
855  * @param config Pointer to the configuration structure.
856  * @param layerIndex Pointer to the configuration structure.
857  */
858 void LCDIF_SetOverlayLayerConfig(LCDIF_Type *base,
859                                  uint8_t displayIndex,
860                                  const lcdif_fb_config_t *config,
861                                  uint8_t layerIndex);
862 
863 /*!
864  * @brief Configure the overlay layer position.
865  *
866  * @Note: For LCDIF of version DC8000 there can be 3 layers in the pre-processing, compared with the older version.
867  * Apart from the video layer, there are also 2 overlay layers which shares the same configurations. Use this API to
868  * configure the overlay layers, and use @ref LCDIF_SetFrameBufferPosition to configure the legacy video layer.
869  *
870  * @param base LCDIF peripheral base address.
871  * @param displayIndex Display index.
872  * @param topLeftX The x value of thr top-left coordinate.
873  * @param topLeftY The y value of thr top-left coordinate.
874  * @param width The width of the layer.
875  * @param height The height of the layer.
876  * @param layerIndex Pointer to the configuration structure.
877  */
878 void LCDIF_SetOverlayLayerPosition(LCDIF_Type *base,
879                                    uint8_t displayIndex,
880                                    uint16_t topLeftX,
881                                    uint16_t topLeftY,
882                                    uint16_t width,
883                                    uint16_t height,
884                                    uint8_t layerIndex);
885 
886 /*!
887  * @brief Sets the frame buffer address for overlay layer.
888  *
889  * @note The address must be 64 bytes aligned.
890  *
891  * @param base LCDIF peripheral base address.
892  * @param displayIndex Display index.
893  * @param address Frame buffer address.
894  * @param layerIndex Which layer to configure.
895  */
896 void LCDIF_SetOverlayLayerAddr(LCDIF_Type *base, uint8_t displayIndex, uint32_t address, uint8_t layerIndex);
897 
898 /*!
899  * @brief Sets the frame buffer stride for overlay layer.
900  *
901  * @param base LCDIF peripheral base address.
902  * @param displayIndex Display index.
903  * @param strideBytes The stride in byte.
904  * @param layerIndex Which layer to configure.
905  */
906 void LCDIF_SetOverlayLayerStride(LCDIF_Type *base, uint8_t displayIndex, uint32_t strideBytes, uint8_t layerIndex);
907 
908 /*!
909  * @brief Sets the frame buffer address for overlay layer 0 for UV plane when the input format is YUV420.
910  *
911  * @param base LCDIF peripheral base address.
912  * @param displayIndex Display index.
913  * @param address Frame buffer address.
914  */
LCDIF_SetOverlayLayerUVAddr(LCDIF_Type * base,uint8_t displayIndex,uint32_t address)915 static inline void LCDIF_SetOverlayLayerUVAddr(LCDIF_Type *base, uint8_t displayIndex, uint32_t address)
916 {
917     /* The frame buffer address and stride must be 32-byte aligned.*/
918     assert(0U == (address & (LCDIF_FB_UV_ALIGN - 1U)));
919 
920     base->DCTILEUVOVERLAYADR = LCDIF_ADDR_CPU_2_IP(address);
921 }
922 
923 /*
924  * @brief Sets the frame buffer stride for overlay layer 0 for UV plane when the input format is YUV420.
925  *
926  * @param base LCDIF peripheral base address.
927  * @param displayIndex Display index.
928  * @param strideBytes The stride in byte.
929  */
LCDIF_SetOverlayLayerUVStride(LCDIF_Type * base,uint8_t displayIndex,uint32_t strideBytes)930 static inline void LCDIF_SetOverlayLayerUVStride(LCDIF_Type *base, uint8_t displayIndex, uint32_t strideBytes)
931 {
932     base->DCTILEUVOVERLAYSTR = LCDIF_ALIGN_ADDR(strideBytes, LCDIF_FB_UV_ALIGN);
933 }
934 
935 /*!
936  * @brief Sets the color for background layer.
937  *
938  * @param base LCDIF peripheral base address.
939  * @param displayIndex Display index.
940  * @param color Background color in ARGB8888 format.
941  */
LCDIF_SetFrameBufferBackground(LCDIF_Type * base,uint8_t displayIndex,uint32_t color)942 static inline void LCDIF_SetFrameBufferBackground(LCDIF_Type *base, uint8_t displayIndex, uint32_t color)
943 {
944     base->FRAMEBUFFERBACKGROUND = color;
945 }
946 
947 /*!
948  * brief Get the alpha blend configuration by porter duff blend mode.
949  *
950  * param mode The blend mode.
951  * param config Pointer to the configuration.
952  * retval kStatus_Success Successfully get the configuration.
953  * retval kStatus_InvalidArgument The blend mode not supported.
954  */
955 status_t LCDIF_GetPorterDuffConfig(lcdif_porter_duff_blend_mode_t mode, lcdif_layer_alpha_blend_config_t *config);
956 #endif
957 /* @} */
958 
959 #if defined(FSL_FEATURE_LCDIF_VERSION_DC8000) & FSL_FEATURE_LCDIF_VERSION_DC8000
960 /*!
961  * @name Panel control
962  * @{
963  */
964 
965 /*!
966  * @brief Gets default panel configuration.
967  *
968  * The default configuration is
969  * @code
970     config->enable = true;
971     config->enableGamma = false;
972     config->order       = kLCDIF_VideoOverlay0Overlay1;
973     config->endian      = kLCDIF_NoSwap;
974    @endcode
975  *
976  * @param config Pointer to the configuration structure.
977  */
978 void LCDIF_PanelGetDefaultConfig(lcdif_panel_config_t *config);
979 
980 /*!
981  * @brief Configure the LCDIF panel.
982  *
983  * @param base LCDIF peripheral base address.
984  * @param displayIndex Display index.
985  * @param config Pointer to the configuration structure.
986  */
987 void LCDIF_SetPanelConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_panel_config_t *config);
988 
989 /*!
990  * @brief Sets the layer order for the color key and alpha blend precess.
991  *
992  * @param base LCDIF peripheral base address.
993  * @param displayIndex Display index.
994  * @param order The order of the 3 configurable layers.
995  */
LCDIF_SetLayerOrder(LCDIF_Type * base,uint8_t displayIndex,lcdif_layer_order_t order)996 static inline void LCDIF_SetLayerOrder(LCDIF_Type *base, uint8_t displayIndex, lcdif_layer_order_t order)
997 {
998     base->BLENDSTACKORDER = (uint32_t)order;
999 }
1000 
1001 /*!
1002  * @brief Sets the endian mode.
1003  *
1004  * @param base LCDIF peripheral base address.
1005  * @param displayIndex Display index.
1006  * @param mode The byte order for the endian mode.
1007  */
LCDIF_SetEndianMode(LCDIF_Type * base,uint8_t displayIndex,lcdif_endian_mode_t mode)1008 static inline void LCDIF_SetEndianMode(LCDIF_Type *base, uint8_t displayIndex, lcdif_endian_mode_t mode)
1009 {
1010     base->SRCCONFIGENDIAN = (uint32_t)mode;
1011 }
1012 
1013 /*!
1014  * @brief Enables the module to update the new set of configuration in the next frame's VBLANK.
1015  *
1016  * @param base LCDIF peripheral base address.
1017  * @param enable True to enable, false to disable.
1018  */
LCDIF_EnableUpdate(LCDIF_Type * base,bool enable)1019 static inline void LCDIF_EnableUpdate(LCDIF_Type *base, bool enable)
1020 {
1021     base->PANELCONTROL = (uint32_t)enable;
1022 }
1023 
1024 /*!
1025  * @brief Enables the gamma correction.
1026  *
1027  * @param base LCDIF peripheral base address.
1028  * @param enable True to enable, false to disable.
1029  */
LCDIF_EnableGamma(LCDIF_Type * base,bool enable)1030 static inline void LCDIF_EnableGamma(LCDIF_Type *base, bool enable)
1031 {
1032     if (enable)
1033     {
1034         base->PANELFUNCTION |= LCDIF_PANELFUNCTION_GAMMA_MASK;
1035     }
1036     else
1037     {
1038         base->PANELFUNCTION &= ~LCDIF_PANELFUNCTION_GAMMA_MASK;
1039     }
1040 }
1041 
1042 /*!
1043  * @brief Enables the panel output.
1044  *
1045  * When disables, all pixels will be black which allows a panel to have correct timing without any pixels.
1046  *
1047  * @param base LCDIF peripheral base address.
1048  * @param enable True to enable, false to disable.
1049  */
LCDIF_EnablePanel(LCDIF_Type * base,bool enable)1050 static inline void LCDIF_EnablePanel(LCDIF_Type *base, bool enable)
1051 {
1052     if (enable)
1053     {
1054         base->PANELFUNCTION |= LCDIF_PANELFUNCTION_OUTPUT_MASK;
1055     }
1056     else
1057     {
1058         base->PANELFUNCTION &= ~LCDIF_PANELFUNCTION_OUTPUT_MASK;
1059     }
1060 }
1061 
1062 /*!
1063  * @brief Starts the interface mode transfer. Self-clear.
1064  *
1065  * All registers will be copied to the working set and resets the pixel counter.
1066  *
1067  * @param base LCDIF peripheral base address.
1068  */
LCDIF_Start(LCDIF_Type * base)1069 static inline void LCDIF_Start(LCDIF_Type *base)
1070 {
1071     base->PANELWORKING = LCDIF_PANELWORKING_WORKING_MASK;
1072 }
1073 
1074 /*!
1075  * @brief Resets the module. Self-clear.
1076  *
1077  * @param base LCDIF peripheral base address.
1078  */
LCDIF_Reset(LCDIF_Type * base)1079 static inline void LCDIF_Reset(LCDIF_Type *base)
1080 {
1081     base->SOFTRESET = LCDIF_SOFTRESET_RESET_MASK;
1082 }
1083 
1084 /*!
1085  * @brief Set the update of the double buffer register ready.
1086  *
1087  * Call this API after updating any double buffered register
1088  * to let the change take effect in next v-blank.
1089  *
1090  * @param base LCDIF peripheral base address.
1091  */
LCDIF_SetUpdateReady(LCDIF_Type * base)1092 static inline void LCDIF_SetUpdateReady(LCDIF_Type *base)
1093 {
1094     base->PANELCONTROL |= LCDIF_PANELCONTROL_VALID_MASK;
1095 }
1096 /* @} */
1097 #endif
1098 
1099 /*!
1100  * @name Dither
1101  * @{
1102  */
1103 
1104 /*!
1105  * @brief Set the dither configuration.
1106  *
1107  * @param base LCDIF peripheral base address.
1108  * @param displayIndex Index to configure.
1109  * @param config Pointer to the configuration structure.
1110  */
1111 void LCDIF_SetDitherConfig(LCDIF_Type *base, uint8_t displayIndex, const lcdif_dither_config_t *config);
1112 
1113 /*! @} */
1114 
1115 /*!
1116  * @name Gamma correction
1117  * @{
1118  */
1119 
1120 /*!
1121  * @brief Set the gamma translation values to the LCDIF gamma table.
1122  *
1123  * @param base LCDIF peripheral base address.
1124  * @param displayIndex Display index.
1125  * @param startIndex Start index in the gamma table that the value will be set to.
1126  * @param gamma The gamma values to set to the gamma table in LCDIF, could be defined using LCDIF_MAKE_GAMMA_VALUE.
1127  * @param gammaLen The length of the @p gamma.
1128  */
1129 void LCDIF_SetGammaData(
1130     LCDIF_Type *base, uint8_t displayIndex, uint16_t startIndex, const uint32_t *gamma, uint16_t gammaLen);
1131 
1132 /*! @} */
1133 
1134 /*!
1135  * @name Interrupts
1136  *
1137  * The interrupt must be enabled, otherwise the interrupt flags will not assert.
1138  *
1139  * @{
1140  */
1141 
1142 /*!
1143  * @brief Enables LCDIF interrupt requests.
1144  *
1145  * @param base LCDIF peripheral base address.
1146  * @param mask The interrupts to enable, pass in as OR'ed value of @ref _lcdif_interrupt.
1147  */
LCDIF_EnableInterrupts(LCDIF_Type * base,uint32_t mask)1148 static inline void LCDIF_EnableInterrupts(LCDIF_Type *base, uint32_t mask)
1149 {
1150     base->DISPLAYINTRENABLE |= mask;
1151 }
1152 
1153 /*!
1154  * @brief Disable LCDIF interrupt requests.
1155  *
1156  * @param base LCDIF peripheral base address.
1157  * @param mask The interrupts to disable, pass in as OR'ed value of @ref _lcdif_interrupt.
1158  */
LCDIF_DisableInterrupts(LCDIF_Type * base,uint32_t mask)1159 static inline void LCDIF_DisableInterrupts(LCDIF_Type *base, uint32_t mask)
1160 {
1161     base->DISPLAYINTRENABLE &= ~mask;
1162 }
1163 
1164 /*!
1165  * @brief Get and clear LCDIF interrupt pending status.
1166  *
1167  * @param base LCDIF peripheral base address.
1168  * @return The interrupt pending status.
1169  *
1170  * @note The interrupt must be enabled, otherwise the interrupt flags will not assert.
1171  */
LCDIF_GetAndClearInterruptPendingFlags(LCDIF_Type * base)1172 static inline uint32_t LCDIF_GetAndClearInterruptPendingFlags(LCDIF_Type *base)
1173 {
1174     return base->DISPLAYINTR;
1175 }
1176 
1177 /*! @} */
1178 
1179 /*!
1180  * @name Cursor
1181  *
1182  * Top-left point and Hot spot are two different cursor point.
1183  *
1184  *   Top-left point is used as the base address for the cursor.
1185  *   Hot spot is used in a search for a corresponding screen coordinate when
1186  *   a selection is made, such as when the "Enter" key or left mouse button
1187  *   is pushed.
1188  *
1189  * @verbatim
1190 
1191      Top-left point
1192           +-------------------------------+
1193           |                               |
1194           |   Hot spot                    |
1195           |      +-------                 |
1196           |      |    \                   |
1197           |      | \   \                  |
1198           |      |  \   \                 |
1199           |          \   \                |
1200           |           \   \               |
1201           |            \   \              |
1202           |             \   \             |
1203           |              \                |
1204           |                               |
1205           +-------------------------------+
1206 
1207    @endverbatim
1208  *
1209  * For format masked, one cursor pixel is 2bits. 32x32 cursor pixels have 32
1210  * cursor color rows. Each cursor color row is 64bits.
1211  *
1212  * cursorColorRow_H[31:0] = colorRow[63:32]
1213  * cursorColorRow_L[31:0] = colorRow[31:0]
1214  * xorCursor = cursorColorRow_H[cursorXPos[4:0]]
1215  * andCursor = cursorColorRow_L[cursorXPos[4:0]]
1216  *
1217  * The output cursor color is:
1218  *
1219  *  andCursor    xorCursor          cursor color
1220  *      0           0           Background register color
1221  *      0           1           Foreground register color
1222  *      1           0           Frame buffer pixel color
1223  *      1           1           Invert frame buffer pixel color
1224  *
1225  * @{
1226  */
1227 
1228 /*!
1229  * @brief Get the hardware cursor default configuration
1230  *
1231  * The default configuration values are:
1232  *
1233  * @code
1234     config->enable = true;
1235     config->format = kLCDIF_CursorMasked;
1236     config->hotspotOffsetX = 0;
1237     config->hotspotOffsetY = 0;
1238    @endcode
1239  *
1240  * @param config Pointer to the hardware cursor configuration structure.
1241  */
1242 void LCDIF_CursorGetDefaultConfig(lcdif_cursor_config_t *config);
1243 
1244 /*!
1245  * @brief Configure the cursor.
1246  *
1247  * @param base LCDIF peripheral base address.
1248  * @param config Cursor configuration.
1249  */
1250 void LCDIF_SetCursorConfig(LCDIF_Type *base, const lcdif_cursor_config_t *config);
1251 
1252 /*!
1253  * @brief Set the cursor hotspot postion
1254  *
1255  * @param base LCDIF peripheral base address.
1256  * @param x X coordinate of the hotspot, range 0 ~ 8191.
1257  * @param y Y coordinate of the hotspot, range 0 ~ 8191.
1258  */
LCDIF_SetCursorHotspotPosition(LCDIF_Type * base,uint16_t x,uint16_t y)1259 static inline void LCDIF_SetCursorHotspotPosition(LCDIF_Type *base, uint16_t x, uint16_t y)
1260 {
1261     base->CURSORLOCATION =
1262         ((uint32_t)y << LCDIF_CURSORLOCATION_Y_SHIFT) | ((uint32_t)x << LCDIF_CURSORLOCATION_X_SHIFT);
1263 }
1264 
1265 /*!
1266  * @brief Set the cursor memory address.
1267  *
1268  * @param base LCDIF peripheral base address.
1269  * @param address Memory address.
1270  */
LCDIF_SetCursorBufferAddress(LCDIF_Type * base,uint32_t address)1271 static inline void LCDIF_SetCursorBufferAddress(LCDIF_Type *base, uint32_t address)
1272 {
1273     base->CURSORADDRESS = LCDIF_ADDR_CPU_2_IP(address);
1274 }
1275 
1276 /*!
1277  * @brief Set the cursor color
1278  *
1279  * @param base LCDIF peripheral base address.
1280  * @param background  Background color, could be defined use @ref LCDIF_MAKE_CURSOR_COLOR
1281  * @param foreground  Foreground color, could be defined use @ref LCDIF_MAKE_CURSOR_COLOR
1282  */
1283 void LCDIF_SetCursorColor(LCDIF_Type *base, uint32_t background, uint32_t foreground);
1284 
1285 /*! @} */
1286 
1287 #if defined(__cplusplus)
1288 }
1289 #endif
1290 
1291 /*! @}*/
1292 
1293 #endif /* FSL_LCDIF_H_ */
1294