Commit b029ad23 authored by Jens Kuske's avatar Jens Kuske
Browse files

Initial version

Based on libvdpau-sunxi 0.4
parents
*.d
*.o
libcedrus.so.1
TARGET = libcedrus.so.1
SRC = cedrus.c cedrus_mem_ve.c cedrus_mem_ion.c
INC = cedrus.h cedrus_regs.h
CFLAGS ?= -Wall -Wextra -O3
LDFLAGS ?=
LIBS = -lpthread
CC ?= gcc
prefix ?= /usr/local
libdir ?= $(prefix)/lib
includedir ?= $(prefix)/include
DEP_CFLAGS = -MD -MP -MQ $@
LIB_CFLAGS = -fpic -fvisibility=hidden
LIB_LDFLAGS = -shared -Wl,-soname,$(TARGET)
OBJ = $(addsuffix .o,$(basename $(SRC)))
DEP = $(addsuffix .d,$(basename $(SRC)))
.PHONY: clean all install uninstall
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(LIB_LDFLAGS) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
clean:
rm -f $(OBJ)
rm -f $(DEP)
rm -f $(TARGET)
install: $(TARGET) $(INC)
install -D $(TARGET) $(DESTDIR)/$(libdir)/$(TARGET)
ln -sf $(TARGET) $(DESTDIR)/$(libdir)/$(basename $(TARGET))
install -D -t $(DESTDIR)/$(includedir)/cedrus/ $(INC)
uninstall:
rm -f $(DESTDIR)/$(libdir)/$(basename $(TARGET))
rm -f $(DESTDIR)/$(libdir)/$(TARGET)
rm -rf $(DESTDIR)/$(includedir)/cedrus
%.o: %.c
$(CC) $(DEP_CFLAGS) $(LIB_CFLAGS) $(CFLAGS) -c $< -o $@
include $(wildcard $(DEP))
libcedrus provides low-level access to the video engine of Allwinner sunxi SoCs.
Installation:
$ make
$ make install
/*
* Copyright (c) 2013-2016 Jens Kuske <jenskuske@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <fcntl.h>
#include <pthread.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "cedrus.h"
#include "cedrus_mem.h"
#include "cedrus_regs.h"
#include "kernel-headers/cedardev_api.h"
#define DEVICE "/dev/cedar_dev"
#define EXPORT __attribute__ ((visibility ("default")))
static struct cedrus
{
int fd;
void *regs;
int version;
int ioctl_offset;
struct cedrus_allocator *allocator;
pthread_mutex_t device_lock;
} ve = { .fd = -1, .device_lock = PTHREAD_MUTEX_INITIALIZER };
EXPORT struct cedrus *cedrus_open(void)
{
if (ve.fd != -1)
return NULL;
struct cedarv_env_infomation info;
ve.fd = open(DEVICE, O_RDWR);
if (ve.fd == -1)
return NULL;
if (ioctl(ve.fd, IOCTL_GET_ENV_INFO, (void *)(&info)) == -1)
goto close;
ve.regs = mmap(NULL, 0x800, PROT_READ | PROT_WRITE, MAP_SHARED, ve.fd, info.address_macc);
if (ve.regs == MAP_FAILED)
goto close;
ve.allocator = cedrus_allocator_ve_new(ve.fd, &info);
if (!ve.allocator)
{
ve.allocator = cedrus_allocator_ion_new();
if (!ve.allocator)
goto unmap;
}
ioctl(ve.fd, IOCTL_ENGINE_REQ, 0);
ve.version = readl(ve.regs + VE_VERSION) >> 16;
if (ve.version >= 0x1667)
ve.ioctl_offset = 1;
ioctl(ve.fd, IOCTL_ENABLE_VE + ve.ioctl_offset, 0);
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);
return &ve;
unmap:
munmap(ve.regs, 0x800);
close:
close(ve.fd);
ve.fd = -1;
return NULL;
}
EXPORT void cedrus_close(struct cedrus *dev)
{
if (dev->fd == -1)
return;
ioctl(dev->fd, IOCTL_DISABLE_VE + dev->ioctl_offset, 0);
ioctl(dev->fd, IOCTL_ENGINE_REL, 0);
munmap(dev->regs, 0x800);
dev->regs = NULL;
dev->allocator->free(dev->allocator);
close(dev->fd);
dev->fd = -1;
}
EXPORT int cedrus_get_ve_version(struct cedrus *dev)
{
if (!dev)
return 0x0;
return dev->version;
}
EXPORT int cedrus_ve_wait(struct cedrus *dev, int timeout)
{
if (!dev)
return -1;
return ioctl(dev->fd, IOCTL_WAIT_VE_DE, 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);
return dev->regs;
}
EXPORT void cedrus_ve_put(struct cedrus *dev)
{
if (!dev)
return;
writel(0x00130007, dev->regs + VE_CTRL);
pthread_mutex_unlock(&dev->device_lock);
}
EXPORT struct cedrus_mem *cedrus_mem_alloc(struct cedrus *dev, size_t size)
{
if (!dev || size == 0)
return NULL;
return dev->allocator->mem_alloc(dev->allocator, (size + 4096 - 1) & ~(4096 - 1));
}
EXPORT void cedrus_mem_free(struct cedrus_mem *mem)
{
if (!mem)
return;
ve.allocator->mem_free(ve.allocator, mem);
}
EXPORT void cedrus_mem_flush_cache(struct cedrus_mem *mem)
{
if (!mem)
return;
ve.allocator->mem_flush(ve.allocator, mem);
}
EXPORT void *cedrus_mem_get_pointer(const struct cedrus_mem *mem)
{
if (!mem)
return NULL;
return mem->virt;
}
EXPORT uint32_t cedrus_mem_get_phys_addr(const struct cedrus_mem *mem)
{
if (!mem)
return 0x0;
return mem->phys;
}
uint32_t phys2bus(uint32_t phys)
{
return phys - 0x40000000;
}
uint32_t bus2phys(uint32_t bus)
{
return bus + 0x40000000;
}
EXPORT uint32_t cedrus_mem_get_bus_addr(const struct cedrus_mem *mem)
{
if (!mem)
return 0x0;
return phys2bus(mem->phys);
}
/*
* Copyright (c) 2013-2016 Jens Kuske <jenskuske@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef CEDRUS_H_
#define CEDRUS_H_
#include <stddef.h>
#include <stdint.h>
typedef struct cedrus cedrus_t;
enum cedrus_engine { CEDRUS_ENGINE_MPEG = 0x0, CEDRUS_ENGINE_H264 = 0x1, CEDRUS_ENGINE_HEVC = 0x4 };
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);
typedef struct cedrus_mem cedrus_mem_t;
cedrus_mem_t *cedrus_mem_alloc(cedrus_t *dev, size_t size);
void cedrus_mem_free(cedrus_mem_t *mem);
void cedrus_mem_flush_cache(cedrus_mem_t *mem);
void *cedrus_mem_get_pointer(const cedrus_mem_t *mem);
uint32_t cedrus_mem_get_phys_addr(const cedrus_mem_t *mem);
uint32_t cedrus_mem_get_bus_addr(const cedrus_mem_t *mem);
#endif
/*
* Copyright (c) 2013-2016 Jens Kuske <jenskuske@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef CEDRUS_MEM_H_
#define CEDRUS_MEM_H_
#include <stddef.h>
#include <stdint.h>
#include "kernel-headers/cedardev_api.h"
struct cedrus_mem
{
void *virt;
uint32_t phys;
size_t size;
};
struct cedrus_allocator
{
struct cedrus_mem *(*mem_alloc)(struct cedrus_allocator *allocator, size_t size);
void (*mem_free)(struct cedrus_allocator *allocator, struct cedrus_mem *mem);
void (*mem_flush)(struct cedrus_allocator *allocator, struct cedrus_mem *mem);
void (*free)(struct cedrus_allocator *allocator);
};
struct cedrus_allocator *cedrus_allocator_ve_new(int ve_fd, const struct cedarv_env_infomation *ve_info);
struct cedrus_allocator *cedrus_allocator_ion_new(void);
uint32_t phys2bus(uint32_t phys);
uint32_t bus2phys(uint32_t bus);
#endif
/*
* Copyright (c) 2015-2016 Jens Kuske <jenskuske@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "cedrus_mem.h"
#include "kernel-headers/ion.h"
#include "kernel-headers/ion_sunxi.h"
struct ion_mem
{
struct cedrus_mem pub;
struct ion_handle *handle;
int fd;
};
struct ion_allocator
{
struct cedrus_allocator pub;
int fd;
};
static struct ion_handle *ion_alloc(int ion_fd, size_t size)
{
struct ion_allocation_data allocation_data = {
.len = size,
.align = 4096,
.heap_id_mask = ION_HEAP_TYPE_DMA,
.flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC,
};
if (ioctl(ion_fd, ION_IOC_ALLOC, &allocation_data))
return NULL;
return allocation_data.handle;
}
static int ion_map(int ion_fd, struct ion_handle *ion_handle)
{
struct ion_fd_data fd_data = {
.handle = ion_handle,
};
if (ioctl(ion_fd, ION_IOC_MAP, &fd_data))
return -1;
return fd_data.fd;
}
static uint32_t ion_get_phys_addr(int ion_fd, struct ion_handle *ion_handle)
{
sunxi_phys_data phys_data = {
.handle = ion_handle,
};
struct ion_custom_data custom_data = {
.cmd = ION_IOC_SUNXI_PHYS_ADDR,
.arg = (unsigned long)(&phys_data),
};
if (ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data))
return 0x0;
return phys_data.phys_addr;
}
static int ion_flush_cache(int ion_fd, void *addr, size_t size)
{
sunxi_cache_range cache_range = {
.start = (long)addr,
.end = (long)addr + size,
};
struct ion_custom_data custom_data = {
.cmd = ION_IOC_SUNXI_FLUSH_RANGE,
.arg = (unsigned long)(&cache_range),
};
if (ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data))
return 0;
return 1;
}
static int ion_free(int ion_fd, struct ion_handle *ion_handle)
{
struct ion_handle_data handle_data = {
.handle = ion_handle,
};
if (ioctl(ion_fd, ION_IOC_FREE, &handle_data))
return 0;
return 1;
}
static struct cedrus_mem *cedrus_allocator_ion_mem_alloc(struct cedrus_allocator *allocator_pub, size_t size)
{
struct ion_allocator *allocator = (struct ion_allocator *)allocator_pub;
struct ion_mem *mem = calloc(1, sizeof(*mem));
if (!mem)
return NULL;
mem->pub.size = size;
mem->handle = ion_alloc(allocator->fd, size);
if (!mem->handle)
goto err;
mem->pub.phys = ion_get_phys_addr(allocator->fd, mem->handle);
if (!mem->pub.phys)
goto err_free;
mem->fd = ion_map(allocator->fd, mem->handle);
if (mem->fd < 0)
goto err_free;
mem->pub.virt = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, mem->fd, 0);
if (mem->pub.virt == MAP_FAILED)
goto err_close;
return &mem->pub;
err_close:
close(mem->fd);
err_free:
ion_free(allocator->fd, mem->handle);
err:
free(mem);
return NULL;
}
static void cedrus_allocator_ion_mem_free(struct cedrus_allocator *allocator_pub, struct cedrus_mem *mem_pub)
{
struct ion_allocator *allocator = (struct ion_allocator *)allocator_pub;
struct ion_mem *mem = (struct ion_mem *)mem_pub;
munmap(mem->pub.virt, mem->pub.size);
close(mem->fd);
ion_free(allocator->fd, mem->handle);
free(mem);
}
static void cedrus_allocator_ion_mem_flush(struct cedrus_allocator *allocator_pub, struct cedrus_mem *mem_pub)
{
struct ion_allocator *allocator = (struct ion_allocator *)allocator_pub;
struct ion_mem *mem = (struct ion_mem *)mem_pub;
ion_flush_cache(allocator->fd, mem->pub.virt, mem->pub.size);
}
static void cedrus_allocator_ion_free(struct cedrus_allocator *allocator_pub)
{
struct ion_allocator *allocator = (struct ion_allocator *)allocator_pub;
close(allocator->fd);
free(allocator);
}
struct cedrus_allocator *cedrus_allocator_ion_new(void)
{
struct ion_allocator *allocator = calloc(1, sizeof(*allocator));
if (!allocator)
return NULL;
allocator->fd = open("/dev/ion", O_RDONLY);
if (allocator->fd == -1)
{
free(allocator);
return NULL;
}
allocator->pub.mem_alloc = cedrus_allocator_ion_mem_alloc;
allocator->pub.mem_free = cedrus_allocator_ion_mem_free;
allocator->pub.mem_flush = cedrus_allocator_ion_mem_flush;
allocator->pub.free = cedrus_allocator_ion_free;
return &allocator->pub;
}
/*
* Copyright (c) 2013-2016 Jens Kuske <jenskuske@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <pthread.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include "cedrus_mem.h"
#include "kernel-headers/cedardev_api.h"
#define PAGE_OFFSET (0xc0000000) // from kernel
struct ve_mem
{
struct cedrus_mem pub;
struct ve_mem *next;
};
struct ve_allocator
{
struct cedrus_allocator pub;
int fd;
struct ve_mem first;
pthread_mutex_t lock;
};
static struct cedrus_mem *cedrus_allocator_ve_mem_alloc(struct cedrus_allocator *allocator_pub, size_t size)
{
struct ve_allocator *allocator = (struct ve_allocator *)allocator_pub;
if (pthread_mutex_lock(&allocator->lock))
return NULL;
void *addr = NULL;
struct cedrus_mem *ret = NULL;
struct ve_mem *c, *best_chunk = NULL;
for (c = &allocator->first; c != NULL; c = c->next)
{
if(c->pub.virt == NULL && c->pub.size >= size)
{
if (best_chunk == NULL || c->pub.size < best_chunk->pub.size)
best_chunk = c;
if (c->pub.size == size)
break;
}
}
if (!best_chunk)
goto out;
int left_size = best_chunk->pub.size - size;
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, allocator->fd, phys2bus(best_chunk->pub.phys) + PAGE_OFFSET);
if (addr == MAP_FAILED)
{
ret = NULL;
goto out;
}
best_chunk->pub.virt = addr;
best_chunk->pub.size = size;
ret = &best_chunk->pub;
if (left_size > 0)
{
c = calloc(1, sizeof(*c));
if (!c)
goto out;
c->pub.phys = best_chunk->pub.phys + size;
c->pub.size = left_size;
c->pub.virt = NULL;
c->next = best_chunk->next;
best_chunk->next = c;
}
out:
pthread_mutex_unlock(&allocator->lock);
return ret;
}
static void cedrus_allocator_ve_mem_free(struct cedrus_allocator *allocator_pub, struct cedrus_mem *mem_pub)
{
struct ve_allocator *allocator = (struct ve_allocator *)allocator_pub;
struct ve_mem *mem = (struct ve_mem *)mem_pub;
if (pthread_mutex_lock(&allocator->lock))
return;
struct ve_mem *c;
for (c = &allocator->first; c != NULL; c = c->next)
{
if (&c->pub == &mem->pub)
{
munmap(c->pub.virt, c->pub.size);
c->pub.virt = NULL;
break;
}
}
for (c = &allocator->first; c != NULL; c = c->next)
{
if (c->pub.virt == NULL)
{
while (c->next != NULL && c->next->pub.virt == NULL)
{
struct ve_mem *n = c->next;
c->pub.size += n->pub.size;
c->next = n->next;
free(n);
}
}
}
pthread_mutex_unlock(&allocator->lock);
}
static void cedrus_allocator_ve_mem_flush(struct cedrus_allocator *allocator_pub, struct cedrus_mem *mem_pub)
{
struct ve_allocator *allocator = (struct ve_allocator *)allocator_pub;
struct ve_mem *mem = (struct ve_mem *)mem_pub;
struct cedarv_cache_range cache_range = {
.start = (long)mem->pub.virt,
.end = (long)mem->pub.virt + mem->pub.size
};
ioctl(allocator->fd, IOCTL_FLUSH_CACHE, &cache_range);
}
static void cedrus_allocator_ve_free(struct cedrus_allocator *allocator_pub)
{
struct ve_allocator *allocator = (struct ve_allocator *)allocator_pub;
free(allocator);
}
struct cedrus_allocator *cedrus_allocator_ve_new(int ve_fd, const struct cedarv_env_infomation *ve_info)
{
if (ve_info->phymem_total_size == 0)
return NULL;
struct ve_allocator *allocator = calloc(1, sizeof(*allocator));
if (!allocator)
return NULL;
allocator->fd = ve_fd;
allocator->first.pub.phys = bus2phys(ve_info->phymem_start - PAGE_OFFSET);
allocator->first.pub.size = ve_info->phymem_total_size;
pthread_mutex_init(&allocator->lock, NULL);
allocator->pub.mem_alloc = cedrus_allocator_ve_mem_alloc;
allocator->pub.mem_free = cedrus_allocator_ve_mem_free;
allocator->pub.mem_flush = cedrus_allocator_ve_mem_flush;
allocator->pub.free = cedrus_allocator_ve_free;
return &allocator->pub;
}
/*
* Copyright (c) 2013-2016 Jens Kuske <jenskuske@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef CEDRUS_REGS_H_
#define CEDRUS_REGS_H_
#include <stdint.h>
static inline void writel(uint32_t val, void *addr)
{
*((volatile uint32_t *)addr) = val;
}
static inline uint32_t readl(void *addr)
{
return *((volatile uint32_t *) addr);
}
#define VE_CTRL 0x000
#define VE_EXTRA_OUT_FMT_OFFSET 0x0e8
#define VE_VERSION 0x0f0
#define VE_MPEG_PIC_HDR 0x100
#define VE_MPEG_VOP_HDR 0x104
#define VE_MPEG_SIZE 0x108
#define VE_MPEG_FRAME_SIZE 0x10c
#define VE_MPEG_MBA 0x110
#define VE_MPEG_CTRL 0x114
#define VE_MPEG_TRIGGER 0x118
#define VE_MPEG_STATUS 0x11c
#define VE_MPEG_TRBTRD_FIELD 0x120
#define VE_MPEG_TRBTRD_FRAME 0x124
#define VE_MPEG_VLD_ADDR 0x128
#define VE_MPEG_VLD_OFFSET 0x12c
#define VE_MPEG_VLD_LEN 0x130
#define VE_MPEG_VLD_END 0x134
#define VE_MPEG_MBH_ADDR 0x138
#define VE_MPEG_DCAC_ADDR 0x13c
#define VE_MPEG_NCF_ADDR 0x144
#define VE_MPEG_REC_LUMA 0x148
#define VE_MPEG_REC_CHROMA 0x14c
#define VE_MPEG_FWD_LUMA 0x150
#define VE_MPEG_FWD_CHROMA 0x154
#define VE_MPEG_BACK_LUMA 0x158
#define VE_MPEG_BACK_CHROMA 0x15c
#define VE_MPEG_IQ_MIN_INPUT 0x180
#define VE_MPEG_QP_INPUT 0x184
#define VE_MPEG_ROT_LUMA 0x1cc
#define VE_MPEG_ROT_CHROMA 0x1d0
#define VE_MPEG_SDROT_CTRL 0x1d4
#define VE_H264_FRAME_SIZE 0x200
#define VE_H264_PIC_HDR 0x204
#define VE_H264_SLICE_HDR 0x208
#define VE_H264_SLICE_HDR2 0x20c
#define VE_H264_PRED_WEIGHT 0x210
#define VE_H264_QP_PARAM 0x21c
#define VE_H264_CTRL 0x220
#define VE_H264_TRIGGER 0x224
#define VE_H264_STATUS 0x228
#define VE_H264_CUR_MB_NUM 0x22c
#define VE_H264_VLD_ADDR 0x230
#define VE_H264_VLD_OFFSET 0x234
#define VE_H264_VLD_LEN 0x238
#define VE_H264_VLD_END 0x23c
#define VE_H264_SDROT_CTRL 0x240
#define VE_H264_SDROT_LUMA 0x244
#define VE_H264_SDROT_CHROMA 0x248
#define VE_H264_OUTPUT_FRAME_IDX 0x24c
#define VE_H264_EXTRA_BUFFER1 0x250
#define VE_H264_EXTRA_BUFFER2 0x254
#define VE_H264_BASIC_BITS 0x2dc
#define VE_H264_RAM_WRITE_PTR 0x2e0
#define VE_H264_RAM_WRITE_DATA 0x2e4
#define VE_SRAM_H264_PRED_WEIGHT_TABLE 0x000
#define VE_SRAM_H264_FRAMEBUFFER_LIST 0x400
#define VE_SRAM_H264_REF_LIST0 0x640
#define VE_SRAM_H264_REF_LIST1 0x664
#define VE_SRAM_H264_SCALING_LISTS 0x800
#define VE_HEVC_NAL_HDR 0x500
#define VE_HEVC_SPS 0x504
#define VE_HEVC_PIC_SIZE 0x508
#define VE_HEVC_PCM_HDR 0x50c
#define VE_HEVC_PPS0 0x510
#define VE_HEVC_PPS1 0x514
#define VE_HEVC_SCALING_LIST_CTRL 0x518
#define VE_HEVC_SLICE_HDR0 0x520
#define VE_HEVC_SLICE_HDR1 0x524
#define VE_HEVC_SLICE_HDR2 0x528
#define VE_HEVC_CTB_ADDR 0x52c
#define VE_HEVC_CTRL 0x530
#define VE_HEVC_TRIG 0x534
#define VE_HEVC_STATUS 0x538
#define VE_HEVC_CTU_NUM 0x53c
#define VE_HEVC_BITS_ADDR 0x540
#define VE_HEVC_BITS_OFFSET 0x544
#define VE_HEVC_BITS_LEN 0x548
#define VE_HEVC_BITS_END_ADDR 0x54c
#define VE_HEVC_REC_BUF_IDX 0x55c
#define VE_HEVC_NEIGHBOR_INFO_ADDR 0x560
#define VE_HEVC_TILE_LIST_ADDR 0x564
#define VE_HEVC_TILE_START_CTB 0x568
#define VE_HEVC_TILE_END_CTB 0x56c
#define VE_HEVC_SCALING_LIST_DC_COEF0 0x578
#define VE_HEVC_SCALING_LIST_DC_COEF1 0x57c
#define VE_HEVC_BITS_DATA 0x5dc
#define VE_HEVC_SRAM_ADDR 0x5e0
#define VE_HEVC_SRAM_DATA 0x5e4
#define VE_SRAM_HEVC_PRED_WEIGHT_LUMA_L0 0x000
#define VE_SRAM_HEVC_PRED_WEIGHT_CHROMA_L0 0x020
#define VE_SRAM_HEVC_PRED_WEIGHT_LUMA_L1 0x060
#define VE_SRAM_HEVC_PRED_WEIGHT_CHROMA_L1 0x080
#define VE_SRAM_HEVC_PIC_LIST 0x400
#define VE_SRAM_HEVC_SCALING_LISTS 0x800
#define VE_SRAM_HEVC_REF_PIC_LIST0 0xc00
#define VE_SRAM_HEVC_REF_PIC_LIST1 0xc10
#endif
Various sunxi-specific kernel header files from sunxi kernel sources at
https://github.com/linux-sunxi/linux-sunxi
https://github.com/allwinner-zh/linux-3.4-sunxi
/*
* Cedarx framework.
* Copyright (c) 2008-2015 Allwinner Technology Co. Ltd.
* Copyright (c) 2014 BZ Chen <bzchen@allwinnertech.com>
*
* This file is part of Cedarx.
*
* Cedarx is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/
#ifndef __CEDARDEV_API_H__
#define __CEDARDEV_API_H__
enum IOCTL_CMD {
IOCTL_UNKOWN = 0x100,
IOCTL_GET_ENV_INFO,
IOCTL_WAIT_VE_DE, //* changed from IOCTL_WAIT_VE to IOCTL_WAIT_VE_DE, it make code compliant.
IOCTL_RESET_VE,
IOCTL_ENABLE_VE,
IOCTL_DISABLE_VE,
IOCTL_SET_VE_FREQ,
IOCTL_CONFIG_AVS2 = 0x200,
IOCTL_GETVALUE_AVS2 ,
IOCTL_PAUSE_AVS2 ,
IOCTL_START_AVS2 ,
IOCTL_RESET_AVS2 ,
IOCTL_ADJUST_AVS2,
IOCTL_ENGINE_REQ,
IOCTL_ENGINE_REL,
IOCTL_ENGINE_CHECK_DELAY,
IOCTL_GET_IC_VER,
IOCTL_ADJUST_AVS2_ABS,
IOCTL_FLUSH_CACHE,
IOCTL_SET_REFCOUNT,
IOCTL_FLUSH_CACHE_ALL,
IOCTL_TEST_VERSION,
IOCTL_READ_REG = 0x300,
IOCTL_WRITE_REG,
};
#define IOCTL_WAIT_VE_EN IOCTL_WAIT_VE_DE //* decoder and encoder is together on 1651.
struct cedarv_env_infomation
{
unsigned int phymem_start;
int phymem_total_size;
unsigned int address_macc;
};
struct cedarv_cache_range
{
long start;
long end;
};
struct cedarv_regop
{
unsigned int addr;
unsigned int value;
};
#endif
/*
* include/linux/ion.h
*
* Copyright (C) 2011 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _LINUX_ION_H
#define _LINUX_ION_H
#include <stdlib.h>
#include <linux/types.h>
struct ion_handle;
/**
* enum ion_heap_types - list of all possible types of heaps
* @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc
* @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc
* @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved
* carveout heap, allocations are physically
* contiguous
* @ION_HEAP_TYPE_DMA: memory allocated via DMA API
* @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask
* is used to identify the heaps, so only 32
* total heap types are supported
*/
enum ion_heap_type {
ION_HEAP_TYPE_SYSTEM,
ION_HEAP_TYPE_SYSTEM_CONTIG,
ION_HEAP_TYPE_CARVEOUT,
ION_HEAP_TYPE_CHUNK,
ION_HEAP_TYPE_DMA,
ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
are at the end of this enum */
ION_NUM_HEAPS = 16,
};
#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM)
#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA)
#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8
/**
* allocation flags - the lower 16 bits are used by core ion, the upper 16
* bits are reserved for use by the heaps themselves.
*/
#define ION_FLAG_CACHED 1 /* mappings of this buffer should be
cached, ion will do cache
maintenance when the buffer is
mapped for dma */
#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created
at mmap time, if this is set
caches must be managed manually */
#ifdef __KERNEL__
struct ion_device;
struct ion_heap;
struct ion_mapper;
struct ion_client;
struct ion_buffer;
/* This should be removed some day when phys_addr_t's are fully
plumbed in the kernel, and all instances of ion_phys_addr_t should
be converted to phys_addr_t. For the time being many kernel interfaces
do not accept phys_addr_t's that would have to */
#define ion_phys_addr_t unsigned long
/**
* struct ion_platform_heap - defines a heap in the given platform
* @type: type of the heap from ion_heap_type enum
* @id: unique identifier for heap. When allocating higher numbers
* will be allocated from first. At allocation these are passed
* as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS.
* @name: used for debug purposes
* @base: base address of heap in physical memory if applicable
* @size: size of the heap in bytes if applicable
* @align: required alignment in physical memory if applicable
* @priv: private info passed from the board file
*
* Provided by the board file.
*/
struct ion_platform_heap {
enum ion_heap_type type;
unsigned int id;
const char *name;
ion_phys_addr_t base;
size_t size;
ion_phys_addr_t align;
void *priv;
};
/**
* struct ion_platform_data - array of platform heaps passed from board file
* @nr: number of structures in the array
* @heaps: array of platform_heap structions
*
* Provided by the board file in the form of platform data to a platform device.
*/
struct ion_platform_data {
int nr;
struct ion_platform_heap heaps[];
};
/**
* ion_reserve() - reserve memory for ion heaps if applicable
* @data: platform data specifying starting physical address and
* size
*
* Calls memblock reserve to set aside memory for heaps that are
* located at specific memory addresses or of specfic sizes not
* managed by the kernel
*/
void ion_reserve(struct ion_platform_data *data);
/**
* ion_client_create() - allocate a client and returns it
* @dev: the global ion device
* @heap_type_mask: mask of heaps this client can allocate from
* @name: used for debugging
*/
struct ion_client *ion_client_create(struct ion_device *dev,
const char *name);
/**
* ion_client_destroy() - free's a client and all it's handles
* @client: the client
*
* Free the provided client and all it's resources including
* any handles it is holding.
*/
void ion_client_destroy(struct ion_client *client);
/**
* ion_alloc - allocate ion memory
* @client: the client
* @len: size of the allocation
* @align: requested allocation alignment, lots of hardware blocks
* have alignment requirements of some kind
* @heap_id_mask: mask of heaps to allocate from, if multiple bits are set
* heaps will be tried in order from highest to lowest
* id
* @flags: heap flags, the low 16 bits are consumed by ion, the
* high 16 bits are passed on to the respective heap and
* can be heap custom
*
* Allocate memory in one of the heaps provided in heap mask and return
* an opaque handle to it.
*/
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
size_t align, unsigned int heap_id_mask,
unsigned int flags);
/**
* ion_free - free a handle
* @client: the client
* @handle: the handle to free
*
* Free the provided handle.
*/
void ion_free(struct ion_client *client, struct ion_handle *handle);
/**
* ion_phys - returns the physical address and len of a handle
* @client: the client
* @handle: the handle
* @addr: a pointer to put the address in
* @len: a pointer to put the length in
*
* This function queries the heap for a particular handle to get the
* handle's physical address. It't output is only correct if
* a heap returns physically contiguous memory -- in other cases
* this api should not be implemented -- ion_sg_table should be used
* instead. Returns -EINVAL if the handle is invalid. This has
* no implications on the reference counting of the handle --
* the returned value may not be valid if the caller is not
* holding a reference.
*/
int ion_phys(struct ion_client *client, struct ion_handle *handle,
ion_phys_addr_t *addr, size_t *len);
/**
* ion_map_dma - return an sg_table describing a handle
* @client: the client
* @handle: the handle
*
* This function returns the sg_table describing
* a particular ion handle.
*/
struct sg_table *ion_sg_table(struct ion_client *client,
struct ion_handle *handle);
/**
* ion_map_kernel - create mapping for the given handle
* @client: the client
* @handle: handle to map
*
* Map the given handle into the kernel and return a kernel address that
* can be used to access this address.
*/
void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle);
/**
* ion_unmap_kernel() - destroy a kernel mapping for a handle
* @client: the client
* @handle: handle to unmap
*/
void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle);
/**
* ion_share_dma_buf() - share buffer as dma-buf
* @client: the client
* @handle: the handle
*/
struct dma_buf *ion_share_dma_buf(struct ion_client *client,
struct ion_handle *handle);
/**
* ion_share_dma_buf_fd() - given an ion client, create a dma-buf fd
* @client: the client
* @handle: the handle
*/
int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle);
/**
* ion_import_dma_buf() - given an dma-buf fd from the ion exporter get handle
* @client: the client
* @fd: the dma-buf fd
*
* Given an dma-buf fd that was allocated through ion via ion_share_dma_buf,
* import that fd and return a handle representing it. If a dma-buf from
* another exporter is passed in this function will return ERR_PTR(-EINVAL)
*/
struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd);
#endif /* __KERNEL__ */
/**
* DOC: Ion Userspace API
*
* create a client by opening /dev/ion
* most operations handled via following ioctls
*
*/
/**
* struct ion_allocation_data - metadata passed from userspace for allocations
* @len: size of the allocation
* @align: required alignment of the allocation
* @heap_id_mask: mask of heap ids to allocate from
* @flags: flags passed to heap
* @handle: pointer that will be populated with a cookie to use to
* refer to this allocation
*
* Provided by userspace as an argument to the ioctl
*/
struct ion_allocation_data {
size_t len;
size_t align;
unsigned int heap_id_mask;
unsigned int flags;
struct ion_handle *handle;
};
/**
* struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair
* @handle: a handle
* @fd: a file descriptor representing that handle
*
* For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
* the handle returned from ion alloc, and the kernel returns the file
* descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace
* provides the file descriptor and the kernel returns the handle.
*/
struct ion_fd_data {
struct ion_handle *handle;
int fd;
};
/**
* struct ion_handle_data - a handle passed to/from the kernel
* @handle: a handle
*/
struct ion_handle_data {
struct ion_handle *handle;
};
/**
* struct ion_custom_data - metadata passed to/from userspace for a custom ioctl
* @cmd: the custom ioctl function to call
* @arg: additional data to pass to the custom ioctl, typically a user
* pointer to a predefined structure
*
* This works just like the regular cmd and arg fields of an ioctl.
*/
struct ion_custom_data {
unsigned int cmd;
unsigned long arg;
};
#define ION_IOC_MAGIC 'I'
/**
* DOC: ION_IOC_ALLOC - allocate memory
*
* Takes an ion_allocation_data struct and returns it with the handle field
* populated with the opaque handle for the allocation.
*/
#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
struct ion_allocation_data)
/**
* DOC: ION_IOC_FREE - free memory
*
* Takes an ion_handle_data struct and frees the handle.
*/
#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
/**
* DOC: ION_IOC_MAP - get a file descriptor to mmap
*
* Takes an ion_fd_data struct with the handle field populated with a valid
* opaque handle. Returns the struct with the fd field set to a file
* descriptor open in the current address space. This file descriptor
* can then be used as an argument to mmap.
*/
#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
/**
* DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
*
* Takes an ion_fd_data struct with the handle field populated with a valid
* opaque handle. Returns the struct with the fd field set to a file
* descriptor open in the current address space. This file descriptor
* can then be passed to another process. The corresponding opaque handle can
* be retrieved via ION_IOC_IMPORT.
*/
#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
/**
* DOC: ION_IOC_IMPORT - imports a shared file descriptor
*
* Takes an ion_fd_data struct with the fd field populated with a valid file
* descriptor obtained from ION_IOC_SHARE and returns the struct with the handle
* filed set to the corresponding opaque handle.
*/
#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)
/**
* DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory
*
* Deprecated in favor of using the dma_buf api's correctly (syncing
* will happend automatically when the buffer is mapped to a device).
* If necessary should be used after touching a cached buffer from the cpu,
* this will make the buffer in memory coherent.
*/
#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data)
/**
* DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl
*
* Takes the argument of the architecture specific ioctl to call and
* passes appropriate userdata for that ioctl
*/
#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data)
#endif /* _LINUX_ION_H */
/*
* include/linux/ion_sunxi.h
*
* Copyright(c) 2013-2015 Allwinnertech Co., Ltd.
* http://www.allwinnertech.com
*
* Author: liugang <liugang@allwinnertech.com>
*
* sunxi ion header file
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __ION_SUNXI_H
#define __ION_SUNXI_H
#define ION_HEAP_TYPE_SUNXI_START (ION_HEAP_TYPE_CUSTOM + 1)
#define ION_HEAP_TYPE_SECURE (ION_HEAP_TYPE_SUNXI_START)
typedef struct {
long start;
long end;
}sunxi_cache_range;
typedef struct {
void *handle;
unsigned long phys_addr;
unsigned long size;
}sunxi_phys_data;
#define DMA_BUF_MAXCNT 8
typedef struct {
unsigned int src_va;
unsigned int src_pa;
unsigned int dst_va;
unsigned int dst_pa;
unsigned int size;
}dma_buf_item;
typedef struct {
int multi_dma;
unsigned int cnt;
dma_buf_item item[DMA_BUF_MAXCNT];
}dma_buf_group;
#define ION_IOC_SUNXI_FLUSH_RANGE 5
#define ION_IOC_SUNXI_FLUSH_ALL 6
#define ION_IOC_SUNXI_PHYS_ADDR 7
#define ION_IOC_SUNXI_DMA_COPY 8
#define ION_IOC_SUNXI_DUMP 9
#ifdef __KERNEL__
int flush_clean_user_range(long start, long end);
int flush_user_range(long start, long end);
void flush_dcache_all(void);
/**
* sunxi_buf_alloc - alloc phys contigous memory in SUNXI platform.
* @size: size in bytes to allocate.
* @paddr: store the start phys address allocated.
*
* return the start virtual address, or 0 if failed.
*/
void *sunxi_buf_alloc(unsigned int size, unsigned int *paddr);
/**
* sunxi_buf_free - free buffer allocated by sunxi_buf_alloc.
* @vaddr: the kernel virt addr of the area.
* @paddr: the start phys addr of the area.
* @size: size in bytes of the area.
*/
void sunxi_buf_free(void *vaddr, unsigned int paddr, unsigned int size);
/**
* sunxi_alloc_phys - alloc phys contigous memory in SUNXI platform.
* @size: size in bytes to allocate.
*
* return the start phys addr, or 0 if failed.
*/
u32 sunxi_alloc_phys(size_t size);
/**
* sunxi_free_phys - free phys contigous memory allocted by sunxi_alloc_phys.
* @paddr: the start phys addr of the area.
* @size: size in bytes of the area.
*/
void sunxi_free_phys(u32 paddr, size_t size);
/**
* sunxi_map_kernel - map phys contigous memory to kernel virtual space.
* @paddr: the start phys addr of the area.
* @size: size in bytes of the area.
*
* return the start virt addr which is in vmalloc space, or NULL if failed.
*/
void *sunxi_map_kernel(unsigned int paddr, unsigned int size);
/**
* sunxi_unmap_kernel - unmap phys contigous memory from kernel space.
* @vaddr: the kernel virt addr of the area.
* @paddr: the start phys addr of the area.
* @size: size in bytes of the area.
*/
void sunxi_unmap_kernel(void *vaddr, unsigned int paddr, unsigned int size);
#endif /* __KERNEL__ */
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment