Files
fml13v01-buildroot/package/starfive/v4l2_test/stf_framebuffer.c
T
mason.huo cf9c62a4f1 package: Move v4l2test to starfive package
1.Create starfive package, and move v4l2test into it.
2.Sync the latest v4l2test package from JH7100.

Signed-off-by: mason.huo <mason.huo@starfivetech.com>

(cherry-pick commit 87583e4004ba7ceefa317d939ea8004f38eb9570 from jh7110-mm-devel branch)
2022-06-10 10:49:06 +08:00

129 lines
4.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2021 StarFive Technology Co., Ltd.
*/
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "common.h"
#include "stf_framebuffer.h"
#include "stf_log.h"
#define FBIOPAN_GET_PP_MODE 0x4609
#define FBIOPAN_SET_PP_MODE 0x460a
void stf_fb_open(FBParam_t *param, char *device_name, char *stfbc_name)
{
LOG(STF_LEVEL_TRACE, "Enter\n");
//open framebuffer
param->fd = open(device_name, O_RDWR);
if (param->fd == -1) {
LOG(STF_LEVEL_ERR, "Error: cannot open framebuffer device.\n");
exit(EXIT_FAILURE);
}
//open stfbc device for pp setting
param->stfbc_fd = open(stfbc_name, O_RDWR);
if (param->stfbc_fd == -1) {
LOG(STF_LEVEL_ERR, "Error: cannot open stfbcdev device.\n");
exit(EXIT_FAILURE);
}
LOG(STF_LEVEL_TRACE, "Exit\n");
}
void stf_fb_close(FBParam_t *param)
{
LOG(STF_LEVEL_TRACE, "Enter\n");
if (param->fd > 0) {
close(param->fd);
param->fd = 0;
}
if (param->stfbc_fd > 0) {
close(param->stfbc_fd);
param->stfbc_fd = 0;
}
LOG(STF_LEVEL_TRACE, "Exit\n");
}
void stf_fb_init(FBParam_t *param, uint32_t v4l2_fmt)
{
int pixformat;
struct pp_mode pp_info[3];
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
LOG(STF_LEVEL_TRACE, "Enter\n");
// step 1: try to set the fb format got from cmd options
pixformat = v4l2fmt_to_fbfmt(v4l2_fmt);
if (-1 == ioctl(param->stfbc_fd, FBIOPAN_GET_PP_MODE, &pp_info[0])) {
LOG(STF_LEVEL_ERR, "Error reading variable information.\n");
exit (EXIT_FAILURE);
}
LOG(STF_LEVEL_INFO, "Before set_pp_mode. get fb format:%d, will set fb format:%d\n",
pp_info[1].src.format, pixformat);
pp_info[1].src.format = pixformat;
if (-1 == ioctl(param->stfbc_fd, FBIOPAN_SET_PP_MODE, &pp_info[0])) {
LOG(STF_LEVEL_ERR, "Error reading variable information.\n");
exit (EXIT_FAILURE);
}
if (-1 == ioctl(param->stfbc_fd, FBIOPAN_GET_PP_MODE, &pp_info[0])) {
LOG(STF_LEVEL_ERR, "Error reading variable information.\n");
exit (EXIT_FAILURE);
}
LOG(STF_LEVEL_INFO, "After set_pp_mode. get fb format:%d\n", pp_info[1].src.format);
pixformat = pp_info[1].src.format;
param->pixformat = pixformat;
// step 2: Get fixed screen information
if (-1 == ioctl(param->fd, FBIOGET_FSCREENINFO, &finfo)) {
LOG(STF_LEVEL_ERR, "Error reading fixed information.\n");
exit (EXIT_FAILURE);
}
memcpy(&(param->finfo), &finfo, sizeof(finfo));
// step 3: Get variable screen information
if (-1 == ioctl(param->fd, FBIOGET_VSCREENINFO, &vinfo)) {
LOG(STF_LEVEL_ERR, "Error reading variable information.\n");
exit (EXIT_FAILURE);
}
memcpy(&(param->vinfo), &vinfo, sizeof(vinfo));
LOG(STF_LEVEL_INFO, "print screen information:\n");
LOG(STF_LEVEL_INFO, " vinfo.xres = %d, vinfo.yres = %d, grayscale = %d\n", vinfo.xres, vinfo.yres, vinfo.grayscale);
LOG(STF_LEVEL_INFO, " vinfo.xoffset = %d, vinfo.yoffset = %d\n", vinfo.xoffset, vinfo.yoffset);
LOG(STF_LEVEL_INFO, " vinfo.bits_per_pixel = %d, finfo.line_length = %d\n", vinfo.bits_per_pixel, finfo.line_length);
// if (ioctl(param->fd, FBIOPUT_VSCREENINFO, &g_vinfo) < 0) {
// LOG(STF_LEVEL_ERR, "FBIOPUT_VSCREENINFO.\n");
// exit (EXIT_FAILURE);
// }
// step 4: mmap fb buf to user space and update the actually screen param
param->width = vinfo.xres;
param->height = vinfo.yres;
param->bpp = vinfo.bits_per_pixel;
param->screen_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// g_screensize = g_vinfo.xres * g_vinfo.yres * 32 / 8;
param->screen_buf = (uint8_t *)mmap(NULL, param->screen_size,
PROT_READ | PROT_WRITE, MAP_SHARED, param->fd, 0);
if (param->screen_buf == (void *)(-1)) {
LOG(STF_LEVEL_ERR, "Error: failed to map framebuffer device to memory.\n");
exit (EXIT_FAILURE) ;
}
memset(param->screen_buf, 0x00, param->screen_size);
LOG(STF_LEVEL_TRACE, "Exit\n");
}
void stf_fb_uninit(FBParam_t *param)
{
LOG(STF_LEVEL_TRACE, "Enter\n");
if (-1 == munmap((void *)param->screen_buf, param->screen_size)) {
LOG(STF_LEVEL_ERR, " Error: framebuffer device munmap() failed.\n");
exit (EXIT_FAILURE) ;
}
LOG(STF_LEVEL_TRACE, "Exit\n");
}