Commit 7e06044e authored by Bob Beckett's avatar Bob Beckett
Browse files

Merge branch 'bob/cnm/wave5-dev-rebase' into 'wave5-dev'

allocator working with fpga

See merge request !1
parents 4d09024c 10d39c51
......@@ -229,7 +229,7 @@ config VIDEO_CODA
config VIDEO_WAVE_VPU
tristate "Chips&Media Wave Codec Driver"
depends on VIDEO_DEV && VIDEO_V4L2 && OF && (ARCH_MXC || COMPILE_TEST)
depends on VIDEO_DEV && VIDEO_V4L2 && OF
select VIDEOBUF2_DMA_CONTIG
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
......
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_WAVE_VPU) += wave5.o
wave5-objs += vpuapi/coda9/coda9.o \
vpuapi/vpuapifunc.o \
wave5-objs += vpuapi/vpuapifunc.o \
vpuapi/wave/wave5.o \
vpuapi/product.o \
vpuapi/vpuapi.o \
vdi/v4l2/vdi.o \
vdi/v4l2/vdi_osal.o \
vdi/v4l2/driver/vmm.o \
vdi/v4l2/driver/vpu_dec.o \
vdi/v4l2/driver/vpu.o \
......
......@@ -80,25 +80,7 @@
//#define SUPPORT_READ_BITSTREAM_IN_ENCODER
#define SUPPORT_MAPCONVERTER
//#define SUPPORT_SW_UART
// #define SUPPORT_SW_UART_V2 // WAVE511 or WAVE521C
// #define SUPPORT_SW_UART_ON_NONOS
#ifdef SUPPORT_SW_UART_ON_NONOS
#if defined(SUPPORT_SW_UART) || defined(SUPPORT_SW_UART_V2)
#else
#error "SUPPORT_SW_UART_ON_NONOS define needs (#if defined(SUPPORT_SW_UART_V2) || defined(SUPPORT_SW_UART))"
#endif
#endif
#endif /* __CONFIG_H__ */
......@@ -36,7 +36,7 @@ ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m := vpu-v4l2.o
vpu-v4l2-objs := vpu.o vpu_dec.o vpu_enc.o vmm.o ../../../vpuapi/vpuapi.o ../../../vpuapi/product.o ../../../vpuapi/vpuapifunc.o ../../../vpuapi/wave/wave5.o ../../../vpuapi/coda9/coda9.o ../../vdi_debug.o ../vdi.o ../vdi_osal.o
vpu-v4l2-objs := vpu.o vpu_dec.o vpu_enc.o vmm.o ../../../vpuapi/vpuapi.o ../../../vpuapi/product.o ../../../vpuapi/vpuapifunc.o ../../../vpuapi/wave/wave5.o ../../vdi_debug.o ../vdi.o
else
......@@ -54,11 +54,10 @@ endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
rm -rf ../vdi.o ../vdi_osal.o
rm -rf ../vdi.o
rm -rf ../../vdi_debug.o
rm -rf ../../../vpuapi/vpuapi.o ../../../vpuapifunc.o ../../../vpuapi/product.o
rm -rf ../../../vpuapi/vpuapi.o ../../../vpuapi/vpuapifunc.o ../../../vpuapi/product.o
rm -rf ../../../vpuapi/wave/wave5.o
rm -rf ../../../vpuapi/coda9/coda9.o
depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend
......
......@@ -499,7 +499,7 @@ vmem_alloc(
unsigned long pid
)
{
avl_node_t *node;
avl_node_t *node = NULL;
page_t *free_page;
int npages, free_size;
int alloc_pageno;
......@@ -623,25 +623,3 @@ vmem_free(
return 0;
}
int
vmem_get_info(
video_mm_t *mm,
vmem_info_t *info
)
{
if (mm == NULL) {
printk(KERN_INFO "vmem_get_info: invalid handle\n");
return -1;
}
if (info == NULL)
return -1;
info->total_pages = mm->num_pages;
info->alloc_pages = mm->alloc_page_count;
info->free_pages = mm->free_page_count;
info->page_size = VMEM_PAGE_SIZE;
return 0;
}
......@@ -83,12 +83,6 @@ vmem_free(
unsigned long pid
);
extern int
vmem_get_info(
video_mm_t *mm,
vmem_info_t *info
);
#if defined (__cplusplus)
}
#endif
......
......@@ -19,8 +19,8 @@
#include "vpu.h"
#include "vpu_dec.h"
#include "vpu_enc.h"
#include "coda9/coda9_regdefine.h"
#include "wave/wave5_regdefine.h"
#include "../../../vpuapi/wave/wave5_regdefine.h"
#include "../../../vpuapi/vpuconfig.h"
#define VPU_PLATFORM_DEVICE_NAME "vdec"
#define VPU_CLK_NAME "vcodec"
......@@ -47,18 +47,6 @@ MODULE_DEVICE_TABLE(pci, ids);
#endif /* CNM_FPGA_PCI_INTERFACE */
#endif /* CNM_FPGA_PLATFORM */
#ifdef VPU_SUPPORT_RESERVED_VIDEO_MEMORY
#ifdef CNM_FPGA_PLATFORM
# define VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE (2*1024*1024*1024UL)
# define VPU_DRAM_PHYSICAL_BASE 0x80000000
#else
# define VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE (62*1024*1024)
# define VPU_DRAM_PHYSICAL_BASE 0x86C00000
#endif /* CNM_FPGA_PLATFORM */
#include "vmm.h"
struct vpudrv_buffer_t s_video_memory = {0};
#endif /*VPU_SUPPORT_RESERVED_VIDEO_MEMORY*/
static void vpu_clk_disable(struct clk *clk);
static int vpu_clk_enable(struct clk *clk);
static struct clk *vpu_clk_get(struct device *dev);
......@@ -66,7 +54,7 @@ static void vpu_clk_put(struct clk *clk);
static struct clk *s_vpu_clk;
struct vpudrv_buffer_t s_vpu_register = {0};
struct vpu_buf s_vpu_register = {0};
unsigned int vpu_debug = 1;
module_param(vpu_debug, uint, 0644);
......@@ -85,8 +73,6 @@ int vpu_wait_interrupt(struct vpu_instance *inst, unsigned int timeout)
{
int irq_status;
spin_lock(&inst->dev->lock);
wait_for_completion_timeout(&inst->dev->irq_done,
msecs_to_jiffies(timeout));
if (inst->dev->irq_status > 0) {
......@@ -101,8 +87,6 @@ int vpu_wait_interrupt(struct vpu_instance *inst, unsigned int timeout)
reinit_completion(&inst->dev->irq_done);
spin_unlock(&inst->dev->lock);
return irq_status;
}
......@@ -121,13 +105,13 @@ static irqreturn_t vpu_irq(int irq, void *dev_id)
inst = v4l2_m2m_get_curr_priv(dev->v4l2_m2m_dev);
if (inst == NULL) {
VLOG(ERR, "VPU instance not ready\n");
pr_err("VPU instance not ready\n");
complete(&dev->irq_done);
} else {
inst->ops->finish_process(inst);
}
} else {
VLOG(ERR, "Interrupt not ready\n");
pr_err("Interrupt not ready\n");
return IRQ_HANDLED;
}
......@@ -153,8 +137,8 @@ static int vpu_irq_module(void *data)
if (PRODUCT_CODE_W_SERIES(product_code))
status = vdi_read_register(0, W5_VPU_VPU_INT_STS);
else if (PRODUCT_CODE_NOT_W_SERIES(product_code))
status = vdi_read_register(0, BIT_INT_STS);
else
WARN_ONCE(1, "unsupported product code 0x%x\n", product_code);
if (status)
vpu_irq(0, data);
......@@ -206,31 +190,31 @@ static const struct v4l2_m2m_ops vpu_m2m_ops = {
static int vpu_load_firmware(struct device *dev)
{
const struct firmware *fw;
RetCode ret = RETCODE_SUCCESS;
Uint32 version;
Uint32 revision;
Uint32 productId;
enum RetCode ret = RETCODE_SUCCESS;
uint32_t version;
uint32_t revision;
uint32_t productId;
if (request_firmware(&fw, VPU_FIRMWARE_NAME, dev)) {
VLOG(ERR, "request_firmware fail\n");
pr_err("request_firmware fail\n");
return -1;
}
ret = VPU_InitWithBitcode(0, (unsigned short *)fw->data, fw->size/2);
ret = VPU_InitWithBitcode(dev, 0, (unsigned short *)fw->data, fw->size/2);
if (ret != RETCODE_SUCCESS) {
VLOG(ERR, "VPU_InitWithBitcode fail\n");
pr_err("VPU_InitWithBitcode fail\n");
return -1;
}
release_firmware(fw);
ret = VPU_GetVersionInfo(0, &version, &revision, &productId);
if (ret != RETCODE_SUCCESS) {
VLOG(ERR, "VPU_GetVersionInfo fail\n");
pr_err("VPU_GetVersionInfo fail\n");
return -1;
}
VLOG(ERR, "ProductId : %08x\n", productId);
VLOG(ERR, "FwVersion : %08x(r%d)\n", version, revision);
pr_err("enum ProductId : %08x\n", productId);
pr_err("FwVersion : %08x(r%d)\n", version, revision);
return 0;
}
......@@ -245,72 +229,57 @@ static int vpu_probe(struct platform_device *pdev)
{
int err = 0;
struct vpu_device *dev;
#ifdef VPU_SUPPORT_RESERVED_VIDEO_MEMORY
unsigned int mem_size;
unsigned long mem_virt;
unsigned long mem_base;
#endif
#ifdef CNM_FPGA_PLATFORM
#ifdef CNM_FPGA_PCI_INTERFACE
int i;
unsigned int reg_size;
unsigned long reg_virt;
unsigned long reg_base;
if (id->vendor != CNM_DEV_VENDOR_ID && id->device != CNM_DEV_DEVICE_ID)
return -ENODEV;
if (pci_enable_device(pdev)) {
VLOG(ERR, "pci_enable_device fail\n");
pr_err("pci_enable_device fail\n");
return -ENODEV;
}
/* limit dma addresses to 2GB. This way we can alias host dma buffers
* in to FPGA memory directly */
pci_set_dma_mask(pdev, DMA_BIT_MASK(31));
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(31));
for (i = 0; i < 6; i++) {
if ((pci_resource_flags(pdev, i) & IORESOURCE_MEM)) {
s_vpu_register.phys_addr = pci_resource_start(pdev, i);
s_vpu_register.daddr = pci_resource_start(pdev, i);
break;
}
}
if (!s_vpu_register.phys_addr) {
VLOG(ERR, "HPI controller has no memory regions defined.\n");
if (!s_vpu_register.daddr) {
pr_err("HPI controller has no memory regions defined.\n");
return -EINVAL;
}
reg_size = CNM_DEV_REGISTER_SIZE;
reg_base = s_vpu_register.phys_addr;
reg_virt = (unsigned long)ioremap(reg_base, reg_size);
s_vpu_register.virt_addr = reg_virt;
s_vpu_register.size = reg_size;
VLOG(ERR, "REGISTER BASE id=%d phys_addr=0x%lx size=%d\n",
i, reg_base, reg_size);
s_vpu_register.size = CNM_DEV_REGISTER_SIZE;
s_vpu_register.vaddr = ioremap(s_vpu_register.daddr, s_vpu_register.size);
#endif
#else
struct resource *res = NULL;
unsigned int reg_size;
unsigned long reg_virt;
unsigned long reg_base;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
/* physical addresses limited to 32 bits */
dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
dma_set_coherent_mask(&pdev->Dev, DMA_BIT_MASK(32));
if (res) {
reg_base = res->start;
reg_size = res->end - res->start;
reg_virt = (unsigned long)ioremap(reg_base, reg_size);
} else {
reg_base = VPU_REG_BASE_ADDR;
reg_size = VPU_REG_SIZE;
reg_virt = (unsigned long)ioremap(reg_base, reg_size);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err("unable to get mem resource\n");
return -EINVAL;
}
s_vpu_register.phys_addr = reg_base;
s_vpu_register.virt_addr = reg_virt;
s_vpu_register.size = reg_size;
VLOG(ERR, "Platform driver phys_addr=0x%lx virt_addr=0x%lx\n",
s_vpu_register.phys_addr, s_vpu_register.virt_addr);
s_vpu_register.daddr = res->start;
s_vpu_register.size = resource_size(res);
s_vpu_register.vaddr = ioremap(s_vpu_register.daddr, s_vpu_register.size);
#endif
pr_info("REGISTER BASE daddr=%pad vaddr=%p size=%zu\n",
&s_vpu_register.daddr, s_vpu_register.vaddr, s_vpu_register.size);
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
......@@ -320,28 +289,27 @@ static int vpu_probe(struct platform_device *pdev)
err = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (err) {
VLOG(ERR, "v4l2_device_register fail\n");
pr_err("v4l2_device_register fail\n");
goto ERROR_PROVE_DEVICE;
}
mutex_init(&dev->mutex);
spin_lock_init(&dev->lock);
init_completion(&dev->irq_done);
dev->v4l2_m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
if (IS_ERR(dev->v4l2_m2m_dev)) {
VLOG(ERR, "v4l2_m2m_init fail\n");
pr_err("v4l2_m2m_init fail\n");
goto ERROR_PROVE_DEVICE;
}
err = vpu_dec_register_device(dev);
if (err) {
VLOG(ERR, "vpu_dec_register_device fail\n");
pr_err("vpu_dec_register_device fail\n");
goto ERROR_PROVE_DEVICE;
}
err = vpu_enc_register_device(dev);
if (err) {
VLOG(ERR, "vpu_enc_register_device fail\n");
pr_err("vpu_enc_register_device fail\n");
goto ERROR_PROVE_DEVICE;
}
......@@ -351,9 +319,9 @@ static int vpu_probe(struct platform_device *pdev)
s_vpu_clk = vpu_clk_get(NULL);
if (!s_vpu_clk)
VLOG(ERR, "Not support clock controller.\n");
pr_err("Not support clock controller.\n");
else
VLOG(ERR, "Get clock controller s_vpu_clk=%p\n", s_vpu_clk);
pr_err("Get clock controller s_vpu_clk=%p\n", s_vpu_clk);
vpu_clk_enable(s_vpu_clk);
......@@ -364,47 +332,29 @@ static int vpu_probe(struct platform_device *pdev)
if (res) {
dev->irq = res->start;
VLOG(ERR, "platform driver irq number=0x%x\n", dev->irq);
pr_err("platform driver irq number=0x%x\n", dev->irq);
}
err = request_threaded_irq(dev->irq, vpu_irq, NULL, 0, "vpu_irq", dev);
if (err) {
VLOG(ERR, "fail to register interrupt handler\n");
pr_err("fail to register interrupt handler\n");
goto ERROR_PROVE_DEVICE;
}
#endif
#ifdef VPU_SUPPORT_RESERVED_VIDEO_MEMORY
mem_size = VPU_INIT_VIDEO_MEMORY_SIZE_IN_BYTE;
mem_base = VPU_DRAM_PHYSICAL_BASE;
#ifdef CNM_FPGA_PLATFORM
mem_virt = VPU_DRAM_PHYSICAL_BASE;
#else
mem_virt = (unsigned long)ioremap(mem_base, PAGE_ALIGN(mem_size));
#endif
s_video_memory.size = mem_size;
s_video_memory.phys_addr = mem_base;
s_video_memory.base = mem_virt;
if (!s_video_memory.base) {
VLOG(ERR, "Fail to remap video memory\n");
#ifdef CNM_FPGA_PLATFORM
err = vdi_init(&pdev->dev, 0);
if (err) {
dev_err(&pdev->dev, "%s(): failed to init vdi: %d\n", __func__, err);
goto ERROR_PROVE_DEVICE;
}
VLOG(ERR, "Reserved video memory phys_addr=0x%lx base=0x%lx\n",
s_video_memory.phys_addr, s_video_memory.base);
#else
VLOG(ERR, "Need to implement customers memory allocator\n");
#endif
#ifdef CNM_FPGA_PLATFORM
vdi_init(0);
vdi_init_fpga(0);
vdi_release(0);
#endif
if (vpu_load_firmware(&pdev->dev)) {
VLOG(ERR, "failed to vpu_load_firmware\n");
pr_err("failed to vpu_load_firmware\n");
goto ERROR_PROVE_DEVICE;
}
#ifdef CNM_FPGA_PLATFORM
......@@ -417,7 +367,7 @@ static int vpu_probe(struct platform_device *pdev)
return 0;
ERROR_PROVE_DEVICE:
if (!dev) {
if (dev) {
vpu_dec_unregister_device(dev);
vpu_enc_unregister_device(dev);
v4l2_m2m_release(dev->v4l2_m2m_dev);
......@@ -434,17 +384,10 @@ static int vpu_probe(struct platform_device *pdev)
#endif
kfree(dev);
}
#ifdef VPU_SUPPORT_RESERVED_VIDEO_MEMORY
if (s_video_memory.base) {
#ifdef CNM_FPGA_PLATFORM
#else
iounmap((void *)s_video_memory.base);
#endif /* CNM_FPGA_PLATFORM */
s_video_memory.base = 0;
if (s_vpu_register.vaddr) {
iounmap((void *)s_vpu_register.vaddr);
s_vpu_register.vaddr = NULL;
}
#endif
if (s_vpu_register.virt_addr)
iounmap((void *)s_vpu_register.virt_addr);
vpu_clk_disable(s_vpu_clk);
vpu_clk_put(s_vpu_clk);
......@@ -462,17 +405,8 @@ static int vpu_remove(struct platform_device *pdev)
{
struct vpu_device *dev = dev_get_drvdata(&pdev->dev);
#ifdef VPU_SUPPORT_RESERVED_VIDEO_MEMORY
if (s_video_memory.base) {
#ifdef CNM_FPGA_PLATFORM
#else
iounmap((void *)s_video_memory.base);
#endif /* CNM_FPGA_PLATFORM */
s_video_memory.base = 0;
}
#endif
if (s_vpu_register.virt_addr)
iounmap((void *)s_vpu_register.virt_addr);
if (s_vpu_register.vaddr)
iounmap((void *)s_vpu_register.vaddr);
vpu_dec_unregister_device(dev);
vpu_enc_unregister_device(dev);
......@@ -481,6 +415,8 @@ static int vpu_remove(struct platform_device *pdev)
vpu_clk_disable(s_vpu_clk);
vpu_clk_put(s_vpu_clk);
vdi_release(0);
#ifdef CNM_FPGA_PLATFORM
if (dev->irq_module_id) {
wake_up_interruptible(&dev->irq_wait);
......@@ -510,9 +446,26 @@ static struct pci_driver vpu_driver = {
};
#endif
#else
#ifdef CONFIG_OF
// TODO: move this file to wave5 layer and convert runtime paramer filling to
// predefined structure used as data here.
static const struct of_device_id wave5_dt_ids[] = {
{ .compatible = "c&m,cm511-vpu", .data = (void *)WAVE511_CODE },
{ .compatible = "c&m,cm517-vpu", .data = (void *)WAVE517_CODE },
{ .compatible = "c&m,cm521-vpu", .data = (void *)WAVE521_CODE },
{ .compatible = "c&m,cm521c-vpu", .data = (void *)WAVE521C_CODE },
{ .compatible = "c&m,cm521c-dual-vpu", .data = (void *)WAVE521C_DUAL_CODE },
{ .compatible = "c&m,cm521e1-vpu", .data = (void *)WAVE521E1_CODE },
{ .compatible = "c&m,cm537-vpu", .data = (void *)WAVE537_CODE },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, wave5_dt_ids);
#endif
static struct platform_driver vpu_driver = {
.driver = {
.name = VPU_PLATFORM_DEVICE_NAME,
.of_match_table = of_match_ptr(wave5_dt_ids),
},
.probe = vpu_probe,
.remove = vpu_remove,
......@@ -571,7 +524,7 @@ int vpu_clk_enable(struct clk *clk)
return 1;
#else
if (!(clk == NULL || IS_ERR(clk))) {
clk_enable(clk);
clk_prepare_enable(clk);
return 1;
}
......
......@@ -25,9 +25,6 @@
#include "../../../vpuapi/vpuconfig.h"
#include "../../../vpuapi/vpuapi.h"
// if this driver knows the dedicated video memory address
#define VPU_SUPPORT_RESERVED_VIDEO_MEMORY
#define DPRINTK(dev, level, fmt, args...) \
v4l2_dbg(level, vpu_debug, &dev->v4l2_dev, "[%s]" fmt, __func__, ##args)
......@@ -35,7 +32,7 @@ struct vpudrv_buffer_t {
unsigned int size;
unsigned long phys_addr;
unsigned long base; // kernel logical address in use kernel
unsigned long virt_addr; // virtual user space address
void __iomem *virt_addr; // virtual user space address
};
struct vpu_device {
......@@ -44,7 +41,6 @@ struct vpu_device {
struct video_device video_dev_dec;
struct video_device video_dev_enc;
struct mutex mutex;
spinlock_t lock;
unsigned int irq_status;
int irq;
struct completion irq_done;
......@@ -93,9 +89,9 @@ struct vpu_instance {
enum vpu_instance_type type;
const struct vpu_instance_ops *ops;
VpuHandle handle;
FrameBuffer frame_buf[MAX_REG_FRAME];
vpu_buffer_t frame_vbuf[MAX_REG_FRAME];
struct CodecInst* handle;
struct FrameBuffer frame_buf[MAX_REG_FRAME];
struct vpu_buf frame_vbuf[MAX_REG_FRAME];
u32 min_dst_frame_buf_count;
u32 queued_src_buf_num;
u32 queued_dst_buf_num;
......@@ -103,7 +99,7 @@ struct vpu_instance {
//Decoder param
struct mutex bitstream_mutex;
vpu_buffer_t bitstream_vbuf;
struct vpu_buf bitstream_vbuf;
bool thumbnail_mode;
//Encoder param
......@@ -127,7 +123,7 @@ struct vpu_buffer {
struct v4l2_m2m_buffer v4l2_m2m_buf;
bool consumed;
#ifdef CNM_FPGA_PLATFORM
vpu_buffer_t vpu_buf;
struct vpu_buf vpu_buf;
#endif
};
......@@ -145,10 +141,7 @@ struct vpu_format {
unsigned int min_height;
};
#ifdef VPU_SUPPORT_RESERVED_VIDEO_MEMORY
extern struct vpudrv_buffer_t s_video_memory;
#endif
extern struct vpudrv_buffer_t s_vpu_register;
extern struct vpu_buf s_vpu_register;
extern unsigned int vpu_debug;
static inline struct vpu_instance *to_vpu_inst(struct v4l2_fh *vfh)
......
......@@ -83,7 +83,7 @@ static const struct vpu_format vpu_dec_fmt_list[2][6] = {