Drivers/VCODEC: support vcodec function for hikey970.
Add VCODEC code in kernel to support vcodec for hikey970. Signed-off-by: xwx495457 <xwx495457@notesmail.huawei.com>
This commit is contained in:
Executable → Regular
@@ -210,4 +210,7 @@ source "drivers/fpga/Kconfig"
|
||||
|
||||
source "drivers/tee/Kconfig"
|
||||
|
||||
source "drivers/vcodec/venc_hivna/Kconfig"
|
||||
|
||||
source "drivers/vcodec/vdec_hivna/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -177,3 +177,5 @@ obj-$(CONFIG_NVMEM) += nvmem/
|
||||
obj-$(CONFIG_FPGA) += fpga/
|
||||
obj-$(CONFIG_TEE) += tee/
|
||||
obj-$(CONFIG_HISILICON_PLATFORM)+= hisi/
|
||||
obj-$(CONFIG_HI_VCODEC_VENC) += vcodec/venc_hivna/
|
||||
obj-$(CONFIG_HI_VCODEC_VDEC) += vcodec/vdec_hivna/
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
menu "Hisilicon video vdec support"
|
||||
config HI_VCODEC_VDEC
|
||||
tristate "Hisilicon video decoder support"
|
||||
default n
|
||||
help
|
||||
This is the hisilicon decoder driver
|
||||
endmenu
|
||||
|
||||
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
obj-$(CONFIG_HI_VCODEC_VDEC) += omxvdec/ vfmw_v4.0/
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
config OMXVDEC
|
||||
tristate "hisilicon omx video decoder support"
|
||||
default n
|
||||
---help---
|
||||
This is the omxvdec driver
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
|
||||
TOP := drivers/../..
|
||||
|
||||
EXTRA_CFLAGS += -DENV_ARMLINUX_KERNEL
|
||||
EXTRA_CFLAGS += -DHIVDEC_SMMU_SUPPORT
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/vcodec/hi_vcodec/vdec_hivna/omxvdec
|
||||
EXTRA_CFLAGS += -Idrivers/vcodec/hi_vcodec/vdec_hivna/vfmw_v4.0
|
||||
EXTRA_CFLAGS += -Idrivers/vcodec/hi_vcodec/vdec_hivna/vfmw_v4.0/format
|
||||
EXTRA_CFLAGS += -fno-pic
|
||||
EXTRA_CFLAGS += -DOMXVDEC_TVP_CONFLICT
|
||||
|
||||
ifneq ($(TARGET_BUILD_VARIANT), user)
|
||||
EXTRA_CFLAGS += -DUSER_DISABLE_VDEC_PROC
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS +=-DPLATFORM_KIRIN970
|
||||
|
||||
#build in
|
||||
obj-$(CONFIG_HI_VCODEC_VDEC) += hi_omxvdec.o
|
||||
hi_omxvdec-objs += omxvdec.o regulator.o
|
||||
|
||||
Executable
+569
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* vdec driver interface
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "omxvdec.h"
|
||||
#include "../vfmw_v4.0/linux_kernel_osal.h"
|
||||
#include "../vfmw_v4.0/vfmw_dts.h"
|
||||
#include "../vfmw_v4.0/scd_drv.h"
|
||||
#include "../vfmw_v4.0/format/vdm_drv.h"
|
||||
#include "../vfmw_v4.0/vfmw_intf.h"
|
||||
/*lint -e774*/
|
||||
|
||||
#define PCTRL_PERI (0xE8A090A4)
|
||||
#define PCTRL_PERI_SATA0 (0xE8A090BC)
|
||||
|
||||
static int gIsNormalInit = 0;
|
||||
|
||||
static int gIsDeviceDetected = 0;
|
||||
static struct class *g_OmxVdecClass = NULL;
|
||||
static const char g_OmxVdecDrvName[] = OMXVDEC_NAME;
|
||||
static dev_t g_OmxVdecDevNum;
|
||||
static OMXVDEC_ENTRY g_OmxVdecEntry;
|
||||
|
||||
//Modified for 64-bit platform
|
||||
typedef enum {
|
||||
T_IOCTL_ARG,
|
||||
T_IOCTL_ARG_COMPAT,
|
||||
T_BUTT,
|
||||
} COMPAT_TYPE_E;
|
||||
|
||||
typedef enum {
|
||||
KIRIN_970_ES,
|
||||
KIRIN_970_CS,
|
||||
KIRIN_980,
|
||||
KIRIN_BUTT,
|
||||
} KIRIN_PLATFORM_E;
|
||||
|
||||
#define CHECK_PARA_SIZE_RETURN(size, para_size, command) \
|
||||
do { \
|
||||
if (size != para_size) { \
|
||||
printk(KERN_CRIT "%s: prarameter_size is error\n", command); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_RETURN(cond, else_print) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
printk(KERN_CRIT "%s : %s\n", __func__, else_print); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_SCENE_EQ_RETURN(cond, else_print) \
|
||||
do { \
|
||||
if (cond) { \
|
||||
printk(KERN_INFO "%s : %s\n", __func__, else_print); \
|
||||
return -EIO; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
static int omxvdec_setup_cdev(OMXVDEC_ENTRY *omxvdec, const struct file_operations *fops)
|
||||
{
|
||||
int rc;
|
||||
struct device *dev;
|
||||
|
||||
g_OmxVdecClass = class_create(THIS_MODULE, "omxvdec_class");
|
||||
if (IS_ERR(g_OmxVdecClass)) {
|
||||
rc = PTR_ERR(g_OmxVdecClass);
|
||||
g_OmxVdecClass = NULL;
|
||||
printk(KERN_CRIT "%s call class_create failed, rc : %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = alloc_chrdev_region(&g_OmxVdecDevNum, 0, 1, "hisi video decoder");
|
||||
if (rc) {
|
||||
printk(KERN_CRIT "%s call alloc_chrdev_region failed, rc : %d\n", __func__, rc);
|
||||
goto cls_destroy;
|
||||
}
|
||||
|
||||
dev = device_create(g_OmxVdecClass, NULL, g_OmxVdecDevNum, NULL, OMXVDEC_NAME);
|
||||
if (IS_ERR(dev)) {
|
||||
rc = PTR_ERR(dev);
|
||||
printk(KERN_CRIT "%s call device_create failed, rc : %d\n", __func__, rc);
|
||||
goto unregister_region;
|
||||
}
|
||||
|
||||
cdev_init(&omxvdec->cdev, fops);
|
||||
omxvdec->cdev.owner = THIS_MODULE;
|
||||
omxvdec->cdev.ops = fops;
|
||||
rc = cdev_add(&omxvdec->cdev, g_OmxVdecDevNum, 1);
|
||||
if (rc < 0) {
|
||||
printk(KERN_CRIT "%s call cdev_add failed, rc : %d\n", __func__, rc);
|
||||
goto dev_destroy;
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
|
||||
dev_destroy:
|
||||
device_destroy(g_OmxVdecClass, g_OmxVdecDevNum);
|
||||
unregister_region:
|
||||
unregister_chrdev_region(g_OmxVdecDevNum, 1);
|
||||
cls_destroy:
|
||||
class_destroy(g_OmxVdecClass);
|
||||
g_OmxVdecClass = NULL;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int omxvdec_cleanup_cdev(OMXVDEC_ENTRY *omxvdec)
|
||||
{
|
||||
if (!g_OmxVdecClass) {
|
||||
printk(KERN_CRIT "%s: Invalid g_OmxVdecClass is NULL", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
cdev_del(&omxvdec->cdev);
|
||||
device_destroy(g_OmxVdecClass, g_OmxVdecDevNum);
|
||||
unregister_chrdev_region(g_OmxVdecDevNum, 1);
|
||||
class_destroy(g_OmxVdecClass);
|
||||
g_OmxVdecClass = NULL;
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static int omxvdec_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret = -EBUSY;
|
||||
OMXVDEC_ENTRY *omxvdec = NULL;
|
||||
|
||||
omxvdec = container_of(inode->i_cdev, OMXVDEC_ENTRY, cdev);
|
||||
|
||||
VDEC_MUTEX_LOCK(&omxvdec->omxvdec_mutex);
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_scd);
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_vdh);
|
||||
|
||||
if (omxvdec->open_count < MAX_OPEN_COUNT) {
|
||||
omxvdec->open_count++;
|
||||
if (omxvdec->open_count == 1) {
|
||||
ret = VDEC_Regulator_Enable();
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "%s : VDEC_Regulator_Enable failed\n", __func__);
|
||||
goto error0;
|
||||
}
|
||||
ret = VCTRL_OpenVfmw();
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "%s : vfmw open failed\n", __func__);
|
||||
goto error1;
|
||||
}
|
||||
gIsNormalInit = 1;
|
||||
}
|
||||
|
||||
file->private_data = omxvdec;
|
||||
ret = HI_SUCCESS;
|
||||
} else {
|
||||
printk(KERN_CRIT "%s open omxvdec instance too much\n", __func__);
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s, open_count : %d\n", __func__, omxvdec->open_count);
|
||||
goto exit;
|
||||
|
||||
error1:
|
||||
(void)VDEC_Regulator_Disable();
|
||||
error0:
|
||||
omxvdec->open_count--;
|
||||
exit:
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_vdh);
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_scd);
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->omxvdec_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int omxvdec_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
OMXVDEC_ENTRY *omxvdec = NULL;
|
||||
int ret = HI_SUCCESS;
|
||||
|
||||
omxvdec = file->private_data;
|
||||
if (omxvdec == NULL) {
|
||||
printk(KERN_CRIT "%s: invalid omxvdec is null\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
VDEC_MUTEX_LOCK(&omxvdec->omxvdec_mutex);
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_scd);
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_vdh);
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
printk(KERN_CRIT "%s: invalid file->private_data is null\n", __func__);
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (omxvdec->open_count > 0)
|
||||
omxvdec->open_count--;
|
||||
|
||||
if (omxvdec->open_count == 0) {
|
||||
VCTRL_CloseVfmw();
|
||||
VDEC_Regulator_Disable();
|
||||
gIsNormalInit = 0;
|
||||
}
|
||||
file->private_data = NULL;
|
||||
|
||||
printk(KERN_INFO "exit %s , open_count : %d\n", __func__, omxvdec->open_count);
|
||||
exit:
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_vdh);
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_scd);
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->omxvdec_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Modified for 64-bit platform */
|
||||
static int omxvdec_compat_get_data(COMPAT_TYPE_E eType, void __user *pUser, void *pData)
|
||||
{
|
||||
int ret = HI_SUCCESS;
|
||||
int s32Data = 0;
|
||||
compat_ulong_t CompatData = 0;
|
||||
OMXVDEC_IOCTL_MSG *pIoctlMsg = (OMXVDEC_IOCTL_MSG *)pData;
|
||||
|
||||
if (NULL == pUser || NULL == pData) {
|
||||
printk(KERN_CRIT "%s: param is null\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
switch (eType) {
|
||||
case T_IOCTL_ARG:
|
||||
if (copy_from_user(pIoctlMsg, pUser, sizeof(*pIoctlMsg))) {
|
||||
printk(KERN_CRIT "%s puser copy failed\n", __func__);
|
||||
ret = HI_FAILURE;
|
||||
}
|
||||
break;
|
||||
case T_IOCTL_ARG_COMPAT: {
|
||||
COMPAT_IOCTL_MSG __user *pCompatMsg = pUser;
|
||||
|
||||
ret |= get_user(s32Data, &(pCompatMsg->chan_num));
|
||||
pIoctlMsg->chan_num = s32Data;
|
||||
|
||||
ret |= get_user(s32Data, &(pCompatMsg->in_size));
|
||||
pIoctlMsg->in_size = s32Data;
|
||||
|
||||
ret |= get_user(s32Data, &(pCompatMsg->out_size));
|
||||
pIoctlMsg->out_size = s32Data;
|
||||
|
||||
ret |= get_user(CompatData, &(pCompatMsg->in));
|
||||
pIoctlMsg->in = (void *) ((unsigned long)CompatData);
|
||||
|
||||
ret |= get_user(CompatData, &(pCompatMsg->out));
|
||||
pIoctlMsg->out = (void *) ((unsigned long)CompatData);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk(KERN_CRIT "%s: unkown type %d\n", __func__, eType);
|
||||
ret = HI_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long omxvdec_ioctl_common(struct file *file, unsigned int cmd, unsigned long arg, COMPAT_TYPE_E type)
|
||||
{
|
||||
int ret;
|
||||
int x_scene;
|
||||
OMXVDEC_IOCTL_MSG vdec_msg;
|
||||
void *u_arg = (void *)arg;
|
||||
OMXVDEC_ENTRY *omxvdec = file->private_data;
|
||||
|
||||
OMXSCD_REG_CFG_S scd_reg_cfg;
|
||||
SCD_STATE_REG_S scd_state_reg;
|
||||
OMXVDH_REG_CFG_S vdm_reg_cfg;
|
||||
VDMHAL_BACKUP_S vdm_state_reg;
|
||||
int vdm_is_run;
|
||||
|
||||
x_scene = VCTRL_Scen_Ident(cmd);
|
||||
CHECK_SCENE_EQ_RETURN(x_scene == 1, "xxx scene");
|
||||
|
||||
CHECK_RETURN(omxvdec != NULL, "omxvdec is null");
|
||||
|
||||
ret = omxvdec_compat_get_data(type, u_arg, &vdec_msg);
|
||||
CHECK_RETURN(ret == HI_SUCCESS, "compat data get failed");
|
||||
|
||||
switch (cmd) {
|
||||
case VDEC_IOCTL_VDM_PROC:
|
||||
CHECK_PARA_SIZE_RETURN(sizeof(vdm_reg_cfg), vdec_msg.in_size, "VDEC_IOCTL_VDM_PROC_IN");
|
||||
CHECK_PARA_SIZE_RETURN(sizeof(vdm_state_reg), vdec_msg.out_size, "VDEC_IOCTL_VDM_PROC_OUT");
|
||||
if (copy_from_user(&vdm_reg_cfg, vdec_msg.in, sizeof(vdm_reg_cfg))) {
|
||||
printk(KERN_CRIT "VDEC_IOCTL_VDM_PROC : copy_from_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_vdh);
|
||||
dsb(sy);
|
||||
|
||||
ret = VCTRL_VDMHal_Process(&vdm_reg_cfg, &vdm_state_reg);
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "VCTRL_VDMHal_Process failed\n");
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_vdh);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_vdh);
|
||||
if (copy_to_user(vdec_msg.out, &vdm_state_reg, sizeof(vdm_state_reg))) {
|
||||
printk(KERN_CRIT "VDEC_IOCTL_VDM_PROC : copy_to_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case VDEC_IOCTL_GET_VDM_HWSTATE:
|
||||
CHECK_PARA_SIZE_RETURN(sizeof(vdm_is_run), vdec_msg.out_size, "VDEC_IOCTL_GET_VDM_HWSTATE");
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_vdh);
|
||||
vdm_is_run = VCTRL_VDMHAL_IsRun();
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_vdh);
|
||||
if (copy_to_user(vdec_msg.out, &vdm_is_run, sizeof(vdm_is_run))) {
|
||||
printk(KERN_CRIT "VDEC_IOCTL_GET_VDM_HWSTATE : copy_to_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case VDEC_IOCTL_SCD_PROC:
|
||||
CHECK_PARA_SIZE_RETURN(sizeof(scd_reg_cfg), vdec_msg.in_size, "VDEC_IOCTL_SCD_PROC_IN");
|
||||
CHECK_PARA_SIZE_RETURN(sizeof(scd_state_reg), vdec_msg.out_size, "VDEC_IOCTL_SCD_PROC_OUT");
|
||||
if (copy_from_user(&scd_reg_cfg, vdec_msg.in, sizeof(scd_reg_cfg))) {
|
||||
printk(KERN_CRIT "VDEC_IOCTL_SCD_PROC : copy_from_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
VDEC_MUTEX_LOCK(&omxvdec->vdec_mutex_scd);
|
||||
dsb(sy);
|
||||
|
||||
ret = VCTRL_SCDHal_Process(&scd_reg_cfg, &scd_state_reg);
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "VCTRL_SCDHal_Process failed\n");
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_scd);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&omxvdec->vdec_mutex_scd);
|
||||
if (copy_to_user(vdec_msg.out, &scd_state_reg, sizeof(scd_state_reg))) {
|
||||
printk(KERN_CRIT "VDEC_IOCTL_SCD_PROC : copy_to_user failed\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* could not handle ioctl */
|
||||
printk(KERN_CRIT "%s %d: cmd : %d is not supported\n", __func__, __LINE__, _IOC_NR(cmd));
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long omxvdec_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return omxvdec_ioctl_common(file, cmd, arg, T_IOCTL_ARG);
|
||||
}
|
||||
/* Modified for 64-bit platform */
|
||||
#ifdef CONFIG_COMPAT
|
||||
static long omxvdec_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
void *user_ptr = compat_ptr(arg);
|
||||
return omxvdec_ioctl_common(file, cmd, (unsigned long)user_ptr, T_IOCTL_ARG_COMPAT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct file_operations omxvdec_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = omxvdec_open,
|
||||
.unlocked_ioctl = omxvdec_ioctl,
|
||||
#ifdef CONFIG_COMPAT
|
||||
.compat_ioctl = omxvdec_compat_ioctl,
|
||||
#endif
|
||||
.release = omxvdec_release,
|
||||
};
|
||||
|
||||
static int omxvdec_probe(struct platform_device *pltdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (gIsDeviceDetected == 1) {
|
||||
printk(KERN_DEBUG "Already probe omxvdec\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pltdev, NULL);
|
||||
|
||||
memset(&g_OmxVdecEntry, 0, sizeof(OMXVDEC_ENTRY)); /* unsafe_function_ignore: memset */
|
||||
VDEC_INIT_MUTEX(&g_OmxVdecEntry.omxvdec_mutex);
|
||||
VDEC_INIT_MUTEX(&g_OmxVdecEntry.vdec_mutex_scd);
|
||||
VDEC_INIT_MUTEX(&g_OmxVdecEntry.vdec_mutex_vdh);
|
||||
|
||||
ret = omxvdec_setup_cdev(&g_OmxVdecEntry, &omxvdec_fops);
|
||||
if (ret < 0) {
|
||||
printk(KERN_CRIT "%s call omxvdec_setup_cdev failed\n", __func__);
|
||||
goto cleanup0;
|
||||
}
|
||||
|
||||
ret = VDEC_Regulator_Probe(&pltdev->dev);
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "%s call Regulator_Initialize failed\n", __func__);
|
||||
goto cleanup1;
|
||||
}
|
||||
|
||||
g_OmxVdecEntry.device = &pltdev->dev;
|
||||
platform_set_drvdata(pltdev, &g_OmxVdecEntry);
|
||||
gIsDeviceDetected = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup1:
|
||||
omxvdec_cleanup_cdev(&g_OmxVdecEntry);
|
||||
|
||||
cleanup0:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int omxvdec_remove(struct platform_device *pltdev)
|
||||
{
|
||||
OMXVDEC_ENTRY *omxvdec = NULL;
|
||||
|
||||
omxvdec = platform_get_drvdata(pltdev);
|
||||
if (omxvdec != NULL) {
|
||||
if (IS_ERR(omxvdec)) {
|
||||
printk(KERN_ERR "call platform_get_drvdata err, errno : %ld\n", PTR_ERR(omxvdec));
|
||||
} else {
|
||||
omxvdec_cleanup_cdev(omxvdec);
|
||||
VDEC_Regulator_Remove(&pltdev->dev);
|
||||
platform_set_drvdata(pltdev, NULL);
|
||||
gIsDeviceDetected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omxvdec_suspend(struct platform_device *pltdev, pm_message_t state)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk(KERN_INFO "%s enter\n", __func__);
|
||||
|
||||
if (gIsNormalInit != 0)
|
||||
VCTRL_Suspend();
|
||||
|
||||
ret = VDEC_Regulator_Disable();
|
||||
if (ret != HI_SUCCESS)
|
||||
printk(KERN_CRIT "%s disable regulator failed\n", __func__);
|
||||
|
||||
printk(KERN_INFO "%s success\n", __func__);
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static int omxvdec_resume(struct platform_device *pltdev)
|
||||
{
|
||||
int ret;
|
||||
CLK_RATE_E resume_clk = VDEC_CLK_RATE_NORMAL;
|
||||
|
||||
printk(KERN_INFO "%s enter\n", __func__);
|
||||
VDEC_Regulator_GetClkRate(&resume_clk);
|
||||
|
||||
if (gIsNormalInit != 0) {
|
||||
ret = VDEC_Regulator_Enable();
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "%s enable regulator failed\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = VDEC_Regulator_SetClkRate(resume_clk);
|
||||
if (ret != HI_SUCCESS)
|
||||
{
|
||||
printk(KERN_CRIT "%s, set clk failed\n", __func__);
|
||||
}
|
||||
|
||||
VCTRL_Resume();
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s success\n", __func__);
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static void omxvdec_device_release(struct device *dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_driver omxvdec_driver = {
|
||||
|
||||
.probe = omxvdec_probe,
|
||||
.remove = omxvdec_remove,
|
||||
.suspend = omxvdec_suspend,
|
||||
.resume = omxvdec_resume,
|
||||
.driver = {
|
||||
.name = (char*) g_OmxVdecDrvName,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = Hisi_Vdec_Match_Table
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device omxvdec_device = {
|
||||
|
||||
.name = g_OmxVdecDrvName,
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = NULL,
|
||||
.release = omxvdec_device_release,
|
||||
},
|
||||
};
|
||||
|
||||
int __init OMXVDEC_DRV_ModInit(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_device_register(&omxvdec_device);
|
||||
if (ret < 0) {
|
||||
printk(KERN_CRIT "%s call platform_device_register failed\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&omxvdec_driver);
|
||||
if (ret < 0) {
|
||||
printk(KERN_CRIT "%s call platform_driver_register failed\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
#ifdef MODULE
|
||||
printk(KERN_INFO "Load hi_omxvdec.ko :%d success\n", OMXVDEC_VERSION);
|
||||
#endif
|
||||
|
||||
return HI_SUCCESS;
|
||||
exit:
|
||||
platform_device_unregister(&omxvdec_device);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __exit OMXVDEC_DRV_ModExit(void)
|
||||
{
|
||||
platform_driver_unregister(&omxvdec_driver);
|
||||
platform_device_unregister(&omxvdec_device);
|
||||
|
||||
#ifdef MODULE
|
||||
printk(KERN_INFO "Unload hi_omxvdec.ko : %d success\n", OMXVDEC_VERSION);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
module_init(OMXVDEC_DRV_ModInit);
|
||||
module_exit(OMXVDEC_DRV_ModExit);
|
||||
|
||||
MODULE_AUTHOR("gaoyajun@hisilicon.com");
|
||||
MODULE_DESCRIPTION("vdec driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#ifndef __OMXVDEC_H__
|
||||
#define __OMXVDEC_H__
|
||||
|
||||
#include "regulator.h"
|
||||
#include "../vfmw_v4.0/public.h"
|
||||
#include "../vfmw_v4.0/scd_drv.h"
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
#endif
|
||||
|
||||
#if defined(__KERNEL__)
|
||||
#include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#define OMXVDEC_NAME "hi_vdec"
|
||||
#define PATH_LEN (256)
|
||||
#define OMXVDEC_VERSION (2017032300)
|
||||
#define MAX_OPEN_COUNT (32)
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (0L)
|
||||
#endif
|
||||
|
||||
#define HI_SUCCESS (0)
|
||||
#define HI_FAILURE (-1)
|
||||
|
||||
#define RETURN_FAIL_IF_COND_IS_TRUE(cond, str) \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
printk(KERN_CRIT "[%s : %d]- %s\n", __func__, __LINE__, str); \
|
||||
return HI_FAILURE; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#define VDEC_INIT_MUTEX(lock) \
|
||||
do { \
|
||||
mutex_init(lock); \
|
||||
} while(0)
|
||||
|
||||
#define VDEC_MUTEX_LOCK(lock) \
|
||||
do { \
|
||||
mutex_lock(lock); \
|
||||
} while(0)
|
||||
|
||||
#define VDEC_MUTEX_UNLOCK(lock) \
|
||||
do { \
|
||||
mutex_unlock(lock); \
|
||||
} while(0)
|
||||
|
||||
typedef struct {
|
||||
unsigned char u8IsMapVirtual;
|
||||
unsigned char u8IsMapped;
|
||||
unsigned int u32ShareFd;
|
||||
unsigned int u32StartPhyAddr;
|
||||
unsigned int u32Size;
|
||||
void *pStartVirAddr;
|
||||
} MEM_BUFFER_S;
|
||||
|
||||
typedef struct hi_OMXVDEC_IOCTL_MSG {
|
||||
int chan_num;
|
||||
int in_size;
|
||||
int out_size;
|
||||
void *in;
|
||||
void *out;
|
||||
} OMXVDEC_IOCTL_MSG;
|
||||
|
||||
//Modified for 64-bit platform
|
||||
typedef struct hi_COMPAT_IOCTL_MSG {
|
||||
int chan_num;
|
||||
int in_size;
|
||||
int out_size;
|
||||
compat_ulong_t in;
|
||||
compat_ulong_t out;
|
||||
} COMPAT_IOCTL_MSG;
|
||||
|
||||
typedef struct {
|
||||
unsigned int open_count;
|
||||
atomic_t nor_chan_num;
|
||||
atomic_t sec_chan_num;
|
||||
MEM_BUFFER_S com_msg_pool;
|
||||
struct mutex omxvdec_mutex;
|
||||
struct mutex vdec_mutex_scd;
|
||||
struct mutex vdec_mutex_vdh;
|
||||
struct cdev cdev;
|
||||
struct device *device;
|
||||
} OMXVDEC_ENTRY;
|
||||
|
||||
typedef int(*VDEC_PROC_CMD) (OMXVDEC_IOCTL_MSG *pVdecMsg);
|
||||
|
||||
#define VDEC_IOCTL_MAGIC 'v'
|
||||
|
||||
#define VDEC_IOCTL_SET_CLK_RATE \
|
||||
_IO(VDEC_IOCTL_MAGIC, 20)
|
||||
|
||||
#define VDEC_IOCTL_GET_VDM_HWSTATE \
|
||||
_IO(VDEC_IOCTL_MAGIC, 21)
|
||||
|
||||
#define VDEC_IOCTL_SCD_PROC \
|
||||
_IO(VDEC_IOCTL_MAGIC, 22)
|
||||
|
||||
#define VDEC_IOCTL_VDM_PROC \
|
||||
_IO(VDEC_IOCTL_MAGIC, 23)
|
||||
|
||||
#endif
|
||||
+395
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* vdec regulator manager
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "regulator.h"
|
||||
|
||||
#include <linux/hisi/hisi-iommu.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
/*lint -e774*/
|
||||
#define VDEC_REGULATOR_NAME "ldo_vdec"
|
||||
#define MEDIA_REGULATOR_NAME "ldo_media"
|
||||
#define VCODEC_CLOCK_NAME "clk_gate_vdecfreq"
|
||||
#define VCODEC_CLK_RATE "dec_clk_rate"
|
||||
|
||||
static unsigned int g_clock_values[] = {450000000, 300000000, 185000000};
|
||||
static unsigned int g_VdecClkRate_l = 185000000;
|
||||
static unsigned int g_VdecClkRate_n = 300000000;
|
||||
static unsigned int g_VdecClkRate_h = 450000000;
|
||||
static unsigned int g_CurClkRate = 0;
|
||||
static int g_VdecPowerOn = 0;
|
||||
|
||||
static struct clk *g_PvdecClk = NULL;
|
||||
static struct regulator *g_VdecRegulator = NULL;
|
||||
static struct regulator *g_MediaRegulator = NULL;
|
||||
static struct iommu_domain *g_VdecSmmuDomain = NULL;
|
||||
|
||||
struct mutex g_RegulatorMutex;
|
||||
static VFMW_DTS_CONFIG_S g_DtsConfig;
|
||||
static CLK_RATE_E g_ResumeClkType = VDEC_CLK_RATE_LOW;
|
||||
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
/*----------------------------------------
|
||||
func: iommu enable intf
|
||||
----------------------------------------*/
|
||||
static int VDEC_Enable_Iommu(struct device *dev)
|
||||
{
|
||||
int ret = HI_FAILURE;
|
||||
g_VdecSmmuDomain = iommu_domain_alloc(dev->bus);
|
||||
if (NULL == g_VdecSmmuDomain) {
|
||||
printk(KERN_ERR "%s iommu_domain_alloc failed!\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = iommu_attach_device(g_VdecSmmuDomain, dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "iommu_attach_device failed!\n");
|
||||
goto out_free_domain;
|
||||
}
|
||||
return HI_SUCCESS;
|
||||
out_free_domain:
|
||||
iommu_domain_free(g_VdecSmmuDomain);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
static void VDEC_Disable_Iommu(struct device *dev)
|
||||
{
|
||||
g_VdecSmmuDomain = NULL;
|
||||
if( g_VdecSmmuDomain && dev) {
|
||||
iommu_detach_device(g_VdecSmmuDomain, dev);
|
||||
iommu_domain_free(g_VdecSmmuDomain);
|
||||
g_VdecSmmuDomain = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static unsigned long long VDEC_GetSmmuBasePhy(struct device *dev)
|
||||
{
|
||||
struct iommu_domain_data *domain_data = NULL;
|
||||
|
||||
if (VDEC_Enable_Iommu(dev) == HI_FAILURE)
|
||||
return 0;
|
||||
|
||||
domain_data = (struct iommu_domain_data *)(g_VdecSmmuDomain->priv);
|
||||
|
||||
return (unsigned long long) (domain_data->phy_pgd_base);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int read_clock_rate_value(struct device_node *np, unsigned int index, unsigned int *clock)
|
||||
{
|
||||
int ret;
|
||||
ret = of_property_read_u32_index(np, VCODEC_CLK_RATE, index, clock);
|
||||
if (ret) {
|
||||
printk(KERN_CRIT "read clock rate[%d] failed\n", index);
|
||||
*clock = g_clock_values[index];
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static int VDEC_Init_ClockRate(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct clk *pvdec_clk = NULL;
|
||||
|
||||
pvdec_clk = devm_clk_get(dev, VCODEC_CLOCK_NAME);
|
||||
if (IS_ERR_OR_NULL(pvdec_clk)) {
|
||||
printk(KERN_CRIT "%s can not get clock\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
g_PvdecClk = pvdec_clk;
|
||||
ret = read_clock_rate_value(dev->of_node, 0, &g_VdecClkRate_h);
|
||||
ret += read_clock_rate_value(dev->of_node, 1, &g_VdecClkRate_n);
|
||||
ret += read_clock_rate_value(dev->of_node, 2, &g_VdecClkRate_l);
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(ret, "read clock failed");
|
||||
|
||||
g_CurClkRate = g_VdecClkRate_l;
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static int VDEC_GetDtsConfigInfo(struct device *dev, VFMW_DTS_CONFIG_S *pDtsConfig)
|
||||
{
|
||||
int ret;
|
||||
struct device_node *np_crg = NULL;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource res;
|
||||
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(dev->of_node == NULL, "device node is null");
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(pDtsConfig == NULL, "dts config is null");
|
||||
|
||||
pDtsConfig->VdecIrqNumNorm = irq_of_parse_and_map(np, 0);
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(pDtsConfig->VdecIrqNumNorm == 0, "get irq num failed");
|
||||
|
||||
/*
|
||||
FIXME irq_of_parse_and_map(np, 1);
|
||||
FIXME irq_of_parse_and_map(np, 2);
|
||||
*/
|
||||
pDtsConfig->VdecIrqNumProt = 323;
|
||||
pDtsConfig->VdecIrqNumSafe = 324;
|
||||
|
||||
/* Get reg base addr & size, return 0 if success */
|
||||
ret = of_address_to_resource(np, 0, &res);
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(ret, "of_address_to_resource failed");
|
||||
|
||||
pDtsConfig->VdhRegBaseAddr = res.start;
|
||||
pDtsConfig->VdhRegRange = resource_size(&res);
|
||||
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
/* Get reg base addr, return 0 if failed */
|
||||
pDtsConfig->SmmuPageBaseAddr = VDEC_GetSmmuBasePhy(dev);
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(pDtsConfig->SmmuPageBaseAddr == 0, "get smmu base addr failed");
|
||||
#endif
|
||||
|
||||
np_crg = of_find_compatible_node(NULL, NULL, "hisilicon,media2-crg");
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(!np_crg, "can't find media2-crg node");
|
||||
|
||||
ret = of_address_to_resource(np_crg, 0, &res);
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(ret, "of_address_to_resource failed");
|
||||
pDtsConfig->PERICRG_RegBaseAddr = res.start;
|
||||
|
||||
ret = VDEC_Init_ClockRate(dev);
|
||||
RETURN_FAIL_IF_COND_IS_TRUE(ret != HI_SUCCESS, "init clock failed");
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************** SHARE FUNC **********************************/
|
||||
|
||||
/*----------------------------------------
|
||||
func: regulator probe entry
|
||||
----------------------------------------*/
|
||||
int VDEC_Regulator_Probe(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
g_VdecRegulator = NULL;
|
||||
g_MediaRegulator = NULL;
|
||||
|
||||
if (dev == NULL) {
|
||||
printk(KERN_CRIT "%s, invalid params", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
memset(&g_DtsConfig, 0, sizeof(g_DtsConfig)); /* unsafe_function_ignore: memset */
|
||||
ret = VDEC_GetDtsConfigInfo(dev, &g_DtsConfig);
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "%s Regulator_GetDtsConfigInfo failed\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = VFMW_SetDtsConfig(&g_DtsConfig);
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_CRIT "%s VFMW_SetDtsConfig failed\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
VDEC_INIT_MUTEX(&g_RegulatorMutex);
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
/*----------------------------------------
|
||||
func: regulator deinitialize
|
||||
----------------------------------------*/
|
||||
int VDEC_Regulator_Remove(struct device * dev)
|
||||
{
|
||||
VDEC_MUTEX_LOCK(&g_RegulatorMutex);
|
||||
|
||||
VDEC_Disable_Iommu(dev);
|
||||
g_VdecRegulator = NULL;
|
||||
g_MediaRegulator = NULL;
|
||||
g_PvdecClk = NULL;
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
/*----------------------------------------
|
||||
func: enable regulator
|
||||
----------------------------------------*/
|
||||
int VDEC_Regulator_Enable(void)
|
||||
{
|
||||
int ret;
|
||||
VDEC_MUTEX_LOCK(&g_RegulatorMutex);
|
||||
|
||||
if (g_VdecPowerOn == 1) {
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
if (g_PvdecClk == NULL) {
|
||||
printk(KERN_CRIT "%s: invalid g_PvdecClk is NULL\n", __func__);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(g_PvdecClk);
|
||||
if (ret != 0) {
|
||||
printk(KERN_CRIT "%s clk_prepare_enable failed\n", __func__);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(g_PvdecClk, g_VdecClkRate_l);
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_CRIT "%s Failed to clk_set_rate:%u, return %d\n", __func__, g_VdecClkRate_l, ret);
|
||||
goto error_unprepare_clk;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "vdec regulator enable\n");
|
||||
g_VdecPowerOn = 1;
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_SUCCESS;
|
||||
|
||||
error_unprepare_clk:
|
||||
clk_disable_unprepare(g_PvdecClk);
|
||||
error_exit:
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/*----------------------------------------
|
||||
func: disable regulator
|
||||
----------------------------------------*/
|
||||
int VDEC_Regulator_Disable(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
VDEC_MUTEX_LOCK(&g_RegulatorMutex);
|
||||
|
||||
if (g_VdecPowerOn == 0) {
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
if (g_PvdecClk == NULL) {
|
||||
printk(KERN_CRIT "%s g_PvdecClk is NULL\n", __func__);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(g_PvdecClk, g_VdecClkRate_l);
|
||||
if (ret) {
|
||||
printk(KERN_CRIT "%s Failed to clk_set_rate:%u, return %d\n", __func__, g_VdecClkRate_l, ret);
|
||||
//goto error_exit;//continue, no return
|
||||
}
|
||||
|
||||
clk_disable_unprepare(g_PvdecClk);
|
||||
|
||||
g_VdecPowerOn = 0;
|
||||
|
||||
printk(KERN_INFO "vdec regulator disable\n");
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_SUCCESS;
|
||||
|
||||
error_exit:
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/*----------------------------------------
|
||||
func: get decoder clock rate
|
||||
----------------------------------------*/
|
||||
void VDEC_Regulator_GetClkRate(CLK_RATE_E *pClkRate)
|
||||
{
|
||||
VDEC_MUTEX_LOCK(&g_RegulatorMutex);
|
||||
*pClkRate = g_ResumeClkType;
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
}
|
||||
|
||||
int VDEC_Regulator_SetClkRate(CLK_RATE_E eClkRate)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int rate = 0;
|
||||
unsigned char need_set_flag = 1;
|
||||
|
||||
VDEC_MUTEX_LOCK(&g_RegulatorMutex);
|
||||
|
||||
if (g_DtsConfig.IsFPGA) {
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(g_PvdecClk)) {
|
||||
printk(KERN_ERR "Couldn't get clk [%s]\n", __func__);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
rate = (unsigned int) clk_get_rate(g_PvdecClk);
|
||||
switch (eClkRate) {
|
||||
case VDEC_CLK_RATE_LOW:
|
||||
if (g_VdecClkRate_l == rate) {
|
||||
need_set_flag = 0;
|
||||
} else {
|
||||
rate = g_VdecClkRate_l;
|
||||
need_set_flag = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case VDEC_CLK_RATE_NORMAL:
|
||||
if (g_VdecClkRate_n == rate) {
|
||||
need_set_flag = 0;
|
||||
}
|
||||
else {
|
||||
rate = g_VdecClkRate_n;
|
||||
need_set_flag = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case VDEC_CLK_RATE_HIGH:
|
||||
if (g_VdecClkRate_h == rate) {
|
||||
need_set_flag = 0;
|
||||
} else {
|
||||
rate = g_VdecClkRate_h;
|
||||
need_set_flag = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "[%s] unsupport clk rate enum %d\n", __func__, eClkRate);
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (need_set_flag == 1) {
|
||||
ret = clk_set_rate(g_PvdecClk, rate);
|
||||
if (ret != 0) {
|
||||
printk(KERN_ERR "Failed to clk_set_rate %u HZ[%s] ret : %d\n", rate, __func__, ret);
|
||||
goto error_exit;
|
||||
}
|
||||
g_CurClkRate = rate;
|
||||
g_ResumeClkType = eClkRate;
|
||||
}
|
||||
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_SUCCESS;
|
||||
|
||||
error_exit:
|
||||
VDEC_MUTEX_UNLOCK(&g_RegulatorMutex);
|
||||
|
||||
return HI_FAILURE;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#ifndef __VDEC_REGULATOR_H__
|
||||
#define __VDEC_REGULATOR_H__
|
||||
|
||||
#include "../vfmw_v4.0/vfmw_dts.h"
|
||||
#include "omxvdec.h"
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
typedef enum {
|
||||
VDEC_CLK_RATE_LOW = 0,
|
||||
VDEC_CLK_RATE_NORMAL,
|
||||
VDEC_CLK_RATE_HIGH,
|
||||
VDEC_CLK_RATE_BUTT,
|
||||
}CLK_RATE_E;
|
||||
|
||||
static const struct of_device_id Hisi_Vdec_Match_Table[] = {
|
||||
{.compatible = "hisi,kirin970-vdec",},
|
||||
{ }
|
||||
};
|
||||
int VDEC_Regulator_Probe(struct device *dev);
|
||||
int VDEC_Regulator_Remove(struct device *dev);
|
||||
int VDEC_Regulator_Enable(void);
|
||||
int VDEC_Regulator_Disable(void);
|
||||
void VDEC_Regulator_GetClkRate(CLK_RATE_E *pClkRate);
|
||||
int VDEC_Regulator_SetClkRate(CLK_RATE_E eClkRate);
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
config VDEC_VFMW
|
||||
tristate "hisilicon video firmware support"
|
||||
default n
|
||||
---help---
|
||||
This is the vfmw driver
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
TOP := drivers/../..
|
||||
VFMW_DIR := drivers/vcodec/vdec_hivna
|
||||
|
||||
include $(VFMW_DIR)/vfmw_v4.0/vfmw_make.cfg
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/vcodec/vdec_hivna
|
||||
EXTRA_CFLAGS += -Idrivers/vcodec/vdec_hivna/omxvdec
|
||||
EXTRA_CFLAGS += $(VFMW_CFLAGS) -fno-pic
|
||||
|
||||
#build in
|
||||
obj-$(CONFIG_HI_VCODEC_VDEC) += hi_vfmw.o
|
||||
hi_vfmw-objs := $(VFMW_CFILES)
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
#ifndef __VDM_DRV_HEADER__
|
||||
#define __VDM_DRV_HEADER__
|
||||
#include "../vfmw.h"
|
||||
#include "../sysconfig.h"
|
||||
|
||||
#define VDMDRV_OK (0)
|
||||
#define VDMDRV_ERR (-1)
|
||||
|
||||
#define MSG_SLOT_SIZE (256)
|
||||
|
||||
#define LUMA_HISTORGAM_NUM (32)
|
||||
|
||||
#define HEVC_ONE_MSG_SLOT_LEN (320) // 64*5
|
||||
#define MAX_FRAME_NUM (32)
|
||||
#ifdef VFMW_HEVC_SUPPORT
|
||||
#define USE_MSG_SLOT_SIZE HEVC_ONE_MSG_SLOT_LEN
|
||||
#else
|
||||
#define USE_MSG_SLOT_SIZE MSG_SLOT_SIZE
|
||||
#endif
|
||||
typedef enum {
|
||||
VDH_SHAREFD_MESSAGE_POOL = 0,
|
||||
VDH_SHAREFD_STREAM_BUF = 1,
|
||||
VDH_SHAREFD_PMV_BUF = 2,
|
||||
VDH_SHAREFD_FRM_BUF = 3,
|
||||
VDH_SHAREFD_MAX = (VDH_SHAREFD_FRM_BUF + MAX_FRAME_NUM)
|
||||
}VDH_SHAREFD;
|
||||
typedef enum {
|
||||
VDH_STATE_REG = 1,
|
||||
INT_STATE_REG = 2,
|
||||
INT_MASK_REG = 3,
|
||||
VCTRL_STATE_REG = 4,
|
||||
} REG_ID_E;
|
||||
|
||||
typedef enum {
|
||||
VDM_IDLE_STATE = 0,
|
||||
VDM_DECODE_STATE = 1,
|
||||
VDM_REPAIR_STATE_0 = 2,
|
||||
VDM_REPAIR_STATE_1 = 3
|
||||
} VDMDRV_STATEMACHINE_E;
|
||||
|
||||
typedef enum {
|
||||
VDMDRV_SLEEP_STAGE_NONE = 0,
|
||||
VDMDRV_SLEEP_STAGE_PREPARE,
|
||||
VDMDRV_SLEEP_STAGE_SLEEP
|
||||
} VDMDRV_SLEEP_STAGE_E;
|
||||
|
||||
typedef enum {
|
||||
FIRST_REPAIR = 0,
|
||||
SECOND_REPAIR
|
||||
} REPAIRTIME_S;
|
||||
|
||||
typedef enum hi_CONFIG_VDH_CMD {
|
||||
CONFIG_VDH_AfterDec_CMD = 200,
|
||||
CONFIG_VDH_ACTIVATEDEC_CMD
|
||||
} CONFIG_VDH_CMD;
|
||||
|
||||
typedef struct {
|
||||
unsigned int vdh_reset_flag;
|
||||
unsigned int GlbResetFlag;
|
||||
int VdhStartRepairFlag;
|
||||
int VdhStartHwDecFlag;
|
||||
int VdhBasicCfg0;
|
||||
int VdhBasicCfg1;
|
||||
int VdhAvmAddr;
|
||||
int VdhVamAddr;
|
||||
int VdhStreamBaseAddr;
|
||||
int VdhEmarId;
|
||||
int VdhYstAddr;
|
||||
int VdhYstride;
|
||||
int VdhUvstride;//VREG_UVSTRIDE_1D
|
||||
int VdhCfgInfoAddr;//CFGINFO_ADDR
|
||||
int VdhUvoffset;
|
||||
int VdhRefPicType;
|
||||
int VdhFfAptEn;
|
||||
REPAIRTIME_S RepairTime;
|
||||
VID_STD_E VidStd;
|
||||
int ValidGroupNum0;
|
||||
int vdh_share_fd[VDH_SHAREFD_MAX];
|
||||
unsigned int vdhFrmBufNum;
|
||||
int IsFrmBufRemap;
|
||||
int IsPmvBufRemap;
|
||||
int IsAllBufRemap;
|
||||
} OMXVDH_REG_CFG_S;
|
||||
|
||||
typedef struct {
|
||||
// vdm register base vir addr
|
||||
int *pVdmRegVirAddr;
|
||||
|
||||
// vdm hal base addr
|
||||
unsigned int HALMemBaseAddr;
|
||||
int HALMemSize;
|
||||
int VahbStride;
|
||||
|
||||
/* message pool */
|
||||
unsigned int MsgSlotAddr[256];
|
||||
int ValidMsgSlotNum;
|
||||
|
||||
/* vlc code table */
|
||||
unsigned int H264TabAddr; /* 32 Kbyte */
|
||||
unsigned int MPEG2TabAddr; /* 32 Kbyte */
|
||||
unsigned int MPEG4TabAddr; /* 32 Kbyte */
|
||||
unsigned int AVSTabAddr; /* 32 Kbyte */
|
||||
unsigned int VC1TabAddr;
|
||||
/* cabac table */
|
||||
unsigned int H264MnAddr;
|
||||
/* nei info for vdh for hevc */
|
||||
unsigned int sed_top_phy_addr;
|
||||
unsigned int pmv_top_phy_addr;
|
||||
unsigned int pmv_left_phy_addr;
|
||||
unsigned int rcn_top_phy_addr;
|
||||
unsigned int mn_phy_addr;
|
||||
unsigned int tile_segment_info_phy_addr;
|
||||
unsigned int dblk_left_phy_addr;
|
||||
unsigned int dblk_top_phy_addr;
|
||||
unsigned int sao_left_phy_addr;
|
||||
unsigned int sao_top_phy_addr;
|
||||
unsigned int ppfd_phy_addr;
|
||||
int ppfd_buf_len;
|
||||
|
||||
/*nei info for vdh */
|
||||
unsigned int SedTopAddr; /* len = 64*4*x */
|
||||
unsigned int PmvTopAddr; /* len = 64*4*x */
|
||||
unsigned int RcnTopAddr; /* len = 64*4*x */
|
||||
unsigned int ItransTopAddr;
|
||||
unsigned int DblkTopAddr;
|
||||
unsigned int PpfdBufAddr;
|
||||
unsigned int PpfdBufLen;
|
||||
|
||||
unsigned int IntensityConvTabAddr;
|
||||
unsigned int BitplaneInfoAddr;
|
||||
unsigned int Vp6TabAddr;
|
||||
unsigned int Vp8TabAddr;
|
||||
|
||||
/* VP9 */
|
||||
unsigned int DblkLeftAddr;
|
||||
unsigned int Vp9ProbTabAddr;
|
||||
unsigned int Vp9ProbCntAddr;
|
||||
|
||||
unsigned char *luma_2d_vir_addr;
|
||||
unsigned int luma_2d_phy_addr;
|
||||
unsigned char *chrom_2d_vir_addr;
|
||||
unsigned int chrom_2d_phy_addr;
|
||||
} VDMHAL_HWMEM_S;
|
||||
|
||||
typedef struct {
|
||||
unsigned int Int_State_Reg;
|
||||
|
||||
unsigned int BasicCfg1;
|
||||
unsigned int VdmState;
|
||||
unsigned int Mb0QpInCurrPic;
|
||||
unsigned int SwitchRounding;
|
||||
unsigned int SedSta;
|
||||
unsigned int SedEnd0;
|
||||
|
||||
unsigned int DecCyclePerPic;
|
||||
unsigned int RdBdwidthPerPic;
|
||||
unsigned int WrBdWidthPerPic;
|
||||
unsigned int RdReqPerPic;
|
||||
unsigned int WrReqPerPic;
|
||||
unsigned int LumaSumHigh;
|
||||
unsigned int LumaSumLow;
|
||||
unsigned int LumaHistorgam[LUMA_HISTORGAM_NUM];
|
||||
} VDMHAL_BACKUP_S;
|
||||
|
||||
extern VDMHAL_HWMEM_S g_HwMem[MAX_VDH_NUM];
|
||||
#endif
|
||||
+553
@@ -0,0 +1,553 @@
|
||||
/*
|
||||
* vdm hal interface
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "vfmw.h"
|
||||
#include "mem_manage.h"
|
||||
//#include "public.h"
|
||||
#include "scd_drv.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "omxvdec.h"
|
||||
#include "linux_kernel_osal.h"
|
||||
|
||||
#ifdef VFMW_MPEG2_SUPPORT
|
||||
#include "vdm_hal_mpeg2.h"
|
||||
#endif
|
||||
#ifdef VFMW_H264_SUPPORT
|
||||
#include "vdm_hal_h264.h"
|
||||
#endif
|
||||
#ifdef VFMW_HEVC_SUPPORT
|
||||
#include "vdm_hal_hevc.h"
|
||||
#endif
|
||||
#ifdef VFMW_MPEG4_SUPPORT
|
||||
#include "vdm_hal_mpeg4.h"
|
||||
#endif
|
||||
#ifdef VFMW_VP8_SUPPORT
|
||||
#include "vdm_hal_vp8.h"
|
||||
#endif
|
||||
#ifdef VFMW_VP9_SUPPORT
|
||||
#include "vdm_hal_vp9.h"
|
||||
#endif
|
||||
#include "vfmw_intf.h"
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
#include "smmu.h"
|
||||
#endif
|
||||
|
||||
VDMHAL_HWMEM_S g_HwMem[MAX_VDH_NUM];
|
||||
VDMHAL_BACKUP_S g_VdmRegState;
|
||||
|
||||
static VDMDRV_SLEEP_STAGE_E s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_NONE;
|
||||
static VDMDRV_STATEMACHINE_E s_VdmState = VDM_IDLE_STATE;
|
||||
|
||||
void VDMHAL_EnableInt(int VdhId)
|
||||
{
|
||||
unsigned int D32 = 0xFFFFFFFE;
|
||||
int *p32 = NULL;
|
||||
|
||||
if (VdhId != 0) {
|
||||
printk(KERN_ERR "VDH ID is wrong\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_HwMem[VdhId].pVdmRegVirAddr == NULL) {
|
||||
p32 = (int *) MEM_Phy2Vir(gVdhRegBaseAddr);
|
||||
if (p32 == NULL) {
|
||||
printk(KERN_ERR "vdm register virtual address not mapped, reset failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
g_HwMem[VdhId].pVdmRegVirAddr = p32;
|
||||
}
|
||||
|
||||
WR_VREG(VREG_INT_MASK, D32, VdhId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int VDMHAL_CfgRpReg(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int D32 = 0;
|
||||
|
||||
WR_VREG(VREG_AVM_ADDR, pVdhRegCfg->VdhAvmAddr, 0);
|
||||
|
||||
D32 = 0x2000C203;
|
||||
WR_VREG(VREG_BASIC_CFG1, D32, 0);
|
||||
|
||||
D32 = 0x00300C03;
|
||||
WR_VREG(VREG_SED_TO, D32, 0);
|
||||
WR_VREG(VREG_ITRANS_TO, D32, 0);
|
||||
WR_VREG(VREG_PMV_TO, D32, 0);
|
||||
WR_VREG(VREG_PRC_TO, D32, 0);
|
||||
WR_VREG(VREG_RCN_TO, D32, 0);
|
||||
WR_VREG(VREG_DBLK_TO, D32, 0);
|
||||
WR_VREG(VREG_PPFD_TO, D32, 0);
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_Init(void)
|
||||
{
|
||||
memset(g_HwMem, 0, sizeof(g_HwMem));
|
||||
memset(&g_VdmRegState, 0, sizeof(g_VdmRegState));
|
||||
|
||||
g_HwMem[0].pVdmRegVirAddr = (int *) MEM_Phy2Vir(gVdhRegBaseAddr);
|
||||
|
||||
VDMHAL_IMP_GlbReset();
|
||||
s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_NONE;
|
||||
s_VdmState = VDM_IDLE_STATE;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_DeInit(void)
|
||||
{
|
||||
s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_NONE;
|
||||
s_VdmState = VDM_IDLE_STATE;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_ResetVdm(int VdhId)
|
||||
{
|
||||
int i;
|
||||
int tmp = 0;
|
||||
unsigned int reg;
|
||||
unsigned int reg_rst_ok;
|
||||
unsigned int *pVdmResetVirAddr;
|
||||
unsigned int *pVdmResetOkVirAddr;
|
||||
|
||||
pVdmResetVirAddr = (unsigned int *) MEM_Phy2Vir(gSOFTRST_REQ_Addr);
|
||||
pVdmResetOkVirAddr = (unsigned int *) MEM_Phy2Vir(gSOFTRST_OK_ADDR);
|
||||
|
||||
if ((pVdmResetVirAddr == NULL)
|
||||
|| (pVdmResetOkVirAddr == NULL)
|
||||
|| (g_HwMem[VdhId].pVdmRegVirAddr == NULL)) {
|
||||
printk(KERN_ERR "map vdm register fail, vir(pVdmResetVirAddr) : (%pK), vir(pVdmResetOkVirAddr) : (%pK)\n", pVdmResetVirAddr, pVdmResetOkVirAddr);
|
||||
return;
|
||||
}
|
||||
|
||||
RD_VREG(VREG_INT_MASK, tmp, VdhId);
|
||||
|
||||
/* require mfde reset */
|
||||
reg = *(volatile unsigned int *)pVdmResetVirAddr;
|
||||
*(volatile unsigned int *)pVdmResetVirAddr = reg | (unsigned int) (1 << MFDE_RESET_CTRL_BIT);
|
||||
|
||||
/* wait for reset ok */
|
||||
for (i = 0; i < 100; i++) {
|
||||
reg_rst_ok = *(volatile unsigned int *)pVdmResetOkVirAddr;
|
||||
if (reg_rst_ok & (1 << MFDE_RESET_OK_BIT))
|
||||
break;
|
||||
VFMW_OSAL_uDelay(10);
|
||||
}
|
||||
|
||||
if (i >= 100)
|
||||
printk(KERN_ERR "%s reset failed\n", __func__);
|
||||
|
||||
/* clear reset require */
|
||||
*(volatile unsigned int *)pVdmResetVirAddr = reg & (unsigned int) (~(1 << MFDE_RESET_CTRL_BIT));
|
||||
|
||||
|
||||
WR_VREG(VREG_INT_MASK, tmp, VdhId);
|
||||
s_VdmState = VDM_IDLE_STATE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_GlbReset(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int reg, reg_rst_ok;
|
||||
unsigned int *pResetVirAddr = NULL;
|
||||
unsigned int *pResetOKVirAddr = NULL;
|
||||
|
||||
pResetVirAddr = (unsigned int *) MEM_Phy2Vir(gSOFTRST_REQ_Addr);
|
||||
pResetOKVirAddr = (unsigned int *) MEM_Phy2Vir(gSOFTRST_OK_ADDR);
|
||||
|
||||
if (pResetVirAddr == NULL || pResetOKVirAddr == NULL) {
|
||||
printk(KERN_ERR "VDMHAL_GlbReset: map vdm register fail, vir(pResetVirAddr) : (%pK), vir(pResetOKVirAddr) : (%pK)\n", pResetVirAddr, pResetOKVirAddr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* require all reset, include mfde scd bpd */
|
||||
reg = *(volatile unsigned int *)pResetVirAddr;
|
||||
*(volatile unsigned int *)pResetVirAddr = reg | (unsigned int) (1 << ALL_RESET_CTRL_BIT);
|
||||
|
||||
/* wait for reset ok */
|
||||
for (i = 0; i < 100; i++) {
|
||||
reg_rst_ok = *(volatile unsigned int *)pResetOKVirAddr;
|
||||
if (reg_rst_ok & (1 << ALL_RESET_OK_BIT))
|
||||
break;
|
||||
VFMW_OSAL_uDelay(10);
|
||||
}
|
||||
|
||||
if (i >= 100)
|
||||
printk(KERN_ERR "Glb Reset Failed\n");
|
||||
|
||||
/* clear reset require */
|
||||
*(volatile unsigned int *)pResetVirAddr = reg & (unsigned int) (~(1 << ALL_RESET_CTRL_BIT));
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_ClearIntState(int VdhId)
|
||||
{
|
||||
int *p32;
|
||||
unsigned int D32 = 0xFFFFFFFF;
|
||||
|
||||
if (VdhId > (MAX_VDH_NUM - 1)) {
|
||||
printk(KERN_ERR "%s: VdhId : %d is more than %d\n", __func__, VdhId, (MAX_VDH_NUM - 1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_HwMem[VdhId].pVdmRegVirAddr == NULL) {
|
||||
if ((p32 = (int *) MEM_Phy2Vir(gVdhRegBaseAddr)) != NULL) {
|
||||
g_HwMem[VdhId].pVdmRegVirAddr = p32;
|
||||
} else {
|
||||
printk(KERN_ERR " %s %d vdm register virtual address not mapped, reset failed\n", __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
WR_VREG(VREG_INT_STATE, D32, VdhId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int VDMHAL_IMP_CheckReg(REG_ID_E reg_id, int VdhId)
|
||||
{
|
||||
int *p32;
|
||||
int dat = 0;
|
||||
unsigned int reg_type;
|
||||
|
||||
if (VdhId > (MAX_VDH_NUM - 1)) {
|
||||
printk(KERN_ERR "%s: Invalid VdhId is %d\n", __func__, VdhId);
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
if (g_HwMem[VdhId].pVdmRegVirAddr == NULL) {
|
||||
if ((p32 = (int *) MEM_Phy2Vir(gVdhRegBaseAddr)) != NULL) {
|
||||
g_HwMem[VdhId].pVdmRegVirAddr = p32;
|
||||
} else {
|
||||
printk(KERN_ERR " %s %d vdm register virtual address not mapped, reset failed\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (reg_id) {
|
||||
case VDH_STATE_REG:
|
||||
reg_type = VREG_VDH_STATE;
|
||||
break;
|
||||
|
||||
case INT_STATE_REG:
|
||||
reg_type = VREG_INT_STATE;
|
||||
break;
|
||||
|
||||
case INT_MASK_REG:
|
||||
reg_type = VREG_INT_MASK;
|
||||
break;
|
||||
|
||||
case VCTRL_STATE_REG:
|
||||
reg_type = VREG_VCTRL_STATE;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s: unkown reg_id is %d\n", __func__, reg_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RD_VREG(reg_type, dat, 0);
|
||||
return dat;
|
||||
}
|
||||
|
||||
int VDMHAL_IMP_PrepareDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
VDMHAL_HWMEM_S *pHwMem = &(g_HwMem[0]);
|
||||
int *p32;
|
||||
|
||||
if (NULL == pHwMem->pVdmRegVirAddr)
|
||||
{
|
||||
if (NULL != (p32 = (int *)MEM_Phy2Vir(gVdhRegBaseAddr)))
|
||||
{
|
||||
pHwMem->pVdmRegVirAddr = p32;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk(KERN_ERR "vdm register virtual address not mapped, VDMHAL_PrepareDecfailed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
}
|
||||
if (VFMW_AVS == pVdhRegCfg->VidStd)
|
||||
WR_SCDREG(REG_AVS_FLAG, 0x00000001);
|
||||
else
|
||||
WR_SCDREG(REG_AVS_FLAG, 0x00000000);
|
||||
|
||||
WR_SCDREG(REG_VDH_SELRST, 0x00000001);
|
||||
|
||||
switch (pVdhRegCfg->VidStd) {
|
||||
#ifdef VFMW_H264_SUPPORT
|
||||
case VFMW_H264:
|
||||
return H264HAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
#ifdef VFMW_HEVC_SUPPORT
|
||||
case VFMW_HEVC:
|
||||
return HEVCHAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
#ifdef VFMW_MPEG2_SUPPORT
|
||||
case VFMW_MPEG2:
|
||||
return MP2HAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
#ifdef VFMW_MPEG4_SUPPORT
|
||||
case VFMW_MPEG4:
|
||||
return MP4HAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
#ifdef VFMW_VP8_SUPPORT
|
||||
case VFMW_VP8:
|
||||
return VP8HAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
#ifdef VFMW_VP9_SUPPORT
|
||||
case VFMW_VP9:
|
||||
return VP9HAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
#ifdef VFMW_MVC_SUPPORT
|
||||
case VFMW_MVC:
|
||||
return H264HAL_StartDec(pVdhRegCfg);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
int VDMHAL_IsVdmRun(int VdhId)
|
||||
{
|
||||
int Data32 = 0;
|
||||
|
||||
if (g_HwMem[VdhId].pVdmRegVirAddr == NULL) {
|
||||
printk(KERN_ERR "VDM register not mapped yet\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
RD_VREG(VREG_VCTRL_STATE, Data32, VdhId);
|
||||
|
||||
return (Data32 == 1 ? 0 : 1);
|
||||
}
|
||||
|
||||
int VDMHAL_IMP_BackupInfo(void)
|
||||
{
|
||||
int i = 0;
|
||||
int regTmp;
|
||||
g_VdmRegState.Int_State_Reg = VDMHAL_IMP_CheckReg(INT_STATE_REG, 0);
|
||||
|
||||
RD_VREG(VREG_BASIC_CFG1, g_VdmRegState.BasicCfg1, 0);
|
||||
RD_VREG(VREG_VDH_STATE, g_VdmRegState.VdmState, 0);
|
||||
|
||||
RD_VREG(VREG_MB0_QP_IN_CURR_PIC, g_VdmRegState.Mb0QpInCurrPic, 0);
|
||||
RD_VREG(VREG_SWITCH_ROUNDING, g_VdmRegState.SwitchRounding, 0);
|
||||
|
||||
{
|
||||
RD_VREG(VREG_SED_STA, g_VdmRegState.SedSta, 0);
|
||||
RD_VREG(VREG_SED_END0, g_VdmRegState.SedEnd0, 0);
|
||||
RD_VREG(VREG_DEC_CYCLEPERPIC, g_VdmRegState.DecCyclePerPic, 0);
|
||||
RD_VREG(VREG_RD_BDWIDTH_PERPIC, g_VdmRegState.RdBdwidthPerPic, 0);
|
||||
RD_VREG(VREG_WR_BDWIDTH_PERPIC, g_VdmRegState.WrBdWidthPerPic, 0);
|
||||
RD_VREG(VREG_RD_REQ_PERPIC, g_VdmRegState.RdReqPerPic, 0);
|
||||
RD_VREG(VREG_WR_REQ_PERPIC, g_VdmRegState.WrReqPerPic, 0);
|
||||
RD_VREG(VREG_LUMA_SUM_LOW, g_VdmRegState.LumaSumLow, 0);
|
||||
RD_VREG(VREG_LUMA_SUM_HIGH, g_VdmRegState.LumaSumHigh, 0);
|
||||
}
|
||||
for (i = 0; i < 32; i++) {
|
||||
regTmp = VREG_LUMA_HISTORGRAM + i * 4;
|
||||
RD_VREG(regTmp, g_VdmRegState.LumaHistorgam[i], 0);
|
||||
}
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
void VDMHAL_GetRegState(VDMHAL_BACKUP_S *pVdmRegState)
|
||||
{
|
||||
memcpy(pVdmRegState, &g_VdmRegState, sizeof(*pVdmRegState));
|
||||
s_VdmState = VDM_IDLE_STATE;
|
||||
}
|
||||
|
||||
int VDMHAL_IMP_PrepareRepair(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
VDMHAL_HWMEM_S *pHwMem = &(g_HwMem[0]);
|
||||
int *p32;
|
||||
int ret;
|
||||
|
||||
if (NULL == pVdhRegCfg)
|
||||
{
|
||||
printk(KERN_ERR "%s: parameter is NULL\n", __func__);
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
if ( NULL == pHwMem->pVdmRegVirAddr )
|
||||
{
|
||||
if ( NULL != (p32 = (int *)MEM_Phy2Vir(gVdhRegBaseAddr)) )
|
||||
{
|
||||
pHwMem->pVdmRegVirAddr = p32;
|
||||
}
|
||||
else
|
||||
{
|
||||
printk(KERN_ERR "vdm register virtual address not mapped, VDMHAL_PrepareRepair failed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
}
|
||||
if (pVdhRegCfg->RepairTime == FIRST_REPAIR) {
|
||||
if (pVdhRegCfg->ValidGroupNum0 > 0)
|
||||
ret = VDMHAL_CfgRpReg(pVdhRegCfg);
|
||||
else
|
||||
ret = VDMHAL_ERR;
|
||||
} else if (pVdhRegCfg->RepairTime == SECOND_REPAIR) {
|
||||
printk(KERN_ERR "SECOND_REPAIR Parameter Error\n");
|
||||
ret = VDMHAL_ERR;
|
||||
} else {
|
||||
printk(KERN_ERR " parameter error\n");
|
||||
ret = VDMHAL_ERR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_StartHwRepair(int VdhId)
|
||||
{
|
||||
int D32 = 0;
|
||||
|
||||
RD_VREG(VREG_BASIC_CFG0, D32, VdhId);
|
||||
|
||||
D32 = 0x4000000;
|
||||
WR_VREG(VREG_BASIC_CFG0, D32, VdhId);
|
||||
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
SMMU_SetMasterReg(MFDE, SECURE_OFF, SMMU_ON);
|
||||
#endif
|
||||
|
||||
VDMHAL_IMP_ClearIntState(VdhId);
|
||||
VDMHAL_EnableInt(VdhId);
|
||||
|
||||
VFMW_OSAL_Mb();
|
||||
WR_VREG(VREG_VDH_START, 0, VdhId);
|
||||
WR_VREG(VREG_VDH_START, 1, VdhId);
|
||||
WR_VREG(VREG_VDH_START, 0, VdhId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VDMHAL_IMP_StartHwDecode(int VdhId)
|
||||
{
|
||||
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
SMMU_SetMasterReg(MFDE, SECURE_OFF, SMMU_ON);
|
||||
#endif
|
||||
|
||||
VDMHAL_IMP_ClearIntState(VdhId);
|
||||
VDMHAL_EnableInt(VdhId);
|
||||
|
||||
VFMW_OSAL_Mb();
|
||||
WR_VREG(VREG_VDH_START, 0, 0);
|
||||
WR_VREG(VREG_VDH_START, 1, 0);
|
||||
WR_VREG(VREG_VDH_START, 0, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VDMHAL_ISR(int VdhId)
|
||||
{
|
||||
VDMHAL_IMP_BackupInfo();
|
||||
VDMHAL_IMP_ClearIntState(VdhId);
|
||||
VFMW_OSAL_GiveEvent(G_VDMHWDONEEVENT);
|
||||
}
|
||||
|
||||
int VDMHAL_HwDecProc(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int ret = VDMDRV_ERR;
|
||||
|
||||
s_VdmState = VDM_DECODE_STATE;
|
||||
|
||||
if (pVdhRegCfg->VdhStartHwDecFlag == 1) {
|
||||
ret = VDMHAL_IMP_PrepareDec(pVdhRegCfg);
|
||||
if (ret == VDMDRV_OK) {
|
||||
VDMHAL_IMP_StartHwDecode(0);
|
||||
} else {
|
||||
ret = VDMDRV_ERR;
|
||||
printk(KERN_ERR "%s prepare dec fail \n", __func__);
|
||||
}
|
||||
} else if (pVdhRegCfg->VdhStartRepairFlag == 1) {
|
||||
ret = VDMHAL_IMP_PrepareRepair(pVdhRegCfg);
|
||||
if (ret == VDMDRV_OK) {
|
||||
VDMHAL_IMP_StartHwRepair(0);
|
||||
} else {
|
||||
ret = VDMDRV_ERR;
|
||||
printk(KERN_ERR "%s prepare repair fail \n", __func__);
|
||||
}
|
||||
} else {
|
||||
ret = VDMDRV_ERR;
|
||||
printk(KERN_ERR "%s process type error \n", __func__);
|
||||
}
|
||||
|
||||
if (ret != VDMDRV_OK) {
|
||||
s_VdmState = VDM_IDLE_STATE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VDMHAL_PrepareSleep(void)
|
||||
{
|
||||
int ret = VDMDRV_OK;
|
||||
|
||||
VFMW_OSAL_SemaDown(G_VDH_SEM);
|
||||
if (s_eVdmDrvSleepState == VDMDRV_SLEEP_STAGE_NONE) {
|
||||
if (VDM_IDLE_STATE == s_VdmState) {
|
||||
printk(KERN_INFO "%s, idle state \n", __func__);
|
||||
s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_SLEEP;
|
||||
} else {
|
||||
printk(KERN_INFO "%s, work state \n", __func__);
|
||||
s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_PREPARE;
|
||||
}
|
||||
|
||||
ret = VDMDRV_OK;
|
||||
} else {
|
||||
ret = VDMDRV_ERR;
|
||||
}
|
||||
|
||||
VFMW_OSAL_SemaUp(G_VDH_SEM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VDMHAL_ForceSleep(void)
|
||||
{
|
||||
printk(KERN_INFO "%s, force state \n", __func__);
|
||||
VFMW_OSAL_SemaDown(G_VDH_SEM);
|
||||
if (s_eVdmDrvSleepState != VDMDRV_SLEEP_STAGE_SLEEP) {
|
||||
VDMHAL_IMP_ResetVdm(0);
|
||||
s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_SLEEP;
|
||||
}
|
||||
|
||||
VFMW_OSAL_SemaUp(G_VDH_SEM);
|
||||
}
|
||||
|
||||
void VDMHAL_ExitSleep(void)
|
||||
{
|
||||
VFMW_OSAL_SemaDown(G_VDH_SEM);
|
||||
s_eVdmDrvSleepState = VDMDRV_SLEEP_STAGE_NONE;
|
||||
VFMW_OSAL_SemaUp(G_VDH_SEM);
|
||||
}
|
||||
|
||||
VDMDRV_SLEEP_STAGE_E VDMHAL_GetSleepStage(void)
|
||||
{
|
||||
return s_eVdmDrvSleepState;
|
||||
}
|
||||
|
||||
void VDMHAL_SetSleepStage(VDMDRV_SLEEP_STAGE_E sleepState)
|
||||
{
|
||||
VFMW_OSAL_SemaDown(G_VDH_SEM);
|
||||
s_eVdmDrvSleepState = sleepState;
|
||||
VFMW_OSAL_SemaUp(G_VDH_SEM);
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
#ifndef _VDM_HAL_HEADER_
|
||||
#define _VDM_HAL_HEADER_
|
||||
|
||||
#include "vdm_drv.h"
|
||||
#include <linux/io.h>
|
||||
#include "../../omxvdec/omxvdec.h"
|
||||
|
||||
#define VDMHAL_OK (0)
|
||||
#define VDMHAL_ERR (-1)
|
||||
|
||||
#define MAX_SLICE_SLOT_NUM (200)
|
||||
|
||||
#define FIRST_REPAIR (0)
|
||||
#define SECOND_REPAIR (1)
|
||||
|
||||
#define MAX_IMG_WIDTH_IN_MB (512)
|
||||
#define MAX_IMG_HALF_HEIGHT_IN_MB (256)
|
||||
#define MAX_IMG_HEIGHT_IN_MB (MAX_IMG_HALF_HEIGHT_IN_MB * 2)
|
||||
#define MAX_MB_NUM_IN_PIC (MAX_IMG_WIDTH_IN_MB * MAX_IMG_HEIGHT_IN_MB)
|
||||
|
||||
#define MAX_SLOT_WIDTH (4096)
|
||||
#define MAX_STRIDE ((1024 * MAX_SLOT_WIDTH / 64 + ((1024) - 1)) & (~ ((1024) - 1)))
|
||||
/************************************************************************/
|
||||
/* Register read/write interface */
|
||||
/************************************************************************/
|
||||
/* mfde register read/write */
|
||||
#if 1
|
||||
#define RD_VREG( reg, dat, VdhId ) \
|
||||
do { \
|
||||
if (VdhId < MAX_VDH_NUM) \
|
||||
dat = readl(((volatile int*)((char*)g_HwMem[VdhId].pVdmRegVirAddr + reg))); \
|
||||
else \
|
||||
dprint(PRN_ALWS,"%s: RD_VREG but VdhId : %d is more than MAX_VDH_NUM : %d\n", __func__, VdhId, MAX_VDH_NUM); \
|
||||
} while(0)
|
||||
|
||||
#define WR_VREG( reg, dat, VdhId ) \
|
||||
do { \
|
||||
if (VdhId < MAX_VDH_NUM) \
|
||||
writel((dat), ((volatile int*)((char*)g_HwMem[VdhId].pVdmRegVirAddr + reg))); \
|
||||
else \
|
||||
dprint(PRN_ALWS,"%s: WR_VREG but VdhId : %d is more than MAX_VDH_NUM : %d\n", __func__, VdhId, MAX_VDH_NUM); \
|
||||
} while(0)
|
||||
#else // xy test
|
||||
#define RD_VREG( reg, dat, VdhId ) \
|
||||
do { \
|
||||
if (VdhId < MAX_VDH_NUM) { \
|
||||
printk(KERN_INFO "%s: RD_VREG \n", __func__ ); \
|
||||
dat = *((volatile int*)((char*)g_HwMem[VdhId].pVdmRegVirAddr + reg)); \
|
||||
} \
|
||||
else \
|
||||
printk(KERN_INFO "%s: RD_VREG but VdhId : %d is more than MAX_VDH_NUM : %d\n", __func__, VdhId, MAX_VDH_NUM); \
|
||||
} while(0)
|
||||
|
||||
#define WR_VREG( reg, dat, VdhId ) \
|
||||
do { \
|
||||
if (VdhId < MAX_VDH_NUM) \
|
||||
(*(volatile int*)((char*)g_HwMem[VdhId].pVdmRegVirAddr + reg)) = dat; \
|
||||
else \
|
||||
printk(KERN_INFO "%s: WR_VREG but VdhId : %d is more than MAX_VDH_NUM : %d\n", __func__, VdhId, MAX_VDH_NUM); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* message pool read/write */
|
||||
#define RD_MSGWORD( vir_addr, dat ) \
|
||||
do { \
|
||||
dat = *((volatile int*)(vir_addr)); \
|
||||
} while(0)
|
||||
|
||||
#define WR_MSGWORD( vir_addr, dat ) \
|
||||
do { \
|
||||
*((volatile int*)((char*)(vir_addr))) = dat; \
|
||||
} while(0)
|
||||
|
||||
/* condition check */
|
||||
#define VDMHAL_ASSERT_RET( cond, else_print ) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
printk(KERN_ERR "%s %d: %s\n", __func__, __LINE__, else_print ); \
|
||||
return VDMHAL_ERR; \
|
||||
} \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef _VDM_HAL_API_HEADER_
|
||||
#define _VDM_HAL_API_HEADER_
|
||||
|
||||
#include "mem_manage.h"
|
||||
#include "vfmw.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
void VDMHAL_IMP_ResetVdm(int VdhId);
|
||||
void VDMHAL_IMP_GlbReset(void);
|
||||
void VDMHAL_IMP_ClearIntState(int VdhId);
|
||||
int VDMHAL_IMP_CheckReg(REG_ID_E reg_id, int VdhId);
|
||||
void VDMHAL_IMP_StartHwRepair(int VdhId);
|
||||
void VDMHAL_IMP_StartHwDecode(int VdhId);
|
||||
int VDMHAL_IMP_PrepareDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
int VDMHAL_IMP_PrepareRepair(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
int VDMHAL_IMP_BackupInfo(void);
|
||||
void VDMHAL_IMP_GetCharacter(void);
|
||||
void VDMHAL_IMP_WriteScdEMARID(void);
|
||||
void VDMHAL_IMP_Init(void);
|
||||
void VDMHAL_IMP_DeInit(void);
|
||||
void VDMHAL_ISR(int VdhId);
|
||||
int VDMHAL_HwDecProc(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
void VDMHAL_GetRegState(VDMHAL_BACKUP_S *pVdmRegState);
|
||||
int VDMHAL_IsVdmRun(int VdhId);
|
||||
int VDMHAL_PrepareSleep(void);
|
||||
void VDMHAL_ForceSleep(void);
|
||||
void VDMHAL_ExitSleep(void);
|
||||
VDMDRV_SLEEP_STAGE_E VDMHAL_GetSleepStage(void);
|
||||
void VDMHAL_SetSleepStage(VDMDRV_SLEEP_STAGE_E sleepState);
|
||||
#endif
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* vdec hal for h264
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include "vfmw.h"
|
||||
#include "mem_manage.h"
|
||||
//#include "public.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vdm_hal_h264.h"
|
||||
|
||||
#include <linux/printk.h>
|
||||
int H264HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
unsigned int D32;
|
||||
|
||||
D32 = 0;
|
||||
((BASIC_CFG0 *)(&D32))->mbamt_to_dec = ((BASIC_CFG0 *)(&pVdhRegCfg->VdhBasicCfg0))->mbamt_to_dec;
|
||||
((BASIC_CFG0 *)(&D32))->load_qmatrix_flag = 1;
|
||||
((BASIC_CFG0 *)(&D32))->marker_bit_detect_en = 0;
|
||||
((BASIC_CFG0 *)(&D32))->ac_last_detect_en = 0;
|
||||
((BASIC_CFG0 *)(&D32))->coef_idx_detect_en = 1;
|
||||
((BASIC_CFG0 *)(&D32))->vop_type_detect_en = 0;
|
||||
((BASIC_CFG0 *)(&D32))->sec_mode_en = 0;
|
||||
WR_VREG(VREG_BASIC_CFG0, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((BASIC_CFG1 *)(&D32))->video_standard = 0x0;
|
||||
//((BASIC_CFG1 *)(&D32))->ddr_stride = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->ddr_stride;
|
||||
((BASIC_CFG1 *)(&D32))->fst_slc_grp = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->fst_slc_grp;
|
||||
((BASIC_CFG1 *)(&D32))->mv_output_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->mv_output_en;
|
||||
((BASIC_CFG1 *)(&D32))->uv_order_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->uv_order_en;
|
||||
((BASIC_CFG1 *)(&D32))->vdh_2d_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->vdh_2d_en;
|
||||
((BASIC_CFG1 *)(&D32))->max_slcgrp_num = 2;
|
||||
((BASIC_CFG1 *)(&D32))->compress_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->compress_en;
|
||||
((BASIC_CFG1 *)(&D32))->ppfd_en = 0;
|
||||
((BASIC_CFG1 *)(&D32))->line_num_output_en = 0;
|
||||
WR_VREG(VREG_BASIC_CFG1, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((AVM_ADDR *)(&D32))->av_msg_addr = (pVdhRegCfg->VdhAvmAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_AVM_ADDR, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((VAM_ADDR *)(&D32))->va_msg_addr = (pVdhRegCfg->VdhVamAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_VAM_ADDR, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((STREAM_BASE_ADDR *)(&D32))->stream_base_addr = (pVdhRegCfg->VdhStreamBaseAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_STREAM_BASE_ADDR, D32, 0);
|
||||
|
||||
D32 = RD_SCDREG(REG_EMAR_ID);
|
||||
if (pVdhRegCfg->VdhEmarId == 0) {
|
||||
D32 = D32 & (~(0x100));
|
||||
} else {
|
||||
D32 = D32 | 0x100;
|
||||
}
|
||||
WR_SCDREG(REG_EMAR_ID, D32);
|
||||
|
||||
D32 = 0x00300C03;
|
||||
WR_VREG(VREG_SED_TO, D32, 0);
|
||||
WR_VREG(VREG_ITRANS_TO, D32, 0);
|
||||
WR_VREG(VREG_PMV_TO, D32, 0);
|
||||
WR_VREG(VREG_PRC_TO, D32, 0);
|
||||
WR_VREG(VREG_RCN_TO, D32, 0);
|
||||
WR_VREG(VREG_DBLK_TO, D32, 0);
|
||||
WR_VREG(VREG_PPFD_TO, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((YSTADDR_1D *)(&D32))->ystaddr_1d = (pVdhRegCfg->VdhYstAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_YSTADDR_1D, D32, 0);
|
||||
|
||||
WR_VREG(VREG_YSTRIDE_1D, pVdhRegCfg->VdhYstride, 0);
|
||||
|
||||
WR_VREG(VREG_UVOFFSET_1D, pVdhRegCfg->VdhUvoffset, 0);
|
||||
|
||||
D32 = 0;
|
||||
WR_VREG(VREG_HEAD_INF_OFFSET, D32, 0);
|
||||
|
||||
WR_VREG(VREG_REF_PIC_TYPE, pVdhRegCfg->VdhRefPicType, 0);
|
||||
|
||||
if (pVdhRegCfg->VdhFfAptEn == 0x2) {
|
||||
D32 = 0x2;
|
||||
} else {
|
||||
D32 = 0x0;
|
||||
}
|
||||
WR_VREG(VREG_FF_APT_EN, D32, 0);
|
||||
|
||||
//UVSTRIDE_1D
|
||||
WR_VREG( VREG_UVSTRIDE_1D, pVdhRegCfg->VdhUvstride, 0 );
|
||||
|
||||
//CFGINFO_ADDR
|
||||
WR_VREG(VREG_CFGINFO_ADDR, pVdhRegCfg->VdhCfgInfoAddr, 0);
|
||||
|
||||
//DDR_INTERLEAVE_MODE
|
||||
D32 = 0x03;
|
||||
WR_VREG(VREG_DDR_INTERLEAVE_MODE, D32, 0);
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef __VDM_HAL_H264_H__
|
||||
#define __VDM_HAL_H264_H__
|
||||
|
||||
#include "mem_manage.h"
|
||||
//#include "memory.h"
|
||||
#include "vfmw_intf.h"
|
||||
int H264HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
#endif
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* vdec hal for hevc
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include "vfmw.h"
|
||||
#include "mem_manage.h"
|
||||
//#include "public.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vdm_hal_hevc.h"
|
||||
#include <linux/printk.h>
|
||||
static int HEVCHAL_CfgVdmReg(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
unsigned int D32;
|
||||
|
||||
//BASIC_CFG0
|
||||
D32 = 0;
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->marker_bit_detect_en = 0;
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->ac_last_detect_en = 0;
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->coef_idx_detect_en = 1; //(run_cnt>64) check enable switch
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->vop_type_detect_en = 0;
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->load_qmatrix_flag = ((HEVC_BASIC_CFG0 *)(&pVdhRegCfg->VdhBasicCfg0))->load_qmatrix_flag;
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->luma_sum_en = 0; //enable switch:conculate luma pixel
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->luma_histogram_en = 0; //enable switch:conculate luma histogram
|
||||
((HEVC_BASIC_CFG0 *)(&D32))->mbamt_to_dec = ((HEVC_BASIC_CFG0 *)(&pVdhRegCfg->VdhBasicCfg0))->mbamt_to_dec;
|
||||
((HEVC_BASIC_CFG0*)(&D32))->vdh_safe_flag = 0;
|
||||
WR_VREG( VREG_BASIC_CFG0, D32, 0 );
|
||||
|
||||
//BASIC_CFG1
|
||||
/*set uv order 0: v first; 1: u first */
|
||||
D32 = 0;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->video_standard = 0xD;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->fst_slc_grp = ((HEVC_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->fst_slc_grp;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->mv_output_en = 1;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->uv_order_en = ((HEVC_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->uv_order_en;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->vdh_2d_en = ((HEVC_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->vdh_2d_en;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->max_slcgrp_num = 3;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->line_num_output_en = 0; //enable switch:output "decodered pixel line of current frame" to DDR
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->frm_cmp_en = ((HEVC_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->frm_cmp_en;
|
||||
((HEVC_BASIC_CFG1 *)(&D32))->ppfd_en = 0;
|
||||
WR_VREG( VREG_BASIC_CFG1, D32, 0 );
|
||||
|
||||
//AVM_ADDR
|
||||
D32 = 0;
|
||||
((AVM_ADDR *)(&D32))->av_msg_addr = (pVdhRegCfg->VdhAvmAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_AVM_ADDR, D32, 0);
|
||||
|
||||
//VAM_ADDR
|
||||
D32 = 0;
|
||||
((VAM_ADDR *)(&D32))->va_msg_addr = (pVdhRegCfg->VdhVamAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_VAM_ADDR, D32, 0);
|
||||
|
||||
//STREAM_BASE_ADDR
|
||||
D32 = 0;
|
||||
((STREAM_BASE_ADDR *)(&D32))->stream_base_addr = (pVdhRegCfg->VdhStreamBaseAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_STREAM_BASE_ADDR, D32, 0);
|
||||
|
||||
//TIME_OUT
|
||||
D32 = 0x00300C03; //Õâ¸öÖµÅäÖà l00214825
|
||||
WR_VREG(VREG_SED_TO, D32, 0);
|
||||
WR_VREG(VREG_ITRANS_TO, D32, 0);
|
||||
WR_VREG(VREG_PMV_TO, D32, 0);
|
||||
WR_VREG(VREG_PRC_TO, D32, 0);
|
||||
WR_VREG(VREG_RCN_TO, D32, 0);
|
||||
WR_VREG(VREG_DBLK_TO, D32, 0);
|
||||
WR_VREG(VREG_PPFD_TO, D32, 0);
|
||||
|
||||
WR_VREG(VREG_YSTADDR_1D, pVdhRegCfg->VdhYstAddr, 0);
|
||||
|
||||
//YSTRIDE_1D
|
||||
WR_VREG(VREG_YSTRIDE_1D, pVdhRegCfg->VdhYstride, 0);
|
||||
|
||||
//UVOFFSET_1D
|
||||
WR_VREG(VREG_UVOFFSET_1D, pVdhRegCfg->VdhUvoffset, 0);
|
||||
|
||||
//HEAD_INF_OFFSET
|
||||
D32 = 0;
|
||||
WR_VREG(VREG_HEAD_INF_OFFSET, D32, 0); //don't match with document l00214825
|
||||
|
||||
//UVSTRIDE_1D
|
||||
WR_VREG( VREG_UVSTRIDE_1D, pVdhRegCfg->VdhUvstride, 0 );
|
||||
|
||||
//CFGINFO_ADDR
|
||||
WR_VREG(VREG_CFGINFO_ADDR, pVdhRegCfg->VdhCfgInfoAddr, 0);
|
||||
|
||||
//DDR_INTERLEAVE_MODE
|
||||
D32 = 0x03;
|
||||
WR_VREG(VREG_DDR_INTERLEAVE_MODE, D32, 0);
|
||||
|
||||
//FF_APT_EN
|
||||
D32 = 0x2;
|
||||
WR_VREG(VREG_FF_APT_EN, D32, 0);
|
||||
|
||||
//EMAR_ADDR
|
||||
D32 = 0x101;
|
||||
WR_SCDREG(REG_EMAR_ID, D32);
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
int HEVCHAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int Ret;
|
||||
|
||||
Ret = HEVCHAL_CfgVdmReg(pVdhRegCfg);
|
||||
if (Ret != VDMHAL_OK) {
|
||||
printk(KERN_ERR "HEVC register config failed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef __VDM_HAL__HEVC_H__
|
||||
#define __VDM_HAL__HEVC_H__
|
||||
|
||||
#include "mem_manage.h"
|
||||
//#include "memory.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
int HEVCHAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
#endif
|
||||
+283
@@ -0,0 +1,283 @@
|
||||
|
||||
#ifndef _VDM_HAL_LOCAL_HEADER_
|
||||
#define _VDM_HAL_LOCAL_HEADER_
|
||||
|
||||
#include "mem_manage.h"
|
||||
#include "vfmw.h"
|
||||
#include "vdm_hal.h"
|
||||
|
||||
#define VHB_STRIDE_BYTE (0x400) // byte stride
|
||||
#define HW_MEM_SIZE (640 * 1024 + 64 * 4)
|
||||
#define HW_HEVC_MEM_SIZE (2 * 1024 * 1024 + 64 * 4) //(4*1024*1024 + 100*1024)
|
||||
|
||||
#define MSG_SLOT_NUM (MAX_SLICE_SLOT_NUM + 5 + 1)
|
||||
#define UP_MSG_SLOT_INDEX (0)
|
||||
#define RP_MSG_SLOT_INDEX (2)
|
||||
#define DN_MSG_HEAD_SLOT_INDEX (4)
|
||||
#define DN_MSG_SLOT_INDEX (5)
|
||||
#define CA_HEVC_MN_ADDR_LEN (1024)
|
||||
#define CA_MN_ADDR_LEN (64 * 4 * 20)
|
||||
#define SED_TOP_ADDR_LEN (352 * 96) //(64*4*96)
|
||||
#define PMV_TOP_ADDR_LEN (352 * 128) //(64*4*96)
|
||||
#define RCN_TOP_ADDR_LEN (352 * 128) //(64*4*96)
|
||||
#define ITRANS_TOP_ADDR_LEN (352 * 128) //(128*128)
|
||||
#define DBLK_TOP_ADDR_LEN (352 * 192) //(128*512)
|
||||
#define PPFD_BUF_LEN_DEFAULT (64 * 4 * 400) //(64*4*800)
|
||||
|
||||
#define INTENSITY_CONV_TAB_ADDR_LEN (256 * 2 * 2 * 3)
|
||||
#define VP8_TAB_ADDR_LEN (32 * 1024)
|
||||
#define VP6_TAB_ADDR_LEN (4 * 1024)
|
||||
#define MAX_REF_FRAME_NUM (16)
|
||||
|
||||
/*********************************************************
|
||||
for hevc
|
||||
**********************************************************/
|
||||
#ifdef VFMW_HEVC_SUPPORT
|
||||
|
||||
/*** UHD decode memory define ***/
|
||||
#define CFG_HEVC_PROFILE_LEVEL_5
|
||||
#define CFG_HEVC_MAX_PIX_HEIGHT (2304)
|
||||
|
||||
#if defined (CFG_HEVC_PROFILE_LEVEL_5)
|
||||
#define HEVC_PROFILE_LEVEL_5
|
||||
#else
|
||||
#define HEVC_PROFILE_LEVEL_6
|
||||
#endif
|
||||
|
||||
#if defined (HEVC_PROFILE_LEVEL_5)
|
||||
#define HEVC_MAX_SLICE_NUM (200)
|
||||
#else
|
||||
#define HEVC_MAX_SLICE_NUM (600)
|
||||
#endif
|
||||
|
||||
#if !defined (CFG_HEVC_MAX_PIX_WIDTH)
|
||||
#define HEVC_MAX_PIX_WIDTH (4096)
|
||||
#else
|
||||
#define HEVC_MAX_PIX_WIDTH (CFG_HEVC_MAX_PIX_WIDTH)
|
||||
#endif
|
||||
|
||||
// 3798MV100 logic support tile num is 20x22
|
||||
#if !defined (CFG_HEVC_MAX_PIX_HEIGHT)
|
||||
#define HEVC_MAX_PIX_HEIGHT (4096)
|
||||
#else
|
||||
#define HEVC_MAX_PIX_HEIGHT (CFG_HEVC_MAX_PIX_HEIGHT)
|
||||
#endif
|
||||
|
||||
|
||||
#define HEVC_SED_TOP_ADDR_LEN (64*4*HEVC_MAX_PIX_WIDTH)
|
||||
#define HEVC_PMV_TOP_ADDR_LEN (64*4*HEVC_MAX_PIX_WIDTH)
|
||||
#define HEVC_PMV_LEFT_ADDR_LEN (64*4*HEVC_MAX_PIX_HEIGHT)
|
||||
#define HEVC_RCN_TOP_ADDR_LEN (64*4*HEVC_MAX_PIX_WIDTH)
|
||||
#define HEVC_TILE_SEGMENT_INFO_LEN (2048) //(512*2+20*4+22*4=1192, 1024????) z00290437 20141024
|
||||
#define HEVC_SAO_LEFT_ADDR_LEN (64*4*HEVC_MAX_PIX_HEIGHT)
|
||||
#define HEVC_DBLK_LEFT_ADDR_LEN (64*4*HEVC_MAX_PIX_HEIGHT)
|
||||
#define HEVC_SAO_TOP_ADDR_LEN (64*4*HEVC_MAX_PIX_WIDTH)
|
||||
#define HEVC_DBLK_TOP_ADDR_LEN (64*4*HEVC_MAX_PIX_WIDTH)
|
||||
/*********************** MSG SLOT PARA DEFINE *********************/
|
||||
#define HEVC_MAX_SLOT_NUM (HEVC_MAX_SLICE_NUM+5) //z00290437 20141025
|
||||
#ifdef VFMW_VP9_SUPPORT
|
||||
#define VP9_MAX_PIC_WIDTH 8192
|
||||
#define VP9_MAX_PIC_HEIGHT 8192
|
||||
|
||||
//============================== VP9 =============================
|
||||
#define VP9_SED_TOP_ADDR_LEN (64*4*VP9_MAX_PIC_WIDTH)
|
||||
#define VP9_PMV_TOP_ADDR_LEN (64*4*VP9_MAX_PIC_WIDTH)
|
||||
#define VP9_RCN_TOP_ADDR_LEN (64*4*VP9_MAX_PIC_WIDTH)
|
||||
#define VP9_DBLK_TOP_ADDR_LEN (64*4*VP9_MAX_PIC_WIDTH)
|
||||
#define VP9_DBLK_LEFT_ADDR_LEN (VP9_MAX_PIC_HEIGHT * 8)
|
||||
|
||||
#ifndef VP9_NEW_PROB
|
||||
#define VP9_PROB_TAB_ADDR_LEN (20 * 64 * 4)//(18 * 64 * 4)
|
||||
#define VP9_PROB_CNT_ADDR_LEN (VP9_MAX_PIC_WIDTH * 4) /* 3301 is enought */
|
||||
#else
|
||||
#define VP9_PROB_TAB_ADDR_LEN (20*64*4)
|
||||
#define VP9_PROB_CNT_ADDR_LEN (20*64*4)
|
||||
#endif // modified by j00367396@20160923
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//control registers
|
||||
#define VREG_VDH_START 0x000
|
||||
#define VREG_BASIC_CFG0 0x008
|
||||
#define VREG_BASIC_CFG1 0x00c
|
||||
#define VREG_AVM_ADDR 0x010
|
||||
#define VREG_VAM_ADDR 0x014
|
||||
#define VREG_STREAM_BASE_ADDR 0x018
|
||||
//state registers
|
||||
#define VREG_VDH_STATE 0x01c
|
||||
#define VREG_VCTRL_STATE 0x028
|
||||
//0x0001FF00: all RAM OnChip
|
||||
//0x0002FF00: all RAM OnChip, except DBLK RAM
|
||||
#define VREG_SED_TO 0x03c
|
||||
#define VREG_ITRANS_TO 0x040
|
||||
#define VREG_PMV_TO 0x044
|
||||
#define VREG_PRC_TO 0x048
|
||||
#define VREG_RCN_TO 0x04c
|
||||
#define VREG_DBLK_TO 0x050
|
||||
#define VREG_PPFD_TO 0x054
|
||||
#define VREG_PART_DEC_OVER_INT_LEVEL 0x05c
|
||||
//1d registers
|
||||
#define VREG_YSTADDR_1D 0x060
|
||||
#define VREG_YSTRIDE_1D 0x064
|
||||
#define VREG_UVOFFSET_1D 0x068
|
||||
//prc registers
|
||||
#define VREG_HEAD_INF_OFFSET 0x06c
|
||||
//ppfd registers
|
||||
#define VREG_PPFD_BUF_ADDR 0x080
|
||||
#define VREG_PPFD_BUF_LEN 0x084
|
||||
#define VREG_REF_PIC_TYPE 0x094
|
||||
#define VREG_FF_APT_EN 0x098
|
||||
|
||||
//mask & clear
|
||||
#define VREG_SAFE_INT_STATE 0x0a8
|
||||
#define VREG_SAFE_INT_MASK 0x0aC
|
||||
#define VREG_NORM_INT_STATE 0x020
|
||||
#define VREG_NORM_INT_MASK 0x024
|
||||
|
||||
#define VREG_INT_STATE VREG_NORM_INT_STATE
|
||||
#define VREG_INT_MASK VREG_NORM_INT_MASK
|
||||
|
||||
#define VREG_UVSTRIDE_1D 0x0c4
|
||||
#define VREG_CFGINFO_ADDR 0x0C8
|
||||
#define VREG_DDR_INTERLEAVE_MODE 0x0F4
|
||||
//clock div offset
|
||||
#define PERI_CRG_CORE_DIV 0xCC
|
||||
#define PERI_CRG_AXI_DIV 0xD0
|
||||
|
||||
//performance count registers
|
||||
#define VREG_DEC_CYCLEPERPIC 0x0B0
|
||||
#define VREG_RD_BDWIDTH_PERPIC 0x0B4
|
||||
#define VREG_WR_BDWIDTH_PERPIC 0x0B8
|
||||
#define VREG_RD_REQ_PERPIC 0x0BC
|
||||
#define VREG_WR_REQ_PERPIC 0x0C0
|
||||
#define VREG_MB0_QP_IN_CURR_PIC 0x0D0
|
||||
#define VREG_SWITCH_ROUNDING 0x0D4
|
||||
//sed registers
|
||||
#define VREG_SED_STA 0x1000
|
||||
#define VREG_SED_END0 0x1014
|
||||
#define VREG_LUMA_HISTORGRAM 0x8100
|
||||
#define VREG_LUMA_SUM_LOW 0x8180
|
||||
#define VREG_LUMA_SUM_HIGH 0x8184
|
||||
|
||||
typedef struct {
|
||||
unsigned int mbamt_to_dec :20;
|
||||
unsigned int memory_clock_gating_en :1;
|
||||
unsigned int module_clock_gating_en :1;
|
||||
unsigned int marker_bit_detect_en :1;
|
||||
unsigned int ac_last_detect_en :1;
|
||||
unsigned int coef_idx_detect_en :1;
|
||||
unsigned int vop_type_detect_en :1;
|
||||
unsigned int reserved :2;
|
||||
unsigned int luma_sum_en :1;
|
||||
unsigned int luma_historgam_en :1;
|
||||
unsigned int load_qmatrix_flag :1;
|
||||
unsigned int sec_mode_en :1;
|
||||
} BASIC_CFG0;
|
||||
|
||||
typedef struct {
|
||||
unsigned int mbamt_to_dec :20;
|
||||
unsigned int memory_clock_gating_en :1;
|
||||
unsigned int module_clock_gating_en :1;
|
||||
unsigned int marker_bit_detect_en :1;
|
||||
unsigned int ac_last_detect_en :1;
|
||||
unsigned int coef_idx_detect_en :1;
|
||||
unsigned int vop_type_detect_en :1;
|
||||
unsigned int work_mode :2;
|
||||
unsigned int luma_sum_en :1;
|
||||
unsigned int luma_histogram_en :1;
|
||||
unsigned int load_qmatrix_flag :1;
|
||||
unsigned int vdh_safe_flag :1;
|
||||
} HEVC_BASIC_CFG0;
|
||||
|
||||
typedef struct {
|
||||
unsigned int video_standard :4;
|
||||
unsigned int reserved: 9;
|
||||
unsigned int uv_order_en :1;
|
||||
unsigned int fst_slc_grp :1;
|
||||
unsigned int mv_output_en :1;
|
||||
unsigned int max_slcgrp_num :12;
|
||||
unsigned int line_num_output_en :1;
|
||||
unsigned int vdh_2d_en :1;
|
||||
unsigned int compress_en :1;
|
||||
unsigned int ppfd_en :1;
|
||||
} BASIC_CFG1;
|
||||
|
||||
typedef struct {
|
||||
unsigned int video_standard :4;
|
||||
unsigned int reserved :9;
|
||||
unsigned int uv_order_en :1;
|
||||
unsigned int fst_slc_grp :1;
|
||||
unsigned int mv_output_en :1;
|
||||
unsigned int max_slcgrp_num :12;
|
||||
unsigned int line_num_output_en :1;
|
||||
unsigned int vdh_2d_en :1;
|
||||
unsigned int frm_cmp_en :1;
|
||||
unsigned int ppfd_en :1;
|
||||
} HEVC_BASIC_CFG1;
|
||||
|
||||
typedef struct {
|
||||
unsigned int video_standard: 4;
|
||||
unsigned int reserved: 9;
|
||||
unsigned int uv_order_en: 1; //l00214825 0624
|
||||
unsigned int fst_slc_grp: 1;
|
||||
unsigned int mv_output_en: 1;
|
||||
unsigned int max_slcgrp_num: 12;
|
||||
unsigned int line_num_output_en: 1;
|
||||
unsigned int vdh_2d_en: 1;
|
||||
unsigned int frm_cmp_en: 1;
|
||||
unsigned int ppfd_en: 1;
|
||||
} VP9_BASIC_CFG1;
|
||||
|
||||
typedef struct {
|
||||
unsigned int av_msg_addr :32;
|
||||
} AVM_ADDR;
|
||||
|
||||
typedef struct {
|
||||
unsigned int va_msg_addr :32;
|
||||
} VAM_ADDR;
|
||||
|
||||
typedef struct {
|
||||
unsigned int stream_base_addr :32;
|
||||
} STREAM_BASE_ADDR;
|
||||
|
||||
typedef struct {
|
||||
unsigned int ystaddr_1d :32;
|
||||
} YSTADDR_1D;
|
||||
|
||||
typedef struct {
|
||||
unsigned int ff_apt_en :1;
|
||||
unsigned int reserved :31;
|
||||
} FF_APT_EN;
|
||||
|
||||
typedef struct {
|
||||
unsigned int ref_pic_type_0 :2;
|
||||
unsigned int ref_pic_type_1 :2;
|
||||
unsigned int ref_pic_type_2 :2;
|
||||
unsigned int ref_pic_type_3 :2;
|
||||
unsigned int ref_pic_type_4 :2;
|
||||
unsigned int ref_pic_type_5 :2;
|
||||
unsigned int ref_pic_type_6 :2;
|
||||
unsigned int ref_pic_type_7 :2;
|
||||
|
||||
unsigned int ref_pic_type_8 :2;
|
||||
unsigned int ref_pic_type_9 :2;
|
||||
unsigned int ref_pic_type_10 :2;
|
||||
unsigned int ref_pic_type_11 :2;
|
||||
unsigned int ref_pic_type_12 :2;
|
||||
unsigned int ref_pic_type_13 :2;
|
||||
unsigned int ref_pic_type_14 :2;
|
||||
unsigned int ref_pic_type_15 :2;
|
||||
} REF_PIC_TYPE;
|
||||
|
||||
typedef struct {
|
||||
unsigned int ppfd_buf_addr :32;
|
||||
} PPFD_BUF_ADDR;
|
||||
|
||||
typedef struct {
|
||||
unsigned int ppfd_buf_len :16;
|
||||
unsigned int reserved :16;
|
||||
} PPFD_BUF_LEN;
|
||||
|
||||
#endif
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* vdec hal for mp2
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#ifndef __VDM_HAL_MPEG2_C__
|
||||
#define __VDM_HAL_MPEG2_C__
|
||||
|
||||
#include "public.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vdm_hal_mpeg2.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
static int MP2HAL_CfgReg(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int D32;
|
||||
D32 = 0;
|
||||
((BASIC_CFG0 *)(&D32))->mbamt_to_dec = ((BASIC_CFG0 *)(&pVdhRegCfg->VdhBasicCfg0))->mbamt_to_dec;
|
||||
((BASIC_CFG0 *)(&D32))->load_qmatrix_flag = 1;
|
||||
((BASIC_CFG0 *)(&D32))->marker_bit_detect_en = 1;
|
||||
((BASIC_CFG0 *)(&D32))->ac_last_detect_en = 0;
|
||||
((BASIC_CFG0 *)(&D32))->coef_idx_detect_en = 1;
|
||||
((BASIC_CFG0 *)(&D32))->vop_type_detect_en = 0;
|
||||
((BASIC_CFG0 *)(&D32))->sec_mode_en = 0;
|
||||
WR_VREG( VREG_BASIC_CFG0, D32, 0 );
|
||||
|
||||
D32 = 0;
|
||||
((BASIC_CFG1 *)(&D32))->video_standard = 0x3;
|
||||
//((BASIC_CFG1 *)(&D32))->ddr_stride = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->ddr_stride;
|
||||
((BASIC_CFG1 *)(&D32))->fst_slc_grp = 1;
|
||||
((BASIC_CFG1 *)(&D32))->mv_output_en = 1;
|
||||
((BASIC_CFG1 *)(&D32))->uv_order_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->uv_order_en;
|
||||
((BASIC_CFG1 *)(&D32))->vdh_2d_en = 1;
|
||||
((BASIC_CFG1 *)(&D32))->max_slcgrp_num = 3;
|
||||
((BASIC_CFG1 *)(&D32))->ppfd_en = 0;
|
||||
((BASIC_CFG1 *)(&D32))->line_num_output_en = 0;
|
||||
((BASIC_CFG1 *)(&D32))->compress_en = 0;
|
||||
/*set uv order 0: v first; 1: u first */
|
||||
WR_VREG( VREG_BASIC_CFG1, D32, 0 );
|
||||
|
||||
D32 = 0;
|
||||
((AVM_ADDR *)(&D32))->av_msg_addr = (pVdhRegCfg->VdhAvmAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_AVM_ADDR, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((VAM_ADDR *)(&D32))->va_msg_addr = (pVdhRegCfg->VdhVamAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_VAM_ADDR, D32, 0);
|
||||
|
||||
WR_VREG(VREG_STREAM_BASE_ADDR, pVdhRegCfg->VdhStreamBaseAddr, 0);
|
||||
|
||||
//EMAR_ADDR
|
||||
D32 = 0x101;
|
||||
WR_SCDREG(REG_EMAR_ID, D32);
|
||||
|
||||
//TIME_OUT
|
||||
D32 = 0x00300C03;
|
||||
WR_VREG(VREG_SED_TO, D32, 0);
|
||||
WR_VREG(VREG_ITRANS_TO, D32, 0);
|
||||
WR_VREG(VREG_PMV_TO, D32, 0);
|
||||
WR_VREG(VREG_PRC_TO, D32, 0);
|
||||
WR_VREG(VREG_RCN_TO, D32, 0);
|
||||
WR_VREG(VREG_DBLK_TO, D32, 0);
|
||||
WR_VREG(VREG_PPFD_TO, D32, 0);
|
||||
|
||||
D32 = 0;
|
||||
((YSTADDR_1D *)(&D32))->ystaddr_1d = (pVdhRegCfg->VdhYstAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_YSTADDR_1D, D32, 0);
|
||||
WR_VREG(VREG_YSTRIDE_1D, pVdhRegCfg->VdhYstride, 0);
|
||||
WR_VREG(VREG_UVOFFSET_1D, pVdhRegCfg->VdhUvoffset, 0);
|
||||
|
||||
D32 = 0;
|
||||
((REF_PIC_TYPE *)(&D32))->ref_pic_type_0 = ((REF_PIC_TYPE *)(&pVdhRegCfg->VdhRefPicType))->ref_pic_type_0;
|
||||
((REF_PIC_TYPE *)(&D32))->ref_pic_type_1 = ((REF_PIC_TYPE *)(&pVdhRegCfg->VdhRefPicType))->ref_pic_type_1;
|
||||
WR_VREG( VREG_REF_PIC_TYPE, D32, 0 );
|
||||
D32 = 0;
|
||||
((FF_APT_EN *)(&D32))->ff_apt_en = 0;//USE_FF_APT_EN;
|
||||
WR_VREG( VREG_FF_APT_EN, D32, 0 );
|
||||
|
||||
//VREG_UVSTRIDE_1D
|
||||
WR_VREG( VREG_UVSTRIDE_1D, pVdhRegCfg->VdhUvstride, 0 );
|
||||
|
||||
//DDR_INTERLEAVE_MODE
|
||||
D32 = 0x03;
|
||||
WR_VREG(VREG_DDR_INTERLEAVE_MODE, D32, 0);
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
int MP2HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
if (MP2HAL_CfgReg(pVdhRegCfg) != VDMHAL_OK) {
|
||||
printk(KERN_ERR "MP2 register config failed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef __VDM_HAL_MPEG2_H__
|
||||
#define __VDM_HAL_MPEG2_H__
|
||||
|
||||
//#include "memory.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
int MP2HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
#endif
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* vdec hal for mp4
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include "vfmw.h"
|
||||
#include "mem_manage.h"
|
||||
//#include "public.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vdm_hal_mpeg4.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
static int MP4HAL_CfgReg(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
unsigned int D32;
|
||||
int SlotWidth;
|
||||
|
||||
//BASIC_CFG0
|
||||
D32 = 0;
|
||||
D32 = (pVdhRegCfg->VdhBasicCfg0 & 0x000FFFFF) // [15:0] mbamt_to_dec
|
||||
| ( 1 << 22 )
|
||||
| ( 0 << 23 )
|
||||
| ( 0 << 24 )
|
||||
| ( 1 << 25 )
|
||||
| ( 1 << 30 ) // ld_qmatrix_flag
|
||||
| ( 0 << 31 ); // Normal Mode
|
||||
WR_VREG( VREG_BASIC_CFG0, D32, 0);
|
||||
|
||||
/*set uv order 0: v first; 1: u first */
|
||||
D32 = 0x2 // [3:0] video_standard
|
||||
| (((pVdhRegCfg->VdhBasicCfg1 >> 13) & 0x1) << 13 ) // uv_order_en
|
||||
| ( 1 << 14 ) // [14] fst_slc_grp
|
||||
| ( 1 << 15 ) // [15] mv_output_en
|
||||
| ( 1 << 16 ) // [27:16] max_slcgrp_num
|
||||
| ( 0 << 28 ) // line_num_output_en
|
||||
| ( 1 << 29 ) // vdh_2d_en //l00214825 0710
|
||||
| ( 0 << 30 ) //compress_en
|
||||
| ( 0 << 31 ); // [31] ppfd_en 0==not ppfd dec
|
||||
WR_VREG(VREG_BASIC_CFG1, D32, 0);
|
||||
|
||||
D32 = (pVdhRegCfg->VdhAvmAddr) & 0xFFFFFFF0; // mpeg4 down msg
|
||||
WR_VREG(VREG_AVM_ADDR, D32, 0);
|
||||
|
||||
D32 = (pVdhRegCfg->VdhVamAddr) & 0xFFFFFFF0; // mpeg4 up msg
|
||||
WR_VREG(VREG_VAM_ADDR, D32, 0);
|
||||
|
||||
WR_VREG(VREG_STREAM_BASE_ADDR, pVdhRegCfg->VdhStreamBaseAddr, 0);
|
||||
|
||||
//EMAR_ADDR
|
||||
D32 = 0x101;
|
||||
|
||||
SlotWidth = pVdhRegCfg->VdhYstride / 8;
|
||||
if (SlotWidth > 1920)
|
||||
{
|
||||
D32 = D32 & (~(0x100));
|
||||
}
|
||||
else
|
||||
{
|
||||
D32 = D32 | (0x100);
|
||||
}
|
||||
|
||||
WR_SCDREG(REG_EMAR_ID, D32);
|
||||
|
||||
D32 = 0x00300C03;
|
||||
WR_VREG(VREG_SED_TO, D32, 0);
|
||||
WR_VREG(VREG_ITRANS_TO, D32, 0);
|
||||
WR_VREG(VREG_PMV_TO, D32, 0);
|
||||
WR_VREG(VREG_PRC_TO, D32, 0);
|
||||
WR_VREG(VREG_RCN_TO, D32, 0);
|
||||
WR_VREG(VREG_DBLK_TO, D32, 0);
|
||||
WR_VREG(VREG_PPFD_TO, D32, 0);
|
||||
|
||||
D32 = (pVdhRegCfg->VdhYstAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_YSTADDR_1D, D32, 0);
|
||||
|
||||
WR_VREG(VREG_YSTRIDE_1D, pVdhRegCfg->VdhYstride, 0);
|
||||
|
||||
WR_VREG(VREG_UVOFFSET_1D, pVdhRegCfg->VdhUvoffset, 0);
|
||||
|
||||
D32 = 0;
|
||||
WR_VREG(VREG_FF_APT_EN, D32, 0);
|
||||
|
||||
WR_VREG( VREG_UVSTRIDE_1D, pVdhRegCfg->VdhUvstride, 0 );
|
||||
|
||||
D32 = 0x03;
|
||||
WR_VREG(VREG_DDR_INTERLEAVE_MODE, D32, 0);
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
|
||||
int MP4HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = MP4HAL_CfgReg(pVdhRegCfg);
|
||||
if (ret != VDMHAL_OK) {
|
||||
printk(KERN_ERR "MP4 register config failed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _VDM_HAL_MPEG4_HEADER_
|
||||
#define _VDM_HAL_MPEG4_HEADER_
|
||||
|
||||
#include "mem_manage.h"
|
||||
//#include "memory.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
int MP4HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
#endif
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* vdec hal for vp8
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#ifndef __VDM_HAL_VP8_C__
|
||||
#define __VDM_HAL_VP8_C__
|
||||
|
||||
//#include "public.h"
|
||||
#include "vdm_hal.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vdm_hal_vp8.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
static int VP8HAL_CfgReg(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
unsigned int D32;
|
||||
|
||||
//BASIC_CFG0
|
||||
D32 = 0;
|
||||
((BASIC_CFG0 *)(&D32))->mbamt_to_dec = ((BASIC_CFG0 *)(&pVdhRegCfg->VdhBasicCfg0))->mbamt_to_dec;
|
||||
((BASIC_CFG0 *)(&D32))->load_qmatrix_flag = 0;
|
||||
((BASIC_CFG0 *)(&D32))->sec_mode_en = 0;
|
||||
WR_VREG( VREG_BASIC_CFG0, D32, 0);
|
||||
|
||||
//BASIC_CFG1
|
||||
/*set uv order 0: v first; 1: u first */
|
||||
D32 = 0x20000000;
|
||||
((BASIC_CFG1 *)(&D32))->video_standard = 0x0C;
|
||||
//((BASIC_CFG1 *)(&D32))->ddr_stride = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->ddr_stride;
|
||||
((BASIC_CFG1 *)(&D32))->fst_slc_grp = 1;
|
||||
((BASIC_CFG1 *)(&D32))->mv_output_en = 1;
|
||||
((BASIC_CFG1 *)(&D32))->uv_order_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->uv_order_en;
|
||||
((BASIC_CFG1 *)(&D32))->vdh_2d_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->vdh_2d_en;
|
||||
((BASIC_CFG1 *)(&D32))->max_slcgrp_num = 0;
|
||||
((BASIC_CFG1 *)(&D32))->compress_en = ((BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->compress_en;
|
||||
((BASIC_CFG1 *)(&D32))->ppfd_en = 0;
|
||||
WR_VREG( VREG_BASIC_CFG1, D32, 0);
|
||||
|
||||
//AVM_ADDR
|
||||
D32 = 0;
|
||||
((AVM_ADDR *)(&D32))->av_msg_addr = (pVdhRegCfg->VdhAvmAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_AVM_ADDR, D32, 0);
|
||||
|
||||
//VAM_ADDR
|
||||
D32 = 0;
|
||||
((VAM_ADDR *)(&D32))->va_msg_addr = (pVdhRegCfg->VdhVamAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_VAM_ADDR, D32, 0);
|
||||
|
||||
//STREAM_BASE_ADDR
|
||||
WR_VREG(VREG_STREAM_BASE_ADDR, pVdhRegCfg->VdhStreamBaseAddr, 0);
|
||||
|
||||
//EMAR_ADDR
|
||||
D32 = 0x101;
|
||||
WR_SCDREG(REG_EMAR_ID, D32);
|
||||
|
||||
//YSTADDR_1D
|
||||
D32 = 0;
|
||||
((YSTADDR_1D *)(&D32))->ystaddr_1d = (pVdhRegCfg->VdhYstAddr) & 0xFFFFFFF0; //caution
|
||||
WR_VREG(VREG_YSTADDR_1D, D32, 0);
|
||||
|
||||
//YSTRIDE_1D
|
||||
WR_VREG(VREG_YSTRIDE_1D, pVdhRegCfg->VdhYstride, 0);
|
||||
|
||||
//UVOFFSET_1D
|
||||
WR_VREG(VREG_UVOFFSET_1D, pVdhRegCfg->VdhUvoffset, 0);
|
||||
|
||||
D32 = 0;
|
||||
WR_VREG(VREG_HEAD_INF_OFFSET, D32, 0);
|
||||
|
||||
WR_VREG( VREG_UVSTRIDE_1D, pVdhRegCfg->VdhUvstride, 0 );
|
||||
|
||||
WR_VREG(VREG_CFGINFO_ADDR, pVdhRegCfg->VdhCfgInfoAddr, 0);
|
||||
|
||||
D32 = 0x03;
|
||||
WR_VREG(VREG_DDR_INTERLEAVE_MODE, D32, 0);
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
int VP8HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int Ret;
|
||||
|
||||
Ret = VP8HAL_CfgReg(pVdhRegCfg);
|
||||
if (Ret != VDMHAL_OK) {
|
||||
printk(KERN_ERR "VP8 register config failed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef __VDM_HAL_VP8_HERAER__
|
||||
#define __VDM_HAL_VP8_HERAER__
|
||||
|
||||
//#include "memory.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
int VP8HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
#endif
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/*!!Warning: Huawei key information asset. No spread without permission. */
|
||||
/*CODEMARK:EG4uRhTwMmgcVFBsBnYHCDadN5jJKSuVyxmmaCmKFU6eJEbB2fyHF9weu4/jer/hxLHb+S1e
|
||||
E0zVg4C3NiZh4Rryzsvo1gOdvy7M+qFCBFQKTTAFAVC3Q4e533WXdeQrddo4r2cqTmRg3Xeb
|
||||
SI3trXaSV012ETxvJrJ/pkfs27/lT6wemL9iW3PaGW8//pmW7hQ7qCDBgWp7sMvcMuyYAWRh
|
||||
jMb6+4xlgVl55z+iUl5XDCi0pMRG2hXB2hXZd5i/HJastZrWJFR4dVOatPlImg==#*/
|
||||
/*--!!Warning: Deleting or modifying the preceding information is prohibited.--*/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
版权所有 (C), 2001-2015, 华为技术有限公司
|
||||
|
||||
******************************************************************************
|
||||
文 件 名 : vdm_hal_vp9.c
|
||||
版 本 号 : 初稿
|
||||
作 者 : z00290437
|
||||
生成日期: 2015-02-03
|
||||
最近修改 :
|
||||
功能描述 : VDMV300 硬件抽象
|
||||
|
||||
修改历史 :
|
||||
1.日 期 :
|
||||
2.作 者 :
|
||||
3.修改内容:
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __VDM_HAL_VP9_C__
|
||||
#define __VDM_HAL_VP9_C__
|
||||
|
||||
//#include "public.h"
|
||||
#include "vdm_hal.h"
|
||||
#include "vdm_hal_api.h"
|
||||
#include "vdm_hal_local.h"
|
||||
#include "vdm_hal_vp9.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
static int VP9HAL_CfgReg(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
unsigned int D32;
|
||||
|
||||
//BASIC_CFG0
|
||||
D32 = 0;
|
||||
((BASIC_CFG0*)(&D32))->mbamt_to_dec = ((BASIC_CFG0 *)(&pVdhRegCfg->VdhBasicCfg0))->mbamt_to_dec;
|
||||
((BASIC_CFG0*)(&D32))->load_qmatrix_flag = 0;
|
||||
//((BASIC_CFG0*)(&D32))->repair_en = 0;
|
||||
|
||||
WR_VREG(VREG_BASIC_CFG0, D32, 0);
|
||||
|
||||
//BASIC_CFG1
|
||||
D32 = 0;
|
||||
((VP9_BASIC_CFG1*)(&D32))->video_standard = 0x0E; //VFMW_VP9;
|
||||
// ((VP9_BASIC_CFG1*)(&D32))->ddr_stride = pVp9DecParam->ddr_stride >> 6;
|
||||
((VP9_BASIC_CFG1*)(&D32))->uv_order_en = ((VP9_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->uv_order_en;
|
||||
((VP9_BASIC_CFG1*)(&D32))->fst_slc_grp = 1;
|
||||
((VP9_BASIC_CFG1*)(&D32))->mv_output_en = 1;
|
||||
((VP9_BASIC_CFG1*)(&D32))->max_slcgrp_num = 3;
|
||||
((VP9_BASIC_CFG1*)(&D32))->line_num_output_en = 0;
|
||||
// ((BASIC_CFG1*)(&D32))->compress_en = pVp9DecParam->Compress_en;
|
||||
((VP9_BASIC_CFG1*)(&D32))->vdh_2d_en = ((VP9_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->vdh_2d_en; ////1; by j00367396
|
||||
((VP9_BASIC_CFG1*)(&D32))->frm_cmp_en = ((VP9_BASIC_CFG1 *)(&pVdhRegCfg->VdhBasicCfg1))->frm_cmp_en; //for tmp linear
|
||||
((VP9_BASIC_CFG1*)(&D32))->ppfd_en = 0;
|
||||
|
||||
WR_VREG(VREG_BASIC_CFG1, D32, 0);
|
||||
|
||||
//AVM_ADDR
|
||||
D32 = 0;
|
||||
((AVM_ADDR*)(&D32))->av_msg_addr = (pVdhRegCfg->VdhAvmAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_AVM_ADDR, D32, 0);
|
||||
|
||||
//VAM_ADDR
|
||||
D32 = 0;
|
||||
((VAM_ADDR*)(&D32))->va_msg_addr = (pVdhRegCfg->VdhVamAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_VAM_ADDR, D32, 0);
|
||||
|
||||
//STREAM_BASE_ADDR
|
||||
WR_VREG(VREG_STREAM_BASE_ADDR, pVdhRegCfg->VdhStreamBaseAddr, 0);
|
||||
|
||||
//PRC_CACHE_TYPE
|
||||
D32 = 0x0;
|
||||
WR_VREG(VREG_FF_APT_EN, D32, 0);
|
||||
|
||||
//EMAR_ADDR
|
||||
D32 = 0x101;
|
||||
WR_SCDREG(REG_EMAR_ID, D32);
|
||||
|
||||
//TIME_OUT
|
||||
D32 = 0x00300C03;
|
||||
WR_VREG(VREG_SED_TO, D32, 0);
|
||||
WR_VREG(VREG_ITRANS_TO, D32, 0);
|
||||
WR_VREG(VREG_PMV_TO, D32, 0);
|
||||
WR_VREG(VREG_PRC_TO, D32, 0);
|
||||
WR_VREG(VREG_RCN_TO, D32, 0);
|
||||
WR_VREG(VREG_DBLK_TO, D32, 0);
|
||||
WR_VREG(VREG_PPFD_TO, D32, 0);
|
||||
|
||||
//DEC_OVER_INT_LEVEL
|
||||
D32 = 60;
|
||||
WR_VREG(VREG_PART_DEC_OVER_INT_LEVEL, D32, 0);
|
||||
|
||||
//YSTADDR_1D
|
||||
D32 = 0;
|
||||
((YSTADDR_1D *)(&D32))->ystaddr_1d = (pVdhRegCfg->VdhYstAddr) & 0xFFFFFFF0;
|
||||
WR_VREG(VREG_YSTADDR_1D, D32, 0);
|
||||
|
||||
//YSTRIDE_1D
|
||||
WR_VREG(VREG_YSTRIDE_1D, pVdhRegCfg->VdhYstride, 0);
|
||||
|
||||
//UVOFFSET_1D
|
||||
WR_VREG(VREG_UVOFFSET_1D, pVdhRegCfg->VdhUvoffset, 0);
|
||||
|
||||
//UVSTRIDE_1D
|
||||
WR_VREG(VREG_UVSTRIDE_1D, pVdhRegCfg->VdhUvstride, 0);
|
||||
|
||||
//CFGINFO_ADDR
|
||||
WR_VREG(VREG_CFGINFO_ADDR, pVdhRegCfg->VdhCfgInfoAddr, 0);
|
||||
|
||||
//DDR_INTERLEAVE_MODE
|
||||
D32 = 0x3;
|
||||
WR_VREG(VREG_DDR_INTERLEAVE_MODE, D32, 0);
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
int VP9HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg)
|
||||
{
|
||||
int Ret;
|
||||
|
||||
Ret = VP9HAL_CfgReg(pVdhRegCfg);
|
||||
if (Ret != VDMHAL_OK) {
|
||||
printk(KERN_ERR "VP9 register config failed\n");
|
||||
return VDMHAL_ERR;
|
||||
}
|
||||
|
||||
return VDMHAL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
#ifndef __VDM_HAL_VP9_H__
|
||||
#define __VDM_HAL_VP9_H__
|
||||
|
||||
//#include "memory.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
int VP9HAL_StartDec(OMXVDH_REG_CFG_S *pVdhRegCfg);
|
||||
#endif //__VDM_HAL_AVS_H__
|
||||
+408
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* osal
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
//#include "public.h"
|
||||
#include "linux_kernel_osal.h"
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
|
||||
/* SpinLock */
|
||||
OSAL_IRQ_SPIN_LOCK g_SpinLock_SCD;
|
||||
OSAL_IRQ_SPIN_LOCK g_SpinLock_VDH;
|
||||
OSAL_IRQ_SPIN_LOCK g_SpinLock_Record;
|
||||
|
||||
/* Mutext */
|
||||
OSAL_TASK_MUTEX g_IntEvent;
|
||||
|
||||
OSAL_TASK_MUTEX g_ScdHwDoneEvent;
|
||||
OSAL_TASK_MUTEX g_VdmHwDoneEvent;
|
||||
|
||||
/* Semaphore */
|
||||
OSAL_SEMA g_SCDSem;
|
||||
OSAL_SEMA g_VDHSem;
|
||||
OSAL_SEMA g_BPDSem;
|
||||
|
||||
/* Extern */
|
||||
extern Vfmw_Osal_Func_Ptr g_vfmw_osal_fun_ptr;
|
||||
|
||||
#define OSAL_Print printk
|
||||
#define MAX_WAIT_EVENT_CNT 100
|
||||
#define TIME_PERIOD(begin, end) ((end >= begin) ? (end - begin) : (0xffffffff - begin + end))
|
||||
|
||||
unsigned int OSAL_GetTimeInMs(void)
|
||||
{
|
||||
unsigned long long SysTime;
|
||||
|
||||
SysTime = sched_clock();
|
||||
do_div(SysTime, 1000000);
|
||||
|
||||
return (unsigned int) SysTime;
|
||||
}
|
||||
|
||||
unsigned int OSAL_GetTimeInUs(void)
|
||||
{
|
||||
unsigned long long SysTime;
|
||||
|
||||
SysTime = sched_clock();
|
||||
do_div(SysTime, 1000);
|
||||
|
||||
return (unsigned int) SysTime;
|
||||
}
|
||||
|
||||
static inline int OSAL_InitEvent(OSAL_EVENT *pEvent, int InitVal)
|
||||
{
|
||||
pEvent->flag = InitVal;
|
||||
init_waitqueue_head(&(pEvent->queue_head));
|
||||
return OSAL_OK;
|
||||
}
|
||||
|
||||
static inline int OSAL_GiveEvent(OSAL_EVENT *pEvent)
|
||||
{
|
||||
pEvent->flag = 1;
|
||||
wake_up_interruptible(&(pEvent->queue_head));
|
||||
|
||||
return OSAL_OK;
|
||||
}
|
||||
|
||||
static inline int OSAL_WaitEvent(OSAL_EVENT *pEvent, int msWaitTime)
|
||||
{
|
||||
int ret;
|
||||
unsigned int cnt = 0;
|
||||
|
||||
unsigned int start_time, cur_time;
|
||||
start_time = VFMW_OSAL_GetTimeInMs();
|
||||
|
||||
do {
|
||||
ret = wait_event_interruptible_timeout((pEvent->queue_head), (pEvent->flag != 0), (msecs_to_jiffies(msWaitTime)));/*lint !e666*/
|
||||
if (ret < 0) {
|
||||
cur_time = VFMW_OSAL_GetTimeInMs();
|
||||
if (TIME_PERIOD(start_time, cur_time) > (unsigned int)msWaitTime) {
|
||||
printk(KERN_CRIT "wait event time out, time : %d, cnt: %d\n", TIME_PERIOD(start_time, cur_time), cnt);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
} while ((pEvent->flag == 0) && (ret < 0));
|
||||
|
||||
if (cnt > MAX_WAIT_EVENT_CNT) {
|
||||
printk(KERN_CRIT "the max cnt of wait_event interrupts by singal is %d\n", cnt);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
printk(KERN_CRIT "wait pEvent signal timeout\n");
|
||||
}
|
||||
|
||||
pEvent->flag = 0; //(pEvent->flag>0)? (pEvent->flag-1): 0;
|
||||
|
||||
return (ret != 0) ? OSAL_OK : OSAL_ERR;
|
||||
}
|
||||
|
||||
unsigned char *OSAL_RegisterMap(unsigned int PhyAddr, unsigned int Size)
|
||||
{
|
||||
return (unsigned char *) ioremap_nocache(PhyAddr, Size);
|
||||
}
|
||||
|
||||
void OSAL_RegisterUnMap(unsigned char *VirAddr, unsigned int Size)
|
||||
{
|
||||
iounmap(VirAddr);
|
||||
return;
|
||||
}
|
||||
|
||||
int OSAL_FileWrite(char *buf, int len, struct file *filp)
|
||||
{
|
||||
int writelen;
|
||||
mm_segment_t oldfs;
|
||||
|
||||
if (filp == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
if (filp->f_op->write == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
if (((filp->f_flags & O_ACCMODE) & (O_WRONLY | O_RDWR)) == 0)
|
||||
return -EACCES;
|
||||
|
||||
oldfs = get_fs();
|
||||
set_fs(KERNEL_DS);/*lint !e501*/
|
||||
writelen = filp->f_op->write(filp, buf, len, &filp->f_pos);
|
||||
set_fs(oldfs);
|
||||
|
||||
return writelen;
|
||||
}
|
||||
|
||||
static inline void OSAL_SEMA_INTIT(OSAL_SEMA *pSem)
|
||||
{
|
||||
sema_init(pSem, 1);
|
||||
}
|
||||
|
||||
static inline int OSAL_DOWN_INTERRUPTIBLE(OSAL_SEMA *pSem)
|
||||
{
|
||||
return down_interruptible(pSem);
|
||||
}
|
||||
|
||||
static inline void OSAL_UP(OSAL_SEMA *pSem)
|
||||
{
|
||||
up(pSem);
|
||||
}
|
||||
|
||||
static inline void OSAL_SpinLockIRQInit(OSAL_IRQ_SPIN_LOCK *pIntrMutex)
|
||||
{
|
||||
spin_lock_init(&pIntrMutex->irq_lock);
|
||||
pIntrMutex->isInit = 1;
|
||||
}
|
||||
|
||||
static inline int OSAL_SpinLockIRQ(OSAL_IRQ_SPIN_LOCK *pIntrMutex)
|
||||
{
|
||||
if (pIntrMutex->isInit == 0) {
|
||||
spin_lock_init(&pIntrMutex->irq_lock);
|
||||
pIntrMutex->isInit = 1;
|
||||
}
|
||||
spin_lock_irqsave(&pIntrMutex->irq_lock, pIntrMutex->irq_lockflags);
|
||||
|
||||
return OSAL_OK;
|
||||
}
|
||||
|
||||
static inline int OSAL_SpinUnLockIRQ(OSAL_IRQ_SPIN_LOCK *pIntrMutex)
|
||||
{
|
||||
spin_unlock_irqrestore(&pIntrMutex->irq_lock, pIntrMutex->irq_lockflags);
|
||||
|
||||
return OSAL_OK;
|
||||
}
|
||||
|
||||
void OSAL_Mb(void)
|
||||
{
|
||||
mb();
|
||||
}
|
||||
|
||||
void OSAL_uDelay(unsigned long usecs)
|
||||
{
|
||||
udelay(usecs);
|
||||
}
|
||||
|
||||
void OSAL_mSleep(unsigned int msecs)
|
||||
{
|
||||
msleep(msecs);
|
||||
}
|
||||
|
||||
int OSAL_RequestIrq(unsigned int irq, OSAL_IRQ_HANDLER_t handler, unsigned long flags, const char *name, void *dev)
|
||||
{
|
||||
return request_irq(irq, (irq_handler_t) handler, flags, name, dev);
|
||||
}
|
||||
|
||||
void OSAL_FreeIrq(unsigned int irq, void *dev)
|
||||
{
|
||||
free_irq(irq, dev);
|
||||
}
|
||||
|
||||
void *OSAL_AllocVirMem(int Size)
|
||||
{
|
||||
return vmalloc(Size);
|
||||
}
|
||||
|
||||
void OSAL_FreeVirMem(void *p)
|
||||
{
|
||||
if (p)
|
||||
vfree(p);
|
||||
}
|
||||
|
||||
OSAL_IRQ_SPIN_LOCK *GetSpinLockByEnum(SpinLockType LockType)
|
||||
{
|
||||
OSAL_IRQ_SPIN_LOCK *pSpinLock = NULL;
|
||||
|
||||
switch (LockType) {
|
||||
case G_SPINLOCK_SCD:
|
||||
pSpinLock = &g_SpinLock_SCD;
|
||||
break;
|
||||
|
||||
case G_SPINLOCK_RECORD:
|
||||
pSpinLock = &g_SpinLock_Record;
|
||||
break;
|
||||
|
||||
case G_SPINLOCK_VDH:
|
||||
pSpinLock = &g_SpinLock_VDH;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s unkown SpinLockType %d\n", __func__, LockType);
|
||||
break;
|
||||
}
|
||||
|
||||
return pSpinLock;
|
||||
}
|
||||
|
||||
void OSAL_SpinLockInit(SpinLockType LockType)
|
||||
{
|
||||
OSAL_IRQ_SPIN_LOCK *pSpinLock = NULL;
|
||||
|
||||
pSpinLock = GetSpinLockByEnum(LockType);
|
||||
|
||||
OSAL_SpinLockIRQInit(pSpinLock);
|
||||
}
|
||||
|
||||
int OSAL_SpinLock(SpinLockType LockType)
|
||||
{
|
||||
OSAL_IRQ_SPIN_LOCK *pSpinLock = NULL;
|
||||
|
||||
pSpinLock = GetSpinLockByEnum(LockType);
|
||||
|
||||
return OSAL_SpinLockIRQ(pSpinLock);
|
||||
}
|
||||
|
||||
int OSAL_SpinUnLock(SpinLockType LockType)
|
||||
{
|
||||
OSAL_IRQ_SPIN_LOCK *pSpinLock = NULL;
|
||||
|
||||
pSpinLock = GetSpinLockByEnum(LockType);
|
||||
|
||||
return OSAL_SpinUnLockIRQ(pSpinLock);
|
||||
}
|
||||
|
||||
OSAL_SEMA *GetSemByEnum(SemType Sem)
|
||||
{
|
||||
OSAL_SEMA *pSem = NULL;
|
||||
|
||||
switch (Sem) {
|
||||
case G_SCD_SEM:
|
||||
pSem = &g_SCDSem;
|
||||
break;
|
||||
|
||||
case G_VDH_SEM:
|
||||
pSem = &g_VDHSem;
|
||||
break;
|
||||
|
||||
case G_BPD_SEM:
|
||||
pSem = &g_BPDSem;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s unkown SemType %d\n", __func__, Sem);
|
||||
break;
|
||||
}
|
||||
|
||||
return pSem;
|
||||
}
|
||||
|
||||
void OSAL_SemInit(SemType Sem)
|
||||
{
|
||||
OSAL_SEMA *pSem = NULL;
|
||||
|
||||
pSem = GetSemByEnum(Sem);
|
||||
|
||||
OSAL_SEMA_INTIT(pSem);
|
||||
}
|
||||
|
||||
int OSAL_SemDown(SemType Sem)
|
||||
{
|
||||
OSAL_SEMA *pSem = NULL;
|
||||
|
||||
pSem = GetSemByEnum(Sem);
|
||||
|
||||
return OSAL_DOWN_INTERRUPTIBLE(pSem);
|
||||
}
|
||||
|
||||
void OSAL_SemUp(SemType Sem)
|
||||
{
|
||||
OSAL_SEMA *pSem = NULL;
|
||||
|
||||
pSem = GetSemByEnum(Sem);
|
||||
|
||||
OSAL_UP(pSem);
|
||||
}
|
||||
|
||||
int OSAL_InitWaitQue(MutexType mutextType, int initVal)
|
||||
{
|
||||
int retVal = OSAL_ERR;
|
||||
|
||||
switch (mutextType) {
|
||||
case G_SCDHWDONEEVENT:
|
||||
retVal = OSAL_InitEvent(&g_ScdHwDoneEvent, initVal);
|
||||
break;
|
||||
|
||||
case G_VDMHWDONEEVENT:
|
||||
retVal = OSAL_InitEvent(&g_VdmHwDoneEvent, initVal);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int OSAL_WakeupWaitQue(MutexType mutexType)
|
||||
{
|
||||
int retVal = OSAL_ERR;
|
||||
|
||||
switch (mutexType) {
|
||||
case G_SCDHWDONEEVENT:
|
||||
retVal = OSAL_GiveEvent(&g_ScdHwDoneEvent);
|
||||
break;
|
||||
|
||||
case G_VDMHWDONEEVENT:
|
||||
retVal = OSAL_GiveEvent(&g_VdmHwDoneEvent);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int OSAL_WaitWaitQue(MutexType mutexType, int waitTimeInMs)
|
||||
{
|
||||
int retVal = OSAL_ERR;
|
||||
|
||||
switch (mutexType) {
|
||||
case G_SCDHWDONEEVENT:
|
||||
retVal = OSAL_WaitEvent(&g_ScdHwDoneEvent, waitTimeInMs);
|
||||
break;
|
||||
|
||||
case G_VDMHWDONEEVENT:
|
||||
retVal = OSAL_WaitEvent(&g_VdmHwDoneEvent, waitTimeInMs);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void OSAL_InitInterface(void)
|
||||
{
|
||||
memset(&g_vfmw_osal_fun_ptr, 0, sizeof(g_vfmw_osal_fun_ptr));
|
||||
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_GetTimeInMs = OSAL_GetTimeInMs;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_GetTimeInUs = OSAL_GetTimeInUs;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_SpinLockInit = OSAL_SpinLockInit;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_SpinLock = OSAL_SpinLock;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_SpinUnLock = OSAL_SpinUnLock;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_SemaInit = OSAL_SemInit;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_SemaDown = OSAL_SemDown;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_SemaUp = OSAL_SemUp;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_Print = OSAL_Print;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_mSleep = OSAL_mSleep;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_Mb = OSAL_Mb;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_uDelay = OSAL_uDelay;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_InitEvent = OSAL_InitWaitQue;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_GiveEvent = OSAL_WakeupWaitQue;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_WaitEvent = OSAL_WaitWaitQue;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_RequestIrq = OSAL_RequestIrq;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_FreeIrq = OSAL_FreeIrq;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_RegisterMap = OSAL_RegisterMap;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_RegisterUnMap = OSAL_RegisterUnMap;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_AllocVirMem = OSAL_AllocVirMem;
|
||||
g_vfmw_osal_fun_ptr.pfun_Osal_FreeVirMem = OSAL_FreeVirMem;
|
||||
}
|
||||
|
||||
#endif
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
|
||||
#ifndef __VFMW_LINUX_KERNEL_OSAL_HEADER__
|
||||
#define __VFMW_LINUX_KERNEL_OSAL_HEADER__
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/version.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/ioctl.h>
|
||||
#include <linux/semaphore.h>
|
||||
|
||||
#include "vfmw_osal_ext.h"
|
||||
|
||||
/*======================================================================*/
|
||||
/* struct define */
|
||||
/*======================================================================*/
|
||||
typedef struct hiKERN_EVENT_S {
|
||||
wait_queue_head_t queue_head;
|
||||
int flag;
|
||||
} OSAL_EVENT;
|
||||
|
||||
typedef struct hiKERN_IRQ_LOCK_S {
|
||||
spinlock_t irq_lock;
|
||||
unsigned long irq_lockflags;
|
||||
int isInit;
|
||||
} OSAL_IRQ_SPIN_LOCK;
|
||||
|
||||
/*======================================================================*/
|
||||
/* define */
|
||||
/*======================================================================*/
|
||||
typedef struct task_struct* OSAL_TASK;
|
||||
typedef struct file OSAL_FILE;
|
||||
typedef struct semaphore OSAL_SEMA;
|
||||
typedef OSAL_EVENT OSAL_TASK_MUTEX;
|
||||
|
||||
|
||||
/*======================================================================*/
|
||||
/* function declare */
|
||||
/*======================================================================*/
|
||||
|
||||
/************************************************************************/
|
||||
/* time: get in ms/us */
|
||||
/************************************************************************/
|
||||
unsigned int OSAL_GetTimeInMs(void);
|
||||
unsigned int OSAL_GetTimeInUs(void);
|
||||
|
||||
/************************************************************************/
|
||||
/* file: open/close/read/write */
|
||||
/************************************************************************/
|
||||
int OSAL_FileWrite(char *buf, int len, struct file *filp);
|
||||
|
||||
/************************************************************************/
|
||||
/* linux kernel osal function pointer initialize */
|
||||
/************************************************************************/
|
||||
void OSAL_InitInterface(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* vdec mem_manager
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include "mem_manage.h"
|
||||
#include "sysconfig.h"
|
||||
#include "vfmw_osal_ext.h"
|
||||
//#include "public.h"
|
||||
#include "linux_kernel_osal.h"
|
||||
|
||||
#define MAX_MEM_MAN_RECORD_NUM (MAX_CHAN_NUM*32)
|
||||
MEM_RECORD_S s_MemRecord[MAX_MEM_MAN_RECORD_NUM];
|
||||
|
||||
void MEM_InitMemManager(void)
|
||||
{
|
||||
VFMW_OSAL_SpinLock(G_SPINLOCK_RECORD);
|
||||
|
||||
memset(s_MemRecord, 0, sizeof(s_MemRecord));
|
||||
|
||||
VFMW_OSAL_SpinUnLock(G_SPINLOCK_RECORD);
|
||||
|
||||
}
|
||||
|
||||
int MEM_AddMemRecord(unsigned int PhyAddr, void *VirAddr, unsigned int Length)
|
||||
{
|
||||
int i;
|
||||
char IsErrorFlag = 0;
|
||||
int TargetPos = -1;
|
||||
int ret = MEM_MAN_ERR;
|
||||
|
||||
VFMW_OSAL_SpinLock(G_SPINLOCK_RECORD);
|
||||
|
||||
for (i = 0; i < MAX_MEM_MAN_RECORD_NUM; i++) {
|
||||
if ((s_MemRecord[i].PhyAddr <= PhyAddr) && (PhyAddr < s_MemRecord[i].PhyAddr + s_MemRecord[i].Length)) {
|
||||
IsErrorFlag = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_MemRecord[i].Length == 0 && TargetPos == -1)
|
||||
TargetPos = i;
|
||||
}
|
||||
|
||||
if (IsErrorFlag == 1) {
|
||||
printk(KERN_CRIT "%s conflict occured\n ", __func__);
|
||||
ret = MEM_MAN_ERR;
|
||||
} else if (TargetPos == -1) {
|
||||
printk(KERN_CRIT "%s no free record slot\n ", __func__);
|
||||
ret = MEM_MAN_ERR;
|
||||
} else {
|
||||
s_MemRecord[TargetPos].PhyAddr = PhyAddr;
|
||||
s_MemRecord[TargetPos].VirAddr = VirAddr;
|
||||
s_MemRecord[TargetPos].Length = Length;
|
||||
ret = MEM_MAN_OK;
|
||||
}
|
||||
|
||||
VFMW_OSAL_SpinUnLock(G_SPINLOCK_RECORD);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MEM_DelMemRecord(unsigned int PhyAddr, void *VirAddr, unsigned int Length)
|
||||
{
|
||||
int i;
|
||||
|
||||
VFMW_OSAL_SpinLock(G_SPINLOCK_RECORD);
|
||||
for (i = 0; i < MAX_MEM_MAN_RECORD_NUM; i++) {
|
||||
if (s_MemRecord[i].Length == 0)
|
||||
continue;
|
||||
|
||||
if (PhyAddr == s_MemRecord[i].PhyAddr && VirAddr == s_MemRecord[i].VirAddr &&
|
||||
Length == s_MemRecord[i].Length) {
|
||||
s_MemRecord[i].Length = 0;
|
||||
s_MemRecord[i].PhyAddr = 0;
|
||||
s_MemRecord[i].VirAddr = 0;
|
||||
VFMW_OSAL_SpinUnLock(G_SPINLOCK_RECORD);
|
||||
|
||||
return MEM_MAN_OK;
|
||||
}
|
||||
}
|
||||
VFMW_OSAL_SpinUnLock(G_SPINLOCK_RECORD);
|
||||
|
||||
return MEM_MAN_ERR;
|
||||
}
|
||||
|
||||
void *MEM_Phy2Vir(unsigned int PhyAddr)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char *VirAddr = NULL;
|
||||
|
||||
for (i = 0; i < MAX_MEM_MAN_RECORD_NUM; i++) {
|
||||
if (s_MemRecord[i].Length == 0)
|
||||
continue;
|
||||
|
||||
if ((PhyAddr >= s_MemRecord[i].PhyAddr) && (PhyAddr < s_MemRecord[i].PhyAddr + s_MemRecord[i].Length)) {
|
||||
VirAddr = s_MemRecord[i].VirAddr + (PhyAddr - s_MemRecord[i].PhyAddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (void *) VirAddr;
|
||||
}
|
||||
|
||||
unsigned int MEM_Vir2Phy(unsigned char *VirAddr)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
unsigned int PhyAddr = 0;
|
||||
for (i = 0; i < MAX_MEM_MAN_RECORD_NUM; i++) {
|
||||
if (s_MemRecord[i].Length == 0)
|
||||
continue;
|
||||
|
||||
if ((VirAddr >= s_MemRecord[i].VirAddr) && (VirAddr < s_MemRecord[i].VirAddr + s_MemRecord[i].Length)) {
|
||||
PhyAddr = s_MemRecord[i].PhyAddr + (VirAddr - s_MemRecord[i].VirAddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return PhyAddr;
|
||||
}
|
||||
|
||||
void MEM_WritePhyWord(unsigned int PhyAddr, unsigned int Data32)
|
||||
{
|
||||
unsigned int *pDst;
|
||||
|
||||
pDst = (unsigned int *) MEM_Phy2Vir(PhyAddr);
|
||||
if (pDst != NULL)
|
||||
writel(Data32, pDst);
|
||||
}
|
||||
|
||||
unsigned int MEM_ReadPhyWord(unsigned int PhyAddr)
|
||||
{
|
||||
unsigned int *pDst;
|
||||
unsigned int Data32;
|
||||
|
||||
Data32 = 0;
|
||||
pDst = (unsigned int *) MEM_Phy2Vir(PhyAddr);
|
||||
if (pDst != NULL) {
|
||||
Data32 = readl((volatile unsigned int *)pDst);
|
||||
}
|
||||
|
||||
return Data32;
|
||||
}
|
||||
|
||||
int MEM_MapRegisterAddr(unsigned int RegStartPhyAddr, unsigned int RegByteLen, MEM_RECORD_S *pMemRecord)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
|
||||
if (pMemRecord == NULL || RegStartPhyAddr == 0 || RegByteLen == 0 || VFMW_OSAL_RegisterMap == NULL)
|
||||
return MEM_MAN_ERR;
|
||||
|
||||
memset(pMemRecord, 0, sizeof(*pMemRecord));
|
||||
|
||||
ptr = VFMW_OSAL_RegisterMap(RegStartPhyAddr, RegByteLen);
|
||||
|
||||
if (ptr != NULL) {
|
||||
pMemRecord->PhyAddr = RegStartPhyAddr;
|
||||
pMemRecord->VirAddr = ptr;
|
||||
pMemRecord->Length = RegByteLen;
|
||||
return MEM_MAN_OK;
|
||||
}
|
||||
|
||||
return MEM_MAN_ERR;
|
||||
}
|
||||
|
||||
void MEM_UnmapRegisterAddr(unsigned int PhyAddr, unsigned char *VirAddr, unsigned int Size)
|
||||
{
|
||||
if (PhyAddr == 0 || VirAddr == 0 || VFMW_OSAL_RegisterUnMap == NULL)
|
||||
return;
|
||||
|
||||
VFMW_OSAL_RegisterUnMap(VirAddr, Size);
|
||||
|
||||
return;
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#ifndef _VFMW_MEM_MANAGE_HEAD_
|
||||
#define _VFMW_MEM_MANAGE_HEAD_
|
||||
|
||||
#include "vfmw.h"
|
||||
|
||||
#define MEM_MAN_ERR -1
|
||||
#define MEM_MAN_OK 0
|
||||
|
||||
typedef struct {
|
||||
unsigned int PhyAddr;
|
||||
unsigned int Length;
|
||||
int IsSecMem;
|
||||
unsigned char *VirAddr;
|
||||
} MEM_RECORD_S;
|
||||
|
||||
void MEM_InitMemManager(void);
|
||||
|
||||
int MEM_AddMemRecord(unsigned int PhyAddr, void *VirAddr, unsigned int Length);
|
||||
|
||||
int MEM_DelMemRecord(unsigned int PhyAddr, void *VirAddr, unsigned int Length);
|
||||
|
||||
void *MEM_Phy2Vir(unsigned int PhyAddr);
|
||||
|
||||
unsigned int MEM_Vir2Phy(unsigned char *VirAddr);
|
||||
|
||||
void MEM_WritePhyWord(unsigned int PhyAddr, unsigned int Data32);
|
||||
|
||||
unsigned int MEM_ReadPhyWord(unsigned int PhyAddr);
|
||||
|
||||
int MEM_MapRegisterAddr(unsigned int RegStartPhyAddr, unsigned int RegByteLen, MEM_RECORD_S *pMemRecord);
|
||||
|
||||
void MEM_UnmapRegisterAddr(unsigned int PhyAddr, unsigned char *VirAddr, unsigned int Size);
|
||||
|
||||
#endif
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#ifndef __PUBLIC_H__
|
||||
#define __PUBLIC_H__
|
||||
|
||||
#include "vfmw.h"
|
||||
|
||||
/* 0X0 : ALWYS, 0X1: ALWYS and FATAL, 0X3: ALWYS and FATAL and ERROR */
|
||||
#define DEFAULT_PRINT_ENABLE (0x3)
|
||||
|
||||
typedef enum {
|
||||
DEV_SCREEN = 1,
|
||||
DEV_SYSLOG,
|
||||
DEV_FILE,
|
||||
DEV_MEM
|
||||
} PRINT_DEVICE_TYPE;
|
||||
|
||||
|
||||
#if 0
|
||||
#define dprint_vfmw_nothing(type, fmt, arg...) ({do{}while(0);0;})
|
||||
|
||||
#define dprint_sos_kernel(type, fmt, arg...) \
|
||||
do{ \
|
||||
if ((PRN_ALWS == type) || (0 != (DEFAULT_PRINT_ENABLE & (1LL << type)))) \
|
||||
{ \
|
||||
printk(KERN_ALERT "VDEC S: "fmt, ##arg); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#define dprint_linux_kernel(type, fmt, arg...) \
|
||||
do{ \
|
||||
if ((PRN_ALWS == type) || (0 != (DEFAULT_PRINT_ENABLE & (1LL << type)))) \
|
||||
{ \
|
||||
printk(KERN_ALERT "VDEC : "fmt, ##arg); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#ifdef HI_ADVCA_FUNCTION_RELEASE
|
||||
#define dprint(type, fmt, arg...) dprint_vfmw_nothing(type, fmt, ##arg)
|
||||
#else
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
#define dprint(type, fmt, arg...) dprint_linux_kernel(type, fmt, ##arg)
|
||||
#else
|
||||
#define dprint(type, fmt, arg...) dprint_vfmw_nothing(type, fmt, ##arg)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#else
|
||||
#ifdef HI_ADVCA_FUNCTION_RELEASE
|
||||
#define dprint(type, fmt, arg...)
|
||||
#else
|
||||
//#define dprint(type, fmt, arg...) printk(type fmt, ##arg)
|
||||
#define dprint(type, fmt, arg...)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
+261
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* vdec driver for scd master
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
//#include "public.h"
|
||||
#include "scd_drv.h"
|
||||
#include "vfmw_intf.h"
|
||||
#include "linux_kernel_osal.h"
|
||||
#include "./format/vdm_hal_api.h"
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
#include "smmu.h"
|
||||
#endif
|
||||
|
||||
static SCDDRV_SLEEP_STAGE_E s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_NONE;
|
||||
static SCD_STATE_REG_S gScdStateReg;
|
||||
static SCD_STATE_E s_SCDState = SCD_IDLE;
|
||||
|
||||
static void PrintScdVtrlReg(void);
|
||||
|
||||
int SCDDRV_ResetSCD(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
unsigned int i;
|
||||
unsigned int reg_rst_ok;
|
||||
unsigned int reg;
|
||||
unsigned int *pScdResetReg = NULL;
|
||||
unsigned int *pScdResetOkReg = NULL;
|
||||
|
||||
pScdResetReg = (unsigned int *) MEM_Phy2Vir(gSOFTRST_REQ_Addr);
|
||||
pScdResetOkReg = (unsigned int *) MEM_Phy2Vir(gSOFTRST_OK_ADDR);
|
||||
|
||||
if (pScdResetReg == NULL || pScdResetOkReg == NULL) {
|
||||
printk(KERN_CRIT "scd reset register map fail\n");
|
||||
return VF_ERR_SYS;
|
||||
}
|
||||
|
||||
tmp = RD_SCDREG(REG_SCD_INT_MASK);
|
||||
|
||||
|
||||
reg = *(volatile unsigned int *)pScdResetReg;
|
||||
*(volatile unsigned int *)pScdResetReg = reg | (unsigned int) (1 << SCD_RESET_CTRL_BIT);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
reg_rst_ok = *(volatile unsigned int *)pScdResetOkReg;
|
||||
if (reg_rst_ok & (1 << SCD_RESET_OK_BIT))
|
||||
break;
|
||||
VFMW_OSAL_uDelay(10);
|
||||
}
|
||||
|
||||
if (i >= 100)
|
||||
printk(KERN_CRIT "%s reset failed\n", __func__);
|
||||
else
|
||||
printk(KERN_INFO "%s reset success\n", __func__);
|
||||
|
||||
*(volatile unsigned int *)pScdResetReg = reg & (unsigned int) (~(1 << SCD_RESET_CTRL_BIT));
|
||||
|
||||
|
||||
WR_SCDREG(REG_SCD_INT_MASK, tmp);
|
||||
|
||||
s_SCDState = SCD_IDLE;
|
||||
return FMW_OK;
|
||||
}
|
||||
|
||||
int SCDDRV_PrepareSleep(void)
|
||||
{
|
||||
int ret = SCDDRV_OK;
|
||||
|
||||
VFMW_OSAL_SemaDown(G_SCD_SEM);
|
||||
if (s_eScdDrvSleepStage == SCDDRV_SLEEP_STAGE_NONE) {
|
||||
if (SCD_IDLE == s_SCDState) {
|
||||
printk(KERN_INFO "%s, idle state \n", __func__);
|
||||
s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_SLEEP;
|
||||
} else {
|
||||
printk(KERN_INFO "%s, decoded state \n", __func__);
|
||||
s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_PREPARE;
|
||||
}
|
||||
|
||||
ret = SCDDRV_OK;
|
||||
} else {
|
||||
ret = SCDDRV_ERR;
|
||||
}
|
||||
|
||||
VFMW_OSAL_SemaUp(G_SCD_SEM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SCDDRV_SLEEP_STAGE_E SCDDRV_GetSleepStage(void)
|
||||
{
|
||||
return s_eScdDrvSleepStage;
|
||||
}
|
||||
|
||||
void SCDDRV_SetSleepStage(SCDDRV_SLEEP_STAGE_E sleepState)
|
||||
{
|
||||
VFMW_OSAL_SemaDown(G_SCD_SEM);
|
||||
s_eScdDrvSleepStage = sleepState;
|
||||
VFMW_OSAL_SemaUp(G_SCD_SEM);
|
||||
}
|
||||
|
||||
void SCDDRV_ForceSleep(void)
|
||||
{
|
||||
printk(KERN_INFO "%s, force state \n", __func__);
|
||||
VFMW_OSAL_SemaDown(G_SCD_SEM);
|
||||
if (s_eScdDrvSleepStage != SCDDRV_SLEEP_STAGE_SLEEP) {
|
||||
SCDDRV_ResetSCD();
|
||||
s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_SLEEP;
|
||||
}
|
||||
VFMW_OSAL_SemaUp(G_SCD_SEM);
|
||||
}
|
||||
|
||||
void SCDDRV_ExitSleep(void)
|
||||
{
|
||||
VFMW_OSAL_SemaDown(G_SCD_SEM);
|
||||
s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_NONE;
|
||||
VFMW_OSAL_SemaUp(G_SCD_SEM);
|
||||
}
|
||||
|
||||
int SCDDRV_WriteReg(SCD_CONFIG_REG_S *pSmCtrlReg )
|
||||
{
|
||||
if (s_SCDState != SCD_IDLE)
|
||||
return SCDDRV_ERR;
|
||||
|
||||
s_SCDState = SCD_WORKING;
|
||||
WR_SCDREG(REG_SCD_INI_CLR, 1);
|
||||
|
||||
// LIST_ADDRESS
|
||||
WR_SCDREG(REG_LIST_ADDRESS, (unsigned int)pSmCtrlReg->DownMsgPhyAddr);
|
||||
|
||||
// UP_ADDRESS
|
||||
WR_SCDREG(REG_UP_ADDRESS, (unsigned int) pSmCtrlReg->UpMsgPhyAddr);
|
||||
|
||||
// UP_LEN
|
||||
WR_SCDREG(REG_UP_LEN, (unsigned int) pSmCtrlReg->UpLen);
|
||||
|
||||
// BUFFER_FIRST
|
||||
WR_SCDREG(REG_BUFFER_FIRST, (unsigned int) pSmCtrlReg->BufferFirst);
|
||||
|
||||
// BUFFER_LAST
|
||||
WR_SCDREG(REG_BUFFER_LAST, (unsigned int) pSmCtrlReg->BufferLast);
|
||||
|
||||
// BUFFER_INI
|
||||
WR_SCDREG(REG_BUFFER_INI, (unsigned int) pSmCtrlReg->BufferIni);
|
||||
|
||||
// SCD_PROTOCOL
|
||||
WR_SCDREG(REG_SCD_PROTOCOL, (unsigned int) ((pSmCtrlReg->ScdLowdlyEnable << 8)
|
||||
| ((pSmCtrlReg->SliceCheckFlag << 4) & 0x10)
|
||||
| (pSmCtrlReg->ScdProtocol & 0x0f)));
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
SMMU_SetMasterReg(SCD, SECURE_OFF, SMMU_ON);
|
||||
#endif
|
||||
|
||||
#ifndef SCD_BUSY_WAITTING
|
||||
WR_SCDREG(REG_SCD_INT_MASK, 0);
|
||||
#endif
|
||||
|
||||
PrintScdVtrlReg();
|
||||
|
||||
// SCD_START
|
||||
WR_SCDREG(REG_SCD_START, 0);
|
||||
WR_SCDREG(REG_SCD_START, (unsigned int) (pSmCtrlReg->ScdStart & 0x01));
|
||||
|
||||
return SCDDRV_OK;
|
||||
}
|
||||
|
||||
void SCDDRV_SaveStateReg(void)
|
||||
{
|
||||
gScdStateReg.ScdProtocol = RD_SCDREG(REG_SCD_PROTOCOL);
|
||||
gScdStateReg.Scdover = RD_SCDREG(REG_SCD_OVER);
|
||||
gScdStateReg.ScdInt = RD_SCDREG(REG_SCD_INT);
|
||||
gScdStateReg.ScdNum = RD_SCDREG(REG_SCD_NUM);
|
||||
gScdStateReg.ScdRollAddr = RD_SCDREG(REG_ROLL_ADDR);
|
||||
gScdStateReg.SrcEaten = RD_SCDREG(REG_SRC_EATEN);
|
||||
gScdStateReg.UpLen = RD_SCDREG(REG_UP_LEN);
|
||||
}
|
||||
|
||||
void SCDDRV_init(void)
|
||||
{
|
||||
memset(&gScdStateReg, 0, sizeof(gScdStateReg));
|
||||
s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_NONE;
|
||||
s_SCDState = SCD_IDLE;
|
||||
}
|
||||
|
||||
void SCDDRV_DeInit(void)
|
||||
{
|
||||
s_eScdDrvSleepStage = SCDDRV_SLEEP_STAGE_NONE;
|
||||
s_SCDState = SCD_IDLE;
|
||||
}
|
||||
|
||||
void SCDDRV_ISR(void)
|
||||
{
|
||||
int dat = 0;
|
||||
|
||||
dat = RD_SCDREG(REG_SCD_OVER) & 0x01;
|
||||
if ((dat & 1) == 0) {
|
||||
printk(KERN_CRIT "End0: SM_SCDIntServeProc()\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SCDDRV_SaveStateReg();
|
||||
WR_SCDREG(REG_SCD_INI_CLR, 1);
|
||||
VFMW_OSAL_GiveEvent(G_SCDHWDONEEVENT);
|
||||
}
|
||||
|
||||
void SCDDRV_GetRegState(SCD_STATE_REG_S *pScdStateReg)
|
||||
{
|
||||
memcpy(pScdStateReg, &gScdStateReg, sizeof(*pScdStateReg));
|
||||
s_SCDState = SCD_IDLE;
|
||||
}
|
||||
|
||||
int WaitSCDFinish(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (SCD_WORKING == s_SCDState) {
|
||||
for (i = 0; i < SCD_TIME_OUT_COUNT; i++) {
|
||||
if ((RD_SCDREG(REG_SCD_OVER) & 1))
|
||||
return SCDDRV_OK;
|
||||
}
|
||||
|
||||
return SCDDRV_ERR;
|
||||
} else {
|
||||
return SCDDRV_OK;
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintScdVtrlReg(void)
|
||||
{
|
||||
SCD_CONFIG_REG_S SmCtrlReg;
|
||||
memset(&SmCtrlReg, 0, sizeof(SmCtrlReg));
|
||||
|
||||
SmCtrlReg.DownMsgPhyAddr = RD_SCDREG(REG_LIST_ADDRESS);
|
||||
SmCtrlReg.UpMsgPhyAddr = RD_SCDREG(REG_UP_ADDRESS);
|
||||
SmCtrlReg.UpLen = RD_SCDREG(REG_UP_LEN);
|
||||
SmCtrlReg.BufferFirst = RD_SCDREG(REG_BUFFER_FIRST);
|
||||
SmCtrlReg.BufferLast = RD_SCDREG(REG_BUFFER_LAST);
|
||||
SmCtrlReg.BufferIni = RD_SCDREG(REG_BUFFER_INI);
|
||||
SmCtrlReg.ScdProtocol = RD_SCDREG(REG_SCD_PROTOCOL);
|
||||
SmCtrlReg.ScdStart = RD_SCDREG(REG_SCD_START);
|
||||
}
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
int SCDDRV_IsScdIdle(void)
|
||||
{
|
||||
int ret = SCDDRV_OK;
|
||||
if (SCD_IDLE == s_SCDState) {
|
||||
ret = SCDDRV_OK;
|
||||
} else if (SCD_WORKING == s_SCDState) {
|
||||
ret = SCDDRV_ERR;
|
||||
} else {
|
||||
ret = SCDDRV_ERR;
|
||||
printk(KERN_ERR "%s : s_SCDState : %d is wrong\n", __func__, s_SCDState);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
#ifndef __SCD_DRV_H__
|
||||
#define __SCD_DRV_H__
|
||||
|
||||
#include "mem_manage.h"
|
||||
//#include "../omxvdec/memory.h"
|
||||
#include "vfmw.h"
|
||||
|
||||
#define SCDDRV_OK (0)
|
||||
#define SCDDRV_ERR (-1)
|
||||
|
||||
#define SCD_TIME_OUT_COUNT (200)
|
||||
|
||||
#define REG_SCD_START (0x800)
|
||||
#define REG_LIST_ADDRESS (0x804)
|
||||
#define REG_UP_ADDRESS (0x808)
|
||||
#define REG_UP_LEN (0x80c)
|
||||
#define REG_BUFFER_FIRST (0x810)
|
||||
#define REG_BUFFER_LAST (0x814)
|
||||
#define REG_BUFFER_INI (0x818)
|
||||
#define REG_SCD_PROTOCOL (0x820)
|
||||
|
||||
/* state registers */
|
||||
#define REG_SCD_OVER (0x840)
|
||||
#define REG_SCD_INT (0x844)
|
||||
#define REG_SCD_NUM (0x84c)
|
||||
#define REG_ROLL_ADDR (0x850)
|
||||
#define REG_SRC_EATEN (0x854)
|
||||
|
||||
#define REG_SCD_SAFE_INT_MASK (0x884)
|
||||
#define REG_SCD_SAFE_INI_CLR (0x888)
|
||||
#define REG_SCD_NORM_INT_MASK (0x81c)
|
||||
#define REG_SCD_NORM_INI_CLR (0x824)
|
||||
|
||||
#define REG_SCD_INT_MASK REG_SCD_NORM_INT_MASK
|
||||
#define REG_SCD_INI_CLR REG_SCD_NORM_INI_CLR
|
||||
|
||||
#define REG_AVS_FLAG (0x0000)
|
||||
#define REG_EMAR_ID (0x0004)
|
||||
#define REG_VDH_SELRST (0x0008)
|
||||
|
||||
#define SM_SCD_UP_INFO_NUM (2)
|
||||
#ifdef CFG_MAX_RAW_NUM
|
||||
#define MAX_STREAM_RAW_NUM (CFG_MAX_RAW_NUM)
|
||||
#else
|
||||
#define MAX_STREAM_RAW_NUM (1024)
|
||||
#endif
|
||||
#ifdef CFG_MAX_SEG_NUM
|
||||
#define MAX_STREAM_SEG_NUM (CFG_MAX_SEG_NUM)
|
||||
#else
|
||||
#define MAX_STREAM_SEG_NUM (1024 + 128)
|
||||
#endif
|
||||
#define SM_MAX_DOWNMSG_SIZE (3 * MAX_STREAM_RAW_NUM * sizeof(SINT32))
|
||||
#define SM_MAX_UPMSG_SIZE (SM_SCD_UP_INFO_NUM * MAX_STREAM_SEG_NUM * sizeof(SINT32))
|
||||
typedef enum {
|
||||
FMW_OK = 0,
|
||||
FMW_ERR_PARAM = -1,
|
||||
FMW_ERR_NOMEM = -2,
|
||||
FMW_ERR_NOTRDY = -3,
|
||||
FMW_ERR_BUSY = -4,
|
||||
FMW_ERR_RAWNULL = -5,
|
||||
FMW_ERR_SEGFULL = -6,
|
||||
FMW_ERR_SCD = -7
|
||||
} FMW_RETVAL_E;
|
||||
|
||||
typedef enum {
|
||||
SCDDRV_SLEEP_STAGE_NONE = 0,
|
||||
SCDDRV_SLEEP_STAGE_PREPARE,
|
||||
SCDDRV_SLEEP_STAGE_SLEEP
|
||||
} SCDDRV_SLEEP_STAGE_E;
|
||||
|
||||
typedef enum {
|
||||
SCD_IDLE = 0,
|
||||
SCD_WORKING,
|
||||
} SCD_STATE_E;
|
||||
|
||||
/* register operator */
|
||||
#define RD_SCDREG(reg) MEM_ReadPhyWord((gScdRegBaseAddr + reg))
|
||||
#define WR_SCDREG(reg, dat) MEM_WritePhyWord((gScdRegBaseAddr + reg),(dat))
|
||||
|
||||
#define FMW_ASSERT_RET( cond, ret ) \
|
||||
do{ \
|
||||
if (!(cond)) \
|
||||
return (ret); \
|
||||
} while (0)
|
||||
|
||||
/*######################################################
|
||||
struct defs.
|
||||
######################################################*/
|
||||
typedef enum {
|
||||
SCD_SHAREFD_MESSAGE_POOL = 0,
|
||||
SCD_SHAREFD_OUTPUT_BUF = 1,
|
||||
SCD_SHAREFD_MAX
|
||||
}SCD_SHAREFD;
|
||||
|
||||
typedef struct {
|
||||
int Scdover;
|
||||
int ScdInt;
|
||||
int ShortScdNum;
|
||||
int ScdNum;
|
||||
unsigned int ScdRollAddr;
|
||||
int SrcEaten;
|
||||
} SM_STATEREG_S;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char SliceCheckFlag;
|
||||
char ScdStart;
|
||||
unsigned int DownMsgPhyAddr;
|
||||
unsigned int UpMsgPhyAddr;
|
||||
int UpLen;
|
||||
unsigned int BufferFirst;
|
||||
unsigned int BufferLast;
|
||||
unsigned int BufferIni;
|
||||
int ScdProtocol;
|
||||
int ScdLowdlyEnable;
|
||||
int scd_share_fd[SCD_SHAREFD_MAX];
|
||||
int IsScdAllBufRemap;
|
||||
} SCD_CONFIG_REG_S;
|
||||
|
||||
typedef struct {
|
||||
int ScdProtocol;
|
||||
int Scdover;
|
||||
int ScdInt;
|
||||
int ScdNum;
|
||||
unsigned int ScdRollAddr;
|
||||
int SrcEaten;
|
||||
int UpLen;
|
||||
} SCD_STATE_REG_S;
|
||||
|
||||
typedef enum hi_CONFIG_SCD_CMD {
|
||||
CONFIG_SCD_REG_CMD = 100,
|
||||
} CONFIG_SCD_CMD;
|
||||
|
||||
typedef struct {
|
||||
CONFIG_SCD_CMD cmd;
|
||||
int eVidStd;
|
||||
unsigned int SResetFlag;
|
||||
unsigned int GlbResetFlag;
|
||||
SCD_CONFIG_REG_S SmCtrlReg;
|
||||
} OMXSCD_REG_CFG_S;
|
||||
|
||||
int SCDDRV_PrepareSleep(void);
|
||||
|
||||
SCDDRV_SLEEP_STAGE_E SCDDRV_GetSleepStage(void);
|
||||
void SCDDRV_SetSleepStage(SCDDRV_SLEEP_STAGE_E sleepState);
|
||||
|
||||
void SCDDRV_ForceSleep(void);
|
||||
|
||||
void SCDDRV_ExitSleep(void);
|
||||
|
||||
int SCDDRV_ResetSCD(void);
|
||||
|
||||
int SCDDRV_WriteReg(SCD_CONFIG_REG_S *pSmCtrlReg );
|
||||
|
||||
void SCDDRV_GetRegState(SCD_STATE_REG_S *pScdStateReg);
|
||||
|
||||
void SCDDRV_ISR(void);
|
||||
|
||||
void SCDDRV_init(void);
|
||||
|
||||
void SCDDRV_DeInit(void);
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
int SCDDRV_IsScdIdle(void);
|
||||
#endif
|
||||
#endif
|
||||
Executable
+479
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* vdec driver for smmu master
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
#include <asm/memory.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/gfp.h>
|
||||
#endif
|
||||
#include <linux/printk.h>
|
||||
#include "smmu.h"
|
||||
//#include "public.h"
|
||||
#include "mem_manage.h"
|
||||
#include "linux_kernel_osal.h"
|
||||
#include <linux/io.h>
|
||||
#include "../omxvdec/omxvdec.h"
|
||||
|
||||
#define SMRx_ID_SIZE 32
|
||||
#define SMMU_RWERRADDR_SIZE 128
|
||||
|
||||
#define HIVDEC_SMMU_COMMON_OFFSET (0x20000)
|
||||
#define HIVDEC_SMMU_MASTER_OFFSET (0xF000)
|
||||
|
||||
#define HIVDEC_SMMU_COMMON_BASE_ADDR (gVdhRegBaseAddr + HIVDEC_SMMU_COMMON_OFFSET)
|
||||
#define HIVDEC_SMMU_MASTER_BASE_ADDR (gVdhRegBaseAddr + HIVDEC_SMMU_MASTER_OFFSET)
|
||||
|
||||
//SMMU common and Master(MFDE/SCD/BPD) virtual base address
|
||||
typedef struct {
|
||||
int *pSMMUCommonBaseVirAddr;
|
||||
int *pSMMUMasterBaseVirAddr;
|
||||
int *pSMMUMFDERegVirAddr;
|
||||
int *pSMMUBPDRegVirAddr;
|
||||
int *pSMMUSCDRegVirAddr;
|
||||
} SMMU_REG_VIR_S;
|
||||
|
||||
SMMU_REG_VIR_S gSmmuRegVir;
|
||||
MEM_DESC_S gAllocMem_RD;
|
||||
MEM_DESC_S gAllocMem_WR;
|
||||
|
||||
int gSmmuInitFlag = 0;
|
||||
int gMfdeSecureFlag = 0;
|
||||
int gMfdeSmmuFlag = 1;
|
||||
int gScdSecureFlag = 0;
|
||||
int gScdSmmuFlag = 1;
|
||||
int gBpdSecureFlag = 0;
|
||||
int gBpdSmmuFlag = 0;
|
||||
|
||||
//smmu common regs r/w
|
||||
#define RD_SMMU_COMMON_VREG( reg, dat ) \
|
||||
do { \
|
||||
(dat) = readl(((volatile int*)((char*)gSmmuRegVir.pSMMUCommonBaseVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
#define WR_SMMU_COMMON_VREG( reg, dat ) \
|
||||
do { \
|
||||
writel((dat), ((volatile int*)((char*)gSmmuRegVir.pSMMUCommonBaseVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
//smmu master regs r/w
|
||||
#define RD_SMMU_MASTER_VREG( reg, dat ) \
|
||||
do { \
|
||||
(dat) = readl(((volatile int*)((char*)gSmmuRegVir.pSMMUMasterBaseVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
#define WR_SMMU_MASTER_VREG( reg, dat ) \
|
||||
do { \
|
||||
writel((dat), ((volatile int*)((char*)gSmmuRegVir.pSMMUMasterBaseVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
//mfde regs r/w
|
||||
#define RD_SMMU_MFDE_VREG( reg, dat ) \
|
||||
do { \
|
||||
(dat) = readl(((volatile int*)((char*)gSmmuRegVir.pSMMUMFDERegVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
#define WR_SMMU_MFDE_VREG( reg, dat ) \
|
||||
do { \
|
||||
writel((dat), ((volatile int*)((char*)gSmmuRegVir.pSMMUMFDERegVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
//bpd regs r/w
|
||||
#define RD_SMMU_BPD_VREG( reg, dat ) \
|
||||
do { \
|
||||
(dat) = readl(((volatile int*)((char*)gSmmuRegVir.pSMMUBPDRegVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
#define WR_SMMU_BPD_VREG( reg, dat ) \
|
||||
do { \
|
||||
writel((dat), ((volatile int*)((char*)gSmmuRegVir.pSMMUBPDRegVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
//scd regs r/w
|
||||
#define RD_SMMU_SCD_VREG( reg, dat ) \
|
||||
do { \
|
||||
(dat) = readl(((volatile int*)((char*)gSmmuRegVir.pSMMUSCDRegVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
#define WR_SMMU_SCD_VREG( reg, dat ) \
|
||||
do { \
|
||||
writel((dat), ((volatile int*)((char*)gSmmuRegVir.pSMMUSCDRegVirAddr + (reg)))); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
*function: set SMMU common register
|
||||
*addr: register's vir addr
|
||||
*val: value to be set
|
||||
*bw: bit width
|
||||
*bs: bit start
|
||||
*/
|
||||
static void set_common_reg(unsigned int addr, int val, int bw, int bs)
|
||||
{
|
||||
int mask = (1UL << bw) - 1UL;
|
||||
int tmp = 0;
|
||||
|
||||
RD_SMMU_COMMON_VREG(addr, tmp);
|
||||
tmp &= ~(mask << bs);/*lint !e502*/
|
||||
WR_SMMU_COMMON_VREG(addr, tmp | ((val & mask) << bs));
|
||||
}
|
||||
|
||||
/**
|
||||
*function: set SMMU master register
|
||||
*addr: register's vir addr
|
||||
*val: value to be set
|
||||
*bw: bit width
|
||||
*bs: bit start
|
||||
*/
|
||||
static void set_master_reg(unsigned int addr, int val, int bw, int bs)
|
||||
{
|
||||
int mask = (1UL << bw) - 1UL;
|
||||
int tmp = 0;
|
||||
|
||||
RD_SMMU_MASTER_VREG(addr, tmp);
|
||||
tmp &= ~(mask << bs);/*lint !e502*/
|
||||
WR_SMMU_MASTER_VREG(addr, (tmp | ((val & mask) << bs)));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*function: set mfde/scd/bpd register
|
||||
*master_type: MFDE/SCD/BPD
|
||||
*addr: register's vir addr
|
||||
*val: value to be set
|
||||
*bw: bit width
|
||||
*bs: bit start
|
||||
*/
|
||||
static void set_vdh_master_reg(SMMU_MASTER_TYPE master_type, unsigned int addr, int val, int bw, int bs)
|
||||
{
|
||||
int mask = (1UL << bw) - 1UL;
|
||||
int tmp = 0;
|
||||
|
||||
switch (master_type) {
|
||||
case MFDE:
|
||||
RD_SMMU_MFDE_VREG(addr, tmp);
|
||||
tmp &= ~(mask << bs);/*lint !e502*/
|
||||
WR_SMMU_MFDE_VREG(addr, tmp | ((val & mask) << bs));
|
||||
break;
|
||||
|
||||
case BPD:
|
||||
RD_SMMU_BPD_VREG(addr, tmp);
|
||||
tmp &= ~(mask << bs);/*lint !e502*/
|
||||
WR_SMMU_BPD_VREG(addr, tmp | ((val & mask) << bs));
|
||||
break;
|
||||
|
||||
case SCD:
|
||||
RD_SMMU_SCD_VREG(addr, tmp);
|
||||
tmp &= ~(mask << bs);/*lint !e502*/
|
||||
WR_SMMU_SCD_VREG(addr, tmp | ((val & mask) << bs));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*function: set mfde mmu cfg register
|
||||
*/
|
||||
static void set_mmu_cfg_reg_mfde(SMMU_MASTER_TYPE master_type, unsigned int secure_en, unsigned int mmu_en)
|
||||
{
|
||||
if (mmu_en) { //MMU enable
|
||||
set_vdh_master_reg(master_type, REG_MFDE_MMU_CFG_EN, 0x1, 1, 12); //[12]mmu_en=1
|
||||
if (secure_en) { //secure
|
||||
printk(KERN_INFO "IN %s not support this mode: mmu_en:secure\n", __func__);
|
||||
printk(KERN_INFO "%s, secure_en:%d, mmu_en:%d\n", __func__, secure_en, mmu_en);
|
||||
set_vdh_master_reg(master_type, REG_MFDE_MMU_CFG_SECURE, 0x1, 1, 31); //[31]secure_en=1
|
||||
} else { //non-secure
|
||||
set_vdh_master_reg(master_type, REG_MFDE_MMU_CFG_SECURE, 0x0, 1, 31); //[31]secure_en=0
|
||||
}
|
||||
} else { //MMU disable
|
||||
set_vdh_master_reg(master_type, REG_MFDE_MMU_CFG_EN, 0x0, 1, 12); //[12]mmu_en=0
|
||||
if (secure_en) { //secure
|
||||
set_vdh_master_reg(master_type, REG_MFDE_MMU_CFG_SECURE, 0x1, 1, 31); //[31]secure_en=1
|
||||
} else { //non-secure
|
||||
printk(KERN_INFO "IN %s not support this mode: non_mmu:non_secure\n", __func__);
|
||||
printk(KERN_INFO "%s, secure_en:%d, mmu_en:%d\n", __func__, secure_en, mmu_en);
|
||||
set_vdh_master_reg(master_type, REG_MFDE_MMU_CFG_SECURE, 0x0, 1, 31); //[31]secure_en=0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*function: set bpd mmu cfg register
|
||||
*/
|
||||
static void set_mmu_cfg_reg_bpd(SMMU_MASTER_TYPE master_type, unsigned int secure_en, unsigned int mmu_en)
|
||||
{
|
||||
if (mmu_en) { //MMU enable
|
||||
set_vdh_master_reg(master_type, REG_BPD_MMU_CFG, 0x1, 1, 21); //[21]mmu_en=1
|
||||
if (secure_en) { //secure
|
||||
printk(KERN_INFO "IN %s not support this mode: mmu_en:secure\n", __func__);
|
||||
printk(KERN_INFO "%s, secure_en:%d, mmu_en:%d\n", __func__, secure_en, mmu_en);
|
||||
set_vdh_master_reg(master_type, REG_BPD_MMU_CFG, 0x1, 1, 20); //[20]secure_en=1
|
||||
} else { //non-secure
|
||||
set_vdh_master_reg(master_type, REG_BPD_MMU_CFG, 0x0, 1, 20); //[20]secure_en=0
|
||||
}
|
||||
} else { //MMU disable
|
||||
set_vdh_master_reg(master_type, REG_BPD_MMU_CFG, 0x0, 1, 21); //[21]mmu_en=0
|
||||
if (secure_en) { //secure
|
||||
set_vdh_master_reg(master_type, REG_BPD_MMU_CFG, 0x1, 1, 20); //[20]secure_en=1
|
||||
} else { //non-secure
|
||||
printk(KERN_INFO "IN %s not support this mode: non_mmu:non_secure\n", __func__);
|
||||
printk(KERN_INFO "%s, secure_en:%d, mmu_en:%d\n", __func__, secure_en, mmu_en);
|
||||
set_vdh_master_reg(master_type, REG_BPD_MMU_CFG, 0x0, 1, 20); //[20]secure_en=0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*function: set scd mmu cfg register
|
||||
*/
|
||||
static void set_mmu_cfg_reg_scd(SMMU_MASTER_TYPE master_type, unsigned int secure_en, unsigned int mmu_en)
|
||||
{
|
||||
if (mmu_en) { //MMU enable
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x1, 1, 9);//[9]mmu_en=1
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x1, 1, 13);//[13]rdbuf_mmu_en=1
|
||||
if (secure_en) { //secure
|
||||
printk(KERN_INFO "IN %s not support this mode: mmu_en:secure\n", __func__);
|
||||
printk(KERN_INFO "%s, secure_en:%d, mmu_en:%d\n", __func__, secure_en, mmu_en);
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x1, 1, 7); //[7]secure_en=1
|
||||
} else { //non-secure
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x0, 1, 7); //[7]secure_en=0
|
||||
}
|
||||
} else { //MMU disable
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x0, 1, 9); //[9]mmu_en=0
|
||||
if (secure_en) { //secure
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x1, 1, 7); //[7]secure_en=1
|
||||
} else { //non-secure
|
||||
printk(KERN_INFO "IN %s not support this mode: non_mmu:non_secure\n", __func__);
|
||||
printk(KERN_INFO "%s, secure_en:%d, mmu_en:%d\n", __func__, secure_en, mmu_en);
|
||||
set_vdh_master_reg(master_type, REG_SCD_MMU_CFG, 0x0, 1, 7); //[7]secure_en=0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int smmu_mem_alloc(unsigned int size, MEM_DESC_S *pMemDesc)
|
||||
{
|
||||
void *virt_addr = NULL;
|
||||
|
||||
if (pMemDesc == NULL) {
|
||||
printk(KERN_ERR "%s: invalid param pMemDesc is NULL\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
if (pMemDesc->VirAddr != 0L) {
|
||||
printk(KERN_ERR "%s param StartVirAddr %pK is not NULL\n", __func__, (void*)pMemDesc->VirAddr);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
if (MEM_CMA_ZERO == pMemDesc->MemType)
|
||||
virt_addr = kzalloc(size, GFP_KERNEL | GFP_DMA); //restrict [0 ~ 4G]
|
||||
else
|
||||
virt_addr = kmalloc(size, GFP_KERNEL | GFP_DMA); //restrict [0 ~ 4G]
|
||||
|
||||
if (!virt_addr) {
|
||||
printk(KERN_ERR "%s Alloc virt_addr failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
pMemDesc->VirAddr = (unsigned long long)virt_addr;
|
||||
pMemDesc->PhyAddr = __pa(virt_addr);/*lint !e648*/
|
||||
|
||||
return SMMU_OK;
|
||||
}
|
||||
|
||||
static void smmu_mem_dealloc(MEM_DESC_S *pMemDesc)
|
||||
{
|
||||
if (pMemDesc == NULL) {
|
||||
printk(KERN_ERR "%s : Invalid pMemDesc is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pMemDesc->VirAddr == 0L) {
|
||||
printk(KERN_ERR "%s : Invalid pMemDesc->VirAddr is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
kfree((void *)pMemDesc->VirAddr);
|
||||
pMemDesc->VirAddr = 0L;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*function: Alloc MEM for TLB miss .
|
||||
*/
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
static int alloc_smmu_tlb_miss_addr(void)
|
||||
{
|
||||
int ret = SMMU_ERR;
|
||||
|
||||
gAllocMem_RD.MemType = MEM_CMA_ZERO;
|
||||
ret = smmu_mem_alloc(SMMU_RWERRADDR_SIZE, &gAllocMem_RD);
|
||||
if (ret != MEM_MAN_OK) {
|
||||
printk(KERN_ERR "%s kzalloc mem for smmu rderr failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
gAllocMem_WR.MemType = MEM_CMA_ZERO;
|
||||
ret = smmu_mem_alloc(SMMU_RWERRADDR_SIZE, &gAllocMem_WR);
|
||||
if (ret != MEM_MAN_OK) {
|
||||
printk(KERN_ERR "%s kzalloc mem for smmu wrerr failed\n", __func__);
|
||||
smmu_mem_dealloc(&gAllocMem_RD);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
return SMMU_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*function: init SMMU global registers.
|
||||
*/
|
||||
void SMMU_InitGlobalReg(void)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
if (gSmmuInitFlag != 1) {
|
||||
printk(KERN_DEBUG "%s Smmu initialization failed\n", __func__);
|
||||
return;
|
||||
}
|
||||
//0000 0000 0000 1111 0000 0000 0011 1000 --> 0x000f0038
|
||||
set_common_reg(SMMU_SCR, 0x0, 1, 0);//SMMU_SCR[0].glb_bypass
|
||||
set_common_reg(SMMU_SCR, 0x3, 2, 1);//SMMU_SCR[1].rqos_en SMMU_SCR[2].wqos_en
|
||||
|
||||
//SMRX_S had set default value. Only need to set SMMU_SMRx_NS secure SID bypass
|
||||
//SMMU_SMRx[0]smr_bypass=0(non-bypass); SMMU_SMRx[2:3]smr_ptw_qos=0x3;
|
||||
for (i = 0; i < SMRx_ID_SIZE; i += 2) {
|
||||
set_common_reg(SMMU_SMRx_NS + i*0x4, 0x1C, 32, 0);//0x00000003 none secure
|
||||
}
|
||||
|
||||
for (i = 1; i < SMRx_ID_SIZE; i += 2) {
|
||||
set_common_reg(SMMU_SMRx_NS + i*0x4, 0x1D, 32, 0);//0x00000002 secure
|
||||
}
|
||||
set_common_reg(SMMU_CB_TTBR0, gSmmuPageBase, 32, 0);
|
||||
set_common_reg(SMMU_FAMA_CTRL1_NS, (gSmmuPageBase>>32)&0x7F, 32, 0);
|
||||
set_common_reg(SMMU_CB_TTBCR, 0x1, 1, 0);
|
||||
|
||||
if (gAllocMem_RD.PhyAddr != 0 && gAllocMem_WR.PhyAddr != 0) {
|
||||
set_common_reg(SMMU_ERR_RDADDR, (gAllocMem_RD.PhyAddr & 0xFFFFFFFF), 32, 0);
|
||||
set_common_reg(SMMU_ADDR_MSB, (gAllocMem_RD.PhyAddr>>32)&0x7F, 7, 0);
|
||||
|
||||
set_common_reg(SMMU_ERR_WRADDR, (gAllocMem_WR.PhyAddr & 0xFFFFFFFF), 32, 0);
|
||||
set_common_reg(SMMU_ADDR_MSB, (gAllocMem_WR.PhyAddr>>32)&0x7F, 7, 7);
|
||||
}
|
||||
//glb_bypass, 0x0: normal mode, 0x1: bypass mode
|
||||
set_master_reg(SMMU_MSTR_GLB_BYPASS, 0x0, 32, 0); //master mmu enable
|
||||
}
|
||||
|
||||
/**
|
||||
*function: set MFDE/SCD/BPD mmu cfg register, MMU or secure.
|
||||
*/
|
||||
void SMMU_SetMasterReg(SMMU_MASTER_TYPE master_type, unsigned char secure_en, unsigned char mmu_en)
|
||||
{
|
||||
switch (master_type) {
|
||||
case MFDE:
|
||||
set_mmu_cfg_reg_mfde(master_type, secure_en, mmu_en);
|
||||
gMfdeSecureFlag = secure_en;
|
||||
gMfdeSmmuFlag = mmu_en;
|
||||
break;
|
||||
|
||||
case SCD:
|
||||
set_mmu_cfg_reg_scd(master_type, secure_en, mmu_en);
|
||||
gScdSecureFlag = secure_en;
|
||||
gScdSmmuFlag = mmu_en;
|
||||
break;
|
||||
|
||||
case BPD:
|
||||
set_mmu_cfg_reg_bpd(master_type, secure_en, mmu_en);
|
||||
gBpdSecureFlag = secure_en;
|
||||
gBpdSmmuFlag = mmu_en;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s unkown master type %d\n", __func__, master_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SMMU_IntServProc(void)
|
||||
{
|
||||
int tmp = -1;
|
||||
RD_SMMU_COMMON_VREG(SMMU_INTSTAT_NS, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_0, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_1, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_2, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_3, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_4, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_5, tmp);
|
||||
RD_SMMU_MASTER_VREG(SMMU_MSTR_DBG_6, tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
*function: get registers virtual address, and alloc mem for TLB miss.
|
||||
*/
|
||||
int SMMU_Init(void)
|
||||
{
|
||||
int ret = SMMU_ERR;
|
||||
memset(&gSmmuRegVir, 0, sizeof(gSmmuRegVir));
|
||||
|
||||
gSmmuRegVir.pSMMUMFDERegVirAddr = (int *) MEM_Phy2Vir(gVdhRegBaseAddr);
|
||||
if (gSmmuRegVir.pSMMUMFDERegVirAddr == NULL) {
|
||||
printk(KERN_ERR "%s pSMMUMFDERegVirAddr is NULL, SMMU Init failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
gSmmuRegVir.pSMMUSCDRegVirAddr = (int *) MEM_Phy2Vir(gScdRegBaseAddr);
|
||||
if (gSmmuRegVir.pSMMUSCDRegVirAddr == NULL) {
|
||||
printk(KERN_ERR "%s pSMMUSCDRegVirAddr is NULL, SMMU Init failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
gSmmuRegVir.pSMMUBPDRegVirAddr = (int *) MEM_Phy2Vir(gBpdRegBaseAddr);
|
||||
if (gSmmuRegVir.pSMMUBPDRegVirAddr == NULL) {
|
||||
printk(KERN_ERR "%s pSMMUBPDRegVirAddr is NULL, SMMU Init failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
gSmmuRegVir.pSMMUCommonBaseVirAddr = (int *) MEM_Phy2Vir(HIVDEC_SMMU_COMMON_BASE_ADDR);
|
||||
if (gSmmuRegVir.pSMMUCommonBaseVirAddr == NULL) {
|
||||
printk(KERN_ERR "%s pSMMUCommonBaseVirAddr is NULL, SMMU Init failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
gSmmuRegVir.pSMMUMasterBaseVirAddr = (int *) MEM_Phy2Vir(HIVDEC_SMMU_MASTER_BASE_ADDR);
|
||||
if (gSmmuRegVir.pSMMUMasterBaseVirAddr == NULL) {
|
||||
printk(KERN_ERR "%s pSMMUMasterBaseVirAddr is NULL, SMMU Init failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
|
||||
memset(&gAllocMem_RD, 0, sizeof(gAllocMem_RD));
|
||||
memset(&gAllocMem_WR, 0, sizeof(gAllocMem_WR));
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
ret = alloc_smmu_tlb_miss_addr();
|
||||
if (ret != SMMU_OK) {
|
||||
printk(KERN_ERR "%s alloc_smmu_tlb_miss_addr failed\n", __func__);
|
||||
return SMMU_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
gSmmuInitFlag = 1;
|
||||
|
||||
return SMMU_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*function: free mem of SMMU_ERR_RDADDR and SMMU_ERR_WRADDR.
|
||||
*/
|
||||
void SMMU_DeInit(void)
|
||||
{
|
||||
if (gAllocMem_RD.PhyAddr != 0)
|
||||
smmu_mem_dealloc(&gAllocMem_RD);
|
||||
|
||||
if (gAllocMem_WR.PhyAddr != 0)
|
||||
smmu_mem_dealloc(&gAllocMem_WR);
|
||||
}
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#ifndef __HIVDEC_SMMU_H__
|
||||
#define __HIVDEC_SMMU_H__
|
||||
|
||||
#include "sysconfig.h" //for VDM_REG_PHY_ADDR, SCD_REG_PHY_ADDR, BPD_REG_PHY_ADDR
|
||||
#include "vfmw.h"
|
||||
|
||||
#define SMMU_OK 0
|
||||
#define SMMU_ERR -1
|
||||
|
||||
#define SECURE_ON 1
|
||||
#define SECURE_OFF 0
|
||||
#define SMMU_ON 1
|
||||
#define SMMU_OFF 0
|
||||
/*******************************************************************************
|
||||
**SMMU COMMON registers
|
||||
*/
|
||||
#define SMMU_SCR (0x0000)
|
||||
|
||||
//non-secure
|
||||
#define SMMU_INTSTAT_NS (0x0018)
|
||||
#define SMMU_SMRx_NS (0x0020) //(0x0020+n*0x4) SMMU control register per stream for non-secure
|
||||
#define SMMU_CB_TTBR0 (0x0204) //SMMU translation table base register for non-secure context bank0
|
||||
#define SMMU_FAMA_CTRL1_NS (0x0224)//SMMU Control Register for FAMA for TCU of Non-Secure Context Bank
|
||||
#define SMMU_CB_TTBCR (0x020C) //SMMU Translation Table Base Control Register for Non-Secure Context Bank
|
||||
#define SMMU_ADDR_MSB (0x0300) //Register for MSB of all 33-bits address configuration
|
||||
#define SMMU_ERR_RDADDR (0x0304) //SMMU Error Address of TLB miss for Read transaction
|
||||
#define SMMU_ERR_WRADDR (0x0308) //SMMU Error Address of TLB miss for Write transaction
|
||||
|
||||
/**********************************************
|
||||
**MASTER(MFDE/SCD/BPD) registers
|
||||
*/
|
||||
#define REG_MFDE_MMU_CFG_SECURE (0x0008)
|
||||
#define REG_MFDE_MMU_CFG_EN (0x000c)
|
||||
#define REG_SCD_MMU_CFG (0x0820)
|
||||
#define REG_BPD_MMU_CFG (0x0004)
|
||||
/***********************************************/
|
||||
|
||||
/*************************************************
|
||||
**SMMU MASTER registers
|
||||
*/
|
||||
#define SMMU_MSTR_GLB_BYPASS (0x0000)
|
||||
|
||||
#define SMMU_MSTR_DBG_0 (0x0010)
|
||||
#define SMMU_MSTR_DBG_1 (0x0014)
|
||||
#define SMMU_MSTR_DBG_2 (0x0018)
|
||||
#define SMMU_MSTR_DBG_3 (0x001c)
|
||||
#define SMMU_MSTR_DBG_4 (0x0020)
|
||||
#define SMMU_MSTR_DBG_5 (0x0024)
|
||||
#define SMMU_MSTR_DBG_6 (0x0028)
|
||||
/***********************************************/
|
||||
|
||||
typedef enum {
|
||||
MFDE = 0,
|
||||
BPD,
|
||||
SCD,
|
||||
} SMMU_MASTER_TYPE;
|
||||
|
||||
int SMMU_Init(void);
|
||||
void SMMU_DeInit(void);
|
||||
void SMMU_SetMasterReg(SMMU_MASTER_TYPE master_type, unsigned char secure_en, unsigned char mmu_en);
|
||||
void SMMU_InitGlobalReg(void);
|
||||
void SMMU_IntServProc(void);
|
||||
|
||||
#endif
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*--------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*!!Warning: This is a key information asset of Huawei Tech Co.,Ltd */
|
||||
/*CODEMARK:kOyQZYzjDpyGdBAEC2GaWinjiDDUykL9e8pckESWBbMVmSWkBuyJO01cTiy3TdzKxGk0oBQa
|
||||
mSMf7J4FkTpfvzHyMxSEsfcbL/G0fFswaAZ8tsS4we+PBWC6a/UNlzCWIaw+Ujkv9NAY+as0
|
||||
fg7WZIRvw27AjvRqJbkRJvqFUORSa6KPQaSBMxCxJTGTTf//sQbjPOyYldN0OVR9ut4HFO4U
|
||||
ZguGQVqcOAJQbE96v6175DqhuprKgQB8R+2fu7VD3qtX+ZJh/t0512oqv+e8YA==*/
|
||||
/*--------------------------------------------------------------------------------------------------------------------------*/
|
||||
#ifndef __VFMW_SYSCONFIG_HEADER__
|
||||
#define __VFMW_SYSCONFIG_HEADER__
|
||||
|
||||
#include "vfmw.h"
|
||||
|
||||
/* valid vdh num */
|
||||
#define MAX_VDH_NUM (1)
|
||||
/* register offset */
|
||||
#define SCD_REG_OFFSET (0xc000)
|
||||
#define BPD_REG_OFFSET (0xd000)
|
||||
|
||||
#define SOFTRST_REQ_OFFSET (0xcc0c)//(0xf80c)
|
||||
#define SOFTRST_OK_OFFSET (0xcc10)//(0xf810)
|
||||
|
||||
#define ALL_RESET_CTRL_BIT (0)
|
||||
#define MFDE_RESET_CTRL_BIT (1)
|
||||
#define SCD_RESET_CTRL_BIT (2)
|
||||
#define BPD_RESET_CTRL_BIT (3)
|
||||
|
||||
#define ALL_RESET_OK_BIT (0)
|
||||
#define MFDE_RESET_OK_BIT (1)
|
||||
#define SCD_RESET_OK_BIT (2)
|
||||
#define BPD_RESET_OK_BIT (3)
|
||||
|
||||
/* FPGA flag */
|
||||
extern unsigned int gIsFPGA;
|
||||
|
||||
/* register base addr & range */
|
||||
extern unsigned int gVdhRegBaseAddr;
|
||||
extern unsigned int gScdRegBaseAddr;
|
||||
extern unsigned int gBpdRegBaseAddr;
|
||||
extern unsigned int gVdhRegRange;
|
||||
extern unsigned int gSOFTRST_REQ_Addr;
|
||||
extern unsigned int gSOFTRST_OK_ADDR;
|
||||
|
||||
/* smmu page table base addr */
|
||||
extern unsigned long long gSmmuPageBase;
|
||||
|
||||
/* peri crg base addr */
|
||||
extern unsigned int gPERICRG_RegBaseAddr;
|
||||
|
||||
/* irq num */
|
||||
extern unsigned int gVdecIrqNumNorm;
|
||||
extern unsigned int gVdecIrqNumProt;
|
||||
extern unsigned int gVdecIrqNumSafe;
|
||||
|
||||
#endif
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#ifndef __VDEC_FIRMWARE_H__
|
||||
#define __VDEC_FIRMWARE_H__
|
||||
|
||||
#define VFMW_VERSION_NUM (2017032400)
|
||||
#define TVP_CHAN_NUM (0)
|
||||
#define MAX_CHAN_NUM (32)
|
||||
#define MAX_FRAME_NUM (32)
|
||||
|
||||
#define VDEC_OK (0)
|
||||
#define VDEC_ERR (-1)
|
||||
#define VF_ERR_SYS (-20)
|
||||
|
||||
typedef enum {
|
||||
VFMW_START_RESERVED = 0,
|
||||
VFMW_H264 = 0,
|
||||
VFMW_VC1,
|
||||
VFMW_MPEG4,
|
||||
VFMW_MPEG2,
|
||||
VFMW_H263,
|
||||
VFMW_DIVX3,
|
||||
VFMW_AVS,
|
||||
VFMW_JPEG,
|
||||
VFMW_REAL8 = 8,
|
||||
VFMW_REAL9 = 9,
|
||||
VFMW_VP6 = 10,
|
||||
VFMW_VP6F,
|
||||
VFMW_VP6A,
|
||||
VFMW_VP8,
|
||||
VFMW_VP9,
|
||||
VFMW_SORENSON,
|
||||
VFMW_MVC,
|
||||
VFMW_HEVC,
|
||||
VFMW_RAW,
|
||||
VFMW_USER, /*## vfmw simply provide frame path. for external decoder, eg. mjpeg ## */
|
||||
VFMW_END_RESERVED
|
||||
} VID_STD_E;
|
||||
|
||||
/*memory type*/
|
||||
typedef enum {
|
||||
MEM_ION = 0, // ion default
|
||||
MEM_ION_CTG, // ion contigeous
|
||||
MEM_CMA, // kmalloc
|
||||
MEM_CMA_ZERO, // kzalloc
|
||||
} MEM_TYPE_E;
|
||||
|
||||
/* memroy description */
|
||||
typedef struct {
|
||||
unsigned char IsSecure;
|
||||
MEM_TYPE_E MemType;
|
||||
unsigned long long PhyAddr;
|
||||
unsigned int Length;
|
||||
unsigned long long VirAddr;
|
||||
} MEM_DESC_S;
|
||||
|
||||
typedef struct {
|
||||
unsigned int IsFPGA;
|
||||
unsigned int VdecIrqNumNorm;
|
||||
unsigned int VdecIrqNumProt;
|
||||
unsigned int VdecIrqNumSafe;
|
||||
unsigned int VdhRegBaseAddr;
|
||||
unsigned int VdhRegRange;
|
||||
unsigned long long SmmuPageBaseAddr;
|
||||
unsigned int PERICRG_RegBaseAddr;
|
||||
} VFMW_DTS_CONFIG_S;
|
||||
|
||||
#endif // __VDEC_FIRMWARE_H__
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
##############################################################
|
||||
# vfmw support config #
|
||||
##############################################################
|
||||
|
||||
################# vfmw_h264 #################################
|
||||
VFMW_H264_SUPPORT = YES
|
||||
#VFMW_H264_SUPPORT = NO
|
||||
|
||||
################# vfmw_hevc #################################
|
||||
VFMW_HEVC_SUPPORT = YES
|
||||
#VFMW_HEVC_SUPPORT = NO
|
||||
|
||||
################# vfmw_mpeg2 #################################
|
||||
VFMW_MPEG2_SUPPORT = YES
|
||||
#VFMW_MPEG2_SUPPORT = NO
|
||||
|
||||
################# vfmw_mpeg4 #################################
|
||||
VFMW_MPEG4_SUPPORT = YES
|
||||
#VFMW_MPEG4_SUPPORT = NO
|
||||
|
||||
################# vfmw_vp8 #################################
|
||||
VFMW_VP8_SUPPORT = YES
|
||||
#VFMW_VP8_SUPPORT = NO
|
||||
|
||||
################# vfmw_vp9 #################################
|
||||
VFMW_VP9_SUPPORT = YES
|
||||
#VFMW_VP9_SUPPORT = NO
|
||||
|
||||
################# vfmw_raw_num #############################
|
||||
#VFMW_RAW_NUM_SUPPORT = YES
|
||||
VFMW_RAW_NUM_SUPPORT = NO
|
||||
VFMW_MAX_RAW_NUM = 256
|
||||
|
||||
################# vfmw_seg_num #############################
|
||||
#VFMW_SEG_NUM_SUPPORT = YES
|
||||
VFMW_SEG_NUM_SUPPORT = NO
|
||||
VFMW_MAX_SEG_NUM = 256
|
||||
|
||||
################# vfmw_scd_msg_buffer ######################
|
||||
#VFMW_SCD_MSG_SUPPORT = YES
|
||||
VFMW_SCD_MSG_SUPPORT = NO
|
||||
VFMW_SCD_MSG_BUF = 64*1024
|
||||
|
||||
################# product_recpos ###########################
|
||||
#VFMW_RECPOS_SUPPORT = YES
|
||||
VFMW_RECPOS_SUPPORT = NO
|
||||
|
||||
################# SCD_SUPPORT ##############################
|
||||
VFMW_SCD_SUPPORT = YES
|
||||
#VFMW_SCD_SUPPORT = NO
|
||||
|
||||
################# VDH_SUPPORT ##############################
|
||||
VFMW_VDH_SUPPORT = YES
|
||||
#VFMW_VDH_SUPPORT = NO
|
||||
|
||||
################# VFMW SYSTEM REG DISABLE ##################
|
||||
VFMW_SYSTEM_REG_DISABLE = YES
|
||||
#VFMW_SYSTEM_REG_DISABLE = NO
|
||||
|
||||
################# VFMW SMMU ################################
|
||||
HIVDEC_SMMU_SUPPORT = YES
|
||||
#HIVDEC_SMMU_SUPPORT = NO
|
||||
|
||||
################# VFMW TVP #################################
|
||||
ifeq ($(TARGET_BOARD_PLATFORM), kirin970)
|
||||
VFMW_TVP_SUPPORT = YES
|
||||
#VFMW_TVP_SUPPORT = NO
|
||||
endif
|
||||
|
||||
|
||||
################# CONSTRAINT_VDH_PERFORMANCE #################################
|
||||
CONSTRAINT_VDH_PERFORMANCE = NO
|
||||
#CONSTRAINT_VDH_PERFORMANCE = YES
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
#include "vfmw_dts.h"
|
||||
#include "sysconfig.h"
|
||||
//#include "public.h"
|
||||
#include "omxvdec.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
unsigned int gIsFPGA = 0;
|
||||
unsigned int gVdhRegBaseAddr = 0;
|
||||
unsigned int gScdRegBaseAddr = 0;
|
||||
unsigned int gBpdRegBaseAddr = 0;
|
||||
unsigned int gVdhRegRange = 0;
|
||||
unsigned int gSOFTRST_REQ_Addr = 0;
|
||||
unsigned int gSOFTRST_OK_ADDR = 0;
|
||||
unsigned long long gSmmuPageBase = 0;
|
||||
unsigned int gPERICRG_RegBaseAddr = 0;
|
||||
|
||||
/* irq num */
|
||||
unsigned int gVdecIrqNumNorm = 0;
|
||||
unsigned int gVdecIrqNumProt = 0;
|
||||
unsigned int gVdecIrqNumSafe = 0;
|
||||
|
||||
int VFMW_SetDtsConfig(VFMW_DTS_CONFIG_S *pDtsConfig)
|
||||
{
|
||||
if (pDtsConfig == NULL) {
|
||||
printk(KERN_ERR "%s : pDtsConfig is NULL\n", __func__);
|
||||
return VDEC_ERR;
|
||||
}
|
||||
|
||||
if (pDtsConfig->VdecIrqNumNorm == 0 || pDtsConfig->VdecIrqNumProt == 0 || pDtsConfig->VdecIrqNumSafe == 0 ||
|
||||
pDtsConfig->VdhRegBaseAddr == 0 || pDtsConfig->VdhRegRange == 0 || pDtsConfig->SmmuPageBaseAddr == 0 ||
|
||||
pDtsConfig->PERICRG_RegBaseAddr == 0) {
|
||||
printk(KERN_ERR "%s invalid param: IsFPGA : %d, VdecIrqNumNorm : %d, VdecIrqNumProt : %d, VdecIrqNumSafe : %d, VdhRegBaseAddr : %pK, VdhRegSize : %d, SmmuPageBaseAddr : %pK, PERICRG_RegBaseAddr : %pK\n", __func__,
|
||||
pDtsConfig->IsFPGA, pDtsConfig->VdecIrqNumNorm, pDtsConfig->VdecIrqNumProt, pDtsConfig->VdecIrqNumSafe, (void *)(uintptr_t)(pDtsConfig->VdhRegBaseAddr), pDtsConfig->VdhRegRange, (void *)(uintptr_t)(pDtsConfig->SmmuPageBaseAddr), (void *)(uintptr_t)(pDtsConfig->PERICRG_RegBaseAddr));
|
||||
return VDEC_ERR;
|
||||
}
|
||||
|
||||
gIsFPGA = pDtsConfig->IsFPGA;
|
||||
gVdecIrqNumNorm = pDtsConfig->VdecIrqNumNorm;
|
||||
gVdecIrqNumProt = pDtsConfig->VdecIrqNumProt;
|
||||
gVdecIrqNumSafe = pDtsConfig->VdecIrqNumSafe;
|
||||
|
||||
gVdhRegBaseAddr = pDtsConfig->VdhRegBaseAddr;
|
||||
gVdhRegRange = pDtsConfig->VdhRegRange;
|
||||
gSmmuPageBase = pDtsConfig->SmmuPageBaseAddr;
|
||||
gPERICRG_RegBaseAddr = pDtsConfig->PERICRG_RegBaseAddr;
|
||||
|
||||
gScdRegBaseAddr = gVdhRegBaseAddr + SCD_REG_OFFSET;
|
||||
gBpdRegBaseAddr = gVdhRegBaseAddr + BPD_REG_OFFSET;
|
||||
gSOFTRST_REQ_Addr = gVdhRegBaseAddr + SOFTRST_REQ_OFFSET;
|
||||
gSOFTRST_OK_ADDR = gVdhRegBaseAddr + SOFTRST_OK_OFFSET;
|
||||
#if 0
|
||||
printk(KERN_ERR "%s invalid param: IsFPGA : %d, VdecIrqNumNorm : %d, VdecIrqNumProt : %d, VdecIrqNumSafe : %d, VdhRegBaseAddr : 0x%x, VdhRegSize : %d, SmmuPageBaseAddr : 0x%x, PERICRG_RegBaseAddr : 0x%x,range = 0x%x\n", __func__,
|
||||
pDtsConfig->IsFPGA, pDtsConfig->VdecIrqNumNorm, pDtsConfig->VdecIrqNumProt, pDtsConfig->VdecIrqNumSafe, (pDtsConfig->VdhRegBaseAddr), pDtsConfig->VdhRegRange, (pDtsConfig->SmmuPageBaseAddr),(uintptr_t)(pDtsConfig->PERICRG_RegBaseAddr),pDtsConfig->VdhRegRange);
|
||||
|
||||
#endif
|
||||
return VDEC_OK;
|
||||
}
|
||||
|
||||
int VFMW_GetDtsConfig(VFMW_DTS_CONFIG_S *pDtsConfig)
|
||||
{
|
||||
if (pDtsConfig == NULL) {
|
||||
printk(KERN_ERR "%s FATAL: pDtsConfig is NULL\n", __func__);
|
||||
return VDEC_ERR;
|
||||
}
|
||||
|
||||
pDtsConfig->IsFPGA = gIsFPGA;
|
||||
pDtsConfig->VdecIrqNumNorm = gVdecIrqNumNorm;
|
||||
pDtsConfig->VdecIrqNumProt = gVdecIrqNumProt;
|
||||
pDtsConfig->VdecIrqNumSafe = gVdecIrqNumSafe;
|
||||
|
||||
pDtsConfig->VdhRegBaseAddr = gVdhRegBaseAddr;
|
||||
pDtsConfig->VdhRegRange = gVdhRegRange;
|
||||
pDtsConfig->SmmuPageBaseAddr = gSmmuPageBase;
|
||||
|
||||
pDtsConfig->PERICRG_RegBaseAddr = gPERICRG_RegBaseAddr;
|
||||
|
||||
return VDEC_OK;
|
||||
}
|
||||
|
||||
#ifdef ENV_ARMLINUX_KERNEL
|
||||
EXPORT_SYMBOL(VFMW_SetDtsConfig);
|
||||
#endif
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#ifndef __VFMW_DTS_H__
|
||||
#define __VFMW_DTS_H__
|
||||
#include "vfmw.h"
|
||||
|
||||
int VFMW_SetDtsConfig(VFMW_DTS_CONFIG_S *pDtsConfig);
|
||||
int VFMW_GetDtsConfig(VFMW_DTS_CONFIG_S *pDtsConfig);
|
||||
|
||||
#endif
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* vfmw interface
|
||||
*
|
||||
* Copyright (c) 2017 Hisilicon Limited
|
||||
*
|
||||
* Author: gaoyajun<gaoyajun@hisilicon.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kern_levels.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
//#include "public.h"
|
||||
#include "vfmw_intf.h"
|
||||
|
||||
#include "../omxvdec/omxvdec.h"
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
#include "smmu.h"
|
||||
#endif
|
||||
#include "./format/vdm_hal_api.h"
|
||||
#include "vfmw_osal_ext.h"
|
||||
#include "linux_kernel_osal.h"
|
||||
#ifndef IRQF_DISABLED
|
||||
#define IRQF_DISABLED (0x00000020)
|
||||
#endif
|
||||
#define VDM_TIMEOUT (400)//ms
|
||||
#define VDM_FPGA_TIMEOUT (500000)//ms
|
||||
#define SCD_TIMEOUT (400)//ms
|
||||
#define SCD_FPGA_TIMEOUT (200000)//ms
|
||||
#define SCEN_IDENT (0x828)
|
||||
#define MAP_SIZE (256 * 1024)
|
||||
|
||||
#define TIME_PERIOD(begin, end) ((end >= begin)? (end-begin):(0xffffffff - begin + end))
|
||||
|
||||
// cppcheck-suppress *
|
||||
#define VCTRL_ASSERT_RET(cond, else_print) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
printk(KERN_ERR "%s %d %s\n", __func__, __LINE__, else_print ); \
|
||||
return VCTRL_ERR; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
static DRV_MEM_S g_RegsBaseAddr;
|
||||
|
||||
Vfmw_Osal_Func_Ptr g_vfmw_osal_fun_ptr;
|
||||
|
||||
void VCTRL_Suspend(void)
|
||||
{
|
||||
unsigned char isScdSleep = 0;
|
||||
unsigned char isVdmSleep = 0;
|
||||
unsigned int SleepCount = 0;
|
||||
unsigned int BeginTime, EntrTime, CurTime;
|
||||
|
||||
EntrTime = VFMW_OSAL_GetTimeInMs();
|
||||
|
||||
SCDDRV_PrepareSleep();
|
||||
|
||||
VDMHAL_PrepareSleep();
|
||||
|
||||
BeginTime = VFMW_OSAL_GetTimeInMs();
|
||||
do {
|
||||
if (SCDDRV_SLEEP_STAGE_SLEEP == SCDDRV_GetSleepStage())
|
||||
isScdSleep = 1;
|
||||
|
||||
if (VDMHAL_GetSleepStage() == VDMDRV_SLEEP_STAGE_SLEEP)
|
||||
isVdmSleep = 1;
|
||||
|
||||
if ((isScdSleep == 1) && (isVdmSleep == 1)) {
|
||||
break;
|
||||
} else {
|
||||
if (SleepCount > 30) {
|
||||
if (isScdSleep != 1) {
|
||||
printk(KERN_ERR "Force scd sleep\n");
|
||||
SCDDRV_ForceSleep();
|
||||
}
|
||||
if (isVdmSleep != 1) {
|
||||
printk(KERN_ERR "Force vdm sleep\n");
|
||||
VDMHAL_ForceSleep();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
VFMW_OSAL_mSleep(10);
|
||||
SleepCount++;
|
||||
}
|
||||
} while ((isScdSleep != 1) || (isVdmSleep != 1));
|
||||
|
||||
CurTime = VFMW_OSAL_GetTimeInMs();
|
||||
printk(KERN_INFO "Vfmw suspend totally take %d ms\n", TIME_PERIOD(EntrTime, CurTime));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VCTRL_Resume(void)
|
||||
{
|
||||
unsigned int EntrTime, CurTime;
|
||||
|
||||
EntrTime = VFMW_OSAL_GetTimeInMs();
|
||||
|
||||
SMMU_InitGlobalReg();
|
||||
|
||||
SCDDRV_ExitSleep();
|
||||
|
||||
VDMHAL_ExitSleep();
|
||||
|
||||
CurTime = VFMW_OSAL_GetTimeInMs();
|
||||
printk(KERN_INFO "Vfmw resume totally take %d ms\n", TIME_PERIOD(EntrTime, CurTime));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int VCTRL_ISR(int irq, void *dev_id)
|
||||
{
|
||||
unsigned int D32;
|
||||
D32 = RD_SCDREG(REG_SCD_INI_CLR)&0x1;
|
||||
if (D32 == 1)
|
||||
SCDDRV_ISR();
|
||||
|
||||
RD_VREG(VREG_INT_STATE, D32, 0);
|
||||
if (D32 == 1)
|
||||
VDMHAL_ISR(0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int VCTRL_RequestIrq(unsigned int IrqNumNorm, unsigned int IrqNumProt, unsigned int IrqNumSafe)
|
||||
{
|
||||
#if !defined(VDM_BUSY_WAITTING)
|
||||
if (VFMW_OSAL_RequestIrq(IrqNumNorm, VCTRL_ISR, IRQF_DISABLED, "vdec_norm_irq", NULL) != 0) { //for 2.6.24ÒÔºó
|
||||
printk(KERN_ERR "Request vdec norm irq %d failed\n", IrqNumNorm);
|
||||
return VCTRL_ERR;
|
||||
}
|
||||
#endif
|
||||
return VCTRL_OK;
|
||||
}
|
||||
|
||||
static void VCTRL_FreeIrq(unsigned int IrqNumNorm, unsigned int IrqNumProt, unsigned int IrqNumSafe)
|
||||
{
|
||||
#if !defined(VDM_BUSY_WAITTING)
|
||||
VFMW_OSAL_FreeIrq(IrqNumNorm, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int VCTRL_HalInit(void)
|
||||
{
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
if (SMMU_Init() != SMMU_OK) {
|
||||
printk(KERN_ERR "SMMU_Init failed\n");
|
||||
return VCTRL_ERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
SCDDRV_init();
|
||||
VDMHAL_IMP_Init();
|
||||
SMMU_InitGlobalReg();
|
||||
|
||||
return VCTRL_OK;
|
||||
}
|
||||
|
||||
static void VCTRL_HalDeInit(void)
|
||||
{
|
||||
#ifdef HIVDEC_SMMU_SUPPORT
|
||||
SMMU_DeInit();
|
||||
#endif
|
||||
VDMHAL_IMP_DeInit();
|
||||
SCDDRV_DeInit();
|
||||
}
|
||||
|
||||
int VCTRL_OpenDrivers(void)
|
||||
{
|
||||
MEM_RECORD_S *pstMem;
|
||||
int ret = VCTRL_ERR;
|
||||
|
||||
pstMem = &g_RegsBaseAddr.stVdhReg;
|
||||
if (MEM_MapRegisterAddr(gVdhRegBaseAddr, MAP_SIZE, pstMem) == MEM_MAN_OK) {
|
||||
if (MEM_AddMemRecord(pstMem->PhyAddr, pstMem->VirAddr, pstMem->Length) != MEM_MAN_OK) {
|
||||
printk(KERN_ERR "%s %d MEM_AddMemRecord failed\n", __func__, __LINE__);
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "Map vdh register failed! gVdhRegBaseAddr : %pK, gVdhRegRange : %d\n",
|
||||
(void *)(uintptr_t)gVdhRegBaseAddr, gVdhRegRange);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = VCTRL_RequestIrq(gVdecIrqNumNorm, gVdecIrqNumProt, gVdecIrqNumSafe);
|
||||
if (ret != VCTRL_OK) {
|
||||
printk(KERN_ERR "VCTRL_RequestIrq failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (VCTRL_HalInit() != VCTRL_OK) {
|
||||
printk(KERN_ERR "VCTRL_HalInit failed\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
VFMW_OSAL_InitEvent(G_SCDHWDONEEVENT, 0);
|
||||
VFMW_OSAL_InitEvent(G_VDMHWDONEEVENT, 0);
|
||||
|
||||
return VCTRL_OK;
|
||||
|
||||
exit:
|
||||
VCTRL_CloseVfmw();
|
||||
return VCTRL_ERR;
|
||||
}
|
||||
|
||||
int VCTRL_OpenVfmw(void)
|
||||
{
|
||||
memset(&g_RegsBaseAddr, 0, sizeof(g_RegsBaseAddr)); /* unsafe_function_ignore: m
|
||||
emset */
|
||||
|
||||
MEM_InitMemManager();
|
||||
if (VCTRL_OpenDrivers() != VCTRL_OK) {
|
||||
printk(KERN_ERR "OpenDrivers fail\n");
|
||||
return VCTRL_ERR;
|
||||
}
|
||||
|
||||
return VCTRL_OK;
|
||||
}
|
||||
|
||||
int VCTRL_CloseVfmw(void)
|
||||
{
|
||||
MEM_RECORD_S *pstMem;
|
||||
|
||||
VCTRL_HalDeInit();
|
||||
|
||||
pstMem = &g_RegsBaseAddr.stVdhReg;
|
||||
if (pstMem->Length != 0) {
|
||||
MEM_UnmapRegisterAddr(pstMem->PhyAddr, pstMem->VirAddr, pstMem->Length);
|
||||
MEM_DelMemRecord(pstMem->PhyAddr, pstMem->VirAddr, pstMem->Length);
|
||||
memset(&g_RegsBaseAddr.stVdhReg, 0, sizeof(g_RegsBaseAddr.stVdhReg)); /* unsafe_function_ignore: m
|
||||
emset */
|
||||
}
|
||||
|
||||
VCTRL_FreeIrq(gVdecIrqNumNorm, gVdecIrqNumProt, gVdecIrqNumSafe);
|
||||
|
||||
return VCTRL_OK;
|
||||
}
|
||||
|
||||
int VCTRL_VDMHal_Process(OMXVDH_REG_CFG_S *pVdmRegCfg, VDMHAL_BACKUP_S *pVdmRegState)
|
||||
{
|
||||
int ret = HI_SUCCESS;
|
||||
VDMDRV_SLEEP_STAGE_E sleepState;
|
||||
|
||||
sleepState = VDMHAL_GetSleepStage();
|
||||
if (VDMDRV_SLEEP_STAGE_SLEEP == sleepState) {
|
||||
printk(KERN_INFO "vdm sleep state\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (pVdmRegCfg->vdh_reset_flag)
|
||||
VDMHAL_IMP_ResetVdm(0);
|
||||
|
||||
VFMW_OSAL_InitEvent(G_VDMHWDONEEVENT, 0);
|
||||
ret = VDMHAL_HwDecProc(pVdmRegCfg);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s config error\n", __func__);
|
||||
} else {
|
||||
ret = VFMW_OSAL_WaitEvent(G_VDMHWDONEEVENT, VDM_TIMEOUT);
|
||||
if (ret == HI_SUCCESS) {
|
||||
VDMHAL_GetRegState(pVdmRegState);
|
||||
} else {
|
||||
printk(KERN_ERR "VFMW_OSAL_WaitEvent wait time out\n");
|
||||
VDMHAL_IMP_ResetVdm(0);
|
||||
}
|
||||
}
|
||||
|
||||
sleepState = VDMHAL_GetSleepStage();
|
||||
if (sleepState == VDMDRV_SLEEP_STAGE_PREPARE)
|
||||
VDMHAL_SetSleepStage(VDMDRV_SLEEP_STAGE_SLEEP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VCTRL_SCDHal_Process(OMXSCD_REG_CFG_S *pScdRegCfg,SCD_STATE_REG_S *pScdStateReg)
|
||||
{
|
||||
int ret = HI_SUCCESS;
|
||||
SCDDRV_SLEEP_STAGE_E sleepState;
|
||||
CONFIG_SCD_CMD cmd = pScdRegCfg->cmd;
|
||||
|
||||
sleepState = SCDDRV_GetSleepStage();
|
||||
if (SCDDRV_SLEEP_STAGE_SLEEP == sleepState) {
|
||||
printk(KERN_INFO "SCD sleep state\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (pScdRegCfg->SResetFlag) {
|
||||
if (SCDDRV_ResetSCD() != HI_SUCCESS) {
|
||||
printk(KERN_ERR "VDEC_IOCTL_SCD_WAIT_HW_DONE Reset SCD failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case CONFIG_SCD_REG_CMD:
|
||||
VFMW_OSAL_InitEvent(G_SCDHWDONEEVENT, 0);
|
||||
ret = SCDDRV_WriteReg(&pScdRegCfg->SmCtrlReg );
|
||||
if (ret != HI_SUCCESS) {
|
||||
printk(KERN_ERR "SCD busy\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = VFMW_OSAL_WaitEvent(G_SCDHWDONEEVENT,SCD_TIMEOUT);
|
||||
if (ret == HI_SUCCESS) {
|
||||
SCDDRV_GetRegState(pScdStateReg);
|
||||
} else {
|
||||
printk(KERN_INFO "VDEC_IOCTL_SCD_WAIT_HW_DONE wait time out\n");
|
||||
SCDDRV_ResetSCD();
|
||||
}
|
||||
|
||||
sleepState = SCDDRV_GetSleepStage();
|
||||
if (sleepState == SCDDRV_SLEEP_STAGE_PREPARE) {
|
||||
SCDDRV_SetSleepStage(SCDDRV_SLEEP_STAGE_SLEEP);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR " cmd type unknown:%d\n", cmd);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int VCTRL_VDMHAL_IsRun(void)
|
||||
{
|
||||
return VDMHAL_IsVdmRun(0);
|
||||
}
|
||||
|
||||
int VCTRL_Scen_Ident(unsigned int cmd)
|
||||
{
|
||||
if ((RD_SCDREG(SCEN_IDENT) == 1) && (cmd != VDEC_IOCTL_SET_CLK_RATE))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VFMW_DRV_ModInit(void)
|
||||
{
|
||||
OSAL_InitInterface();
|
||||
VFMW_OSAL_SemaInit(G_SCD_SEM);
|
||||
VFMW_OSAL_SemaInit(G_VDH_SEM);
|
||||
VFMW_OSAL_SemaInit(G_BPD_SEM);
|
||||
|
||||
VFMW_OSAL_SpinLockInit(G_SPINLOCK_SCD);
|
||||
VFMW_OSAL_SpinLockInit(G_SPINLOCK_VDH);
|
||||
VFMW_OSAL_SpinLockInit(G_SPINLOCK_RECORD);
|
||||
VFMW_OSAL_InitEvent(G_SCDHWDONEEVENT, 0);
|
||||
VFMW_OSAL_InitEvent(G_VDMHWDONEEVENT, 0);
|
||||
|
||||
#ifdef MODULE
|
||||
printk(KERN_INFO "%s : Load hi_vfmw.ko (%d) success\n", __func__, VFMW_VERSION_NUM);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VFMW_DRV_ModExit(void)
|
||||
{
|
||||
#ifdef MODULE
|
||||
printk(KERN_INFO "%s : Unload hi_vfmw.ko (%d) success\n",__func__, VFMW_VERSION_NUM);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(VFMW_DRV_ModInit);
|
||||
module_exit(VFMW_DRV_ModExit);
|
||||
|
||||
MODULE_AUTHOR("gaoyajun");
|
||||
MODULE_LICENSE("GPL");
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
#ifndef __VFMW_INTF_H__
|
||||
#define __VFMW_INTF_H__
|
||||
//#include "../omxvdec/memory.h"
|
||||
#include "./format/vdm_drv.h"
|
||||
#include "scd_drv.h"
|
||||
|
||||
#define VCTRL_OK 0
|
||||
#define VCTRL_ERR -1
|
||||
#define MSG_POOL_ADDR_CHECK
|
||||
|
||||
typedef struct hiDRV_MEM_S {
|
||||
MEM_RECORD_S stVdhReg;
|
||||
} DRV_MEM_S;
|
||||
|
||||
int VCTRL_OpenDrivers(void);
|
||||
|
||||
int VCTRL_OpenVfmw(void);
|
||||
|
||||
int VCTRL_CloseVfmw(void);
|
||||
|
||||
int VCTRL_VDMHal_Process(OMXVDH_REG_CFG_S *pVdmRegCfg, VDMHAL_BACKUP_S *pVdmRegStatei);
|
||||
|
||||
int VCTRL_SCDHal_Process(OMXSCD_REG_CFG_S *pScdRegCfg, SCD_STATE_REG_S *pScdStateReg);
|
||||
|
||||
int VCTRL_VDMHAL_IsRun(void);
|
||||
|
||||
void VCTRL_Suspend(void);
|
||||
|
||||
void VCTRL_Resume(void);
|
||||
|
||||
int VCTRL_Scen_Ident(unsigned int cmd);
|
||||
|
||||
#endif
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
################################################################################################
|
||||
# purpose:
|
||||
# This file provide two vars: VFMW_CFLAGS, VFMW_CFILES
|
||||
# VFMW_CFLAGS --- compile options for vfmw
|
||||
# VFMW_CFILES --- specify the files to be compiled
|
||||
###############################################################################################
|
||||
VFMW_DIR := drivers/vcodec/vdec_hivna/vfmw_v4.0
|
||||
|
||||
VFMW_INC_DIR := $(VFMW_DIR)
|
||||
|
||||
SCENE_DIR := kirin
|
||||
|
||||
include $(VFMW_DIR)/vfmw_config.cfg
|
||||
|
||||
#===============================================================================
|
||||
# options
|
||||
#===============================================================================
|
||||
VFMW_CFLAGS := -DENV_ARMLINUX_KERNEL
|
||||
VFMW_CFLAGS += -DSCD_MP4_SLICE_ENABLE
|
||||
VFMW_CFLAGS += -DVFMW_EXTRA_TYPE_DEFINE
|
||||
VFMW_CFLAGS += -DPRODUCT_KIRIN
|
||||
VFMW_CFLAGS += -DQ_MATRIX_FIXED
|
||||
VFMW_CFLAGS += -DPLATFORM_KIRIN970
|
||||
|
||||
ifneq ($(TARGET_BUILD_VARIANT),user)
|
||||
VFMW_CFLAGS += -DUSER_DISABLE_VDEC_PROC
|
||||
endif
|
||||
|
||||
################ VDH_VERSION #############
|
||||
ifeq ($(VFMW_VDH_SUPPORT),YES)
|
||||
VDH_DIR := format
|
||||
VFMW_CFLAGS += -DVFMW_VDH_SUPPORT
|
||||
endif
|
||||
##########################################
|
||||
|
||||
################ TEST OPTION ############
|
||||
#VFMW_CFLAGS += -DKTEST_VFMW_SLEEP
|
||||
ifeq ($(VFMW_TEST),YES)
|
||||
VFMW_CFLAGS += -DVFMW_KTEST
|
||||
endif
|
||||
##########################################
|
||||
|
||||
################ SMMU VERSION ############
|
||||
ifeq ($(HIVDEC_SMMU_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DHIVDEC_SMMU_SUPPORT
|
||||
endif
|
||||
##########################################
|
||||
|
||||
#===============================================================================
|
||||
# include path
|
||||
#===============================================================================
|
||||
VFMW_CFLAGS += -I$(VFMW_INC_DIR)
|
||||
|
||||
#===============================================================================
|
||||
# VFMW_CFILES
|
||||
#===============================================================================
|
||||
VFMW_CFILES := vfmw_dts.o
|
||||
VFMW_CFILES += linux_kernel_osal.o \
|
||||
mem_manage.o \
|
||||
vfmw_intf.o \
|
||||
scd_drv.o
|
||||
|
||||
#===============================================================================
|
||||
# vdh hal seclect
|
||||
#===============================================================================
|
||||
VFMW_CFILES += $(VDH_DIR)/vdm_hal.o
|
||||
|
||||
#===============================================================================
|
||||
# SMMU hal seclect
|
||||
#===============================================================================
|
||||
ifeq ($(HIVDEC_SMMU_SUPPORT),YES)
|
||||
VFMW_CFILES += smmu.o
|
||||
endif
|
||||
|
||||
#===============================================================================
|
||||
# vfmw video type support
|
||||
#===============================================================================
|
||||
################# vfmw_h264 #################
|
||||
ifeq ($(VFMW_H264_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_H264_SUPPORT
|
||||
VFMW_CFILES += $(VDH_DIR)/vdm_hal_h264.o
|
||||
endif
|
||||
|
||||
################# vfmw_hevc #################
|
||||
ifeq ($(VFMW_HEVC_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_HEVC_SUPPORT
|
||||
VFMW_CFILES += /$(VDH_DIR)/vdm_hal_hevc.o
|
||||
endif
|
||||
|
||||
################# vfmw_mpeg2 #################
|
||||
ifeq ($(VFMW_MPEG2_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_MPEG2_SUPPORT
|
||||
VFMW_CFILES += $(VDH_DIR)/vdm_hal_mpeg2.o
|
||||
endif
|
||||
|
||||
################# vfmw_mpeg4 #################
|
||||
ifeq ($(VFMW_MPEG4_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_MPEG4_SUPPORT
|
||||
VFMW_CFILES += $(VDH_DIR)/vdm_hal_mpeg4.o
|
||||
endif
|
||||
|
||||
################# vfmw_bpd #################
|
||||
ifeq ($(VFMW_BPD_H_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_BPD_H_SUPPORT
|
||||
endif
|
||||
|
||||
################# vfmw_vp8 #################
|
||||
ifeq ($(VFMW_VP8_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_VP8_SUPPORT
|
||||
VFMW_CFILES += $(VDH_DIR)/vdm_hal_vp8.o
|
||||
endif
|
||||
|
||||
################# vfmw_vp9 #################
|
||||
ifeq ($(VFMW_VP9_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DVFMW_VP9_SUPPORT
|
||||
VFMW_CFILES += $(VDH_DIR)/vdm_hal_vp9.o
|
||||
endif
|
||||
|
||||
################# vfmw_raw_num #################
|
||||
ifeq ($(VFMW_RAW_NUM_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DCFG_MAX_RAW_NUM=$(VFMW_MAX_RAW_NUM)
|
||||
endif
|
||||
|
||||
################# vfmw_seg_num #################
|
||||
ifeq ($(VFMW_SEG_NUM_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DCFG_MAX_SEG_NUM=$(VFMW_MAX_SEG_NUM)
|
||||
endif
|
||||
|
||||
################# vfmw_scd_msg_buffer ##########
|
||||
ifeq ($(VFMW_SCD_MSG_SUPPORT),YES)
|
||||
VFMW_CFLAGS += -DCFG_SCD_BUF=$(VFMW_SCD_MSG_BUF)
|
||||
endif
|
||||
|
||||
################# VFMW_SYSTEM_REG_DISABLE #######
|
||||
ifeq ($(VFMW_SYSTEM_REG_DISABLE),YES)
|
||||
VFMW_CFLAGS += -DVFMW_SYSTEM_REG_DISABLE
|
||||
endif
|
||||
|
||||
################# CONSTRAINT_VDH_PERFORMANCE #######
|
||||
ifeq ($(CONSTRAINT_VDH_PERFORMANCE),YES)
|
||||
VFMW_CFLAGS += -DCONSTRAINT_VDH_PERFORMANCE
|
||||
endif
|
||||
|
||||
################# TARGET_BOARD_PLATFORM############
|
||||
ifeq ($(TARGET_BOARD_PLATFORM), hi3660)
|
||||
VFMW_CFLAGS +=-DPLATFORM_HI3660
|
||||
endif
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
|
||||
#ifndef __VFMW_OSAL_EXT_HEADER__
|
||||
#define __VFMW_OSAL_EXT_HEADER__
|
||||
|
||||
#include "vfmw.h"
|
||||
#include "mem_manage.h"
|
||||
|
||||
#define OSAL_OK 0
|
||||
#define OSAL_ERR -1
|
||||
|
||||
typedef int(*OSAL_IRQ_HANDLER_t) (int, void *);
|
||||
|
||||
typedef enum SpinLockType {
|
||||
G_SPINLOCK_SCD = 0,
|
||||
G_SPINLOCK_VDH,
|
||||
G_SPINLOCK_RECORD,
|
||||
} SpinLockType;
|
||||
|
||||
typedef enum MutexType {
|
||||
G_SCDHWDONEEVENT = 0,
|
||||
G_VDMHWDONEEVENT,
|
||||
} MutexType;
|
||||
|
||||
typedef enum SemType {
|
||||
G_SCD_SEM = 0,
|
||||
G_VDH_SEM,
|
||||
G_BPD_SEM,
|
||||
} SemType;
|
||||
|
||||
typedef unsigned int (*FN_OSAL_GetTimeInMs) (void);
|
||||
typedef unsigned int (*FN_OSAL_GetTimeInUs) (void);
|
||||
typedef void (*FN_OSAL_SpinLockInit) (SpinLockType);
|
||||
typedef int (*FN_OSAL_SpinLock) (SpinLockType);
|
||||
typedef int (*FN_OSAL_SpinUnlock) (SpinLockType);
|
||||
typedef void (*FN_OSAL_SemaInit) (SemType);
|
||||
typedef int (*FN_OSAL_SemaDown) (SemType);
|
||||
typedef void (*FN_OSAL_SemaUp) (SemType);
|
||||
typedef int (*FN_OSAL_Print) (const char *, ...);
|
||||
typedef void (*FN_OSAL_Mb) (void);
|
||||
typedef void (*FN_OSAL_uDelay) (unsigned long);
|
||||
typedef void (*FN_OSAL_mSleep) (unsigned int);
|
||||
typedef int (*FN_OSAL_InitEvent) (MutexType, int);
|
||||
typedef int (*FN_OSAL_GiveEvent) (MutexType);
|
||||
typedef int (*FN_OSAL_WaitEvent) (MutexType, int);
|
||||
typedef int (*FN_OSAL_MemAlloc) (unsigned char *, unsigned int, unsigned int, unsigned int, MEM_DESC_S *);
|
||||
typedef int (*FN_OSAL_MemFree) (MEM_DESC_S *);
|
||||
typedef unsigned char *(*FN_OSAL_RegisterMap) (unsigned int, unsigned int);
|
||||
typedef void (*FN_OSAL_RegisterUnMap) (unsigned char *, unsigned int);
|
||||
typedef unsigned char *(*FN_OSAL_Mmap) (unsigned int, unsigned int);
|
||||
typedef unsigned char *(*FN_OSAL_MmapCache) (unsigned int, unsigned int);
|
||||
typedef void (*FN_OSAL_MunMap) (unsigned char *);
|
||||
typedef int (*FN_OSAL_RequestIrq) (unsigned int, OSAL_IRQ_HANDLER_t, unsigned long, const char *, void *);
|
||||
typedef void (*FN_OSAL_FreeIrq) (unsigned int, void *);
|
||||
typedef void *(*FN_OSAL_AllocVirMem) (int);
|
||||
typedef void (*FN_OSAL_FreeVirMem) (void *);
|
||||
typedef int (*FN_OSAL_ProcInit) (void);
|
||||
typedef void (*FN_OSAL_ProcExit) (void);
|
||||
|
||||
typedef struct Vfmw_Osal_Func_Ptr {
|
||||
FN_OSAL_GetTimeInMs pfun_Osal_GetTimeInMs;
|
||||
FN_OSAL_GetTimeInUs pfun_Osal_GetTimeInUs;
|
||||
FN_OSAL_SpinLockInit pfun_Osal_SpinLockInit;
|
||||
FN_OSAL_SpinLock pfun_Osal_SpinLock;
|
||||
FN_OSAL_SpinUnlock pfun_Osal_SpinUnLock;
|
||||
FN_OSAL_SemaInit pfun_Osal_SemaInit;
|
||||
FN_OSAL_SemaDown pfun_Osal_SemaDown;
|
||||
FN_OSAL_SemaUp pfun_Osal_SemaUp;
|
||||
FN_OSAL_Print pfun_Osal_Print;
|
||||
FN_OSAL_Mb pfun_Osal_Mb;
|
||||
FN_OSAL_uDelay pfun_Osal_uDelay;
|
||||
FN_OSAL_mSleep pfun_Osal_mSleep;
|
||||
FN_OSAL_InitEvent pfun_Osal_InitEvent;
|
||||
FN_OSAL_GiveEvent pfun_Osal_GiveEvent;
|
||||
FN_OSAL_WaitEvent pfun_Osal_WaitEvent;
|
||||
FN_OSAL_RequestIrq pfun_Osal_RequestIrq;
|
||||
FN_OSAL_FreeIrq pfun_Osal_FreeIrq;
|
||||
FN_OSAL_MemAlloc pfun_Osal_MemAlloc;
|
||||
FN_OSAL_MemFree pfun_Osal_MemFree;
|
||||
FN_OSAL_RegisterMap pfun_Osal_RegisterMap;
|
||||
FN_OSAL_RegisterUnMap pfun_Osal_RegisterUnMap;
|
||||
FN_OSAL_Mmap pfun_Osal_Mmap;
|
||||
FN_OSAL_MmapCache pfun_Osal_MmapCache;
|
||||
FN_OSAL_MunMap pfun_Osal_MunMap;
|
||||
FN_OSAL_AllocVirMem pfun_Osal_AllocVirMem;
|
||||
FN_OSAL_FreeVirMem pfun_Osal_FreeVirMem;
|
||||
FN_OSAL_ProcInit pfun_Osal_ProcInit;
|
||||
FN_OSAL_ProcExit pfun_Osal_ProcExit;
|
||||
} Vfmw_Osal_Func_Ptr;
|
||||
|
||||
extern Vfmw_Osal_Func_Ptr g_vfmw_osal_fun_ptr;
|
||||
|
||||
#define VFMW_OSAL_GetTimeInMs g_vfmw_osal_fun_ptr.pfun_Osal_GetTimeInMs
|
||||
#define VFMW_OSAL_GetTimeInUs g_vfmw_osal_fun_ptr.pfun_Osal_GetTimeInUs
|
||||
#define VFMW_OSAL_SpinLockInit g_vfmw_osal_fun_ptr.pfun_Osal_SpinLockInit
|
||||
#define VFMW_OSAL_SpinLock g_vfmw_osal_fun_ptr.pfun_Osal_SpinLock
|
||||
#define VFMW_OSAL_SpinUnLock g_vfmw_osal_fun_ptr.pfun_Osal_SpinUnLock
|
||||
#define VFMW_OSAL_SemaInit g_vfmw_osal_fun_ptr.pfun_Osal_SemaInit
|
||||
#define VFMW_OSAL_SemaDown g_vfmw_osal_fun_ptr.pfun_Osal_SemaDown
|
||||
#define VFMW_OSAL_SemaUp g_vfmw_osal_fun_ptr.pfun_Osal_SemaUp
|
||||
#define VFMW_OSAL_Print g_vfmw_osal_fun_ptr.pfun_Osal_Print
|
||||
#define VFMW_OSAL_Mb g_vfmw_osal_fun_ptr.pfun_Osal_Mb
|
||||
#define VFMW_OSAL_uDelay g_vfmw_osal_fun_ptr.pfun_Osal_uDelay
|
||||
#define VFMW_OSAL_mSleep g_vfmw_osal_fun_ptr.pfun_Osal_mSleep
|
||||
#define VFMW_OSAL_InitEvent g_vfmw_osal_fun_ptr.pfun_Osal_InitEvent
|
||||
#define VFMW_OSAL_GiveEvent g_vfmw_osal_fun_ptr.pfun_Osal_GiveEvent
|
||||
#define VFMW_OSAL_WaitEvent g_vfmw_osal_fun_ptr.pfun_Osal_WaitEvent
|
||||
#define VFMW_OSAL_RequestIrq g_vfmw_osal_fun_ptr.pfun_Osal_RequestIrq
|
||||
#define VFMW_OSAL_FreeIrq g_vfmw_osal_fun_ptr.pfun_Osal_FreeIrq
|
||||
#define VFMW_OSAL_MemAlloc g_vfmw_osal_fun_ptr.pfun_Osal_MemAlloc
|
||||
#define VFMW_OSAL_MemFree g_vfmw_osal_fun_ptr.pfun_Osal_MemFree
|
||||
#define VFMW_OSAL_RegisterMap g_vfmw_osal_fun_ptr.pfun_Osal_RegisterMap
|
||||
#define VFMW_OSAL_RegisterUnMap g_vfmw_osal_fun_ptr.pfun_Osal_RegisterUnMap
|
||||
#define VFMW_OSAL_Mmap g_vfmw_osal_fun_ptr.pfun_Osal_Mmap
|
||||
#define VFMW_OSAL_MmapCache g_vfmw_osal_fun_ptr.pfun_Osal_MmapCache
|
||||
#define VFMW_OSAL_MunMap g_vfmw_osal_fun_ptr.pfun_Osal_MunMap
|
||||
#define VFMW_OSAL_AllocVirMem g_vfmw_osal_fun_ptr.pfun_Osal_AllocVirMem
|
||||
#define VFMW_OSAL_FreeVirMem g_vfmw_osal_fun_ptr.pfun_Osal_FreeVirMem
|
||||
#define VFMW_OSAL_ProcInit g_vfmw_osal_fun_ptr.pfun_Osal_ProcInit
|
||||
#define VFMW_OSAL_ProcExit g_vfmw_osal_fun_ptr.pfun_Osal_ProcExit
|
||||
|
||||
#endif
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
menu "Hisilicon video venc support"
|
||||
config HI_VCODEC_VENC
|
||||
#depends on ANDROID_PMEM
|
||||
tristate "Support for venc"
|
||||
default n
|
||||
help
|
||||
The decode device provides venc function
|
||||
endmenu
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
# Add your debugging flag (or not) to CFLAGS
|
||||
include drivers/vcodec/venc_hivna/drv_venc_make.cfg
|
||||
|
||||
EXTRA_CFLAGS += $(VENC_CFLAGS) -fno-pic
|
||||
EXTRA_CFLAGS += -Idrivers/vcodec/venc_hivna
|
||||
EXTRA_CFLAGS += -DPLATFORM_KIRIN970
|
||||
|
||||
obj-$(CONFIG_HI_VCODEC_VENC) += hi_omxvenc.o
|
||||
hi_omxvenc-objs := venc_regulator.o \
|
||||
drv_venc_intf.o \
|
||||
drv_venc_efl.o \
|
||||
drv_venc_osal.o \
|
||||
drv_venc.o \
|
||||
hal_venc.o \
|
||||
hi_drv_mem.o
|
||||
|
||||
+12728
File diff suppressed because it is too large
Load Diff
Executable
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C), 2004-2050, Hisilicon Tech. Co., Ltd.
|
||||
*
|
||||
* File Name : drv_venc.c
|
||||
* Version : Initial Draft
|
||||
* Author : Hisilicon multimedia software group
|
||||
* Created : 2010/04/07
|
||||
* Last Modified :
|
||||
* Description :
|
||||
* Function List :
|
||||
*
|
||||
* History :
|
||||
* 1.Date :
|
||||
* Author : j00131665
|
||||
* Modification : Created file
|
||||
*/
|
||||
#include "drv_venc.h"
|
||||
#include "venc_regulator.h"
|
||||
#include "drv_venc_osal.h"
|
||||
|
||||
unsigned int b_Regular_down_flag = 1;
|
||||
|
||||
/* 外边复位vedu, 并设置时钟,撤销复位l00214825 */
|
||||
int VENC_DRV_BoardInit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
HI_DBG_VENC("enter %s()\n", __func__);
|
||||
|
||||
ret = Venc_Regulator_Enable();/*lint !e838 */
|
||||
if (ret != 0){
|
||||
HI_INFO_VENC("enable regulator failed\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
HI_DBG_VENC("exit %s ()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
void VENC_DRV_BoardDeinit(void)
|
||||
{
|
||||
HI_DBG_VENC("enter %s ()\n", __func__);
|
||||
|
||||
Venc_Regulator_Disable();
|
||||
|
||||
HI_DBG_VENC("exit %s ()\n", __func__);
|
||||
}
|
||||
|
||||
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#ifndef __DRV_VENC_H__
|
||||
#define __DRV_VENC_H__
|
||||
|
||||
#include "Vedu_RegAll_Kirin970.h"
|
||||
#include "drv_venc_efl.h"
|
||||
#include <linux/fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hisi/hisi-iommu.h>
|
||||
#include <linux/iommu.h>
|
||||
|
||||
#ifndef _M_IX86
|
||||
typedef unsigned long long HI_U64;
|
||||
#else
|
||||
typedef __int64 HI_U64;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0L
|
||||
#endif
|
||||
#define HI_SUCCESS (0)
|
||||
#define HI_FAILURE (-1)
|
||||
#define MAX_STREAMBUF_NUM (16)
|
||||
#define IOC_TYPE_VENC 'V'
|
||||
|
||||
extern unsigned int b_Regular_down_flag;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VENC_SET_CFGREG = 100,
|
||||
VENC_SET_CFGREGSIMPLE
|
||||
}CMD_TYPE;
|
||||
|
||||
typedef enum {
|
||||
VENC_CLK_RATE_LOW = 0,
|
||||
VENC_CLK_RATE_NORMAL,
|
||||
VENC_CLK_RATE_HIGH,
|
||||
} VENC_CLK_TYPE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int InteralShareFd;
|
||||
int ImageShareFd;
|
||||
int StreamShareFd[MAX_STREAMBUF_NUM];
|
||||
int StreamHeadShareFd;
|
||||
}VENC_MEM_INFO_S;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CMD_TYPE cmd;
|
||||
|
||||
int bResetReg;
|
||||
int bClkCfg;
|
||||
int bFirstNal2Send;
|
||||
unsigned int bSecureFlag;
|
||||
U_FUNC_VCPI_RAWINT hw_done_type;
|
||||
S_HEVC_AVC_REGS_TYPE_CFG all_reg;
|
||||
VENC_CLK_TYPE clk_type;
|
||||
VENC_MEM_INFO_S mem_info;
|
||||
}VENC_REG_INFO_S;
|
||||
|
||||
#define CMD_VENC_START_ENCODE _IOWR(IOC_TYPE_VENC, 0x32, VENC_REG_INFO_S)
|
||||
|
||||
int VENC_DRV_BoardInit(void);
|
||||
void VENC_DRV_BoardDeinit(void);
|
||||
int VENC_DRV_MemProcAdd(void);
|
||||
void VENC_DRV_MemProcDel(void);
|
||||
|
||||
void VENC_HAL_ClrAllInt(S_HEVC_AVC_REGS_TYPE * pVeduReg);
|
||||
void VENC_HAL_DisableAllInt(S_HEVC_AVC_REGS_TYPE * pVeduReg);
|
||||
int VENC_HAL_ResetReg(void);
|
||||
void VENC_HAL_StartEncode(S_HEVC_AVC_REGS_TYPE * pVeduReg);
|
||||
void VENC_HAL_Get_CfgRegSimple(VENC_REG_INFO_S * pVeduReg);
|
||||
void VENC_HAL_Get_Reg_Venc(VENC_REG_INFO_S * pVeduReg);
|
||||
void VeduHal_CfgReg_IntraSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg_LambdaSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg_QpgmapSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg_AddrSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg_SlcHeadSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg_SMMUSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg_PREMMUSet(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgRegSimple(VENC_REG_INFO_S * channelcfg);
|
||||
void VeduHal_CfgReg(VENC_REG_INFO_S * regcfginfo);
|
||||
void VENC_HAL_SetSmmuAddr(S_HEVC_AVC_REGS_TYPE * pVeduReg);
|
||||
#endif //__DRV_VENC_H__
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
##############################################################
|
||||
# VENC DRV CFG #
|
||||
##############################################################
|
||||
|
||||
############## VENC_SIMULATE #######################
|
||||
#VENC_SIMULATE = YES
|
||||
VENC_SIMULATE = NO
|
||||
|
||||
############## TEST_TIME ###########################
|
||||
#TEST_TIME = YES
|
||||
TEST_TIME = NO
|
||||
|
||||
############## SLICE_INT_EN ########################
|
||||
#SLICE_INT_EN = YES
|
||||
SLICE_INT_EN = NO
|
||||
|
||||
############## RE_ENCODE_EN ########################
|
||||
#RE_ENCODE_EN = YES
|
||||
RE_ENCODE_EN = NO
|
||||
|
||||
############## SPLIT_SPS_PPS #######################
|
||||
SPLIT_SPS_PPS = YES
|
||||
#SPLIT_SPS_PPS = NO
|
||||
|
||||
############## SHUTDOWN_REGULATOR_EN ###############
|
||||
#SHUTDOWN_REGULATOR_EN = YES
|
||||
SHUTDOWN_REGULATOR_EN = NO
|
||||
|
||||
############## IRQ_EN ##############################
|
||||
IRQ_EN = YES
|
||||
#IRQ_EN = NO
|
||||
|
||||
############## MD5_WC_EN ###########################
|
||||
#MD5_WC_EN = YES
|
||||
MD5_WC_EN = NO
|
||||
|
||||
############## RCN_DBG_EN ###########################
|
||||
#RCN_DBG_EN = YES
|
||||
RCN_DBG_EN = NO
|
||||
|
||||
############## HARDWARE_SPLIT_SPS_PPS_EN ###########
|
||||
#HARDWARE_SPLIT_SPS_PPS_EN = YES
|
||||
HARDWARE_SPLIT_SPS_PPS_EN = NO
|
||||
|
||||
############## OUTPUT_LOWDELAY_EN ##################
|
||||
#OUTPUT_LOWDELAY_EN = YES
|
||||
OUTPUT_LOWDELAY_EN = NO
|
||||
|
||||
############## SAO_LOWPOWER_EN #####################
|
||||
#SAO_LOWPOWER_EN = YES
|
||||
SAO_LOWPOWER_EN = NO
|
||||
|
||||
############## VENC_VOLT_HOLD #####################
|
||||
#VENC_VOLT_HOLD = YES
|
||||
VENC_VOLT_HOLD = NO
|
||||
|
||||
|
||||
############## VENC_SMMU_QOS_PRINT #####################
|
||||
#VENC_SMMU_QOS_PRINT = YES
|
||||
VENC_SMMU_QOS_PRINT = NO
|
||||
|
||||
############## VENC_TIMER_ENABLE #####################
|
||||
#VENC_TIMER_ENABLE = YES
|
||||
VENC_TIMER_ENABLE = NO
|
||||
|
||||
Executable
+196
@@ -0,0 +1,196 @@
|
||||
#include "drv_venc_efl.h"
|
||||
#include "drv_venc_osal.h"
|
||||
#include "hi_drv_mem.h"
|
||||
|
||||
|
||||
/*lint -e774 -e697 -e838*/
|
||||
/*lint -e685 -e568 -e687 -e701 -e713 -e574 -e702 -e737*/
|
||||
unsigned int gVencIsFPGA = 0;
|
||||
unsigned int gVeduIrqNumNorm = 0;
|
||||
unsigned int gVeduIrqNumPort = 0;
|
||||
unsigned int gVeduIrqNumSafe = 0;
|
||||
unsigned int gVencRegBaseAddr = 0;
|
||||
unsigned int gVencRegRange = 0;
|
||||
HI_U64 gSmmuPageBaseAddr = 0;
|
||||
|
||||
U_FUNC_VCPI_RAWINT g_hw_done_type ;
|
||||
VEDU_OSAL_EVENT g_hw_done_event;
|
||||
|
||||
/*******************************************************************/
|
||||
VeduEfl_IpCtx_S VeduIpCtx;
|
||||
|
||||
int VENC_SetDtsConfig(VeduEfl_DTS_CONFIG_S *pDtsConfig)
|
||||
{
|
||||
if (!pDtsConfig){
|
||||
HI_FATAL_VENC("pDtsConfig is NULL\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (pDtsConfig->VeduIrqNumNorm == 0 || pDtsConfig->VeduIrqNumProt == 0 || pDtsConfig->VeduIrqNumSafe == 0 || pDtsConfig->VencRegBaseAddr == 0 ||
|
||||
pDtsConfig->VencRegRange == 0 || pDtsConfig->SmmuPageBaseAddr == 0){
|
||||
HI_ERR_VENC("invalid param, VeduIrqNumNorm:%d, VeduIrqNumProt:%d, VeduIrqNumSafe:%d, VencRegBaseAddr:%pK, VencRegRange:%d, SmmuPageBaseAddr:%pK\n",
|
||||
pDtsConfig->VeduIrqNumNorm, pDtsConfig->VeduIrqNumProt, pDtsConfig->VeduIrqNumSafe, (void *)(uintptr_t)(pDtsConfig->VencRegBaseAddr), pDtsConfig->VencRegRange, (void *)(uintptr_t)(pDtsConfig->SmmuPageBaseAddr));
|
||||
return HI_FAILURE;
|
||||
}
|
||||
gVencIsFPGA = pDtsConfig->IsFPGA;
|
||||
gVeduIrqNumNorm = pDtsConfig->VeduIrqNumNorm;
|
||||
gVeduIrqNumPort = pDtsConfig->VeduIrqNumProt;
|
||||
gVeduIrqNumSafe = pDtsConfig->VeduIrqNumSafe;
|
||||
|
||||
gVencRegBaseAddr = pDtsConfig->VencRegBaseAddr;
|
||||
gVencRegRange = pDtsConfig->VencRegRange;
|
||||
gSmmuPageBaseAddr = pDtsConfig->SmmuPageBaseAddr;
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static void Venc_ISR(void)
|
||||
{
|
||||
unsigned int *pINTCLR = NULL;
|
||||
S_HEVC_AVC_REGS_TYPE *pAllReg = NULL;
|
||||
|
||||
HI_DBG_VENC("enter %s ()\n", __func__);
|
||||
|
||||
if (!VeduIpCtx.pRegBase) {
|
||||
HI_ERR_VENC("VeduIpCtx.pRegBase invalid");
|
||||
return ;
|
||||
}
|
||||
pAllReg = (S_HEVC_AVC_REGS_TYPE *)VeduIpCtx.pRegBase;/*lint !e826 */
|
||||
pINTCLR = (unsigned int *)&(pAllReg->VEDU_VCPI_INTCLR.u32);
|
||||
|
||||
g_hw_done_type.bits.vcpi_rint_vedu_timeout = pAllReg->FUNC_VCPI_RAWINT.bits.vcpi_rint_vedu_timeout;
|
||||
g_hw_done_type.bits.vcpi_rint_vedu_slice_end = pAllReg->FUNC_VCPI_RAWINT.bits.vcpi_rint_vedu_slice_end;
|
||||
g_hw_done_type.bits.vcpi_rint_ve_eop = pAllReg->FUNC_VCPI_RAWINT.bits.vcpi_rint_ve_eop;
|
||||
|
||||
#ifdef VENC_SIMULATE
|
||||
pAllReg->FUNC_VCPI_RAWINT.bits.vcpi_rint_ve_eop = 0;
|
||||
#endif
|
||||
if (g_hw_done_type.bits.vcpi_rint_vedu_timeout
|
||||
|| g_hw_done_type.bits.vcpi_rint_ve_eop) {
|
||||
*pINTCLR = 0xFFFFFFFF;
|
||||
VENC_DRV_OsalGiveEvent(&g_hw_done_event);
|
||||
} else {
|
||||
*pINTCLR = 0xFFFFFFBE;
|
||||
}
|
||||
|
||||
HI_DBG_VENC("out %s ()\n", __func__);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Function :
|
||||
Description: IP-VEDU & IP-JPGE Open & Close
|
||||
Calls :
|
||||
Input :
|
||||
Output :
|
||||
Return :
|
||||
Others :
|
||||
******************************************************************************/
|
||||
int VENC_DRV_EflOpenVedu(void)
|
||||
{
|
||||
HI_DBG_VENC("enter %s()\n", __func__);
|
||||
|
||||
HiMemSet((void *)&VeduIpCtx, 0, sizeof(VeduIpCtx));
|
||||
|
||||
if (VENC_DRV_OsalLockCreate( &VeduIpCtx.pChnLock ) == HI_FAILURE){
|
||||
HI_ERR_VENC("VENC_DRV_OsalLockCreate failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
VeduIpCtx.pRegBase = (unsigned int *)HiMmap(gVencRegBaseAddr, gVencRegRange);
|
||||
|
||||
if (!VeduIpCtx.pRegBase){
|
||||
HI_ERR_VENC("ioremap failed\n");
|
||||
VENC_DRV_OsalLockDestroy( VeduIpCtx.pChnLock );
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
HI_DBG_VENC("HI_DDR_MEM_Init\n");
|
||||
if (HI_SUCCESS != DRV_MEM_INIT()) {
|
||||
HI_ERR_VENC("DRV_MEM_INIT failed\n");
|
||||
VENC_DRV_OsalLockDestroy( VeduIpCtx.pChnLock );
|
||||
HiMunmap(VeduIpCtx.pRegBase);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
VeduIpCtx.IpFree = 1;
|
||||
VENC_HAL_SetSmmuAddr((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
VENC_HAL_DisableAllInt((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
VENC_HAL_ClrAllInt ((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
#ifdef IRQ_EN
|
||||
if (VENC_DRV_OsalIrqInit(gVeduIrqNumNorm, Venc_ISR) == HI_FAILURE){
|
||||
HI_ERR_VENC("VENC_DRV_OsalIrqInit failed\n");
|
||||
VENC_DRV_OsalLockDestroy( VeduIpCtx.pChnLock );
|
||||
HiMunmap(VeduIpCtx.pRegBase);
|
||||
DRV_MEM_EXIT();
|
||||
return HI_FAILURE;
|
||||
}
|
||||
#endif
|
||||
/* creat thread to manage channel */
|
||||
VeduIpCtx.StopTask = 0;
|
||||
VeduIpCtx.TaskRunning = 0;
|
||||
|
||||
VENC_DRV_OsalInitEvent(&g_hw_done_event, 0);
|
||||
|
||||
HI_DBG_VENC("exit %s()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
int VENC_DRV_EflCloseVedu( void )
|
||||
{
|
||||
unsigned int TimeOutCnt = 0;
|
||||
#ifdef MD5_WC_EN
|
||||
int i = 0;
|
||||
unsigned char digesttmp[16] ;
|
||||
unsigned char digesttmp2[100] ;
|
||||
HiMemSet(digesttmp, 0, 16);
|
||||
HiMemSet(digesttmp2, 0, 100);
|
||||
#endif
|
||||
HI_DBG_VENC("enter %s()\n", __func__);
|
||||
VeduIpCtx.StopTask = 1;
|
||||
|
||||
while ((VeduIpCtx.TaskRunning) && (TimeOutCnt < 100)) {
|
||||
HiSleepMs(1);
|
||||
TimeOutCnt ++;
|
||||
}
|
||||
|
||||
VENC_HAL_DisableAllInt((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
VENC_HAL_ClrAllInt((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
|
||||
#ifdef IRQ_EN
|
||||
VENC_DRV_OsalIrqFree(gVeduIrqNumNorm);
|
||||
#endif
|
||||
HiMunmap(VeduIpCtx.pRegBase);
|
||||
DRV_MEM_EXIT();
|
||||
VENC_DRV_OsalLockDestroy( VeduIpCtx.pChnLock );
|
||||
|
||||
HI_DBG_VENC("exit %s()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
int VENC_DRV_EflSuspendVedu(void)
|
||||
{
|
||||
unsigned int TimeOutCnt = 0;
|
||||
HI_INFO_VENC("enter %s()\n", __func__);
|
||||
|
||||
VeduIpCtx.StopTask = 1;
|
||||
|
||||
while ((VeduIpCtx.TaskRunning) && (TimeOutCnt < 100)) {
|
||||
HiSleepMs(1);
|
||||
TimeOutCnt ++;
|
||||
}
|
||||
|
||||
HI_INFO_VENC("exit %s()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
int VENC_DRV_EflResumeVedu(void)
|
||||
{
|
||||
HI_INFO_VENC("enter %s()\n", __func__);
|
||||
|
||||
VeduIpCtx.StopTask = 0;
|
||||
VeduIpCtx.TaskRunning = 0;
|
||||
|
||||
HI_INFO_VENC("exit %s()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#ifndef __DRV_VENC_EFL_H__
|
||||
#define __DRV_VENC_EFL_H__
|
||||
|
||||
#include "hi_drv_mem.h"
|
||||
#include "drv_venc.h"
|
||||
|
||||
enum {
|
||||
VEDU_H265 = 0,
|
||||
VEDU_H264 = 1
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
unsigned int IpFree; /* for channel control */
|
||||
unsigned long long CurrHandle;//HI_U64 CurrHandle; /* used in ISR */
|
||||
unsigned int *pRegBase;
|
||||
void *pChnLock; /* lock ChnCtx[MAX_CHN] */
|
||||
void *pTask_Frame; /* for both venc & omxvenc */
|
||||
void *pTask_Stream; /* juse for omxvenc */
|
||||
unsigned int StopTask;
|
||||
unsigned int TaskRunning; /* to block Close IP */
|
||||
unsigned int bReEncode;
|
||||
} VeduEfl_IpCtx_S;
|
||||
|
||||
typedef struct {
|
||||
unsigned int IsFPGA;
|
||||
unsigned int VeduIrqNumNorm;
|
||||
unsigned int VeduIrqNumProt;
|
||||
unsigned int VeduIrqNumSafe;
|
||||
unsigned int VencRegBaseAddr;
|
||||
unsigned int VencRegRange;
|
||||
unsigned int normalRate;
|
||||
unsigned int highRate;
|
||||
unsigned int lowRate;
|
||||
unsigned long long SmmuPageBaseAddr;//HI_U64 SmmuPageBaseAddr;
|
||||
} VeduEfl_DTS_CONFIG_S;
|
||||
|
||||
int VENC_DRV_EflOpenVedu(void);
|
||||
int VENC_DRV_EflCloseVedu(void);
|
||||
int VENC_DRV_EflResumeVedu(void);
|
||||
int VENC_DRV_EflSuspendVedu(void);
|
||||
int VENC_SetDtsConfig(VeduEfl_DTS_CONFIG_S* info);
|
||||
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
#endif //__DRV_VENC_EFL_H__
|
||||
|
||||
Executable
+534
@@ -0,0 +1,534 @@
|
||||
|
||||
/*
|
||||
* Copyright (C), 2001-2011, Hisilicon Tech. Co., Ltd.
|
||||
*
|
||||
* File Name : viu.c
|
||||
* Version : Initial Draft
|
||||
* Author : Hisilicon multimedia software group
|
||||
* Created :
|
||||
* Description :
|
||||
*
|
||||
* History :
|
||||
* 1.Date : 2010/03/17
|
||||
* Author : j00131665
|
||||
* Modification: Created file
|
||||
*/
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "drv_venc_osal.h"
|
||||
#include "drv_venc.h"
|
||||
#include "venc_regulator.h"
|
||||
#include "drv_venc.h"
|
||||
#define VERSION_STRING "1234"
|
||||
#define PCTRL_PERI 0xE8A090A4
|
||||
#define PCTRL_PERI_SATA0 (0xE8A090BC)
|
||||
#define MAX_OPEN_COUNT 3
|
||||
/*lint -e750 -e838 -e715*/
|
||||
#ifndef VM_RESERVED /*for kernel up to 3.7.0 version*/
|
||||
# define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
|
||||
#endif
|
||||
|
||||
/*============Deviece===============*/
|
||||
typedef struct {
|
||||
dev_t dev;
|
||||
struct device* venc_device;
|
||||
//struct device* venc_device_2;
|
||||
struct cdev cdev;
|
||||
struct class* venc_class;
|
||||
}VENC_ENTRY;
|
||||
|
||||
typedef enum {
|
||||
KIRIN_960,
|
||||
KIRIN_970_ES,
|
||||
KIRIN_970_CS,
|
||||
}KIRIN_PLATFORM_E;
|
||||
|
||||
typedef struct {
|
||||
MEM_BUFFER_S internalbuffer;
|
||||
MEM_BUFFER_S imagebuffer;
|
||||
MEM_BUFFER_S streambuffer[MAX_STREAMBUF_NUM];
|
||||
MEM_BUFFER_S streamheadbuffer;
|
||||
}VENC_MEM_INFO;
|
||||
|
||||
struct semaphore g_VencMutex;
|
||||
|
||||
static int g_vencOpenFlag = 0;
|
||||
static int g_vencDevDetected = 0;
|
||||
|
||||
//VENC device open times
|
||||
atomic_t g_VencCount = ATOMIC_INIT(0);
|
||||
|
||||
int VENC_DRV_Resume(struct platform_device *pltdev);
|
||||
int VENC_DRV_Suspend(struct platform_device *pltdev, pm_message_t state);
|
||||
|
||||
static int VENC_DRV_SetupCdev(VENC_ENTRY *venc, const struct file_operations *fops);
|
||||
static int VENC_DRV_CleanupCdev(VENC_ENTRY *venc);
|
||||
static int VENC_DRV_Probe(struct platform_device * pltdev);
|
||||
static int VENC_DRV_Remove(struct platform_device *pltdev);
|
||||
|
||||
extern VeduEfl_IpCtx_S VeduIpCtx;
|
||||
extern U_FUNC_VCPI_RAWINT g_hw_done_type;
|
||||
extern VEDU_OSAL_EVENT g_hw_done_event;
|
||||
extern unsigned int gVencIsFPGA;
|
||||
|
||||
static int venc_drv_waithwdone(U_FUNC_VCPI_RAWINT *hw_done_type)
|
||||
{
|
||||
int Ret = HI_FAILURE;
|
||||
|
||||
Ret = VENC_DRV_OsalWaitEvent(&g_hw_done_event, msecs_to_jiffies(500));/*lint !e712 !e747 */
|
||||
|
||||
if (Ret != 0) {
|
||||
hw_done_type->u32 = 0;
|
||||
HI_ERR_VENC("wait timeout, Ret value is %d\n", Ret);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
*hw_done_type = g_hw_done_type;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
static int venc_drv_register_info(VENC_REG_INFO_S *regcfginfo)
|
||||
{
|
||||
int Ret = HI_SUCCESS;
|
||||
CMD_TYPE cmd = regcfginfo->cmd;
|
||||
switch (cmd) {
|
||||
case VENC_SET_CFGREG:
|
||||
if (regcfginfo->bResetReg == 1)
|
||||
{
|
||||
Ret = VENC_HAL_ResetReg();
|
||||
if (Ret != HI_SUCCESS)
|
||||
{
|
||||
HI_ERR_VENC("reset venc hal reset reg, Ret:%d\n", Ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VeduHal_CfgReg(regcfginfo);
|
||||
|
||||
VENC_HAL_StartEncode((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
|
||||
Ret = venc_drv_waithwdone(®cfginfo->hw_done_type) ;
|
||||
|
||||
if((Ret == HI_SUCCESS ) && (!regcfginfo->hw_done_type.bits.vcpi_rint_vedu_timeout))
|
||||
{
|
||||
VENC_HAL_Get_Reg_Venc(regcfginfo);
|
||||
HI_DBG_VENC("get venc hal reg info\n");
|
||||
}
|
||||
break;
|
||||
case VENC_SET_CFGREGSIMPLE:
|
||||
VeduHal_CfgRegSimple(regcfginfo);
|
||||
|
||||
VENC_HAL_StartEncode((S_HEVC_AVC_REGS_TYPE*)(VeduIpCtx.pRegBase));/*lint !e826 */
|
||||
|
||||
Ret = venc_drv_waithwdone(®cfginfo->hw_done_type) ;
|
||||
|
||||
if((Ret == HI_SUCCESS ) && (!regcfginfo->hw_done_type.bits.vcpi_rint_vedu_timeout))
|
||||
{
|
||||
VENC_HAL_Get_Reg_Venc(regcfginfo);
|
||||
HI_DBG_VENC("get venc hal reg info\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
HI_ERR_VENC("cmd type unknown:0x%x in default case\n", cmd);
|
||||
Ret = HI_FAILURE;
|
||||
break;
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
static int VENC_DRV_Open(struct inode *finode, struct file *ffile)
|
||||
{
|
||||
int Ret = 0;
|
||||
|
||||
Ret = HiVENC_DOWN_INTERRUPTIBLE(&g_VencMutex);
|
||||
if (Ret) {
|
||||
HI_FATAL_VENC("Open down interruptible failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (atomic_read(&g_VencCount) == MAX_OPEN_COUNT) {
|
||||
HI_FATAL_VENC("open venc too much\n");
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (atomic_inc_return(&g_VencCount) == 1) {
|
||||
Ret = VENC_DRV_BoardInit();
|
||||
if (Ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("board init failed, ret value is %d\n", Ret);
|
||||
atomic_dec(&g_VencCount);
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
Ret = VENC_DRV_EflOpenVedu();
|
||||
if (Ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("venc firmware layer open failed, ret value is %d\n", Ret);
|
||||
atomic_dec(&g_VencCount);
|
||||
VENC_DRV_BoardDeinit();
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
g_vencOpenFlag = 1;
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
|
||||
HI_INFO_VENC("Open venc device successfully\n");
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
static int VENC_DRV_Close(struct inode *finode, struct file *ffile)
|
||||
{
|
||||
int Ret = 0;
|
||||
|
||||
Ret = HiVENC_DOWN_INTERRUPTIBLE(&g_VencMutex);
|
||||
if (Ret) {
|
||||
HI_FATAL_VENC("Close down interruptible failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (atomic_dec_and_test(&g_VencCount)) {
|
||||
Ret = VENC_DRV_EflCloseVedu();
|
||||
if (Ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("venc firmware layer close failed, ret value is %d\n", Ret);
|
||||
VENC_DRV_BoardDeinit();
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
VENC_DRV_BoardDeinit();
|
||||
g_vencOpenFlag = 0;
|
||||
}
|
||||
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
|
||||
HI_INFO_VENC("Close venc device successfully\n");
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
int VENC_DRV_Suspend(struct platform_device *pltdev, pm_message_t state)
|
||||
{
|
||||
int Ret = 0;
|
||||
HI_INFO_VENC("enter\n");
|
||||
|
||||
Ret = HiVENC_DOWN_INTERRUPTIBLE(&g_VencMutex);
|
||||
if (Ret) {
|
||||
HI_ERR_VENC("Suspend down interruptible failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (!g_vencOpenFlag) {
|
||||
HI_INFO_VENC("venc device already suspend\n");
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
Ret = VENC_DRV_EflSuspendVedu();
|
||||
if (Ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("venc firmware layer suspend failed, ret value is %d\n", Ret);
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
VENC_DRV_BoardDeinit();
|
||||
g_hw_done_event.flag = 0;
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
|
||||
HI_INFO_VENC("exit\n");
|
||||
return HI_SUCCESS;
|
||||
}/*lint !e715*/
|
||||
|
||||
int VENC_DRV_Resume(struct platform_device *pltdev)
|
||||
{
|
||||
int Ret = 0;
|
||||
HI_INFO_VENC("enter\n");
|
||||
|
||||
Ret = HiVENC_DOWN_INTERRUPTIBLE(&g_VencMutex);
|
||||
if (Ret) {
|
||||
HI_FATAL_VENC("Resume down interruptible failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
if (!g_vencOpenFlag) {
|
||||
HI_INFO_VENC("venc device already resume\n");
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return 0;
|
||||
}
|
||||
Ret = VENC_DRV_BoardInit();
|
||||
if (Ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("board init failed, ret value is %d\n", Ret);
|
||||
atomic_dec(&g_VencCount);
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
Ret = VENC_DRV_EflResumeVedu();
|
||||
if (Ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("venc firmware layer resume failed, ret value is %d\n", Ret);
|
||||
atomic_dec(&g_VencCount);
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
HI_INFO_VENC("exit\n");
|
||||
return HI_SUCCESS;
|
||||
}/*lint !e715*/
|
||||
|
||||
static long VENC_Ioctl(struct file *file, unsigned int ucmd, unsigned long uarg)
|
||||
{
|
||||
int Ret;
|
||||
int cmd = (int)ucmd;
|
||||
void *arg = (void *)uarg;
|
||||
VENC_REG_INFO_S *regcfginfo = NULL;
|
||||
VENC_MEM_INFO VencMapInfo;
|
||||
|
||||
if (!arg) {
|
||||
//HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
HI_FATAL_VENC("uarg is NULL\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_VENC_START_ENCODE:/*lint !e30 !e142*/
|
||||
VeduIpCtx.TaskRunning = 1;
|
||||
regcfginfo = (VENC_REG_INFO_S *)arg;
|
||||
HiMemSet((void*)&VencMapInfo, 0, sizeof(VencMapInfo));
|
||||
|
||||
VENC_DRV_OsalInitEvent(&g_hw_done_event, 0);
|
||||
|
||||
Ret = venc_drv_register_info(regcfginfo);
|
||||
VeduIpCtx.TaskRunning = 0;
|
||||
HI_DBG_VENC("venc cfg reg info, Ret:%d\n", Ret);
|
||||
break;
|
||||
default:
|
||||
HI_ERR_VENC("venc cmd unknown:0x%x\n", ucmd);
|
||||
Ret = HI_FAILURE;
|
||||
break;
|
||||
}
|
||||
//HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return Ret;
|
||||
}
|
||||
static long VENC_DRV_Ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
long Ret;
|
||||
|
||||
Ret = HiVENC_DOWN_INTERRUPTIBLE(&g_VencMutex);
|
||||
if (Ret != 0)
|
||||
{
|
||||
HI_FATAL_VENC("Ioctl, down interruptible failed\n");
|
||||
return Ret;
|
||||
}
|
||||
Ret = (long)HI_DRV_UserCopy(file, cmd, arg, VENC_Ioctl);
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMutex);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
static struct file_operations VENC_FOPS =
|
||||
{
|
||||
.owner = THIS_MODULE,/*lint !e64 */
|
||||
.open = VENC_DRV_Open,
|
||||
.unlocked_ioctl = VENC_DRV_Ioctl,
|
||||
.compat_ioctl = VENC_DRV_Ioctl,
|
||||
.release = VENC_DRV_Close,
|
||||
};/*lint !e785 */
|
||||
|
||||
static const struct of_device_id venc_of_match[] = {
|
||||
{ .compatible = "hisi,kirin970-venc", },/*lint !e785 */
|
||||
{ }/*lint !e785 */
|
||||
};
|
||||
|
||||
static struct platform_driver Venc_driver = {
|
||||
.probe = VENC_DRV_Probe,
|
||||
.remove = VENC_DRV_Remove,
|
||||
.suspend = VENC_DRV_Suspend,
|
||||
.resume = VENC_DRV_Resume,
|
||||
.driver = {
|
||||
.name = "hi_venc",
|
||||
.owner = THIS_MODULE,/*lint !e64 */
|
||||
.of_match_table = venc_of_match
|
||||
},/*lint !e785 */
|
||||
};/*lint !e785 */
|
||||
|
||||
static struct platform_device Venc_device = {
|
||||
.name = "hi_venc",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = NULL,
|
||||
.release = NULL,
|
||||
},/*lint !e785 */
|
||||
};/*lint !e785 */
|
||||
|
||||
static int VENC_DRV_SetupCdev(VENC_ENTRY *venc, const struct file_operations *fops)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
HI_INFO_VENC("enter %s()\n", __func__);
|
||||
err = alloc_chrdev_region(&venc->dev, 0, 1, "hi_venc");
|
||||
if (err < 0) {
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
HiMemSet((void*)&(venc->cdev), 0, sizeof(struct cdev));
|
||||
cdev_init(&(venc->cdev), &VENC_FOPS);
|
||||
|
||||
venc->cdev.owner = THIS_MODULE;/*lint !e64 */
|
||||
venc->cdev.ops = &VENC_FOPS;
|
||||
err = cdev_add(&(venc->cdev), venc->dev, 1);
|
||||
|
||||
/*在/sys/class/目录下创建设备类别目录hi_venc*/
|
||||
venc->venc_class = class_create(THIS_MODULE, "hi_venc");/*lint !e64 */
|
||||
if (IS_ERR(venc->venc_class)) {
|
||||
err = PTR_ERR(venc->venc_class);/*lint !e712 */
|
||||
HI_ERR_VENC("Fail to create hi_venc class\n");
|
||||
goto unregister_region;
|
||||
//return HI_FAILURE;/*lint !e438 */
|
||||
}
|
||||
|
||||
/*在/dev/目录和/sys/class/hi_venc目录下分别创建设备文件hi_venc*/
|
||||
venc->venc_device = device_create(venc->venc_class, NULL, venc->dev, "%s", "hi_venc");
|
||||
if (IS_ERR(venc->venc_device)) {
|
||||
err = PTR_ERR(venc->venc_device);/*lint !e712 */
|
||||
HI_ERR_VENC("Fail to create hi_venc device\n");
|
||||
goto cls_destroy;
|
||||
//return HI_FAILURE;/*lint !e438 */
|
||||
}
|
||||
|
||||
HI_INFO_VENC("exit %s()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
|
||||
cls_destroy:
|
||||
class_destroy(venc->venc_class);
|
||||
venc->venc_class = NULL;
|
||||
unregister_region:
|
||||
unregister_chrdev_region(venc->dev, 1);
|
||||
return 0;
|
||||
}/*lint !e550 */
|
||||
|
||||
static int VENC_DRV_CleanupCdev(VENC_ENTRY *venc)
|
||||
{
|
||||
/*销毁设备类别和设备*/
|
||||
if (venc->venc_class) {
|
||||
device_destroy(venc->venc_class,venc->dev);
|
||||
class_destroy(venc->venc_class);
|
||||
}
|
||||
|
||||
cdev_del(&(venc->cdev));
|
||||
unregister_chrdev_region(venc->dev,1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int VENC_DRV_Probe(struct platform_device * pltdev)
|
||||
{
|
||||
int ret = HI_FAILURE;
|
||||
VENC_ENTRY *venc = NULL;
|
||||
|
||||
HI_INFO_VENC("omxvenc prepare to probe\n");
|
||||
HiVENC_INIT_MUTEX(&g_VencMutex);
|
||||
if (g_vencDevDetected) {
|
||||
HI_INFO_VENC("venc device detected already\n");
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
venc = HiMemVAlloc(sizeof(VENC_ENTRY));/*lint !e747 */
|
||||
if (!venc) {
|
||||
HI_FATAL_VENC("call vmalloc failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
HiMemSet((void *)venc, 0, sizeof(VENC_ENTRY));
|
||||
ret = VENC_DRV_SetupCdev(venc, &VENC_FOPS);
|
||||
if (ret < 0) {
|
||||
HI_ERR_VENC("setup char device failed\n");
|
||||
goto free;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pltdev, venc);
|
||||
g_vencDevDetected = 1;
|
||||
|
||||
ret = Venc_Regulator_Init(pltdev);
|
||||
if (ret < 0) {
|
||||
HI_FATAL_VENC("init regulator failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
HI_INFO_VENC("omxvenc probe successfully\n");
|
||||
return ret;
|
||||
|
||||
cleanup:
|
||||
VENC_DRV_CleanupCdev(venc);
|
||||
free:
|
||||
HiMemVFree(venc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int VENC_DRV_Remove(struct platform_device *pltdev)
|
||||
{
|
||||
VENC_ENTRY *venc = NULL;
|
||||
HI_INFO_VENC("omxvenc prepare to remove\n");
|
||||
|
||||
venc = platform_get_drvdata(pltdev);
|
||||
if (venc) {
|
||||
VENC_DRV_CleanupCdev(venc);
|
||||
Venc_Regulator_Deinit(pltdev);
|
||||
}
|
||||
else {
|
||||
HI_ERR_VENC("get platform drvdata err\n");
|
||||
}
|
||||
|
||||
platform_set_drvdata(pltdev,NULL);
|
||||
HiMemVFree(venc);
|
||||
g_vencDevDetected = 0;
|
||||
|
||||
HI_INFO_VENC("remove omxvenc successfully\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init VENC_DRV_ModInit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
HI_INFO_VENC("enter %s()\n", __func__);
|
||||
|
||||
ret = platform_device_register(&Venc_device);
|
||||
if (ret < 0) {
|
||||
HI_ERR_VENC("regist platform device failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = platform_driver_register(&Venc_driver);/*lint !e64 */
|
||||
if (ret < 0) {
|
||||
HI_ERR_VENC("regist platform driver failed\n");
|
||||
goto exit;
|
||||
}
|
||||
HI_INFO_VENC("success\n");
|
||||
#ifdef MODULE
|
||||
HI_INFO_VENC("Load hi_venc.ko success\t(%s)\n", VERSION_STRING);
|
||||
#endif
|
||||
HI_INFO_VENC("exit %s()\n", __func__);
|
||||
return HI_SUCCESS;
|
||||
exit:
|
||||
platform_device_unregister(&Venc_device);
|
||||
#ifdef MODULE
|
||||
HI_ERR_VENC("Load hi_venc.ko failed\t(%s)\n", VERSION_STRING);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VENC_DRV_ModExit(void)
|
||||
{
|
||||
HI_INFO_VENC("enter %s()\n", __func__);
|
||||
platform_driver_unregister(&Venc_driver);
|
||||
platform_device_unregister(&Venc_device);
|
||||
|
||||
HI_INFO_VENC("exit %s()\n", __func__);
|
||||
return;
|
||||
}
|
||||
/*lint -e528*/
|
||||
module_init(VENC_DRV_ModInit); /*lint !e528*/
|
||||
module_exit(VENC_DRV_ModExit); /*lint !e528*/
|
||||
/*lint -e753*/
|
||||
MODULE_LICENSE("Dual BSD/GPL"); /*lint !e753*/
|
||||
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
##########################################################
|
||||
# VENC DRV MAKE CONFIG #
|
||||
##########################################################
|
||||
|
||||
include drivers/vcodec/venc_hivna/drv_venc_config.cfg
|
||||
|
||||
############## VENC_SIMULATE #######################
|
||||
ifeq ($(VENC_SIMULATE),YES)
|
||||
VENC_CFLAGS := -DVENC_SIMULATE
|
||||
endif
|
||||
|
||||
############## TEST_TIME ###########################
|
||||
ifeq ($(TEST_TIME),YES)
|
||||
VENC_CFLAGS += -DTEST_TIME
|
||||
endif
|
||||
|
||||
############## SLICE_INT_EN ########################
|
||||
ifeq ($(SLICE_INT_EN),YES)
|
||||
VENC_CFLAGS += -DSLICE_INT_EN
|
||||
endif
|
||||
|
||||
############## RE_ENCODE_EN ########################
|
||||
ifeq ($(RE_ENCODE_EN),YES)
|
||||
VENC_CFLAGS += -DRE_ENCODE_EN
|
||||
endif
|
||||
|
||||
############## SPLIT_SPS_PPS #######################
|
||||
ifeq ($(SPLIT_SPS_PPS),YES)
|
||||
VENC_CFLAGS += -DSPLIT_SPS_PPS
|
||||
endif
|
||||
|
||||
############## SHUTDOWN_REGULATOR_EN ###############
|
||||
ifeq ($(SHUTDOWN_REGULATOR_EN),YES)
|
||||
VENC_CFLAGS += -DSHUTDOWN_REGULATOR_EN
|
||||
endif
|
||||
|
||||
############## IRQ_EN ##############################
|
||||
ifeq ($(IRQ_EN),YES)
|
||||
VENC_CFLAGS += -DIRQ_EN
|
||||
endif
|
||||
|
||||
############## MD5_WC_EN ###########################
|
||||
ifeq ($(MD5_WC_EN),YES)
|
||||
VENC_CFLAGS += -DMD5_WC_EN
|
||||
endif
|
||||
|
||||
############## RCN_DBG_EN ###########################
|
||||
ifeq ($(RCN_DBG_EN),YES)
|
||||
VENC_CFLAGS += -DRCN_DBG_EN
|
||||
endif
|
||||
|
||||
############## HARDWARE_SPLIT_SPS_PPS_EN ###########
|
||||
ifeq ($(HARDWARE_SPLIT_SPS_PPS_EN), YES)
|
||||
VENC_CFLAGS += -DHARDWARE_SPLIT_SPS_PPS_EN
|
||||
endif
|
||||
|
||||
############## OUTPUT_LOWDELAY_EN ##################
|
||||
ifeq ($(OUTPUT_LOWDELAY_EN),YES)
|
||||
VENC_CFLAGS += -DOUTPUT_LOWDELAY_EN
|
||||
endif
|
||||
|
||||
############## SAO_LOWPOWER_EN #####################
|
||||
ifeq ($(SAO_LOWPOWER_EN),YES)
|
||||
VENC_CFLAGS += -DSAO_LOWPOWER_EN
|
||||
endif
|
||||
|
||||
############## VENC_VOLT_HOLD ######################
|
||||
ifeq ($(VENC_VOLT_HOLD),YES)
|
||||
VENC_CFLAGS += -DVENC_VOLT_HOLD
|
||||
endif
|
||||
|
||||
|
||||
############## VENC_SMMU_QOS_PRINT ######################
|
||||
ifeq ($(VENC_SMMU_QOS_PRINT),YES)
|
||||
VENC_CFLAGS += -DVENC_SMMU_QOS_PRINT
|
||||
endif
|
||||
|
||||
############## VENC_TIMER_ENABLE #####################
|
||||
ifeq ($(VENC_TIMER_ENABLE),YES)
|
||||
VENC_CFLAGS += -DVENC_TIMER_ENABLE
|
||||
endif
|
||||
|
||||
Executable
+258
@@ -0,0 +1,258 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "drv_venc_osal.h"
|
||||
#include "hi_drv_mem.h"
|
||||
|
||||
#define TIME_PERIOD(begin, end) ((end >= begin) ? (end - begin) : (0xffffffff - begin + end))
|
||||
|
||||
/*lint -e747 -e712 -e732 -e715 -e774 -e845 -e438 -e838*/
|
||||
unsigned int g_VencPrintEnable = 0xf;
|
||||
|
||||
char *pszMsg[((char)VENC_ALW) + 1] = {"FATAL","ERR","WARN","IFO","DBG"}; /*lint !e785 */
|
||||
char g_VencPrintMsg[1024];
|
||||
|
||||
static void (*ptrVencCallBack)(void);
|
||||
|
||||
static irqreturn_t VENC_DRV_OsalVencISR(int Irq, void *DevID)
|
||||
{
|
||||
(*ptrVencCallBack)();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int VENC_DRV_OsalIrqInit( unsigned int Irq, void (*ptrCallBack)(void))
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (Irq != 0) {
|
||||
ptrVencCallBack = ptrCallBack;
|
||||
ret = request_irq(Irq, VENC_DRV_OsalVencISR, 0, "DT_device", NULL);
|
||||
} else {
|
||||
HI_FATAL_VENC("params is invaild\n");
|
||||
ret = HI_FAILURE;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
return HI_SUCCESS;
|
||||
} else {
|
||||
HI_FATAL_VENC("request irq failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
void VENC_DRV_OsalIrqFree(unsigned int Irq)
|
||||
{
|
||||
free_irq(Irq, NULL);
|
||||
}
|
||||
|
||||
int VENC_DRV_OsalLockCreate(void **phLock)
|
||||
{
|
||||
spinlock_t *pLock = NULL;
|
||||
|
||||
pLock = (spinlock_t *)vmalloc(sizeof(spinlock_t));
|
||||
|
||||
if (!pLock) {
|
||||
HI_FATAL_VENC("vmalloc failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
spin_lock_init( pLock );
|
||||
*phLock = pLock;
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
void VENC_DRV_OsalLockDestroy( void* hLock )
|
||||
{
|
||||
if (hLock) {
|
||||
vfree((void *)hLock);
|
||||
//hLock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* 初始化事件 */
|
||||
/************************************************************************/
|
||||
int VENC_DRV_OsalInitEvent(VEDU_OSAL_EVENT *pEvent, int InitVal)
|
||||
{
|
||||
pEvent->flag = InitVal;
|
||||
init_waitqueue_head(&(pEvent->queue_head));
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* 发出事件唤醒 */
|
||||
/************************************************************************/
|
||||
int VENC_DRV_OsalGiveEvent(VEDU_OSAL_EVENT *pEvent)
|
||||
{
|
||||
pEvent->flag = 1;
|
||||
wake_up(&(pEvent->queue_head));
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
HI_U64 get_sys_time(void)
|
||||
{
|
||||
HI_U64 sys_time;
|
||||
|
||||
sys_time = sched_clock();
|
||||
do_div(sys_time, 1000000);
|
||||
|
||||
return sys_time;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* 等待事件 */
|
||||
/* 事件发生返回OSAL_OK,超时返回OSAL_ERR 若condition不满足就阻塞等待 */
|
||||
/* 被唤醒返回 0 ,超时返回非-1 */
|
||||
/************************************************************************/
|
||||
int VENC_DRV_OsalWaitEvent(VEDU_OSAL_EVENT *pEvent, unsigned int msWaitTime)
|
||||
{
|
||||
int l_ret = 0;
|
||||
unsigned int cnt = 0;
|
||||
|
||||
HI_U64 start_time, cur_time;
|
||||
start_time = get_sys_time();
|
||||
|
||||
do {
|
||||
l_ret = wait_event_interruptible_timeout((pEvent->queue_head), (pEvent->flag != 0), (msecs_to_jiffies(msWaitTime))); /*lint !e665 !e666 !e40 !e713 !e578*/
|
||||
if (l_ret < 0) {
|
||||
cur_time = get_sys_time();
|
||||
if (TIME_PERIOD(start_time, cur_time) > (HI_U64)msWaitTime) {
|
||||
HI_FATAL_VENC("wait event time out, time : %lld, cnt: %d\n", TIME_PERIOD(start_time, cur_time), cnt);
|
||||
l_ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cnt++;
|
||||
} while ((pEvent->flag == 0) && (l_ret < 0));
|
||||
|
||||
if (cnt > 100) {
|
||||
HI_FATAL_VENC("the max cnt of wait_event interrupts by singal is %d\n", cnt);
|
||||
}
|
||||
|
||||
if (l_ret == 0) {
|
||||
HI_FATAL_VENC("wait pEvent signal timeout\n");
|
||||
}
|
||||
|
||||
pEvent->flag = 0;//(pEvent->flag>0)? (pEvent->flag-1): 0;
|
||||
return (l_ret != 0) ? HI_SUCCESS : HI_FAILURE;
|
||||
}
|
||||
|
||||
int HiMemCpy(void*a_pHiDstMem, void *a_pHiSrcMem, size_t a_Size)
|
||||
{
|
||||
if ((!a_pHiDstMem) || (!a_pHiSrcMem)) {
|
||||
HI_FATAL_VENC("params is invaild\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
memcpy((void *)a_pHiDstMem, (void *)a_pHiSrcMem, a_Size); /* unsafe_function_ignore: memcpy */
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
int HiMemSet(void *a_pHiDstMem, int a_Value, size_t a_Size)
|
||||
{
|
||||
if (!a_pHiDstMem) {
|
||||
HI_FATAL_VENC("params is invaild\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
memset((void *)a_pHiDstMem, a_Value, a_Size); /* unsafe_function_ignore: memset */
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
void HiSleepMs(unsigned int a_MilliSec)
|
||||
{
|
||||
msleep(a_MilliSec);
|
||||
}
|
||||
|
||||
unsigned int* HiMmap(unsigned int Addr ,unsigned int Range)
|
||||
{
|
||||
unsigned int *res_addr = NULL;
|
||||
res_addr = (unsigned int *)ioremap(Addr, Range);
|
||||
return res_addr;
|
||||
}
|
||||
|
||||
void HiMunmap(unsigned int * pMemAddr)
|
||||
{
|
||||
if (!pMemAddr) {
|
||||
HI_FATAL_VENC("params is invaild\n");
|
||||
return;
|
||||
}
|
||||
|
||||
iounmap(pMemAddr);
|
||||
}
|
||||
|
||||
int HiStrNCmp(const char* pStrName,const char* pDstName,int nSize)
|
||||
{
|
||||
int ret = 0;
|
||||
if (pStrName && pDstName) {
|
||||
ret = strncmp(pStrName,pDstName,nSize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
void *HiMemVAlloc(unsigned int nMemSize)
|
||||
{
|
||||
void * memaddr = NULL;
|
||||
if (nMemSize) {
|
||||
memaddr = vmalloc(nMemSize);
|
||||
}
|
||||
return memaddr;
|
||||
}
|
||||
|
||||
void HiMemVFree(void *pMemAddr)
|
||||
{
|
||||
if (pMemAddr) {
|
||||
vfree((void *)pMemAddr);
|
||||
}
|
||||
}
|
||||
|
||||
void HiVENC_INIT_MUTEX(void *pSem)
|
||||
{
|
||||
if (pSem) {
|
||||
sema_init((struct semaphore *)pSem, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int HiVENC_DOWN_INTERRUPTIBLE(void *pSem)
|
||||
{
|
||||
int Ret = -1;
|
||||
if (pSem) {
|
||||
Ret = down_interruptible((struct semaphore *)pSem);
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
void HiVENC_UP_INTERRUPTIBLE(void *pSem)
|
||||
{
|
||||
if (pSem) {
|
||||
up((struct semaphore *)pSem);
|
||||
}
|
||||
}
|
||||
|
||||
void HI_PRINT(unsigned int type,char *file, int line , char *function, char *msg, ... )
|
||||
{
|
||||
va_list args;
|
||||
unsigned int uTotalChar;
|
||||
|
||||
if ( ((1 << type) & g_VencPrintEnable) == 0 && (type != VENC_ALW) ) /*lint !e701 */
|
||||
return ;
|
||||
|
||||
va_start(args, msg);
|
||||
|
||||
uTotalChar = vsnprintf(g_VencPrintMsg, sizeof(g_VencPrintMsg), msg, args); /* unsafe_function_ignore: vsnprintf */
|
||||
g_VencPrintMsg[sizeof(g_VencPrintMsg) - 1] = '\0';
|
||||
|
||||
va_end(args);
|
||||
|
||||
if (uTotalChar <= 0 || uTotalChar >= 1023) /*lint !e775 */
|
||||
return;
|
||||
|
||||
printk(KERN_ALERT "%s:<%d:%s>%s \n", pszMsg[type], line, function, g_VencPrintMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#ifndef __DRV_VENC_OSAL_H__
|
||||
#define __DRV_VENC_OSAL_H__
|
||||
|
||||
#include <linux/rtc.h>
|
||||
|
||||
typedef struct hiKERN_EVENT_S
|
||||
{
|
||||
wait_queue_head_t queue_head;
|
||||
int flag;
|
||||
} KERN_EVENT_S;
|
||||
|
||||
typedef KERN_EVENT_S VEDU_OSAL_EVENT;
|
||||
typedef unsigned long VEDU_LOCK_FLAG;
|
||||
|
||||
#define MESCS_TO_JIFFIES(time) msecs_to_jiffies(time)
|
||||
#define HiWaitEvent( pEvent, flag) wait_event_interruptible((pEvent), (flag))
|
||||
#define HiWaitEventTimeOut( pEvent, flag, msWaitTime) wait_event_interruptible_timeout((pEvent), (flag), (msWaitTime))
|
||||
|
||||
extern unsigned int g_VencPrintEnable;
|
||||
|
||||
typedef enum {
|
||||
VENC_FATAL = 0,
|
||||
VENC_ERR,
|
||||
VENC_WARN,
|
||||
VENC_INFO,
|
||||
VENC_DBG,
|
||||
VENC_ALW,
|
||||
}VENC_PRINT_TYPE;
|
||||
|
||||
#define HI_FATAL_VENC(fmt,...) HI_PRINT(VENC_FATAL,(char *)__FILE__, (int)__LINE__, (char *)__FUNCTION__, fmt, ##__VA_ARGS__)
|
||||
#define HI_ERR_VENC(fmt,...) HI_PRINT(VENC_ERR,(char *)__FILE__, (int)__LINE__, (char *)__FUNCTION__, fmt, ##__VA_ARGS__)
|
||||
#define HI_WARN_VENC(fmt,...) HI_PRINT(VENC_WARN,(char *)__FILE__, (int)__LINE__, (char *)__FUNCTION__, fmt,##__VA_ARGS__)
|
||||
#define HI_INFO_VENC(fmt,...) HI_PRINT(VENC_INFO,(char *)__FILE__, (int)__LINE__, (char *)__FUNCTION__, fmt,##__VA_ARGS__)
|
||||
#define HI_DBG_VENC(fmt,...) HI_PRINT(VENC_DBG,(char *)__FILE__, (int)__LINE__, (char *)__FUNCTION__, fmt,##__VA_ARGS__)
|
||||
|
||||
void HI_PRINT(unsigned int type, char *file, int line, char *function, char *msg, ... );
|
||||
unsigned int* HiMmap(unsigned int Addr ,unsigned int Range);
|
||||
void HiMunmap(unsigned int * pMemAddr);
|
||||
int HiStrNCmp(const char* pStrName,const char* pDstName,int nSize);
|
||||
void HiSleepMs(unsigned int a_MilliSec);
|
||||
void* HiMemVAlloc(unsigned int nMemSize);
|
||||
void HiMemVFree(void * pMemAddr);
|
||||
int HiMemSet(void * a_pHiDstMem, int a_Value, size_t a_Size);
|
||||
int HiMemCpy(void * a_pHiDstMem, void * a_pHiSrcMem, size_t a_Size);
|
||||
void HiVENC_INIT_MUTEX(void* pSem);
|
||||
int HiVENC_DOWN_INTERRUPTIBLE(void* pSem);
|
||||
void HiVENC_UP_INTERRUPTIBLE(void* pSem);
|
||||
int VENC_DRV_OsalIrqInit(unsigned int Irq, void(*ptrCallBack)(void));
|
||||
void VENC_DRV_OsalIrqFree(unsigned int Irq);
|
||||
int VENC_DRV_OsalLockCreate (void** phLock);
|
||||
void VENC_DRV_OsalLockDestroy(void* hLock);
|
||||
unsigned int GetTimeInUs(void);
|
||||
int VENC_DRV_OsalInitEvent( VEDU_OSAL_EVENT *pEvent, int InitVal );
|
||||
int VENC_DRV_OsalGiveEvent( VEDU_OSAL_EVENT *pEvent );
|
||||
int VENC_DRV_OsalWaitEvent( VEDU_OSAL_EVENT *pEvent, unsigned int msWaitTime );
|
||||
|
||||
|
||||
#endif //__DRV_VENC_OSAL_H__
|
||||
|
||||
Executable
+3296
File diff suppressed because it is too large
Load Diff
Executable
+239
@@ -0,0 +1,239 @@
|
||||
#include "drv_venc_osal.h"
|
||||
#include "hi_drv_mem.h"
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
|
||||
#define MAX_BUFFER_SIZE (10*1024)
|
||||
|
||||
char *g_sbuf = NULL;
|
||||
int g_venc_node_num = 0;
|
||||
|
||||
struct semaphore g_VencMemSem;
|
||||
venc_mem_buf g_venc_mem_node[MAX_KMALLOC_MEM_NODE];
|
||||
|
||||
VENC_SMMU_ERR_ADDR g_smmu_err_mem;
|
||||
|
||||
int DRV_MEM_INIT(void)
|
||||
{
|
||||
char *sbuf;
|
||||
int s32Ret;
|
||||
MEM_BUFFER_S MEM_SMMU_RD_ADDR;
|
||||
MEM_BUFFER_S MEM_SMMU_WR_ADDR;
|
||||
|
||||
HiVENC_INIT_MUTEX(&g_VencMemSem);
|
||||
|
||||
sbuf = HiMemVAlloc(MAX_BUFFER_SIZE);
|
||||
if (!sbuf) {
|
||||
HI_FATAL_VENC("call vmalloc failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
HiMemSet((void *)&g_venc_mem_node, 0, MAX_KMALLOC_MEM_NODE*sizeof(g_venc_mem_node[0]));
|
||||
HiMemSet((void *)&g_smmu_err_mem, 0, sizeof(g_smmu_err_mem));
|
||||
HiMemSet((void *)&MEM_SMMU_RD_ADDR, 0, sizeof(MEM_BUFFER_S));
|
||||
HiMemSet((void *)&MEM_SMMU_WR_ADDR, 0, sizeof(MEM_BUFFER_S));
|
||||
|
||||
MEM_SMMU_RD_ADDR.u32Size = SMMU_RWERRADDR_SIZE;
|
||||
s32Ret = DRV_MEM_KAlloc("SMMU_RDERR", "OMXVENC", &MEM_SMMU_RD_ADDR);
|
||||
if (s32Ret != HI_SUCCESS ) {
|
||||
HI_ERR_VENC("SMMU_RDERR alloc failed\n");
|
||||
goto err_sbuf_exit;
|
||||
}
|
||||
|
||||
MEM_SMMU_WR_ADDR.u32Size = SMMU_RWERRADDR_SIZE;
|
||||
s32Ret = DRV_MEM_KAlloc("SMMU_WRERR", "OMXVENC", &MEM_SMMU_WR_ADDR);
|
||||
if (s32Ret != HI_SUCCESS ) {
|
||||
HI_ERR_VENC("SMMU_WRERR alloc failed\n");
|
||||
goto err_rd_smmu_exit;
|
||||
}
|
||||
|
||||
g_smmu_err_mem.RdAddr = MEM_SMMU_RD_ADDR.u64StartPhyAddr;//config alloc phyaddr,in order system don't dump
|
||||
g_smmu_err_mem.WrAddr = MEM_SMMU_WR_ADDR.u64StartPhyAddr;
|
||||
g_sbuf = sbuf;
|
||||
HiMemSet((void *)g_sbuf, 0, MAX_BUFFER_SIZE);
|
||||
|
||||
return HI_SUCCESS;
|
||||
|
||||
err_rd_smmu_exit:
|
||||
DRV_MEM_KFree(&MEM_SMMU_RD_ADDR);
|
||||
err_sbuf_exit:
|
||||
HiMemVFree(sbuf);
|
||||
|
||||
return HI_FAILURE;
|
||||
|
||||
}
|
||||
|
||||
int DRV_MEM_EXIT(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (g_sbuf) {
|
||||
HiMemVFree(g_sbuf);
|
||||
g_sbuf = NULL;
|
||||
}
|
||||
|
||||
/* Exit kfree mem for register's VEDU_COMN1_REGS.COMN1_SMMU_ERR_RDADDRR*/
|
||||
for (i = 0; i < MAX_KMALLOC_MEM_NODE; i++) {
|
||||
if (g_venc_mem_node[i].virt_addr != NULL) {
|
||||
kfree(g_venc_mem_node[i].virt_addr);
|
||||
HiMemSet(&g_venc_mem_node[i], 0, sizeof(g_venc_mem_node[i]));
|
||||
}
|
||||
}
|
||||
|
||||
g_venc_node_num = 0;
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
/* kalloc */
|
||||
int DRV_MEM_KAlloc(const char* bufName, const char *zone_name, MEM_BUFFER_S *psMBuf)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = HI_FAILURE;
|
||||
void *virt_addr = NULL;
|
||||
|
||||
if (psMBuf == NULL || psMBuf->u32Size == 0) {
|
||||
HI_FATAL_VENC("invalid Param, psMBuf is NULL or size is zero\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HiVENC_DOWN_INTERRUPTIBLE(&g_VencMemSem)) {
|
||||
HI_FATAL_VENC("Kalloc, down_interruptible failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_KMALLOC_MEM_NODE; i++) {
|
||||
if ((0 == g_venc_mem_node[i].phys_addr) && (g_venc_mem_node[i].virt_addr == NULL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == MAX_KMALLOC_MEM_NODE) {
|
||||
HI_FATAL_VENC("No free ion mem node\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
virt_addr = kmalloc(psMBuf->u32Size, GFP_KERNEL | GFP_DMA);/*lint !e747*/
|
||||
if (IS_ERR_OR_NULL(virt_addr)) {
|
||||
HI_FATAL_VENC("call kzalloc failed, size : %d\n", psMBuf->u32Size);
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
memset(virt_addr, 0, psMBuf->u32Size); /* unsafe_function_ignore: memset */ /*lint !e668*/
|
||||
|
||||
psMBuf->pStartVirAddr = virt_addr;
|
||||
psMBuf->u64StartPhyAddr = __pa(virt_addr);/*lint !e648 !e834 !e712*/
|
||||
|
||||
snprintf(g_venc_mem_node[i].node_name, MAX_MEM_NAME_LEN, "%s", bufName); /* unsafe_function_ignore: snprintf */
|
||||
|
||||
snprintf(g_venc_mem_node[i].zone_name, MAX_MEM_NAME_LEN, "%s", zone_name); /* unsafe_function_ignore: snprintf */
|
||||
|
||||
g_venc_mem_node[i].virt_addr = psMBuf->pStartVirAddr;
|
||||
g_venc_mem_node[i].phys_addr = psMBuf->u64StartPhyAddr;
|
||||
g_venc_mem_node[i].size = psMBuf->u32Size;
|
||||
|
||||
g_venc_node_num++;
|
||||
|
||||
ret = HI_SUCCESS;
|
||||
|
||||
err_exit:
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMemSem);
|
||||
return ret; /*lint !e593*/
|
||||
} /*lint !e593*/
|
||||
|
||||
/* kfree */
|
||||
int DRV_MEM_KFree(const MEM_BUFFER_S *psMBuf)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret = HI_FAILURE;
|
||||
|
||||
if (NULL == psMBuf || psMBuf->pStartVirAddr == NULL || psMBuf->u64StartPhyAddr == 0) {
|
||||
HI_FATAL_VENC("invalid Parameters\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HiVENC_DOWN_INTERRUPTIBLE(&g_VencMemSem)) {
|
||||
HI_FATAL_VENC("Kfree, down interruptible failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<MAX_KMALLOC_MEM_NODE; i++) {
|
||||
if ((psMBuf->u64StartPhyAddr == g_venc_mem_node[i].phys_addr) &&
|
||||
(psMBuf->pStartVirAddr == g_venc_mem_node[i].virt_addr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == MAX_KMALLOC_MEM_NODE) {
|
||||
HI_FATAL_VENC("No free ion mem node\n");
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
kfree(g_venc_mem_node[i].virt_addr);
|
||||
HiMemSet(&g_venc_mem_node[i], 0, sizeof(g_venc_mem_node[i]));/*lint !e866 */
|
||||
g_venc_node_num = (g_venc_node_num > 0)?(g_venc_node_num-1):0;
|
||||
|
||||
ret = HI_SUCCESS;
|
||||
|
||||
err_exit:
|
||||
HiVENC_UP_INTERRUPTIBLE(&g_VencMemSem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int HI_DRV_UserCopy(struct file *file, unsigned int cmd, unsigned long arg,
|
||||
long (*func)(struct file *file, unsigned int cmd, unsigned long uarg))
|
||||
{
|
||||
//HI_CHAR sbuf[768];
|
||||
void *parg = NULL;
|
||||
int err = -EINVAL;
|
||||
|
||||
/* Copy arguments into temp kernel buffer */
|
||||
if (!(void __user*)arg) {
|
||||
HI_FATAL_VENC("arg is NULL\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (_IOC_SIZE(cmd) <= MAX_BUFFER_SIZE) {
|
||||
parg = g_sbuf;
|
||||
} else {
|
||||
HI_FATAL_VENC("cmd size is too long\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!parg) {
|
||||
HI_FATAL_VENC("parg is NULL\n");
|
||||
goto out;
|
||||
}
|
||||
err = -EFAULT;
|
||||
if (_IOC_DIR(cmd) & _IOC_WRITE) {
|
||||
if (copy_from_user(parg, (void __user*)arg, _IOC_SIZE(cmd))) {/*lint !e747 */
|
||||
HI_FATAL_VENC("copy_from_user failed, cmd value is 0x%x\n", cmd);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* call driver */
|
||||
err = func(file, cmd, (long)(parg)); /*lint !e732 !e712*/
|
||||
if (err == -ENOIOCTLCMD)
|
||||
err = -EINVAL;
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
/* Copy results into user buffer */
|
||||
switch (_IOC_DIR(cmd)) {
|
||||
case _IOC_READ:
|
||||
case (_IOC_WRITE | _IOC_READ):
|
||||
if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) {/*lint !e747 */
|
||||
HI_FATAL_VENC("copy_to_user failed, cmd value is 0x%x\n", cmd);
|
||||
err = -EFAULT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C), 2001-2011, Hisilicon Tech. Co., Ltd.
|
||||
*
|
||||
* File Name : hi_type.h
|
||||
* Version : Initial Draft
|
||||
* Author : Hisilicon multimedia software group
|
||||
* Created : 2005/4/23
|
||||
*
|
||||
* Last Modified :
|
||||
* Description : The common data type defination
|
||||
* Function List :
|
||||
*
|
||||
* History :
|
||||
* 1.Date : 2008/06/28
|
||||
* Author : c42025
|
||||
* Modification: modified definition for HI_S8
|
||||
*
|
||||
* 2.Date : 2008/10/31
|
||||
* Author : z44949
|
||||
* Modification: Translate the chinese comment
|
||||
*/
|
||||
#ifndef __HI_DRV_MEM_H__
|
||||
#define __HI_DRV_MEM_H__
|
||||
#include "drv_venc.h"
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/hisi/hisi_ion.h>
|
||||
|
||||
|
||||
#define MAX_MEM_NAME_LEN (15)
|
||||
#define MAX_KMALLOC_MEM_NODE (16) /*1 channel need 2 node ,there is have max 8 channels*/
|
||||
#define MAX_ION_MEM_NODE (200)
|
||||
#define SMMU_RWERRADDR_SIZE (128)
|
||||
|
||||
typedef struct {
|
||||
unsigned long long RdAddr; // HI_U64
|
||||
unsigned long long WrAddr; // HI_U64
|
||||
} VENC_SMMU_ERR_ADDR;
|
||||
|
||||
typedef struct {
|
||||
void *pStartVirAddr;
|
||||
unsigned long long u64StartPhyAddr; // HI_U64
|
||||
unsigned int u32Size;
|
||||
unsigned char u8IsMapped;
|
||||
unsigned int u32ShareFd;
|
||||
} MEM_BUFFER_S;
|
||||
|
||||
typedef struct {
|
||||
char node_name[MAX_MEM_NAME_LEN];
|
||||
char zone_name[MAX_MEM_NAME_LEN];
|
||||
void* virt_addr;
|
||||
unsigned long long phys_addr; // HI_U64
|
||||
unsigned int size;
|
||||
struct ion_handle *handle;
|
||||
} venc_mem_buf;
|
||||
|
||||
/***********************************************************************************
|
||||
memory menage relative functions
|
||||
***********************************************************************************/
|
||||
int HI_DRV_UserCopy(struct file *file, unsigned int cmd, unsigned long arg, long (*func)(struct file *file, unsigned int cmd, unsigned long uarg));
|
||||
|
||||
/**************************************platform.h**************************************************/
|
||||
int DRV_MEM_INIT(void);
|
||||
int DRV_MEM_EXIT(void);
|
||||
int DRV_MEM_KAlloc(const char* bufName, const char *zone_name, MEM_BUFFER_S *psMBuf);
|
||||
int DRV_MEM_KFree(const MEM_BUFFER_S *psMBuf);
|
||||
|
||||
/**************************************************************************************/
|
||||
|
||||
|
||||
#endif /* __HI_DRV_MEM_H__ */
|
||||
|
||||
Executable
+275
@@ -0,0 +1,275 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/hisi/hisi-iommu.h>
|
||||
|
||||
#include "venc_regulator.h"
|
||||
#include "drv_venc_osal.h"
|
||||
#include "drv_venc.h"
|
||||
|
||||
#define VENC_CLK_RATE "enc_clk_rate"
|
||||
#define VENC_REGULATOR_NAME "ldo_venc"
|
||||
#define MEDIA_REGULATOR_NAME "ldo_media"
|
||||
#define VENC_CLOCK_NAME "clk_gate_vencfreq"
|
||||
|
||||
static struct clk *g_PvencClk = NULL;
|
||||
struct iommu_domain *g_hisi_mmu_domain = NULL;
|
||||
static VeduEfl_DTS_CONFIG_S g_VencDtsConfig;
|
||||
static VENC_CLK_TYPE g_currClk = VENC_CLK_RATE_LOW;
|
||||
|
||||
static unsigned int g_vencQosMode = 0x2;
|
||||
static int g_VencPowerOn = 0;
|
||||
/*lint -e838 -e747 -e774 -e845*/
|
||||
static int Venc_Enable_Iommu(struct platform_device *pdev)
|
||||
{
|
||||
struct iommu_domain *hisi_domain = NULL;
|
||||
struct iommu_domain_data* domain_data = NULL;
|
||||
struct device *dev = NULL;
|
||||
//uint64_t phy_pgd_base = 0;
|
||||
int ret = HI_FAILURE;
|
||||
|
||||
if ((!pdev ) || (!(&pdev->dev))){
|
||||
HI_ERR_VENC("%s, invalid Parameters\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
dev = &pdev->dev;
|
||||
hisi_domain = iommu_domain_alloc(dev->bus);
|
||||
if (!hisi_domain) {
|
||||
HI_ERR_VENC("%s, iommu_domain_alloc failed\n", __func__);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = iommu_attach_device(hisi_domain, dev);
|
||||
if (ret){
|
||||
HI_ERR_VENC("iommu_attach_device failed\n");
|
||||
goto out_free_domain;
|
||||
}
|
||||
|
||||
g_hisi_mmu_domain = hisi_domain;
|
||||
domain_data = (struct iommu_domain_data *)(g_hisi_mmu_domain->priv);
|
||||
if (domain_data == NULL){
|
||||
//pCtx->phy_pgd_base = (uint64_t)(domain_data->phy_pgd_base);
|
||||
//}else{
|
||||
goto out_detach_device;
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
|
||||
out_detach_device:
|
||||
iommu_detach_device(g_hisi_mmu_domain, dev);
|
||||
out_free_domain:
|
||||
iommu_domain_free(hisi_domain);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
static int Venc_Disable_Iommu(struct platform_device *pdev)
|
||||
{
|
||||
if( g_hisi_mmu_domain && pdev) {
|
||||
iommu_detach_device(g_hisi_mmu_domain, &pdev->dev);
|
||||
iommu_domain_free(g_hisi_mmu_domain);
|
||||
g_hisi_mmu_domain = NULL;
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
static int Venc_GetDtsConfigInfo(struct platform_device *pdev, VeduEfl_DTS_CONFIG_S *pDtsConfig)
|
||||
{
|
||||
unsigned int rate_h = 0;
|
||||
unsigned int rate_n = 0;
|
||||
unsigned int rate_l = 0;
|
||||
int ret = HI_FAILURE;
|
||||
struct resource res;
|
||||
struct clk *pvenc_clk = NULL;
|
||||
struct device_node *np = NULL;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct iommu_domain_data *domain_data = NULL;
|
||||
|
||||
if (!dev) {
|
||||
HI_FATAL_VENC("invalid argument, dev is NULL\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
np = dev->of_node;
|
||||
|
||||
HiMemSet(&res, 0, sizeof(res));
|
||||
if ((!np) || (!pDtsConfig)) {
|
||||
HI_FATAL_VENC("invalid argument np or pDtsConfig is NULL\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/* 1 read IRQ num from dts */
|
||||
pDtsConfig->VeduIrqNumNorm = irq_of_parse_and_map(np, 0);
|
||||
if (pDtsConfig->VeduIrqNumNorm == 0) {
|
||||
HI_FATAL_VENC("parse and map irq VeduIrqNumNorm failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
pDtsConfig->VeduIrqNumProt = irq_of_parse_and_map(np, 1);
|
||||
if (pDtsConfig->VeduIrqNumProt == 0) {
|
||||
HI_FATAL_VENC("parse and map irq VeduIrqNumProt failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
pDtsConfig->VeduIrqNumSafe = irq_of_parse_and_map(np, 2);
|
||||
if (pDtsConfig->VeduIrqNumSafe == 0) {
|
||||
HI_FATAL_VENC("parse and map irq VeduIrqNumSafe failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/* 2 read venc register start address, range */
|
||||
ret = of_address_to_resource(np, 0, &res);
|
||||
if (ret) {
|
||||
HI_FATAL_VENC("address to resource failed, ret value is %d\n", ret);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
pDtsConfig->VencRegBaseAddr = res.start;/*lint !e712 */
|
||||
pDtsConfig->VencRegRange = resource_size(&res);/*lint !e712 */
|
||||
|
||||
/* 3 read venc clk rate [low, high], venc clock */
|
||||
pvenc_clk = devm_clk_get(dev, VENC_CLOCK_NAME);
|
||||
if (IS_ERR_OR_NULL(pvenc_clk)) {
|
||||
HI_FATAL_VENC("can not get venc clock, pvenc_clk is 0x%pK\n", pvenc_clk);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
g_PvencClk = pvenc_clk;
|
||||
|
||||
ret = of_property_read_u32_index(np, VENC_CLK_RATE, 0, &rate_h);
|
||||
ret += of_property_read_u32_index(np, VENC_CLK_RATE, 1, &rate_n);
|
||||
ret += of_property_read_u32_index(np, VENC_CLK_RATE, 2, &rate_l);
|
||||
if (ret) {
|
||||
HI_FATAL_VENC("can not get venc rate, return %d\n", ret);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
pDtsConfig->highRate = rate_h;
|
||||
pDtsConfig->normalRate = rate_n;
|
||||
pDtsConfig->lowRate = rate_l;
|
||||
HI_INFO_VENC("venc_clk_rate: highRate:%u, normalRate:%u, lowRate:%u\n", pDtsConfig->highRate, pDtsConfig->normalRate, pDtsConfig->lowRate);
|
||||
|
||||
/* 4 get venc qos mode */
|
||||
ret = of_property_read_u32(np, "venc_qos_mode", &g_vencQosMode);
|
||||
if (ret) {
|
||||
g_vencQosMode = 0x2;
|
||||
HI_ERR_VENC("get venc qos mode failed set default\n");
|
||||
}
|
||||
|
||||
domain_data = (struct iommu_domain_data *)(g_hisi_mmu_domain->priv);
|
||||
if (domain_data) {
|
||||
pDtsConfig->SmmuPageBaseAddr = (uint64_t)(domain_data->phy_pgd_base);
|
||||
HI_INFO_VENC("SmmuPageBaseAddr is 0x%pK\n", __func__, pDtsConfig->SmmuPageBaseAddr);
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
int Venc_Regulator_Init(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!pdev) {
|
||||
HI_FATAL_VENC("invalid argument\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/* 1 create smmu domain */
|
||||
ret = Venc_Enable_Iommu(pdev);
|
||||
if (ret < 0) {
|
||||
HI_FATAL_VENC("enable venc iommu failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/* 2 read venc dts info from dts */
|
||||
HiMemSet(&g_VencDtsConfig, 0, sizeof(VeduEfl_DTS_CONFIG_S));
|
||||
ret = Venc_GetDtsConfigInfo(pdev, &g_VencDtsConfig);
|
||||
if (ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("get venc DTS config info failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
/* 3 set dts into to efi */
|
||||
ret = VENC_SetDtsConfig(&g_VencDtsConfig);
|
||||
if (ret != HI_SUCCESS) {
|
||||
HI_FATAL_VENC("set venc DTS config info failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
void Venc_Regulator_Deinit(struct platform_device *pdev)
|
||||
{
|
||||
if (pdev)
|
||||
Venc_Disable_Iommu(pdev);
|
||||
}
|
||||
|
||||
int Venc_Regulator_Enable(void)
|
||||
{
|
||||
int ret = HI_FAILURE;
|
||||
if (1 == g_VencPowerOn) {
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
if(IS_ERR_OR_NULL(g_PvencClk)) {
|
||||
HI_FATAL_VENC("invalid_argument g_PvencClk:0x%pK\n",
|
||||
g_PvencClk);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(g_PvencClk);
|
||||
if (ret != 0) {
|
||||
HI_FATAL_VENC("prepare clk enable failed\n");
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(g_PvencClk, g_VencDtsConfig.lowRate);
|
||||
if(ret != 0) {
|
||||
HI_FATAL_VENC("set clk low rate failed\n");
|
||||
goto on_error_prepare_clk;
|
||||
}
|
||||
|
||||
g_currClk = VENC_CLK_RATE_LOW;
|
||||
|
||||
ret = clk_set_rate(g_PvencClk, g_VencDtsConfig.lowRate);
|
||||
if(ret != 0) {
|
||||
HI_FATAL_VENC("set clk low rate failed\n");
|
||||
goto on_error_prepare_clk;
|
||||
}
|
||||
g_VencPowerOn = 1;
|
||||
|
||||
HI_INFO_VENC("++\n");
|
||||
return HI_SUCCESS;
|
||||
|
||||
on_error_prepare_clk:
|
||||
clk_disable_unprepare(g_PvencClk);
|
||||
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
int Venc_Regulator_Disable(void)
|
||||
{
|
||||
int ret = HI_FAILURE;
|
||||
HI_INFO_VENC("Venc_Regulator_Disable\n");
|
||||
|
||||
if (0 == g_VencPowerOn) {
|
||||
return HI_SUCCESS;
|
||||
}
|
||||
|
||||
if(IS_ERR_OR_NULL(g_PvencClk)) {
|
||||
HI_FATAL_VENC("invalid_argument g_PvencClk:0x%pK\n",g_PvencClk);
|
||||
return HI_FAILURE;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(g_PvencClk, g_VencDtsConfig.lowRate);
|
||||
if(ret != 0) {
|
||||
HI_ERR_VENC("set clk lowrate:%u failed\n", g_VencDtsConfig.lowRate);
|
||||
//return HI_FAILURE;//continue, no need return
|
||||
}
|
||||
g_currClk = VENC_CLK_RATE_LOW;
|
||||
clk_disable_unprepare(g_PvencClk);
|
||||
|
||||
g_VencPowerOn = 0;
|
||||
HI_INFO_VENC("--\n");
|
||||
return HI_SUCCESS;
|
||||
}/*lint !e715 */
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#ifndef __VENC_REGULATOR_H__
|
||||
#define __VENC_REGULATOR_H__
|
||||
#include "drv_venc.h"
|
||||
#include <linux/fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
int Venc_Regulator_Init(struct platform_device *pdev);
|
||||
void Venc_Regulator_Deinit(struct platform_device *pdev);
|
||||
int Venc_Regulator_Enable(void);
|
||||
int Venc_Regulator_Disable(void);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user