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