• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021–2022 Beijing OSWare Technology Co., Ltd
3  * This file contains confidential and proprietary information of
4  * OSWare Technology Co., Ltd
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include "display_layer.h"
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <sys/mman.h>
24 #include <securec.h>
25 #include "display_type.h"
26 #include "hdf_log.h"
27 #include "hdf_io_service_if.h"
28 #include "hdf_sbuf.h"
29 #include "osal_mem.h"
30 
31 #define DEV_ID                   0
32 #define LAYER_ID                 0
33 #define FB_PATH                  "/dev/fb0"
34 #define DISP_WIDTH               800
35 #define DISP_HEIGHT              480
36 #define BITS_PER_PIXEL           32
37 #define BITS_TO_BYTE             8
38 #define DISP_SERVICE_NAME        "hdf_disp"
39 #define DISP_CMD_GET_PANELINFO   1
40 
41 #undef  HDF_LOG_TAG
42 #define HDF_LOG_TAG              display_layer_c
43 
44 /* output timing */
45 enum IntfSync {
46     OUTPUT_USER = 0,          /* User timing */
47     OUTPUT_PAL,               /* PAL standard */
48     OUTPUT_NTSC,              /* NTSC standard */
49     OUTPUT_1080P24,           /* 1920 x 1080 at 24 Hz. */
50     OUTPUT_1080P25,           /* 1920 x 1080 at 25 Hz. */
51     OUTPUT_1080P30,           /* 1920 x 1080 at 30 Hz. */
52     OUTPUT_720P50,            /* 1280 x  720 at 50 Hz. */
53     OUTPUT_720P60,            /* 1280 x  720 at 60 Hz. */
54     OUTPUT_1080I50,           /* 1920 x 1080 at 50 Hz, interlace. */
55     OUTPUT_1080I60,           /* 1920 x 1080 at 60 Hz, interlace. */
56     OUTPUT_1080P50,           /* 1920 x 1080 at 50 Hz. */
57     OUTPUT_1080P60,           /* 1920 x 1080 at 60 Hz. */
58     OUTPUT_576P50,            /* 720  x  576 at 50 Hz. */
59     OUTPUT_480P60,            /* 720  x  480 at 60 Hz. */
60     OUTPUT_800X600_60,        /* VESA 800 x 600 at 60 Hz (non-interlaced) */
61     OUTPUT_1024X768_60,       /* VESA 1024 x 768 at 60 Hz (non-interlaced) */
62     OUTPUT_1280X1024_60,      /* VESA 1280 x 1024 at 60 Hz (non-interlaced) */
63     OUTPUT_1366X768_60,       /* VESA 1366 x 768 at 60 Hz (non-interlaced) */
64     OUTPUT_1440X900_60,       /* VESA 1440 x 900 at 60 Hz (non-interlaced) CVT Compliant */
65     OUTPUT_1280X800_60,       /* 1280*800@60Hz VGA@60Hz */
66     OUTPUT_1600X1200_60,      /* VESA 1600 x 1200 at 60 Hz (non-interlaced) */
67     OUTPUT_1680X1050_60,      /* VESA 1680 x 1050 at 60 Hz (non-interlaced) */
68     OUTPUT_1920X1200_60,      /* VESA 1920 x 1600 at 60 Hz (non-interlaced) CVT (Reduced Blanking) */
69     OUTPUT_640X480_60,        /* VESA 640 x 480 at 60 Hz (non-interlaced) CVT */
70     OUTPUT_960H_PAL,          /* ITU-R BT.1302 960 x 576 at 50 Hz (interlaced) */
71     OUTPUT_960H_NTSC,         /* ITU-R BT.1302 960 x 480 at 60 Hz (interlaced) */
72     OUTPUT_1920X2160_30,      /* 1920x2160_30 */
73     OUTPUT_2560X1440_30,      /* 2560x1440_30 */
74     OUTPUT_2560X1440_60,      /* 2560x1440_60 */
75     OUTPUT_2560X1600_60,      /* 2560x1600_60 */
76     OUTPUT_3840X2160_24,      /* 3840x2160_24 */
77     OUTPUT_3840X2160_25,      /* 3840x2160_25 */
78     OUTPUT_3840X2160_30,      /* 3840x2160_30 */
79     OUTPUT_3840X2160_50,      /* 3840x2160_50 */
80     OUTPUT_3840X2160_60,      /* 3840x2160_60 */
81     OUTPUT_4096X2160_24,      /* 4096x2160_24 */
82     OUTPUT_4096X2160_25,      /* 4096x2160_25 */
83     OUTPUT_4096X2160_30,      /* 4096x2160_30 */
84     OUTPUT_4096X2160_50,      /* 4096x2160_50 */
85     OUTPUT_4096X2160_60,      /* 4096x2160_60 */
86     OUTPUT_320X240_60,        /* For ota5182 at 60 Hz (8bit) */
87     OUTPUT_320X240_50,        /* For ili9342 at 50 Hz (6bit) */
88     OUTPUT_240X320_50,        /* Hi3559AV100: For ili9341 at 50 Hz (6bit) */
89     OUTPUT_240X320_60,        /* For ili9341 at 60 Hz (16bit) */
90     OUTPUT_800X600_50,        /* For LCD     at 50 Hz (24bit) */
91     OUTPUT_720X1280_60,       /* For MIPI DSI Tx 720 x1280 at 60 Hz */
92     OUTPUT_1080X1920_60,      /* For MIPI DSI Tx 1080x1920 at 60 Hz */
93     OUTPUT_7680X4320_30,      /* For HDMI2.1 at 30 Hz */
94 };
95 
96 struct DispInfo {
97     uint32_t width;
98     uint32_t hbp;
99     uint32_t hfp;
100     uint32_t hsw;
101     uint32_t height;
102     uint32_t vbp;
103     uint32_t vfp;
104     uint32_t vsw;
105     uint32_t frameRate;
106     uint32_t intfType;
107     enum IntfSync intfSync;
108     uint32_t minLevel;
109     uint32_t maxLevel;
110     uint32_t defLevel;
111 };
112 
113 struct LayerPrivate {
114     int32_t  fd;
115     uint32_t width;
116     uint32_t height;
117     int32_t  pitch;
118     void     *fbAddr;
119     uint32_t fbSize;
120     void     *layerAddr;
121     PixelFormat pixFmt;
122 };
123 
124 struct LayerManager {
125     pthread_mutex_t mutex;
126     pthread_mutexattr_t mutexattr;
127     int32_t count;
128 };
129 
130 static struct LayerManager g_layerManager;
131 
GetLayerMgr(void)132 static void GetLayerMgr(void)
133 {
134     g_layerManager.count++;
135 }
136 
PutLayerMgr(void)137 static int32_t PutLayerMgr(void)
138 {
139     g_layerManager.count--;
140     return g_layerManager.count;
141 }
142 
LockLayerMgr(void)143 static void LockLayerMgr(void)
144 {
145     pthread_mutex_lock(&g_layerManager.mutex);
146 }
147 
UnlockLayerMgr(void)148 static void UnlockLayerMgr(void)
149 {
150     pthread_mutex_unlock(&g_layerManager.mutex);
151 }
152 
DispCmdSend(const uint32_t cmd,struct HdfSBuf * reqData,struct HdfSBuf * respData)153 static int32_t DispCmdSend(const uint32_t cmd, struct HdfSBuf *reqData, struct HdfSBuf *respData)
154 {
155     struct HdfIoService *dispService = NULL;
156 
157     dispService = HdfIoServiceBind(DISP_SERVICE_NAME);
158     if ((dispService == NULL) || (dispService->dispatcher == NULL) || (dispService->dispatcher->Dispatch == NULL)) {
159         HDF_LOGE("%s:bad remote service found", __func__);
160         return DISPLAY_FAILURE;
161     }
162     int32_t ret = dispService->dispatcher->Dispatch(&dispService->object, cmd, reqData, respData);
163     if (ret != DISPLAY_SUCCESS) {
164         HDF_LOGE("%s: cmd=%u, ret=%d", __func__, cmd, ret);
165         HdfIoServiceRecycle(dispService);
166         return DISPLAY_FAILURE;
167     }
168     HdfIoServiceRecycle(dispService);
169     return DISPLAY_SUCCESS;
170 }
171 
GetInfo(uint32_t devId,struct DispInfo * info)172 static int32_t GetInfo(uint32_t devId, struct DispInfo *info)
173 {
174     struct DispInfo *tmpInfo = NULL;
175     struct HdfSBuf *data = NULL;
176     struct HdfSBuf *reply = NULL;
177 
178     if (info == NULL) {
179         HDF_LOGE("%s: invalid param", __func__);
180         return DISPLAY_FAILURE;
181     }
182     data = HdfSbufObtainDefaultSize();
183     if (data == NULL) {
184         HDF_LOGE("%s: obtain data sbuf fail", __func__);
185         return DISPLAY_FAILURE;
186     }
187     reply = HdfSbufObtainDefaultSize();
188     if (reply == NULL) {
189         HDF_LOGE("%s: obtain reply sbuf fail", __func__);
190         HdfSbufRecycle(data);
191         return DISPLAY_FAILURE;
192     }
193     if (!HdfSbufWriteUint32(data, devId)) {
194         HDF_LOGE("HdfSbufWriteUint32 failure");
195         HdfSbufRecycle(data);
196         HdfSbufRecycle(reply);
197         return DISPLAY_FAILURE;
198     }
199     if (DispCmdSend(DISP_CMD_GET_PANELINFO, data, reply) != DISPLAY_SUCCESS) {
200         HDF_LOGE("cmd:DISP_CMD_GET_PANEL_INFO failure");
201         HdfSbufRecycle(data);
202         HdfSbufRecycle(reply);
203         return DISPLAY_FAILURE;
204     }
205     uint32_t dataSize = 0;
206     if (!HdfSbufReadBuffer(reply, (const void **)(&tmpInfo), &dataSize) || dataSize != sizeof(struct DispInfo)) {
207         HDF_LOGE("HdfSbufReadBuffer failure");
208         HdfSbufRecycle(data);
209         HdfSbufRecycle(reply);
210         return DISPLAY_FAILURE;
211     }
212     if (memcpy_s(info, sizeof(struct DispInfo), tmpInfo, dataSize) != EOK) {
213         HDF_LOGE("memcpy_s failure");
214         HdfSbufRecycle(data);
215         HdfSbufRecycle(reply);
216         return DISPLAY_FAILURE;
217     }
218     HdfSbufRecycle(data);
219     HdfSbufRecycle(reply);
220     return DISPLAY_SUCCESS;
221 }
222 
GetLayerInstance(void)223 static struct LayerPrivate *GetLayerInstance(void)
224 {
225     static int32_t count;
226     static struct DispInfo info;
227     static struct LayerPrivate layerPriv = {
228         .fd = -1,
229         .width = DISP_WIDTH,
230         .height = DISP_HEIGHT,
231         .pixFmt = PIXEL_FMT_RGBA_8888,
232     };
233 
234     if (count == 0) {
235         count = 1;
236         if (GetInfo(DEV_ID, &info) == DISPLAY_SUCCESS) {
237             layerPriv.width = info.width;
238             layerPriv.height = info.height;
239         } else {
240             HDF_LOGI("%s: GetInfo failed, use default setting", __func__);
241         }
242     }
243     return &layerPriv;
244 }
245 
InitDisplay(uint32_t devId)246 static int32_t InitDisplay(uint32_t devId)
247 {
248     if (devId != DEV_ID) {
249         HDF_LOGE("%s: devId invalid", __func__);
250         return DISPLAY_FAILURE;
251     }
252     return DISPLAY_SUCCESS;
253 }
254 
DeinitDisplay(uint32_t devId)255 static int32_t DeinitDisplay(uint32_t devId)
256 {
257     if (devId != DEV_ID) {
258         HDF_LOGE("%s: devId invalid", __func__);
259         return DISPLAY_FAILURE;
260     }
261     return DISPLAY_SUCCESS;
262 }
263 
SetBackground(void)264 static void SetBackground(void)
265 {
266     struct LayerPrivate *priv = GetLayerInstance();
267     uint32_t i;
268     uint32_t j;
269     uint32_t *framebuffer = (uint32_t *)priv->fbAddr;
270     for (j = 0; j < priv->height; j++) {
271         for (i = 0; i < priv->width; i++) {
272             framebuffer[i + j * priv->width] = 0xFF; // Blue background
273         }
274     }
275 }
276 
CreateLayer(uint32_t devId,const LayerInfo * layerInfo,uint32_t * layerId)277 static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
278 {
279     if (layerInfo == NULL || layerId == NULL) {
280         HDF_LOGE("%s: pointer is null", __func__);
281         return DISPLAY_NULL_PTR;
282     }
283     if (devId != DEV_ID) {
284         HDF_LOGE("%s: devId invalid", __func__);
285         return DISPLAY_FAILURE;
286     }
287     LockLayerMgr();
288     struct LayerPrivate *priv = GetLayerInstance();
289     priv->fd = open(FB_PATH, O_RDWR, 0);
290     if (priv->fd < 0) {
291         HDF_LOGE("%s: open fb dev failed", __func__);
292         UnlockLayerMgr();
293         return DISPLAY_FD_ERR;
294     }
295     priv->pitch = layerInfo->width * BITS_PER_PIXEL / BITS_TO_BYTE;
296     priv->fbSize = ((priv->pitch * priv->height) + 0xfff) & (~0xfff);
297     priv->fbAddr = (void *)mmap(NULL, priv->fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, 0);
298     if (priv->fbAddr == NULL) {
299         HDF_LOGE("%s: mmap fb address failure, errno: %d", __func__, errno);
300         close(priv->fd);
301         priv->fd = -1;
302         priv->pitch = 0;
303         priv->fbSize = 0;
304         UnlockLayerMgr();
305         return DISPLAY_FAILURE;
306     }
307     SetBackground();
308     *layerId = LAYER_ID;
309     HDF_LOGI("%s: open layer success", __func__);
310     UnlockLayerMgr();
311     return DISPLAY_SUCCESS;
312 }
313 
CloseLayer(uint32_t devId,uint32_t layerId)314 static int32_t CloseLayer(uint32_t devId, uint32_t layerId)
315 {
316     if (devId != DEV_ID) {
317         HDF_LOGE("%s: devId invalid", __func__);
318         return DISPLAY_FAILURE;
319     }
320     if (layerId != LAYER_ID) {
321         HDF_LOGE("%s: layerId invalid", __func__);
322         return DISPLAY_FAILURE;
323     }
324     LockLayerMgr();
325     struct LayerPrivate *priv = GetLayerInstance();
326     if (priv->fd >= 0) {
327         close(priv->fd);
328     }
329     if (priv->layerAddr != NULL) {
330         free(priv->layerAddr);
331         priv->layerAddr = NULL;
332     }
333     if (priv->fbAddr != NULL) {
334         munmap(priv->fbAddr, priv->fbSize);
335     }
336     priv->fd = -1;
337     UnlockLayerMgr();
338     return DISPLAY_SUCCESS;
339 }
340 
GetDisplayInfo(uint32_t devId,DisplayInfo * dispInfo)341 static int32_t GetDisplayInfo(uint32_t devId, DisplayInfo *dispInfo)
342 {
343     if (dispInfo == NULL) {
344         HDF_LOGE("%s: dispInfo is null", __func__);
345         return DISPLAY_NULL_PTR;
346     }
347     if (devId != DEV_ID) {
348         HDF_LOGE("%s: devId invalid", __func__);
349         return DISPLAY_FAILURE;
350     }
351     LockLayerMgr();
352     struct LayerPrivate *priv = GetLayerInstance();
353     dispInfo->width = priv->width;
354     dispInfo->height = priv->height;
355     dispInfo->rotAngle = ROTATE_NONE;
356     HDF_LOGD("%s: width = %u, height = %u, rotAngle = %u", __func__, dispInfo->width,
357         dispInfo->height, dispInfo->rotAngle);
358     UnlockLayerMgr();
359     return DISPLAY_SUCCESS;
360 }
361 
Flush(uint32_t devId,uint32_t layerId,LayerBuffer * buffer)362 static int32_t Flush(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
363 {
364     int32_t ret;
365 
366     if (devId != DEV_ID) {
367         HDF_LOGE("%s: devId invalid", __func__);
368         return DISPLAY_FAILURE;
369     }
370     if (layerId != LAYER_ID) {
371         HDF_LOGE("%s: layerId invalid", __func__);
372         return DISPLAY_FAILURE;
373     }
374     if (buffer == NULL) {
375         HDF_LOGE("%s: buffer is null", __func__);
376         return DISPLAY_FAILURE;
377     }
378 
379     HDF_LOGD("%s: width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->width,
380         buffer->height, buffer->pixFormat, buffer->pitch);
381     LockLayerMgr();
382     struct LayerPrivate *priv = GetLayerInstance();
383     ret = memcpy_s(priv->fbAddr, priv->fbSize, buffer->data.virAddr, priv->fbSize);
384     if (ret != EOK) {
385         HDF_LOGE("%s: memcpy_s fail, ret %d", __func__, ret);
386         UnlockLayerMgr();
387         return ret;
388     }
389     UnlockLayerMgr();
390     return DISPLAY_SUCCESS;
391 }
392 
GetLayerBuffer(uint32_t devId,uint32_t layerId,LayerBuffer * buffer)393 static int32_t GetLayerBuffer(uint32_t devId, uint32_t layerId, LayerBuffer *buffer)
394 {
395     if (buffer == NULL) {
396         HDF_LOGE("%s: buffer is null", __func__);
397         return DISPLAY_NULL_PTR;
398     }
399     if (devId != DEV_ID) {
400         HDF_LOGE("%s: devId invalid", __func__);
401         return DISPLAY_FAILURE;
402     }
403     if (layerId != LAYER_ID) {
404         HDF_LOGE("%s: layerId invalid", __func__);
405         return DISPLAY_FAILURE;
406     }
407     LockLayerMgr();
408     struct LayerPrivate *priv = GetLayerInstance();
409     if (priv->fd < 0) {
410         HDF_LOGE("%s: fd invalid", __func__);
411         UnlockLayerMgr();
412         return DISPLAY_FAILURE;
413     }
414     buffer->fenceId = 0;
415     buffer->width = priv->width;
416     buffer->height = priv->height;
417     buffer->pixFormat = priv->pixFmt;
418     buffer->pitch = priv->pitch;
419     buffer->data.virAddr = malloc(priv->fbSize);
420     if (buffer->data.virAddr == NULL) {
421         HDF_LOGE("%s: malloc failure", __func__);
422         UnlockLayerMgr();
423         return DISPLAY_FAILURE;
424     }
425     priv->layerAddr = buffer->data.virAddr;
426     (void)memset_s(buffer->data.virAddr, priv->fbSize, 0x00, priv->fbSize);
427     HDF_LOGD("%s: fenceId = %d, width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->fenceId,
428         buffer->width, buffer->height, buffer->pixFormat, buffer->pitch);
429     UnlockLayerMgr();
430     return DISPLAY_SUCCESS;
431 }
432 
LayerInitialize(LayerFuncs ** funcs)433 int32_t LayerInitialize(LayerFuncs **funcs)
434 {
435     static LayerFuncs *lFuncs = NULL;
436 
437     if (funcs == NULL) {
438         HDF_LOGE("%s: funcs is null", __func__);
439         return DISPLAY_NULL_PTR;
440     }
441     if (lFuncs == NULL) {
442         lFuncs = (LayerFuncs *)OsalMemCalloc(sizeof(LayerFuncs));
443         if (lFuncs == NULL) {
444             HDF_LOGE("%s: lFuncs is null", __func__);
445             return DISPLAY_NULL_PTR;
446         }
447         pthread_mutexattr_init(&g_layerManager.mutexattr);
448         pthread_mutexattr_setpshared(&g_layerManager.mutexattr, PTHREAD_PROCESS_SHARED);
449         pthread_mutex_init(&g_layerManager.mutex, &g_layerManager.mutexattr);
450         lFuncs->InitDisplay = InitDisplay;
451         lFuncs->DeinitDisplay = DeinitDisplay;
452         lFuncs->GetDisplayInfo = GetDisplayInfo;
453         lFuncs->CreateLayer = CreateLayer;
454         lFuncs->CloseLayer = CloseLayer;
455         lFuncs->Flush = Flush;
456         lFuncs->GetLayerBuffer = GetLayerBuffer;
457     }
458     *funcs = lFuncs;
459     GetLayerMgr();
460     HDF_LOGI("%s: success", __func__);
461     return DISPLAY_SUCCESS;
462 }
463 
LayerUninitialize(LayerFuncs * funcs)464 int32_t LayerUninitialize(LayerFuncs *funcs)
465 {
466     if (funcs == NULL) {
467         HDF_LOGE("%s: funcs is null", __func__);
468         return DISPLAY_NULL_PTR;
469     }
470     if (PutLayerMgr() == 0) {
471         pthread_mutexattr_destroy(&g_layerManager.mutexattr);
472         pthread_mutex_destroy(&g_layerManager.mutex);
473         OsalMemFree(funcs);
474     }
475     HDF_LOGI("%s: layer uninitialize success", __func__);
476     return DISPLAY_SUCCESS;
477 }
478