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 */ 43enum 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 94struct 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 111struct 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 122struct LayerManager { 123 pthread_mutex_t mutex; 124 pthread_mutexattr_t mutexattr; 125 int32_t count; 126}; 127 128static struct LayerManager g_layerManager; 129 130static void GetLayerMgr(void) 131{ 132 g_layerManager.count++; 133} 134 135static int32_t PutLayerMgr(void) 136{ 137 g_layerManager.count--; 138 return g_layerManager.count; 139} 140 141static void LockLayerMgr(void) 142{ 143 pthread_mutex_lock(&g_layerManager.mutex); 144} 145 146static void UnlockLayerMgr(void) 147{ 148 pthread_mutex_unlock(&g_layerManager.mutex); 149} 150 151static 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 170static 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 212ERR: 213 HdfSbufRecycle(data); 214 HdfSbufRecycle(reply); 215 return DISPLAY_FAILURE; 216} 217 218static 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 241static 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 250static 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 259static 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 272static 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 309static 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 336static 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 357static 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 388static 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 428int32_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 459int32_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