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