Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## UPD:
Improved to work with EN and DE depended to the value of engine select bits.

libcedrus provides low-level access to the video engine of Allwinner sunxi SoCs.

Installation:
Expand Down
59 changes: 50 additions & 9 deletions cedrus.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#define DEVICE "/dev/cedar_dev"
#define EXPORT __attribute__ ((visibility ("default")))

static pthread_mutex_t open_lock = PTHREAD_MUTEX_INITIALIZER;
static int open_count;

static struct cedrus
{
int fd;
Expand All @@ -44,16 +47,22 @@ static struct cedrus
pthread_mutex_t device_lock;
} ve = { .fd = -1, .device_lock = PTHREAD_MUTEX_INITIALIZER };

EXPORT struct cedrus *cedrus_open(void)
EXPORT cedrus_t *cedrus_open(void)
{
if (ve.fd != -1)
return NULL;
pthread_mutex_lock(&open_lock);
if (ve.fd != -1) {
open_count++;
pthread_mutex_unlock(&open_lock);
return &ve;
}

struct cedarv_env_infomation info;

ve.fd = open(DEVICE, O_RDWR);
if (ve.fd == -1)
if (ve.fd == -1) {
pthread_mutex_unlock(&open_lock);
return NULL;
}

if (ioctl(ve.fd, IOCTL_GET_ENV_INFO, (void *)(&info)) == -1)
goto close;
Expand Down Expand Up @@ -87,22 +96,35 @@ EXPORT struct cedrus *cedrus_open(void)
ioctl(ve.fd, IOCTL_SET_VE_FREQ + ve.ioctl_offset, 320);
ioctl(ve.fd, IOCTL_RESET_VE + ve.ioctl_offset, 0);

writel(0x00130007, ve.regs + VE_CTRL);
writel(0x00130000 | VE_CTRL_ENGINE_RESET, ve.regs + VE_CTRL);

//printf("[libcedrus SUNXI] VE version 0x%04x opened\n", ve.version);
open_count++;
pthread_mutex_unlock(&open_lock);
return &ve;

unmap:
munmap(ve.regs, 0x800);

close:
close(ve.fd);
ve.fd = -1;
pthread_mutex_unlock(&open_lock);
return NULL;
}

EXPORT void cedrus_close(struct cedrus *dev)
{
if (dev->fd == -1)
pthread_mutex_lock(&open_lock);
if (dev->fd == -1) {
pthread_mutex_unlock(&open_lock);
return;
}

if (--open_count) {
pthread_mutex_unlock(&open_lock);
return;
}

ioctl(dev->fd, IOCTL_DISABLE_VE + dev->ioctl_offset, 0);
ioctl(dev->fd, IOCTL_ENGINE_REL, 0);
Expand All @@ -114,6 +136,7 @@ EXPORT void cedrus_close(struct cedrus *dev)

close(dev->fd);
dev->fd = -1;
pthread_mutex_unlock(&open_lock);
}

EXPORT int cedrus_get_ve_version(struct cedrus *dev)
Expand All @@ -126,18 +149,26 @@ EXPORT int cedrus_get_ve_version(struct cedrus *dev)

EXPORT int cedrus_ve_wait(struct cedrus *dev, int timeout)
{
unsigned int engine_wait = IOCTL_WAIT_VE_DE;
unsigned int reg = 0;
if (!dev)
return -1;

return ioctl(dev->fd, IOCTL_WAIT_VE_DE, timeout);
if (((reg = readl(dev->regs + VE_CTRL)) & VE_CTRL_ENGINE_FIELD) == VE_CTRL_ENGINE_AVC) {
engine_wait = IOCTL_WAIT_VE_DE + dev->ioctl_offset;
}

//printf("ve engine %04X, ve wait %d\n", reg, engine_wait);

return ioctl(dev->fd, engine_wait, timeout);
}

EXPORT void *cedrus_ve_get(struct cedrus *dev, enum cedrus_engine engine, uint32_t flags)
{
if (!dev || pthread_mutex_lock(&dev->device_lock))
return NULL;

writel(0x00130000 | (engine & 0xf) | (flags & ~0xf), dev->regs + VE_CTRL);
writel(0x00130000 | (engine & VE_CTRL_ENGINE_FIELD) | (flags & ~VE_CTRL_ENGINE_FIELD), dev->regs + VE_CTRL);

return dev->regs;
}
Expand All @@ -147,7 +178,7 @@ EXPORT void cedrus_ve_put(struct cedrus *dev)
if (!dev)
return;

writel(0x00130007, dev->regs + VE_CTRL);
writel(0x00130000 | VE_CTRL_ENGINE_RESET, dev->regs + VE_CTRL);
pthread_mutex_unlock(&dev->device_lock);
}

Expand Down Expand Up @@ -214,3 +245,13 @@ EXPORT uint32_t cedrus_mem_get_bus_addr(const struct cedrus_mem *mem)

return phys2bus(mem->phys);
}

EXPORT void cedrus_ve_reset(struct cedrus *dev)
{
if (!dev)
return;

writel(0x1, dev->regs + VE_RESET);
usleep(1000);
writel(0x0, dev->regs + VE_RESET);
}
9 changes: 8 additions & 1 deletion cedrus.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@

#include <stddef.h>
#include <stdint.h>
#include "cedrus_regs.h"

typedef struct cedrus cedrus_t;

enum cedrus_engine { CEDRUS_ENGINE_MPEG = 0x0, CEDRUS_ENGINE_H264 = 0x1, CEDRUS_ENGINE_HEVC = 0x4 };
enum cedrus_engine {
CEDRUS_ENGINE_MPEG = VE_CTRL_ENGINE_MPEG,
CEDRUS_ENGINE_H264 = VE_CTRL_ENGINE_H264,
CEDRUS_ENGINE_HEVC = VE_CTRL_ENGINE_HEVC,
CEDRUS_ENGINE_AVC = VE_CTRL_ENGINE_AVC
};

cedrus_t *cedrus_open(void);
void cedrus_close(cedrus_t *dev);
int cedrus_get_ve_version(cedrus_t *dev);
int cedrus_ve_wait(cedrus_t *dev, int timeout);
void *cedrus_ve_get(cedrus_t *dev, enum cedrus_engine engine, uint32_t flags);
void cedrus_ve_put(cedrus_t *dev);
void cedrus_ve_reset(cedrus_t *dev);

typedef struct cedrus_mem cedrus_mem_t;

Expand Down
Loading