mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
amlvideo2: initial add the driver
PD#138714: initial add the driver 1.Add amlogic amlvideo2 driver; 2.device tree support of amlvideo2 for p212/q200/skt; 3.related Makefiles/Kconfig/Headfiles update; Change-Id: I6cbd4e7f19a7ec7199106f586f195a2099130e09 Signed-off-by: Guosong Zhou <guosong.zhou@amlogic.com>
This commit is contained in:
committed by
Jianxin Pan
parent
d3567bedb4
commit
385e4e65a1
16
MAINTAINERS
16
MAINTAINERS
@@ -13668,3 +13668,19 @@ ANDROID LOGGER Driver
|
||||
M: Frank Chen <frank.chen@amlogic.com>
|
||||
F: drivers/staging/android/logger.c
|
||||
F: drivers/staging/android/logger.h
|
||||
|
||||
AMLOGIC AMLVIDEO2 DRIVER
|
||||
M: Guosong Zhou <guosong.zhou@amlogic.com>
|
||||
F: arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts
|
||||
F: arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts
|
||||
F: arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts
|
||||
F: arch/arm64/boot/dts/amlogic/gxm_skt.dts
|
||||
F: arch/arm64/configs/meson64_defconfig
|
||||
F: drivers/amlogic/media/Kconfig
|
||||
F: drivers/amlogic/media/Makefile
|
||||
F: drivers/amlogic/media/common/Kconfig
|
||||
F: drivers/amlogic/media/common/Makefile
|
||||
F: drivers/amlogic/media/common/vfm/vfm.c
|
||||
F: drivers/amlogic/media/common/v4l_util/*
|
||||
F: drivers/amlogic/media/video_processor/*
|
||||
F: include/linux/amlogic/media/v4l_util/*
|
||||
@@ -763,6 +763,13 @@
|
||||
hw-version = <2>;
|
||||
};
|
||||
|
||||
amlvideo2 {
|
||||
compatible = "amlogic, amlvideo2";
|
||||
dev_name = "amlvideo2";
|
||||
status = "okay";
|
||||
cma_mode = <1>;
|
||||
};
|
||||
|
||||
/*if you want to use vdin just modify status to "ok"*/
|
||||
vdin0 {
|
||||
compatible = "amlogic, vdin";
|
||||
|
||||
@@ -760,6 +760,13 @@
|
||||
hw-version = <2>;
|
||||
};
|
||||
|
||||
amlvideo2 {
|
||||
compatible = "amlogic, amlvideo2";
|
||||
dev_name = "amlvideo2";
|
||||
status = "okay";
|
||||
cma_mode = <1>;
|
||||
};
|
||||
|
||||
/*if you want to use vdin just modify status to "ok"*/
|
||||
vdin0 {
|
||||
compatible = "amlogic, vdin";
|
||||
|
||||
@@ -792,6 +792,13 @@
|
||||
hw-version = <2>;
|
||||
};
|
||||
|
||||
amlvideo2 {
|
||||
compatible = "amlogic, amlvideo2";
|
||||
dev_name = "amlvideo2";
|
||||
status = "okay";
|
||||
cma_mode = <1>;
|
||||
};
|
||||
|
||||
/*if you want to use vdin just modify status to "ok"*/
|
||||
vdin0 {
|
||||
compatible = "amlogic, vdin";
|
||||
|
||||
@@ -577,6 +577,14 @@
|
||||
interrupts = <0 89 1>;
|
||||
interrupt-names = "rdma";
|
||||
};
|
||||
|
||||
amlvideo2 {
|
||||
compatible = "amlogic, amlvideo2";
|
||||
dev_name = "amlvideo2";
|
||||
status = "okay";
|
||||
cma_mode = <1>;
|
||||
};
|
||||
|
||||
/*if you want to use vdin just modify status to "ok"*/
|
||||
vdin0 {
|
||||
compatible = "amlogic, vdin";
|
||||
|
||||
@@ -200,6 +200,7 @@ CONFIG_AMLOGIC_ION=y
|
||||
CONFIG_AMLOGIC_MEDIA_RDMA=y
|
||||
CONFIG_AMLOGIC_MEDIA_VFM=y
|
||||
CONFIG_AMLOGIC_VPU=y
|
||||
CONFIG_AMLOGIC_VIDEOBUF_RESOURCE=y
|
||||
CONFIG_AMLOGIC_VOUT=y
|
||||
CONFIG_AMLOGIC_VOUT_SERVE=y
|
||||
CONFIG_AMLOGIC_CVBS_OUTPUT=y
|
||||
@@ -215,6 +216,8 @@ CONFIG_AMLOGIC_MEDIA_VIN=y
|
||||
CONFIG_AMLOGIC_MEDIA_TVIN=y
|
||||
CONFIG_AMLOGIC_MEDIA_VDIN=y
|
||||
CONFIG_AMLOGIC_MEDIA_VIUIN=y
|
||||
CONFIG_AMLOGIC_VIDEO_PROCESSOR=y
|
||||
CONFIG_AMLOGIC_V4L_VIDEO2=y
|
||||
CONFIG_AMLOGIC_MMC=y
|
||||
CONFIG_AMLOGIC_VRTC=y
|
||||
CONFIG_AMLOGIC_SMARTCARD=y
|
||||
|
||||
@@ -47,6 +47,7 @@ source "drivers/amlogic/media/osd_ext/Kconfig"
|
||||
source "drivers/amlogic/media/logo/Kconfig"
|
||||
source "drivers/amlogic/media/deinterlace/Kconfig"
|
||||
source "drivers/amlogic/media/vin/Kconfig"
|
||||
source "drivers/amlogic/media/video_processor/Kconfig"
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -7,3 +7,4 @@ obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += osd_ext/
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += logo/
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += deinterlace/
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_VIN) += vin/
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_DRIVERS) += video_processor/
|
||||
@@ -6,3 +6,4 @@ source "drivers/amlogic/media/common/ion_dev/Kconfig"
|
||||
source "drivers/amlogic/media/common/rdma/Kconfig"
|
||||
source "drivers/amlogic/media/common/vfm/Kconfig"
|
||||
source "drivers/amlogic/media/common/vpu/Kconfig"
|
||||
source "drivers/amlogic/media/common/v4l_util/Kconfig"
|
||||
|
||||
@@ -7,3 +7,4 @@ obj-$(CONFIG_AMLOGIC_ION) += ion_dev/
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_RDMA) += rdma/
|
||||
obj-$(CONFIG_AMLOGIC_MEDIA_VFM) += vfm/
|
||||
obj-$(CONFIG_AMLOGIC_VPU) += vpu/
|
||||
obj-$(CONFIG_AMLOGIC_VIDEOBUF_RESOURCE) += v4l_util/
|
||||
|
||||
9
drivers/amlogic/media/common/v4l_util/Kconfig
Normal file
9
drivers/amlogic/media/common/v4l_util/Kconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# V4L UTIL configuration
|
||||
#
|
||||
|
||||
config AMLOGIC_VIDEOBUF_RESOURCE
|
||||
bool "Amlogic V4L UTIL Support"
|
||||
default n
|
||||
help
|
||||
Select to enable V4L UTIL support
|
||||
5
drivers/amlogic/media/common/v4l_util/Makefile
Normal file
5
drivers/amlogic/media/common/v4l_util/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for V4L UTIL
|
||||
#
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_VIDEOBUF_RESOURCE) += videobuf-res.o
|
||||
368
drivers/amlogic/media/common/v4l_util/videobuf-res.c
Normal file
368
drivers/amlogic/media/common/v4l_util/videobuf-res.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* drivers/amlogic/media/common/v4l_util/videobuf-res.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/amlogic/media/v4l_util/videobuf-res.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
struct videobuf_res_memory {
|
||||
u32 magic;
|
||||
void *vaddr;
|
||||
resource_size_t phy_addr;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
|
||||
#define pr_dbg(fmt, args...) pr_info("videobuf-res: " fmt, ## args)
|
||||
|
||||
#define MAGIC_RE_MEM 0x123039dc
|
||||
#define MAGIC_CHECK(is, should) { \
|
||||
if (unlikely((is) != (should))) { \
|
||||
pr_err("magic mismatch: %x expected %x\n", \
|
||||
(is), (should)); \
|
||||
WARN_ON(!is); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define dprintk(level, fmt, arg...) { \
|
||||
if ((debug) >= (level)) \
|
||||
pr_dbg("vbuf-resource: " fmt, ## arg); \
|
||||
}
|
||||
|
||||
static void *res_alloc(struct videobuf_queue *q, size_t boff,
|
||||
unsigned long size, resource_size_t *phy_addr)
|
||||
{
|
||||
void __iomem *ret = NULL;
|
||||
struct videobuf_res_privdata *res = NULL;
|
||||
long res_size = 0;
|
||||
|
||||
WARN_ON(!size);
|
||||
|
||||
WARN_ON(!q->priv_data);
|
||||
|
||||
res = (struct videobuf_res_privdata *)q->priv_data;
|
||||
MAGIC_CHECK(res->magic, MAGIC_RE_MEM);
|
||||
|
||||
res_size = res->end-res->start+1;
|
||||
if (boff+size <= res_size) {
|
||||
*phy_addr = res->start+boff;
|
||||
/* ret = ioremap_wc(*phy_addr,size); */
|
||||
/* if(!ret) */
|
||||
/* *phy_addr = 0; */
|
||||
} else{
|
||||
pr_err("videobuf_res alloc buff is too small: %lx expected %lx\n",
|
||||
res_size, boff+size);
|
||||
}
|
||||
return (void *)ret;
|
||||
}
|
||||
|
||||
static void res_free(struct videobuf_res_memory *mem)
|
||||
{
|
||||
if (mem->vaddr)
|
||||
iounmap((void __iomem *)mem->vaddr);
|
||||
mem->vaddr = NULL;
|
||||
mem->size = 0;
|
||||
mem->phy_addr = 0;
|
||||
/*return;*/
|
||||
}
|
||||
|
||||
static void
|
||||
videobuf_vm_open(struct vm_area_struct *vma)
|
||||
{
|
||||
struct videobuf_mapping *map = vma->vm_private_data;
|
||||
|
||||
dprintk(2, "vm_open %p [count=%u,vma=%08lx-%08lx]\n",
|
||||
map, map->count, vma->vm_start, vma->vm_end);
|
||||
|
||||
map->count++;
|
||||
}
|
||||
|
||||
static void videobuf_vm_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct videobuf_mapping *map = vma->vm_private_data;
|
||||
struct videobuf_queue *q = map->q;
|
||||
int i;
|
||||
|
||||
dprintk(2, "vm_close %p [count=%u,vma=%08lx-%08lx]\n",
|
||||
map, map->count, vma->vm_start, vma->vm_end);
|
||||
|
||||
map->count--;
|
||||
if (map->count == 0) {
|
||||
struct videobuf_res_memory *mem;
|
||||
|
||||
dprintk(1, "munmap %p q=%p\n", map, q);
|
||||
videobuf_queue_lock(q);
|
||||
|
||||
/* We need first to cancel streams, before unmapping */
|
||||
if (q->streaming)
|
||||
videobuf_queue_cancel(q);
|
||||
|
||||
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
|
||||
if (q->bufs[i] == NULL)
|
||||
continue;
|
||||
|
||||
if (q->bufs[i]->map != map)
|
||||
continue;
|
||||
|
||||
mem = q->bufs[i]->priv;
|
||||
if (mem) {
|
||||
/* This callback is called only if kernel has
|
||||
* allocated memory and this memory is mmapped.
|
||||
* In this case, memory should be freed,
|
||||
* in order to do memory unmap.
|
||||
*/
|
||||
|
||||
MAGIC_CHECK(mem->magic, MAGIC_RE_MEM);
|
||||
|
||||
dprintk(1, "buf[%d] freeing %p\n",
|
||||
i, mem->vaddr);
|
||||
|
||||
res_free(mem);
|
||||
}
|
||||
|
||||
q->bufs[i]->map = NULL;
|
||||
q->bufs[i]->baddr = 0;
|
||||
}
|
||||
|
||||
kfree(map);
|
||||
|
||||
videobuf_queue_unlock(q);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct videobuf_vm_ops = {
|
||||
.open = videobuf_vm_open,
|
||||
.close = videobuf_vm_close,
|
||||
};
|
||||
|
||||
static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
|
||||
{
|
||||
struct videobuf_res_memory *mem;
|
||||
struct videobuf_buffer *vb;
|
||||
|
||||
vb = kzalloc(size + sizeof(*mem), GFP_KERNEL);
|
||||
if (vb) {
|
||||
mem = vb->priv = ((char *)vb) + size;
|
||||
mem->magic = MAGIC_RE_MEM;
|
||||
|
||||
dprintk(1, "%s: allocated at %p(%ld+%ld) & %p(%ld)\n",
|
||||
__func__, vb, (long)sizeof(*vb),
|
||||
(long)size - sizeof(*vb),
|
||||
mem, (long)sizeof(*mem));
|
||||
}
|
||||
|
||||
return vb;
|
||||
}
|
||||
|
||||
static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
|
||||
{
|
||||
struct videobuf_res_memory *mem = buf->priv;
|
||||
|
||||
WARN_ON(!mem);
|
||||
MAGIC_CHECK(mem->magic, MAGIC_RE_MEM);
|
||||
|
||||
return mem->vaddr;
|
||||
}
|
||||
|
||||
static int __videobuf_iolock(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *vb,
|
||||
struct v4l2_framebuffer *fbuf)
|
||||
{
|
||||
struct videobuf_res_memory *mem = vb->priv;
|
||||
|
||||
WARN_ON(!mem);
|
||||
MAGIC_CHECK(mem->magic, MAGIC_RE_MEM);
|
||||
|
||||
switch (vb->memory) {
|
||||
case V4L2_MEMORY_MMAP:
|
||||
dprintk(1, "%s memory method MMAP\n", __func__);
|
||||
|
||||
/* All handling should be done by __videobuf_mmap_mapper() */
|
||||
if (!mem->phy_addr) {
|
||||
pr_err("%s memory is not alloced/mmapped.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case V4L2_MEMORY_USERPTR:
|
||||
dprintk(1, "%s memory method USERPTR\n", __func__);
|
||||
return -EINVAL;
|
||||
case V4L2_MEMORY_OVERLAY:
|
||||
default:
|
||||
dprintk(1, "%s memory method OVERLAY/unknown\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __videobuf_mmap_mapper(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *buf,
|
||||
struct vm_area_struct *vma)
|
||||
{
|
||||
struct videobuf_res_memory *mem;
|
||||
struct videobuf_mapping *map;
|
||||
int retval;
|
||||
unsigned long size;
|
||||
|
||||
dprintk(2, "%s\n", __func__);
|
||||
|
||||
/* create mapping + update buffer list */
|
||||
map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
|
||||
if (!map)
|
||||
return -ENOMEM;
|
||||
|
||||
buf->map = map;
|
||||
map->q = q;
|
||||
|
||||
buf->baddr = vma->vm_start;
|
||||
|
||||
mem = buf->priv;
|
||||
WARN_ON(!mem);
|
||||
MAGIC_CHECK(mem->magic, MAGIC_RE_MEM);
|
||||
|
||||
mem->size = PAGE_ALIGN(buf->bsize);
|
||||
mem->vaddr = res_alloc(q, buf->boff, mem->size, &mem->phy_addr);
|
||||
|
||||
/* if ((!mem->vaddr)||(!mem->phy_addr)){ */
|
||||
if (!mem->phy_addr) {
|
||||
pr_err("res_alloc size %ld failed\n",
|
||||
mem->size);
|
||||
goto error;
|
||||
}
|
||||
dprintk(1, "res_alloc data is at addr 0x%p (size %lu)\n",
|
||||
(void *)mem->phy_addr, mem->size);
|
||||
|
||||
/* Try to remap memory */
|
||||
|
||||
size = vma->vm_end - vma->vm_start;
|
||||
size = (size < mem->size) ? size : mem->size;
|
||||
|
||||
/* vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); */
|
||||
/* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
|
||||
retval = remap_pfn_range(vma, vma->vm_start,
|
||||
mem->phy_addr >> PAGE_SHIFT,
|
||||
size, vma->vm_page_prot);
|
||||
if (retval) {
|
||||
pr_err("mmap: remap failed with error %d. ", retval);
|
||||
res_free(mem);
|
||||
goto error;
|
||||
}
|
||||
|
||||
vma->vm_ops = &videobuf_vm_ops;
|
||||
vma->vm_flags |= (VM_DONTEXPAND | VM_IO |
|
||||
(VM_DONTEXPAND | VM_DONTDUMP));
|
||||
vma->vm_private_data = map;
|
||||
|
||||
dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx)",
|
||||
map, q, vma->vm_start, vma->vm_end, (long int)buf->bsize);
|
||||
dprintk(1, "pgoff %08lx buf %d, vm flag 0x%lx\n",
|
||||
vma->vm_pgoff, buf->i, vma->vm_flags);
|
||||
|
||||
videobuf_vm_open(vma);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
kfree(map);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static struct videobuf_qtype_ops qops = {
|
||||
.magic = MAGIC_QTYPE_OPS,
|
||||
|
||||
.alloc_vb = __videobuf_alloc_vb,
|
||||
.iolock = __videobuf_iolock,
|
||||
.mmap_mapper = __videobuf_mmap_mapper,
|
||||
.vaddr = __videobuf_to_vaddr,
|
||||
};
|
||||
|
||||
void videobuf_queue_res_init(struct videobuf_queue *q,
|
||||
const struct videobuf_queue_ops *ops,
|
||||
struct device *dev,
|
||||
spinlock_t *irqlock,
|
||||
enum v4l2_buf_type type,
|
||||
enum v4l2_field field,
|
||||
unsigned int msize,
|
||||
void *priv,
|
||||
struct mutex *ext_lock)
|
||||
{
|
||||
struct videobuf_res_privdata *res =
|
||||
(struct videobuf_res_privdata *)priv;
|
||||
|
||||
WARN_ON(!res);
|
||||
MAGIC_CHECK(res->magic, MAGIC_RE_MEM);
|
||||
|
||||
if (res->start >= res->end) {
|
||||
pr_err("videobuf_queue_res_init: resource is invalid.\n");
|
||||
return;
|
||||
}
|
||||
videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize,
|
||||
priv, &qops, ext_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(videobuf_queue_res_init);
|
||||
|
||||
resource_size_t videobuf_to_res(struct videobuf_buffer *buf)
|
||||
{
|
||||
struct videobuf_res_memory *mem = buf->priv;
|
||||
|
||||
WARN_ON(!mem);
|
||||
MAGIC_CHECK(mem->magic, MAGIC_RE_MEM);
|
||||
|
||||
return mem->phy_addr;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(videobuf_to_res);
|
||||
|
||||
void videobuf_res_free(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *buf)
|
||||
{
|
||||
struct videobuf_res_memory *mem = buf->priv;
|
||||
|
||||
/* mmapped memory can't be freed here, otherwise mmapped region
|
||||
* would be released, while still needed. In this case, the memory
|
||||
release should happen inside videobuf_vm_close().
|
||||
So, it should free memory only if the memory were allocated for
|
||||
read() operation.
|
||||
*/
|
||||
if (buf->memory != V4L2_MEMORY_USERPTR)
|
||||
return;
|
||||
|
||||
if (!mem)
|
||||
return;
|
||||
|
||||
MAGIC_CHECK(mem->magic, MAGIC_RE_MEM);
|
||||
|
||||
/* handle user space pointer case */
|
||||
if (buf->baddr)
|
||||
return;
|
||||
|
||||
/* read() method */
|
||||
res_free(mem);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(videobuf_res_free);
|
||||
|
||||
MODULE_DESCRIPTION("helper module to manage video4linux resource buffers");
|
||||
MODULE_AUTHOR("Amlogic");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -327,9 +327,9 @@ static void vfm_init(void)
|
||||
char def_mipi_id[] = "default_mipi";
|
||||
char def_mipi_name_chain[] = "vdin mipi";
|
||||
#endif /**/
|
||||
#ifdef CONFIG_V4L_AMLOGIC_VIDEO2
|
||||
#ifdef CONFIG_AMLOGIC_V4L_VIDEO2
|
||||
char def_amlvideo2_id[] = "default_amlvideo2";
|
||||
char def_amlvideo2_chain[] = "vdin1 amlvideo2_1";
|
||||
char def_amlvideo2_chain[] = "vdin1 amlvideo2.1";
|
||||
#endif /**/
|
||||
#if (defined CONFIG_TVIN_AFE) || (defined CONFIG_TVIN_HDMI)
|
||||
#ifdef CONFIG_POST_PROCESS_MANAGER
|
||||
@@ -356,7 +356,7 @@ static void vfm_init(void)
|
||||
#if (defined CONFIG_TVIN_AFE) || (defined CONFIG_TVIN_HDMI)
|
||||
vfm_map_add(tvpath_id, tvpath_chain);
|
||||
#endif /**/
|
||||
#ifdef CONFIG_V4L_AMLOGIC_VIDEO2
|
||||
#ifdef CONFIG_AMLOGIC_V4L_VIDEO2
|
||||
vfm_map_add(def_amlvideo2_id, def_amlvideo2_chain);
|
||||
#endif /**/
|
||||
}
|
||||
|
||||
20
drivers/amlogic/media/video_processor/Kconfig
Normal file
20
drivers/amlogic/media/video_processor/Kconfig
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Amlogic video processor configuation
|
||||
#
|
||||
|
||||
menu "Amlogic Video Processor Support"
|
||||
|
||||
config AMLOGIC_VIDEO_PROCESSOR
|
||||
bool "Amlogic Video Processor Driver"
|
||||
default n
|
||||
help
|
||||
Amlogic Video Processor module support.
|
||||
Video Processor module includes ION_VIDEO, PPMGR, VIDEO_DEV and etc.
|
||||
|
||||
if AMLOGIC_VIDEO_PROCESSOR
|
||||
|
||||
source "drivers/amlogic/media/video_processor/video_dev/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
endmenu
|
||||
1
drivers/amlogic/media/video_processor/Makefile
Normal file
1
drivers/amlogic/media/video_processor/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
obj-$(CONFIG_AMLOGIC_V4L_VIDEO2) += video_dev/
|
||||
18
drivers/amlogic/media/video_processor/video_dev/Kconfig
Normal file
18
drivers/amlogic/media/video_processor/video_dev/Kconfig
Normal file
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Amlogic video2 device configuation
|
||||
#
|
||||
|
||||
menu "V4L2 Video Support"
|
||||
|
||||
config AMLOGIC_V4L_VIDEO2
|
||||
tristate "Amlogic v4l video2 device support"
|
||||
depends on VIDEO_DEV
|
||||
select VIDEOBUF_GEN
|
||||
depends on AMLOGIC_MEDIA_COMMON
|
||||
depends on AMLOGIC_VIDEOBUF_RESOURCE
|
||||
depends on AMLOGIC_MEDIA_GE2D
|
||||
default n
|
||||
help
|
||||
Select to enable "Amlogic v4l video2 device support.
|
||||
|
||||
endmenu
|
||||
9
drivers/amlogic/media/video_processor/video_dev/Makefile
Normal file
9
drivers/amlogic/media/video_processor/video_dev/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# Makefile for the amlogic video device interface device drivers.
|
||||
#
|
||||
asflags-y =-mfloat-abi=softfp -mfpu=neon
|
||||
amlcm-objs := common/vfutil.o
|
||||
amlvideo2dri-objs := amlvideo2.o
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_V4L_VIDEO2) +=amlvideo2dri.o
|
||||
|
||||
6111
drivers/amlogic/media/video_processor/video_dev/amlvideo2.c
Normal file
6111
drivers/amlogic/media/video_processor/video_dev/amlvideo2.c
Normal file
File diff suppressed because it is too large
Load Diff
23
drivers/amlogic/media/video_processor/video_dev/amlvideo2.h
Normal file
23
drivers/amlogic/media/video_processor/video_dev/amlvideo2.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* drivers/amlogic/media/video_processor/video_dev/amlvideo2.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 AMLVIDEO2_H_
|
||||
#define AMLVIDEO2_H_
|
||||
|
||||
/* void vf_inqueue(struct vframe_s *vf, const char *receiver); */
|
||||
|
||||
#endif /* AMLVIDEO2_H_ */
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* drivers/amlogic/media/video_processor/video_dev/common/vfp-queue.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 __VFP_QUEUE_H__
|
||||
#define __VFP_QUEUE_H__
|
||||
#include "vfp.h"
|
||||
|
||||
static inline bool vfq_full(struct vfq_s *q)
|
||||
{
|
||||
bool ret = (((q->wp+1) % q->size) == q->rp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
106
drivers/amlogic/media/video_processor/video_dev/common/vfp.h
Normal file
106
drivers/amlogic/media/video_processor/video_dev/common/vfp.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* drivers/amlogic/media/video_processor/video_dev/common/vfp.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 __VFP_H_
|
||||
#define __VFP_H_
|
||||
|
||||
struct vfq_s {
|
||||
int rp;
|
||||
int wp;
|
||||
int size;
|
||||
int pre_rp;
|
||||
int pre_wp;
|
||||
struct vframe_s **pool;
|
||||
};
|
||||
|
||||
static inline void vfq_lookup_start(struct vfq_s *q)
|
||||
{
|
||||
q->pre_rp = q->rp;
|
||||
q->pre_wp = q->wp;
|
||||
}
|
||||
static inline void vfq_lookup_end(struct vfq_s *q)
|
||||
{
|
||||
q->rp = q->pre_rp;
|
||||
q->wp = q->pre_wp;
|
||||
}
|
||||
|
||||
static inline void vfq_init(struct vfq_s *q, u32 size, struct vframe_s **pool)
|
||||
{
|
||||
q->rp = q->wp = 0;
|
||||
q->size = size;
|
||||
q->pool = pool;
|
||||
}
|
||||
|
||||
static inline bool vfq_empty(struct vfq_s *q)
|
||||
{
|
||||
return q->rp == q->wp;
|
||||
}
|
||||
|
||||
static inline void vfq_push(struct vfq_s *q, struct vframe_s *vf)
|
||||
{
|
||||
int wp = q->wp;
|
||||
|
||||
/*ToDo*/
|
||||
smp_mb();
|
||||
|
||||
q->pool[wp] = vf;
|
||||
|
||||
/*ToDo*/
|
||||
smp_wmb();
|
||||
|
||||
q->wp = (wp == (q->size - 1)) ? 0 : (wp + 1);
|
||||
}
|
||||
|
||||
static inline struct vframe_s *vfq_pop(struct vfq_s *q)
|
||||
{
|
||||
struct vframe_s *vf;
|
||||
int rp;
|
||||
|
||||
if (vfq_empty(q))
|
||||
return NULL;
|
||||
|
||||
rp = q->rp;
|
||||
|
||||
/*ToDo*/
|
||||
smp_rmb();
|
||||
|
||||
vf = q->pool[rp];
|
||||
|
||||
/*ToDo*/
|
||||
smp_mb();
|
||||
|
||||
q->rp = (rp == (q->size - 1)) ? 0 : (rp + 1);
|
||||
|
||||
return vf;
|
||||
}
|
||||
|
||||
static inline struct vframe_s *vfq_peek(struct vfq_s *q)
|
||||
{
|
||||
return (vfq_empty(q)) ? NULL : q->pool[q->rp];
|
||||
}
|
||||
|
||||
static inline int vfq_level(struct vfq_s *q)
|
||||
{
|
||||
int level = q->wp - q->rp;
|
||||
|
||||
if (level < 0)
|
||||
level += q->size;
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
#endif /* __VFP_H_ */
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* drivers/amlogic/media/video_processor/video_dev/common/vfutil.c
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
/* #include <linux/fiq_bridge.h> */
|
||||
#include <linux/fs.h>
|
||||
/* #include <mach/am_regs.h> */
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/amlogic/amports/ptsserv.h>
|
||||
#include <linux/amlogic/amports/timestamp.h>
|
||||
#include <linux/amlogic/amports/tsync.h>
|
||||
#include <linux/amlogic/canvas/canvas.h>
|
||||
#include <linux/amlogic/amports/vframe.h>
|
||||
#include <linux/amlogic/amports/vframe_provider.h>
|
||||
#include <linux/amlogic/amports/amstream.h>
|
||||
#include <linux/amlogic/vout/vout_notify.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
static struct vframe_provider_s *vfp;
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
|
||||
void v4l_reg_provider(struct vframe_provider_s *prov)
|
||||
{
|
||||
ulong flags;
|
||||
|
||||
spin_lock_irqsave(&lock, flags);
|
||||
|
||||
if (vfp)
|
||||
vf_unreg_provider(vfp);
|
||||
|
||||
vfp = prov;
|
||||
spin_unlock_irqrestore(&lock, flags);
|
||||
}
|
||||
|
||||
void v4l_unreg_provider(void)
|
||||
{
|
||||
ulong flags;
|
||||
/* int deinterlace_mode = get_deinterlace_mode(); */
|
||||
|
||||
spin_lock_irqsave(&lock, flags);
|
||||
|
||||
vfp = NULL;
|
||||
|
||||
/* if (deinterlace_mode == 2) { */
|
||||
/* disable_pre_deinterlace(); */
|
||||
/* } */
|
||||
/* printk("-----%s------\n",__func__); */
|
||||
spin_unlock_irqrestore(&lock, flags);
|
||||
}
|
||||
|
||||
const struct vframe_provider_s *v4l_get_vfp(void)
|
||||
{
|
||||
return vfp;
|
||||
}
|
||||
45
include/linux/amlogic/media/v4l_util/videobuf-res.h
Normal file
45
include/linux/amlogic/media/v4l_util/videobuf-res.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* include/linux/amlogic/media/v4l_util/videobuf-res.h
|
||||
*
|
||||
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 _VIDEOBUF_RES_H
|
||||
#define _VIDEOBUF_RES_H
|
||||
|
||||
#include <media/videobuf-core.h>
|
||||
|
||||
struct videobuf_res_privdata {
|
||||
/* const* char dev_name; */
|
||||
u32 magic;
|
||||
resource_size_t start;
|
||||
resource_size_t end;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
void videobuf_queue_res_init(struct videobuf_queue *q,
|
||||
const struct videobuf_queue_ops *ops,
|
||||
struct device *dev,
|
||||
spinlock_t *irqlock,
|
||||
enum v4l2_buf_type type,
|
||||
enum v4l2_field field,
|
||||
unsigned int msize,
|
||||
void *priv,
|
||||
struct mutex *ext_lock);
|
||||
|
||||
resource_size_t videobuf_to_res(struct videobuf_buffer *buf);
|
||||
void videobuf_res_free(struct videobuf_queue *q,
|
||||
struct videobuf_buffer *buf);
|
||||
|
||||
#endif /* _VIDEOBUF_RES_H */
|
||||
Reference in New Issue
Block a user