1 /*
2  * Copyright 2019-2022 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef FSL_LCDIFV2_H_
10 #define FSL_LCDIFV2_H_
11 
12 #include "fsl_common.h"
13 
14 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (0 != FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET))
15 #include "fsl_memory.h"
16 #endif
17 
18 /*!
19  * @addtogroup lcdifv2
20  * @{
21  */
22 
23 /*******************************************************************************
24  * Definitions
25  ******************************************************************************/
26 
27 /*! @name Driver version */
28 /*! @{ */
29 /*! @brief LCDIF v2 driver version */
30 #define FSL_LCDIFV2_DRIVER_VERSION (MAKE_VERSION(2, 3, 2))
31 /*! @} */
32 
33 #if defined(FSL_FEATURE_LCDIFV2_LAYER_COUNT) && (!defined(LCDIFV2_LAYER_COUNT))
34 #define LCDIFV2_LAYER_COUNT FSL_FEATURE_LCDIFV2_LAYER_COUNT
35 #endif
36 
37 #if defined(FSL_FEATURE_LCDIFV2_LAYER_CSC_COUNT) && (!defined(LCDIFV2_LAYER_CSC_COUNT))
38 #define LCDIFV2_LAYER_CSC_COUNT FSL_FEATURE_LCDIFV2_LAYER_CSC_COUNT
39 #endif
40 
41 #if (defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && (0 != FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET))
42 #define LCDIFV2_ADDR_CPU_2_IP(addr) (MEMORY_ConvertMemoryMapAddress((uint32_t)(addr), kMEMORY_Local2DMA))
43 #else
44 #define LCDIFV2_ADDR_CPU_2_IP(addr) (addr)
45 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
46 
47 /*! @brief LCDIF v2 FIFO empty interrupt. */
48 #define LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(layer) (1UL << ((uint32_t)(layer) + 24U))
49 /*! @brief LCDIF v2 DMA done interrupt. */
50 #define LCDIFV2_MAKE_DMA_DONE_INTERRUPT(layer) (1UL << ((uint32_t)(layer) + 16U))
51 /*! @brief LCDIF v2 DMA error interrupt. */
52 #define LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(layer) (1UL << ((uint32_t)(layer) + 8U))
53 
54 /* LUT memory entery number. */
55 #define LCDIFV2_LUT_ENTRY_NUM 256U
56 
57 /*!
58  * @brief LCDIF v2 signal polarity flags
59  */
60 enum _lcdifv2_polarity_flags
61 {
62     kLCDIFV2_VsyncActiveHigh          = 0U, /*!< VSYNC active high. */
63     kLCDIFV2_HsyncActiveHigh          = 0U, /*!< HSYNC active high. */
64     kLCDIFV2_DataEnableActiveHigh     = 0U, /*!< Data enable line active high. */
65     kLCDIFV2_DriveDataOnRisingClkEdge = 0U, /*!< Output data on rising clock edge, capture data
66                                                  on falling clock edge. */
67     kLCDIFV2_DataActiveHigh = 0U,           /*!< Data active high. */
68 
69     kLCDIFV2_VsyncActiveLow            = LCDIFV2_CTRL_INV_VS_MASK,   /*!< VSYNC active low. */
70     kLCDIFV2_HsyncActiveLow            = LCDIFV2_CTRL_INV_HS_MASK,   /*!< HSYNC active low. */
71     kLCDIFV2_DataEnableActiveLow       = LCDIFV2_CTRL_INV_DE_MASK,   /*!< Data enable line active low. */
72     kLCDIFV2_DriveDataOnFallingClkEdge = LCDIFV2_CTRL_INV_PXCK_MASK, /*!< Output data on falling clock edge, capture
73                                                                         data on rising clock edge. */
74     kLCDIFV2_DataActiveLow = LCDIFV2_CTRL_NEG_MASK,                  /*!< Data active high. */
75 };
76 
77 /*!
78  * @brief The LCDIF v2 interrupts.
79  */
80 enum _lcdifv2_interrupt
81 {
82     kLCDIFV2_Layer0FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(0), /*!< Layer 0 FIFO empty. */
83     kLCDIFV2_Layer1FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(1), /*!< Layer 1 FIFO empty. */
84     kLCDIFV2_Layer2FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(2), /*!< Layer 2 FIFO empty. */
85     kLCDIFV2_Layer3FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(3), /*!< Layer 3 FIFO empty. */
86     kLCDIFV2_Layer4FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(4), /*!< Layer 4 FIFO empty. */
87     kLCDIFV2_Layer5FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(5), /*!< Layer 5 FIFO empty. */
88     kLCDIFV2_Layer6FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(6), /*!< Layer 6 FIFO empty. */
89     kLCDIFV2_Layer7FifoEmptyInterrupt  = LCDIFV2_MAKE_FIFO_EMPTY_INTERRUPT(7), /*!< Layer 7 FIFO empty. */
90     kLCDIFV2_Layer0DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(0),   /*!< Layer 0 DMA done. */
91     kLCDIFV2_Layer1DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(1),   /*!< Layer 1 DMA done. */
92     kLCDIFV2_Layer2DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(2),   /*!< Layer 2 DMA done. */
93     kLCDIFV2_Layer3DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(3),   /*!< Layer 3 DMA done. */
94     kLCDIFV2_Layer4DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(4),   /*!< Layer 4 DMA done. */
95     kLCDIFV2_Layer5DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(5),   /*!< Layer 5 DMA done. */
96     kLCDIFV2_Layer6DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(6),   /*!< Layer 6 DMA done. */
97     kLCDIFV2_Layer7DmaDoneInterrupt    = LCDIFV2_MAKE_DMA_DONE_INTERRUPT(7),   /*!< Layer 7 DMA done. */
98     kLCDIFV2_Layer0DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(0),  /*!< Layer 0 DMA error. */
99     kLCDIFV2_Layer1DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(1),  /*!< Layer 1 DMA error. */
100     kLCDIFV2_Layer2DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(2),  /*!< Layer 2 DMA error. */
101     kLCDIFV2_Layer3DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(3),  /*!< Layer 3 DMA error. */
102     kLCDIFV2_Layer4DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(4),  /*!< Layer 4 DMA error. */
103     kLCDIFV2_Layer5DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(5),  /*!< Layer 5 DMA error. */
104     kLCDIFV2_Layer6DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(6),  /*!< Layer 6 DMA error. */
105     kLCDIFV2_Layer7DmaErrorInterrupt   = LCDIFV2_MAKE_DMA_ERROR_INTERRUPT(7),  /*!< Layer 7 DMA error. */
106     kLCDIFV2_VerticalBlankingInterrupt = (1U << 2U), /*!< Start of vertical blanking period. */
107     kLCDIFV2_OutputUnderrunInterrupt   = (1U << 1U), /*!< Output buffer underrun. */
108     kLCDIFV2_VsyncEdgeInterrupt        = (1U << 0U), /*!< Interrupt at VSYNC edge. */
109 };
110 
111 /*! @brief The LCDIF v2 output line order. */
112 typedef enum _lcdifv2_line_order
113 {
114     kLCDIFV2_LineOrderRGB = 0, /*!< RGB */
115     kLCDIFV2_LineOrderRBG,     /*!< RBG */
116     kLCDIFV2_LineOrderGBR,     /*!< GBR */
117     kLCDIFV2_LineOrderGRB,     /*!< GRB */
118     kLCDIFV2_LineOrderBRG,     /*!< BRG */
119     kLCDIFV2_LineOrderBGR,     /*!< BGR */
120 } lcdifv2_line_order_t;
121 
122 /*!
123  * @brief LCDIF v2 display configure structure.
124  */
125 typedef struct _lcdifv2_display_config
126 {
127     uint16_t panelWidth;    /*!< Display panel width, pixels per line. */
128     uint16_t panelHeight;   /*!< Display panel height, how many lines per panel. */
129     uint8_t hsw;            /*!< HSYNC pulse width. */
130     uint8_t hfp;            /*!< Horizontal front porch. */
131     uint8_t hbp;            /*!< Horizontal back porch. */
132     uint8_t vsw;            /*!< VSYNC pulse width. */
133     uint8_t vfp;            /*!< Vrtical front porch. */
134     uint8_t vbp;            /*!< Vertical back porch. */
135     uint32_t polarityFlags; /*!< OR'ed value of @ref _lcdifv2_polarity_flags, used to contol the signal polarity. */
136     lcdifv2_line_order_t lineOrder; /*!< Line order. */
137 } lcdifv2_display_config_t;
138 
139 /*! @brief LCDIF v2 color space conversion mode. */
140 typedef enum _lcdifv2_csc_mode
141 {
142     kLCDIFV2_CscDisable = 0U, /*!< Disable the CSC. */
143     kLCDIFV2_CscYUV2RGB,      /*!< YUV to RGB. */
144     kLCDIFV2_CscYCbCr2RGB,    /*!< YCbCr to RGB. */
145 } lcdifv2_csc_mode_t;
146 
147 /*! @brief LCDIF v2 pixel format. */
148 typedef enum _lcdifv2_pixel_format
149 {
150     kLCDIFV2_PixelFormatIndex1BPP = LCDIFV2_CTRLDESCL5_BPP(0U), /*!< LUT index 1 bit. */
151     kLCDIFV2_PixelFormatIndex2BPP = LCDIFV2_CTRLDESCL5_BPP(1U), /*!< LUT index 2 bit. */
152     kLCDIFV2_PixelFormatIndex4BPP = LCDIFV2_CTRLDESCL5_BPP(2U), /*!< LUT index 4 bit. */
153     kLCDIFV2_PixelFormatIndex8BPP = LCDIFV2_CTRLDESCL5_BPP(3U), /*!< LUT index 8 bit. */
154     kLCDIFV2_PixelFormatRGB565    = LCDIFV2_CTRLDESCL5_BPP(4U), /*!< RGB565, two pixels use 32 bits. */
155     kLCDIFV2_PixelFormatARGB1555  = LCDIFV2_CTRLDESCL5_BPP(5U), /*!< ARGB1555, two pixels use 32 bits. */
156     kLCDIFV2_PixelFormatARGB4444  = LCDIFV2_CTRLDESCL5_BPP(6U), /*!< ARGB4444, two pixels use 32 bits. */
157     kLCDIFV2_PixelFormatUYVY      = LCDIFV2_CTRLDESCL5_BPP(7U) |
158                                LCDIFV2_CTRLDESCL5_YUV_FORMAT(0U), /*!< UYVY, only layer 0 and layer 1 support this. */
159     kLCDIFV2_PixelFormatVYUY = LCDIFV2_CTRLDESCL5_BPP(7U) |
160                                LCDIFV2_CTRLDESCL5_YUV_FORMAT(1U), /*!< VYUY, only layer 0 and layer 1 support this. */
161     kLCDIFV2_PixelFormatYUYV = LCDIFV2_CTRLDESCL5_BPP(7U) |
162                                LCDIFV2_CTRLDESCL5_YUV_FORMAT(2U), /*!< YUYV, only layer 0 and layer 1 support this. */
163     kLCDIFV2_PixelFormatYVYU = LCDIFV2_CTRLDESCL5_BPP(7U) |
164                                LCDIFV2_CTRLDESCL5_YUV_FORMAT(3U), /*!< YVYU, only layer 0 and layer 1 support this. */
165     kLCDIFV2_PixelFormatRGB888   = LCDIFV2_CTRLDESCL5_BPP(8U),    /*!< RGB888 packed, one pixel uses 24 bits. */
166     kLCDIFV2_PixelFormatARGB8888 = LCDIFV2_CTRLDESCL5_BPP(9U),    /*!< ARGB8888 unpacked, one pixel uses 32 bits. */
167     kLCDIFV2_PixelFormatABGR8888 = LCDIFV2_CTRLDESCL5_BPP(10U),   /*!< ABGR8888 unpacked, one pixel uses 32 bits. */
168 } lcdifv2_pixel_format_t;
169 
170 /*! @brief LCDIF v2 source buffer configuration. */
171 typedef struct _lcdifv2_buffer_config
172 {
173     uint16_t strideBytes; /*!< Number of bytes between two vertically adjacent pixels, suggest 64-bit aligned. */
174     lcdifv2_pixel_format_t pixelFormat; /*!< Source buffer pixel format. */
175 } lcdifv2_buffer_config_t;
176 
177 /*!
178  * @brief LCDIF v2 layer alpha blending mode.
179  */
180 typedef enum _lcdifv2_alpha_mode
181 {
182     kLCDIFV2_AlphaDisable,   /*!< Disable alpha blend. */
183     kLCDIFV2_AlphaOverride,  /*!< Use the gobal alpha value, pixel defined alpha value is overridden. */
184     kLCDIFV2_AlphaEmbedded,  /*!< Use the pixel defined alpha value. */
185     kLCDIFV2_AlphaPoterDuff, /*!< Use the PoterDuff alpha blending. */
186 } lcdifv2_alpha_mode_t;
187 
188 /*!
189  * @brief LCDIF v2 PoterDuff alpha mode.
190  */
191 typedef enum _lcdifv2_pd_alpha_mode
192 {
193     kLCDIFV2_PD_AlphaStraight = 0, /*!< Straight mode. */
194     kLCDIFV2_PD_AlphaInversed = 1, /*!< Inversed mode. */
195 } lcdifv2_pd_alpha_mode_t;
196 
197 /*!
198  * @brief LCDIF v2 PoterDuff color mode.
199  */
200 typedef enum _lcdifv2_pd_color_mode
201 {
202     kLCDIFV2_PD_ColorNoAlpha   = 0, /*!< Output color directly. */
203     kLCDIFV2_PD_ColorWithAlpha = 1, /*!< Output color multiples alpha. */
204 } lcdifv2_pd_color_mode_t;
205 
206 /*!
207  * @brief LCDIF v2 PoterDuff global alpha mode.
208  */
209 typedef enum _lcdifv2_pd_global_alpha_mode
210 {
211     kLCDIFV2_PD_GlobalAlpha = 0, /*!< Use global alpha. */
212     kLCDIFV2_PD_LocalAlpha  = 1, /*!< Use local alpha. */
213     kLCDIFV2_PD_ScaledAlpha = 2, /*!< Use scaled alpha. */
214 } lcdifv2_pd_global_alpha_mode_t;
215 
216 /*!
217  * @brief LCDIF v2 PoterDuff factor mode.
218  */
219 typedef enum _lcdifv2_pd_factor_mode
220 {
221     kLCDIFV2_PD_FactorOne           = 0, /*!< Use 1. */
222     kLCDIFV2_PD_FactorZero          = 1, /*!< Use 0. */
223     kLCDIFV2_PD_FactorStraightAlpha = 2, /*!< Use straight alpha. */
224     kLCDIFV2_PD_FactorInversedAlpha = 3, /*!< Use inversed alpha. */
225 } lcdifv2_pd_factor_mode_t;
226 
227 /*!
228  * @brief LCDIF v2 layer alpha blending configuration.
229  */
230 typedef struct _lcdifv2_blend_config
231 {
232     uint8_t globalAlpha;                              /*!< Global alpha value, only used when
233                                                         @ref alphaMode is @ref kLCDIFV2_AlphaOverride or
234                                                         @ref kLCDIFV2_AlphaPoterDuff */
235     lcdifv2_alpha_mode_t alphaMode;                   /*!< Alpha mode. */
236     lcdifv2_pd_alpha_mode_t pdAlphaMode;              /*!< PoterDuff alpha mode, only used when @ref alphaMode is @ref
237                                                         kLCDIFV2_AlphaPoterDuff */
238     lcdifv2_pd_color_mode_t pdColorMode;              /*!< PoterDuff color mode, only used when @ref alphaMode is @ref
239                                                         kLCDIFV2_AlphaPoterDuff */
240     lcdifv2_pd_global_alpha_mode_t pdGlobalAlphaMode; /*!< PoterDuff global alpha mode, only used when @ref alphaMode is
241                                            @ref kLCDIFV2_AlphaPoterDuff */
242     lcdifv2_pd_factor_mode_t pdFactorMode;            /*!< PoterDuff factor mode, only used when @ref alphaMode is @ref
243                                                       kLCDIFV2_AlphaPoterDuff */
244 } lcdifv2_blend_config_t;
245 
246 /*! @brief LCDIFv2 Porter Duff blend mode. Note: Don't change the enum item value */
247 typedef enum _lcdifv2_pd_blend_mode
248 {
249     kLCDIFV2_PD_Src = 0, /*!< Source Only */
250     kLCDIFV2_PD_Atop,    /*!< Source Atop */
251     kLCDIFV2_PD_Over,    /*!< Source Over */
252     kLCDIFV2_PD_In,      /*!< Source In. */
253     kLCDIFV2_PD_Out,     /*!< Source Out. */
254     kLCDIFV2_PD_Dst,     /*!< Destination Only. */
255     kLCDIFV2_PD_DstAtop, /*!< Destination Atop. */
256     kLCDIFV2_PD_DstOver, /*!< Destination Over. */
257     kLCDIFV2_PD_DstIn,   /*!< Destination In. */
258     kLCDIFV2_PD_DstOut,  /*!< Destination Out. */
259     kLCDIFV2_PD_Xor,     /*!< XOR. */
260     kLCDIFV2_PD_Clear,   /*!< Clear. */
261     kLCDIFV2_PD_Max,     /*!< Used for boarder detection. */
262 } lcdifv2_pd_blend_mode_t;
263 
264 /*! @brief LCDIFv2 Porter Duff layer. Note: Don't change the enum item value */
265 typedef enum _lcdifv2_pd_layer
266 {
267     kLCDIFV2_PD_SrcLayer  = 0, /*!< Source layer.      */
268     kLCDIFV2_PD_DestLayer = 1, /*!< Destination layer. */
269     kLCDIFV2_PD_LayerMax  = 2, /*!< Used for boarder detection. */
270 } lcdifv2_pd_layer_t;
271 
272 /*******************************************************************************
273  * APIs
274  ******************************************************************************/
275 
276 #if defined(__cplusplus)
277 extern "C" {
278 #endif /* __cplusplus */
279 
280 /*!
281  * @name LCDIF v2 initialization and de-initialization
282  * @{
283  */
284 
285 /*!
286  * @brief Initializes the LCDIF v2.
287  *
288  * This function ungates the LCDIF v2 clock and release the peripheral reset.
289  *
290  * @param base LCDIF v2 peripheral base address.
291  */
292 void LCDIFV2_Init(LCDIFV2_Type *base);
293 
294 /*!
295  * @brief Deinitializes the LCDIF peripheral.
296  *
297  * @param base LCDIF peripheral base address.
298  */
299 void LCDIFV2_Deinit(LCDIFV2_Type *base);
300 
301 /*!
302  * @brief Reset the LCDIF v2.
303  *
304  * @param base LCDIF peripheral base address.
305  */
306 void LCDIFV2_Reset(LCDIFV2_Type *base);
307 
308 /*! @} */
309 
310 /*!
311  * @name Display
312  * @{
313  */
314 
315 /*!
316  * @brief Gets the LCDIF display default configuration structure.
317  *
318  * This function sets the configuration structure to default values.
319  * The default configuration is set to the following values.
320  * @code
321     config->panelWidth    = 0U;
322     config->panelHeight   = 0U;
323     config->hsw           = 3U;
324     config->hfp           = 3U;
325     config->hbp           = 3U;
326     config->vsw           = 3U;
327     config->vfp           = 3U;
328     config->vbp           = 3U;
329     config->polarityFlags = kLCDIFV2_VsyncActiveHigh | kLCDIFV2_HsyncActiveHigh | kLCDIFV2_DataEnableActiveHigh |
330                             kLCDIFV2_DriveDataOnRisingClkEdge | kLCDIFV2_DataActiveHigh;
331     config->lineOrder       = kLCDIFV2_LineOrderRGB;
332     @endcode
333  *
334  * @param config Pointer to the LCDIF configuration structure.
335  */
336 void LCDIFV2_DisplayGetDefaultConfig(lcdifv2_display_config_t *config);
337 
338 /*!
339  * @brief Set the LCDIF v2 display configurations.
340  *
341  * @param base LCDIF peripheral base address.
342  * @param config Pointer to the LCDIF configuration structure.
343  */
344 void LCDIFV2_SetDisplayConfig(LCDIFV2_Type *base, const lcdifv2_display_config_t *config);
345 
346 /*!
347  * @brief Enable or disable the display
348  *
349  * @param base LCDIF peripheral base address.
350  * @param enable Enable or disable.
351  */
LCDIFV2_EnableDisplay(LCDIFV2_Type * base,bool enable)352 static inline void LCDIFV2_EnableDisplay(LCDIFV2_Type *base, bool enable)
353 {
354     if (enable)
355     {
356         base->DISP_PARA |= LCDIFV2_DISP_PARA_DISP_ON_MASK;
357     }
358     else
359     {
360         base->DISP_PARA &= ~LCDIFV2_DISP_PARA_DISP_ON_MASK;
361     }
362 }
363 
364 /*! @} */
365 
366 /*!
367  * @name Interrupts
368  * @{
369  */
370 
371 /*!
372  * @brief Enables LCDIF interrupt requests.
373  *
374  * @param base LCDIF peripheral base address.
375  * @param domain CPU domain the interrupt signal routed to.
376  * @param mask interrupt source, OR'ed value of _lcdifv2_interrupt.
377  */
LCDIFV2_EnableInterrupts(LCDIFV2_Type * base,uint8_t domain,uint32_t mask)378 static inline void LCDIFV2_EnableInterrupts(LCDIFV2_Type *base, uint8_t domain, uint32_t mask)
379 {
380     base->INT[domain].INT_ENABLE |= mask;
381 }
382 
383 /*!
384  * @brief Disables LCDIF interrupt requests.
385  *
386  * @param base LCDIF peripheral base address.
387  * @param domain CPU domain the interrupt signal routed to.
388  * @param mask interrupt source, OR'ed value of _lcdifv2_interrupt.
389  */
LCDIFV2_DisableInterrupts(LCDIFV2_Type * base,uint8_t domain,uint32_t mask)390 static inline void LCDIFV2_DisableInterrupts(LCDIFV2_Type *base, uint8_t domain, uint32_t mask)
391 {
392     base->INT[domain].INT_ENABLE &= ~mask;
393 }
394 
395 /*!
396  * @brief Get LCDIF interrupt peding status.
397  *
398  * @param base LCDIF peripheral base address.
399  * @param domain CPU domain the interrupt signal routed to.
400  * @return Interrupt pending status, OR'ed value of _lcdifv2_interrupt.
401  */
LCDIFV2_GetInterruptStatus(LCDIFV2_Type * base,uint8_t domain)402 static inline uint32_t LCDIFV2_GetInterruptStatus(LCDIFV2_Type *base, uint8_t domain)
403 {
404     return base->INT[domain].INT_STATUS;
405 }
406 
407 /*!
408  * @brief Clear LCDIF interrupt peding status.
409  *
410  * @param base LCDIF peripheral base address.
411  * @param domain CPU domain the interrupt signal routed to.
412  * @param mask of the flags to clear, OR'ed value of _lcdifv2_interrupt.
413  */
LCDIFV2_ClearInterruptStatus(LCDIFV2_Type * base,uint8_t domain,uint32_t mask)414 static inline void LCDIFV2_ClearInterruptStatus(LCDIFV2_Type *base, uint8_t domain, uint32_t mask)
415 {
416     base->INT[domain].INT_STATUS = mask;
417 }
418 
419 /*! @} */
420 
421 /*!
422  * @name LUT
423  * @{
424  */
425 
426 /*!
427  * @brief Set the LUT data.
428  *
429  * This function sets the specific layer LUT data, if @p useShadowLoad is true,
430  * call @ref LCDIFV2_TriggerLayerShadowLoad after this function, the
431  * LUT will be loaded to the hardware during next vertical blanking period.
432  * If @p useShadowLoad is false, the LUT data is loaded to hardware directly.
433  *
434  * @param base LCDIF v2 peripheral base address.
435  * @param layerIndex Which layer to set.
436  * @param lutData The LUT data to load.
437  * @param count Count of @p lutData.
438  * @param useShadowLoad Use shadow load.
439  * @retval kStatus_Success Set success.
440  * @retval kStatus_Fail Previous LUT data is not loaded to hardware yet.
441  */
442 status_t LCDIFV2_SetLut(
443     LCDIFV2_Type *base, uint8_t layerIndex, const uint32_t *lutData, uint16_t count, bool useShadowLoad);
444 
445 /*! @} */
446 
447 /*!
448  * @name Layer operation
449  * @{
450  */
451 
452 /*!
453  * @brief Set the layer dimension.
454  *
455  * @param base LCDIFv2 peripheral base address.
456  * @param layerIndex Layer layerIndex.
457  * @param width Layer width in pixel.
458  * @param height Layer height.
459  *
460  * @note The layer width must be in multiples of the number of pixels that can be stored in 32 bits
461  */
LCDIFV2_SetLayerSize(LCDIFV2_Type * base,uint8_t layerIndex,uint16_t width,uint16_t height)462 static inline void LCDIFV2_SetLayerSize(LCDIFV2_Type *base, uint8_t layerIndex, uint16_t width, uint16_t height)
463 {
464     base->LAYER[layerIndex].CTRLDESCL1 =
465         ((uint32_t)height << LCDIFV2_CTRLDESCL1_HEIGHT_SHIFT) | ((uint32_t)width << LCDIFV2_CTRLDESCL1_WIDTH_SHIFT);
466 }
467 
468 /*!
469  * @brief Set the layer position in output frame.
470  *
471  * @param base LCDIFv2 peripheral base address.
472  * @param layerIndex Layer layerIndex.
473  * @param offsetX Horizontal offset, start from 0.
474  * @param offsetY Vertical offset, start from 0.
475  */
LCDIFV2_SetLayerOffset(LCDIFV2_Type * base,uint8_t layerIndex,uint16_t offsetX,uint16_t offsetY)476 static inline void LCDIFV2_SetLayerOffset(LCDIFV2_Type *base, uint8_t layerIndex, uint16_t offsetX, uint16_t offsetY)
477 {
478     base->LAYER[layerIndex].CTRLDESCL2 =
479         ((uint32_t)offsetX << LCDIFV2_CTRLDESCL2_POSX_SHIFT) | ((uint32_t)offsetY << LCDIFV2_CTRLDESCL2_POSY_SHIFT);
480 }
481 
482 /*!
483  * @brief Set the layer source buffer configuration.
484  *
485  * @param base LCDIFv2 peripheral base address.
486  * @param layerIndex Layer layerIndex.
487  * @param config Pointer to the configuration.
488  */
489 void LCDIFV2_SetLayerBufferConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_buffer_config_t *config);
490 
491 /*!
492  * @brief Set the layer source buffer address.
493  *
494  * This function is used for fast runtime source buffer change.
495  *
496  * @param base LCDIFv2 peripheral base address.
497  * @param layerIndex Layer layerIndex.
498  * @param addr The new source buffer address passed to the layer, should be 64-bit aligned.
499  */
LCDIFV2_SetLayerBufferAddr(LCDIFV2_Type * base,uint8_t layerIndex,uint32_t addr)500 static inline void LCDIFV2_SetLayerBufferAddr(LCDIFV2_Type *base, uint8_t layerIndex, uint32_t addr)
501 {
502     base->LAYER[layerIndex].CTRLDESCL4 = LCDIFV2_ADDR_CPU_2_IP(addr);
503 }
504 
505 /*!
506  * @brief Enable or disable the layer.
507  *
508  * @param base LCDIFv2 peripheral base address.
509  * @param layerIndex Layer layerIndex.
510  * @param enable Pass in true to enable, false to disable.
511  */
LCDIFV2_EnableLayer(LCDIFV2_Type * base,uint8_t layerIndex,bool enable)512 static inline void LCDIFV2_EnableLayer(LCDIFV2_Type *base, uint8_t layerIndex, bool enable)
513 {
514     if (enable)
515     {
516         base->LAYER[layerIndex].CTRLDESCL5 |= LCDIFV2_CTRLDESCL5_EN_MASK;
517     }
518     else
519     {
520         base->LAYER[layerIndex].CTRLDESCL5 &= ~LCDIFV2_CTRLDESCL5_EN_MASK;
521     }
522 }
523 
524 /*!
525  * @brief Trigger the layer configuration shadow load.
526  *
527  * The new layer configurations are written to the shadow registers first,
528  * When all configurations written finished, call this function, then shadowed
529  * control registers are updated to the active control registers on VSYNC of
530  * next frame.
531  *
532  * @param base LCDIFv2 peripheral base address.
533  * @param layerIndex Layer layerIndex.
534  */
LCDIFV2_TriggerLayerShadowLoad(LCDIFV2_Type * base,uint8_t layerIndex)535 static inline void LCDIFV2_TriggerLayerShadowLoad(LCDIFV2_Type *base, uint8_t layerIndex)
536 {
537     base->LAYER[layerIndex].CTRLDESCL5 |= LCDIFV2_CTRLDESCL5_SHADOW_LOAD_EN_MASK;
538 }
539 
540 /*!
541  * @brief Set the layer back ground color.
542  *
543  * The back ground color is used when layer not actived.
544  *
545  * @param base LCDIFv2 peripheral base address.
546  * @param layerIndex Index of the layer.
547  * @param backGroundColor Background color to use when this layer is not active.
548  */
LCDIFV2_SetLayerBackGroundColor(LCDIFV2_Type * base,uint8_t layerIndex,uint32_t backGroundColor)549 static inline void LCDIFV2_SetLayerBackGroundColor(LCDIFV2_Type *base, uint8_t layerIndex, uint32_t backGroundColor)
550 {
551     base->LAYER[layerIndex].CTRLDESCL6 = backGroundColor;
552 }
553 
554 /*!
555  * @brief Set the layer alpha blend mode.
556  *
557  * @param base LCDIFv2 peripheral base address.
558  * @param layerIndex Index of the CSC unit.
559  * @param config Pointer to the blend configuration.
560  */
561 void LCDIFV2_SetLayerBlendConfig(LCDIFV2_Type *base, uint8_t layerIndex, const lcdifv2_blend_config_t *config);
562 
563 /*!
564  * @brief Set the color space conversion mode.
565  *
566  * Supports YUV2RGB and YCbCr2RGB.
567  *
568  * @param base LCDIFv2 peripheral base address.
569  * @param layerIndex Index of the layer.
570  * @param mode The conversion mode.
571  */
572 void LCDIFV2_SetCscMode(LCDIFV2_Type *base, uint8_t layerIndex, lcdifv2_csc_mode_t mode);
573 
574 /*! @} */
575 
576 /*!
577  * @name Porter Duff
578  * @{
579  */
580 
581 /*!
582  * @brief Get the blend configuration for Porter Duff blend.
583  *
584  * This function gets the blend configuration for Porter Duff blend,
585  * config->pdFactorMode is set according to @p layer and @p mode,
586  * other blend configurations are set to:
587  *
588  * @code
589     config->pdAlphaMode = kLCDIFV2_PD_AlphaStraight;
590     config->pdColorMode = kLCDIFV2_PD_ColorStraight;
591     config->pdGlobalAlphaMode = kLCDIFV2_PD_LocalAlpha;
592     config->alphaMode = kLCDIFV2_AlphaPoterDuff;
593    @endcode
594  *
595  * This is the basic Porter Duff blend configuration, user still could
596  * modify the configurations after this function.
597  *
598  * @param mode Porter Duff blend mode.
599  * @param layer The configuration for source layer or destination layer.
600  * @param config Pointer to the configuration.
601  * @retval kStatus_Success Get the configuration successfully.
602  * @retval kStatus_InvalidArgument The argument is invalid.
603  */
604 status_t LCDIFV2_GetPorterDuffConfig(lcdifv2_pd_blend_mode_t mode,
605                                      lcdifv2_pd_layer_t layer,
606                                      lcdifv2_blend_config_t *config);
607 
608 /*! @} */
609 
610 /*!
611  * @name Misc
612  * @{
613  */
614 
615 /*!
616  * @brief Get the global alpha values for multiple layer blend.
617  *
618  * This function calculates the global alpha value for each layer based on the
619  * desired blended alpha.
620  *
621  * When all layers use the global alpha, the relationship of blended alpha
622  * and global alpha of each layer is:
623  *
624  * Layer 7: ba7 = ga7
625  * Layer 6: ba6 = ga6 * (1-ga7)
626  * Layer 5: ba5 = ga5 * (1-ga6) * (1-ga7)
627  * Layer 4: ba4 = ga4 * (1-ga5) * (1-ga6) * (1-ga7)
628  * Layer 3: ba3 = ga3 * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
629  * Layer 2: ba2 = ga2 * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
630  * Layer 1: ba1 = ga1 * (1-ga2) * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
631  * Layer 0: ba0 =   1 * (1-ga1) * (1-ga2) * (1-ga3) * (1-ga4) * (1-ga5) * (1-ga6) * (1-ga7)
632  *
633  * Here baN is the blended alpha of layer N, gaN is the global alpha configured to layer N.
634  *
635  * This function calculates the global alpha based on the blended alpha. The @p blendedAlpha and
636  * @p globalAlpha are all arrays of size @p layerCount. The first layer is a background layer,
637  * so blendedAlpha[0] is useless, globalAlpha[0] is always 255.
638  *
639  * @param[in] blendedAlpha The desired blended alpha value, alpha range 0~255.
640  * @param[out] globalAlpha Calculated global alpha set to each layer register.
641  * @param[in] layerCount Total layer count.
642  * @retval kStatus_Success Get successfully.
643  * @retval kStatus_InvalidArgument The argument is invalid.
644  */
645 status_t LCDIFV2_GetMultiLayerGlobalAlpha(const uint8_t blendedAlpha[], uint8_t globalAlpha[], uint8_t layerCount);
646 
647 /*! @} */
648 
649 #if defined(__cplusplus)
650 }
651 #endif /* __cplusplus */
652 
653 /*! @} */
654 
655 #endif /*FSL_LCDIFV2_H_*/
656