open drm device

This commit is contained in:
Vincent Wei
2019-06-10 16:11:18 +08:00
parent 59e79143fb
commit 1a5383b9bf
5 changed files with 179 additions and 14 deletions

View File

@@ -902,6 +902,8 @@ CheckDRM()
VIDEO_DRIVERS="$VIDEO_DRIVERS drm/libvideo_drm.la"
DEP_LIBS="$DEP_LIBS -ldrm"
need_udev="yes"
DRM_INC_DIR="`$PKG_CONFIG --variable includedir libdrm`/drm"
AC_SUBST(DRM_INC_DIR)
else
AC_MSG_WARN([$video_drm])
fi

View File

@@ -84,6 +84,49 @@ struct commlcd_info {
extern "C" {
#endif /* __cplusplus */
#ifdef _MGGAL_DRM
#include <stdint.h>
/*
* this struct should be defined by the driver
*/
struct _DrmDriver;
typedef struct _DrmDriver DrmDriver;
typedef struct _DrmDriverOps {
DrmDriver* (*create_driver) (int device_fd);
void (*destroy_driver) (DrmDriver *driver);
uint32_t (* create_buffer) (DrmDriver *driver,
unsigned int width, unsigned int height,
unsigned int *pitch);
BOOL (* fetch_buffer) (DrmDriver *driver,
uint32_t buffer_id,
unsigned int *width, unsigned int *height,
unsigned int *pitch);
BOOL (* map_buffer) (DrmDriver *driver,
uint32_t buffer_id);
void (* unmap_buffer) (DrmDriver *driver,
uint32_t buffer_id);
char * (* begin_flush) (DrmDriver *driver,
uint32_t buffer_id);
void (* end_flush) (DrmDriver *driver,
uint32_t buffer_id);
void (* destroy_buffer) (DrmDriver *driver,
uint32_t buffer_id);
} DrmDriverOps;
/* implement this stub to return the DRM driver operators */
DrmDriverOps* __drm_ex_driver_get (const char* driver_name);
#endif /* _MGGAL_DRM */
/* external stubs for COMMLCD NEWGAL engine */
#ifdef _MGGAL_COMMLCD

View File

@@ -1,6 +1,6 @@
## Makefile.am for the drm video driver
AM_CPPFLAGS = -I$(abs_top_srcdir)/src/include -I$(abs_top_srcdir)/include -I$(abs_top_srcdir)/src/newgal/
AM_CPPFLAGS = -I$(abs_top_srcdir)/src/include -I$(abs_top_srcdir)/include -I$(abs_top_srcdir)/src/newgal/ -I$(DRM_INC_DIR)
noinst_LTLIBRARIES = libvideo_drm.la

View File

@@ -35,16 +35,27 @@
#include <stdlib.h>
#include <string.h>
#define _DEBUG
#include "common.h"
#include "newgal.h"
#include "sysvideo.h"
#include "pixels_c.h"
#ifdef _MGGAL_DRM
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <drm/drm.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "minigui.h"
#include "newgal.h"
#include "exstubs.h"
#include "pixels_c.h"
#include "drmvideo.h"
#define DRMVID_DRIVER_NAME "drm"
#define DRM_DRIVER_NAME "drm"
/* Initialization/Query functions */
static int DRM_VideoInit(_THIS, GAL_PixelFormat *vformat);
@@ -61,15 +72,104 @@ static void DRM_FreeHWSurface(_THIS, GAL_Surface *surface);
static int DRM_Available(void)
{
return(1);
return drmAvailable();
}
static void DRM_DeleteDevice(GAL_VideoDevice *device)
{
if (device->hidden->driver && device->hidden->driver_ops) {
device->hidden->driver_ops->destroy_driver(device->hidden->driver);
}
free(device->hidden);
free(device);
}
static char* find_driver_for_device (const char *dev_name)
{
char *driver;
int major_number, minor_number;
struct stat file_attrs;
char *device_path;
char device_link_path[PATH_MAX + 1] = "";
int ret;
if (stat (dev_name, &file_attrs) < 0) {
_ERR_PRINTF("NEWGAL>DRM: failed to call stat on %s\n", dev_name);
return NULL;
}
if (!S_ISCHR (file_attrs.st_mode)) {
_ERR_PRINTF("NEWGAL>DRM: %s is not a character device\n", dev_name);
return NULL;
}
major_number = major (file_attrs.st_rdev);
minor_number = minor (file_attrs.st_rdev);
ret = asprintf (&device_path, "/sys/dev/char/%d:%d/device/driver",
major_number, minor_number);
if (ret < 0) {
_ERR_PRINTF("NEWGAL>DRM: failed to call asprintf to build device path\n");
return NULL;
}
if (readlink (device_path, device_link_path,
sizeof (device_link_path) - 1) < 0) {
free (device_path);
return NULL;
}
_DBG_PRINTF("NEWGAL>DRM: device link path: %s\n", device_link_path);
free (device_path);
driver = strrchr (device_link_path, '/');
if (driver == NULL)
return NULL;
return strdup (driver + strlen ("/"));
}
static int open_drm_device(GAL_VideoDevice *device)
{
char *driver_name;
int device_fd;
driver_name = find_driver_for_device(device->hidden->dev_name);
_DBG_PRINTF("NEWGAL>DRM: Trye to load DRM driver: %s\n", driver_name);
device_fd = drmOpen(driver_name, NULL);
if (device_fd < 0) {
_ERR_PRINTF("drmOpen failed");
free(driver_name);
return -1;
}
if (strcmp(driver_name, "i915") == 0) {
_DBG_PRINTF("NEWGAL>DRM: found driver: i915\n");
}
else {
#ifdef __TARGET_EXTERNAL__
device->hidden->driver_ops = __drm_ex_driver_get(driver_name);
#endif
}
free (driver_name);
if (device->hidden->driver_ops == NULL) {
close (device_fd);
return -1;
}
device->hidden->driver = device->hidden->driver_ops->create_driver(device_fd);
if (device->hidden->driver == NULL) {
close(device_fd);
return -1;
}
device->hidden->dev_fd = device_fd;
return 0;
}
static GAL_VideoDevice *DRM_CreateDevice(int devindex)
{
GAL_VideoDevice *device;
@@ -77,18 +177,30 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
/* Initialize all variables that we clean on shutdown */
device = (GAL_VideoDevice *)malloc(sizeof(GAL_VideoDevice));
if ( device ) {
memset(device, 0, (sizeof *device));
memset(device, 0, (sizeof (*device)));
device->hidden = (struct GAL_PrivateVideoData *)
malloc((sizeof *device->hidden));
malloc((sizeof (*device->hidden)));
}
if ( (device == NULL) || (device->hidden == NULL) ) {
if ((device == NULL) || (device->hidden == NULL)) {
GAL_OutOfMemory();
if ( device ) {
if (device) {
free(device);
}
return(0);
return NULL;
}
memset(device->hidden, 0, (sizeof (*device->hidden)));
if (GetMgEtcValue ("drm", "device",
device->hidden->dev_name, LEN_DEVICE_NAME) < 0) {
strcpy(device->hidden->dev_name, "/dev/dri/card0");
_WRN_PRINTF("No drm.device defined, use the default '/dev/dri/card0'");
}
device->hidden->dev_fd = -1;
open_drm_device(device);
if (device->hidden->dev_fd < 0) {
return NULL;
}
memset(device->hidden, 0, (sizeof *device->hidden));
/* Set the function pointers */
device->VideoInit = DRM_VideoInit;
@@ -112,14 +224,14 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
}
VideoBootStrap DRM_bootstrap = {
DRMVID_DRIVER_NAME, "Linux DRM video driver",
DRM_DRIVER_NAME, "Linux DRM video driver",
DRM_Available, DRM_CreateDevice
};
static int DRM_VideoInit(_THIS, GAL_PixelFormat *vformat)
{
_MG_PRINTF("NEWGAL>DRM: Calling init method!\n");
_DBG_PRINTF("NEWGAL>DRM: Calling init method!\n");
/* Determine the screen depth (use default 8-bit depth) */
/* we change this during the GAL_SetVideoMode implementation... */

View File

@@ -41,7 +41,15 @@
/* Private display data */
#define LEN_DEVICE_NAME 31
struct GAL_PrivateVideoData {
char dev_name[LEN_DEVICE_NAME + 1];
int dev_fd;
DrmDriverOps* driver_ops;
DrmDriver* driver;
int w, h;
void *buffer;
};