1 /*
2  * Copyright 2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_dc_fb_dbi.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 const dc_fb_ops_t g_dcFbOpsDbi = {
14     .init                  = DC_FB_DBI_Init,
15     .deinit                = DC_FB_DBI_Deinit,
16     .enableLayer           = DC_FB_DBI_EnableLayer,
17     .disableLayer          = DC_FB_DBI_DisableLayer,
18     .setLayerConfig        = DC_FB_DBI_SetLayerConfig,
19     .getLayerDefaultConfig = DC_FB_DBI_GetLayerDefaultConfig,
20     .setFrameBuffer        = DC_FB_DBI_SetFrameBuffer,
21     .getProperty           = DC_FB_DBI_GetProperty,
22     .setCallback           = DC_FB_DBI_SetCallback,
23 };
24 
25 /*******************************************************************************
26  * Prototypes
27  ******************************************************************************/
DC_FB_DBI_FrameDoneCallback(status_t status,void * userData)28 static void DC_FB_DBI_FrameDoneCallback(status_t status, void *userData)
29 {
30     dc_fb_dbi_handle_t *dcDbiHandle;
31 
32     dcDbiHandle = (dc_fb_dbi_handle_t *)userData;
33 
34     /* Frame buffer data has been sent to the panel, the frame buffer is free
35      * to be used for set new data, call the callback to notify upper layer.
36      * The callback is set in application or fbdev.
37      */
38     dcDbiHandle->callback(dcDbiHandle->cbParam, (void *)dcDbiHandle->frameBuffer);
39 }
40 
41 /*******************************************************************************
42  * Variables
43  ******************************************************************************/
44 
45 /*******************************************************************************
46  * Code
47  ******************************************************************************/
DC_FB_DBI_Init(const dc_fb_t * dc)48 status_t DC_FB_DBI_Init(const dc_fb_t *dc)
49 {
50     status_t status = kStatus_Success;
51 
52     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
53 
54     if (0U == dcDbiHandle->initTimes++)
55     {
56         /* Initialize the panel. */
57         DBI_IFACE_SetMemoryDoneCallback(dcDbiHandle->dbiIface, DC_FB_DBI_FrameDoneCallback, dcDbiHandle);
58     }
59 
60     return status;
61 }
62 
DC_FB_DBI_Deinit(const dc_fb_t * dc)63 status_t DC_FB_DBI_Deinit(const dc_fb_t *dc)
64 {
65     status_t status = kStatus_Success;
66 
67     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
68 
69     if (dcDbiHandle->initTimes > 0U)
70     {
71         if (--dcDbiHandle->initTimes == 0U)
72         {
73             status = DBI_IFACE_SetDiplayOn(dcDbiHandle->dbiIface, false);
74         }
75     }
76 
77     return status;
78 }
79 
DC_FB_DBI_EnableLayer(const dc_fb_t * dc,uint8_t layer)80 status_t DC_FB_DBI_EnableLayer(const dc_fb_t *dc, uint8_t layer)
81 {
82     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
83     return DBI_IFACE_SetDiplayOn(dcDbiHandle->dbiIface, true);
84 }
85 
DC_FB_DBI_DisableLayer(const dc_fb_t * dc,uint8_t layer)86 status_t DC_FB_DBI_DisableLayer(const dc_fb_t *dc, uint8_t layer)
87 {
88     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
89     return DBI_IFACE_SetDiplayOn(dcDbiHandle->dbiIface, false);
90 }
91 
DC_FB_DBI_SetLayerConfig(const dc_fb_t * dc,uint8_t layer,dc_fb_info_t * fbInfo)92 status_t DC_FB_DBI_SetLayerConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
93 {
94     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
95 
96     dcDbiHandle->fbInfo = *fbInfo;
97 
98     return DBI_IFACE_SelectArea(dcDbiHandle->dbiIface, fbInfo->startX, fbInfo->startY,
99                                 fbInfo->startX + fbInfo->width - 1U, fbInfo->startY + fbInfo->height - 1U);
100 }
101 
DC_FB_DBI_GetLayerDefaultConfig(const dc_fb_t * dc,uint8_t layer,dc_fb_info_t * fbInfo)102 status_t DC_FB_DBI_GetLayerDefaultConfig(const dc_fb_t *dc, uint8_t layer, dc_fb_info_t *fbInfo)
103 {
104     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
105 
106     fbInfo->startX      = 0;
107     fbInfo->startY      = 0;
108     fbInfo->width       = dcDbiHandle->width;
109     fbInfo->height      = dcDbiHandle->height;
110     fbInfo->strideBytes = dcDbiHandle->width * VIDEO_GetPixelSizeBits(dcDbiHandle->pixelFormat) / 8U;
111     fbInfo->pixelFormat = dcDbiHandle->pixelFormat;
112 
113     return kStatus_Success;
114 }
115 
DC_FB_DBI_SetFrameBuffer(const dc_fb_t * dc,uint8_t layer,void * frameBuffer)116 status_t DC_FB_DBI_SetFrameBuffer(const dc_fb_t *dc, uint8_t layer, void *frameBuffer)
117 {
118     status_t status;
119 
120     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
121     dc_fb_info_t *fbInfo;
122     dcDbiHandle->frameBuffer = frameBuffer;
123 
124     if (dcDbiHandle->useTEPin)
125     {
126         /* Save to send at TE. */
127         dcDbiHandle->fbWaitTE = true;
128         status                = kStatus_Success;
129     }
130     else
131     {
132         fbInfo = &dcDbiHandle->fbInfo;
133         status = DBI_IFACE_WriteMemory(dcDbiHandle->dbiIface, (const uint8_t *)frameBuffer,
134                                        (uint32_t)fbInfo->strideBytes * (uint32_t)fbInfo->height);
135     }
136 
137     return status;
138 }
139 
DC_FB_DBI_GetProperty(const dc_fb_t * dc)140 uint32_t DC_FB_DBI_GetProperty(const dc_fb_t *dc)
141 {
142     return 0U;
143 }
144 
DC_FB_DBI_SetCallback(const dc_fb_t * dc,uint8_t layer,dc_fb_callback_t callback,void * param)145 void DC_FB_DBI_SetCallback(const dc_fb_t *dc, uint8_t layer, dc_fb_callback_t callback, void *param)
146 {
147     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
148 
149     dcDbiHandle->callback = callback;
150     dcDbiHandle->cbParam  = param;
151 }
152 
DC_FB_DBI_TE_IRQHandler(const dc_fb_t * dc)153 void DC_FB_DBI_TE_IRQHandler(const dc_fb_t *dc)
154 {
155     dc_fb_dbi_handle_t *dcDbiHandle = (dc_fb_dbi_handle_t *)dc->prvData;
156     dc_fb_info_t *fbInfo            = &dcDbiHandle->fbInfo;
157 
158     if (dcDbiHandle->fbWaitTE)
159     {
160         dcDbiHandle->fbWaitTE = false;
161         (void)DBI_IFACE_WriteMemory(dcDbiHandle->dbiIface, (const uint8_t *)dcDbiHandle->frameBuffer,
162                               (uint32_t)fbInfo->strideBytes * (uint32_t)fbInfo->height);
163     }
164 }
165