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