From: Alpha Lin Date: Wed, 7 Jan 2015 01:29:18 +0000 (+0800) Subject: VPU, Disable iommu when decoding failure X-Git-Tag: firefly_0821_release~4335 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b5936892be05094ba2127c1e7f7c4f7183333c12;p=firefly-linux-kernel-4.4.55.git VPU, Disable iommu when decoding failure Disable iommu when decoding failure, so the iommu could restore its state when the decoding resume. Without this step, iommu will work in invalid state. Signed-off-by: Alpha Lin --- diff --git a/arch/arm/mach-rockchip/vcodec_service.c b/arch/arm/mach-rockchip/vcodec_service.c index 293e08ccc8c2..faae1061ef63 100644 --- a/arch/arm/mach-rockchip/vcodec_service.c +++ b/arch/arm/mach-rockchip/vcodec_service.c @@ -36,7 +36,9 @@ #include #include #include +#ifdef CONFIG_REGMAP #include +#endif #include #include @@ -303,18 +305,18 @@ enum VPU_DEC_FMT { * @author ChenHengming (2011-5-3) */ typedef struct vpu_session { - VPU_CLIENT_TYPE type; + enum VPU_CLIENT_TYPE type; /* a linked list of data so we can access them for debugging */ - struct list_head list_session; + struct list_head list_session; /* a linked list of register data waiting for process */ - struct list_head waiting; + struct list_head waiting; /* a linked list of register data in processing */ - struct list_head running; + struct list_head running; /* a linked list of register data processed */ - struct list_head done; - wait_queue_head_t wait; - pid_t pid; - atomic_t task_running; + struct list_head done; + wait_queue_head_t wait; + pid_t pid; + atomic_t task_running; } vpu_session; /** @@ -323,16 +325,16 @@ typedef struct vpu_session { * @author ChenHengming (2011-5-4) */ typedef struct vpu_reg { - VPU_CLIENT_TYPE type; - VPU_FREQ freq; - vpu_session *session; - struct list_head session_link; /* link to vpu service session */ - struct list_head status_link; /* link to register set list */ - unsigned long size; + enum VPU_CLIENT_TYPE type; + VPU_FREQ freq; + vpu_session *session; + struct list_head session_link; /* link to vpu service session */ + struct list_head status_link; /* link to register set list */ + unsigned long size; #if defined(CONFIG_VCODEC_MMU) - struct list_head mem_region_list; + struct list_head mem_region_list; #endif - unsigned long *reg; + unsigned long *reg; } vpu_reg; typedef struct vpu_device { @@ -389,63 +391,69 @@ struct vpu_subdev_data { vpu_device dec_dev; VPU_HW_INFO_E *hw_info; - unsigned long reg_size; + u32 reg_size; unsigned long state; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dir; + struct dentry *debugfs_file_regs; +#endif + #if defined(CONFIG_VCODEC_MMU) struct device *mmu_dev; #endif }; typedef struct vpu_service_info { - struct wake_lock wake_lock; - struct delayed_work power_off_work; - struct mutex lock; - struct list_head waiting; /* link to link_reg in struct vpu_reg */ - struct list_head running; /* link to link_reg in struct vpu_reg */ - struct list_head done; /* link to link_reg in struct vpu_reg */ - struct list_head session; /* link to list_session in struct vpu_session */ - atomic_t total_running; - bool enabled; - vpu_reg *reg_codec; - vpu_reg *reg_pproc; - vpu_reg *reg_resev; - VPUHwDecConfig_t dec_config; - VPUHwEncConfig_t enc_config; - - bool auto_freq; - bool bug_dec_addr; - atomic_t freq_status; - - struct clk *aclk_vcodec; - struct clk *hclk_vcodec; - struct clk *clk_core; - struct clk *clk_cabac; - struct clk *pd_video; - - struct device *dev; - - struct dentry *debugfs_dir; - struct dentry *debugfs_file_regs; + struct wake_lock wake_lock; + struct delayed_work power_off_work; + struct mutex lock; + struct list_head waiting; /* link to link_reg in struct vpu_reg */ + struct list_head running; /* link to link_reg in struct vpu_reg */ + struct list_head done; /* link to link_reg in struct vpu_reg */ + struct list_head session; /* link to list_session in struct vpu_session */ + atomic_t total_running; + bool enabled; + vpu_reg *reg_codec; + vpu_reg *reg_pproc; + vpu_reg *reg_resev; + struct vpu_dec_config dec_config; + struct vpu_enc_config enc_config; + + bool auto_freq; + bool bug_dec_addr; + atomic_t freq_status; + + struct clk *aclk_vcodec; + struct clk *hclk_vcodec; + struct clk *clk_core; + struct clk *clk_cabac; + struct clk *pd_video; + + struct device *dev; u32 irq_status; #if defined(CONFIG_VCODEC_MMU) - struct ion_client *ion_client; - struct list_head mem_region_list; + struct ion_client *ion_client; + struct list_head mem_region_list; #endif - enum vcodec_device_id dev_id; + enum vcodec_device_id dev_id; enum VCODEC_RUNNING_MODE curr_mode; u32 prev_mode; - struct delayed_work simulate_work; + struct delayed_work simulate_work; u32 mode_bit; u32 mode_ctrl; u32 *reg_base; u32 ioaddr; +#ifdef CONFIG_REGMAP + struct regmap *grf_base; +#else u32 *grf_base; +#endif char *name; u32 subcnt; @@ -464,7 +472,7 @@ struct vcodec_combo { typedef struct vpu_request { unsigned long *req; - unsigned long size; + u32 size; } vpu_request; /* debugfs root directory for all device (vpu, hevc).*/ @@ -522,6 +530,16 @@ static void vcodec_enter_mode(struct vpu_subdev_data *data) } #endif bits = 1 << pservice->mode_bit; +#ifdef CONFIG_REGMAP + regmap_read(pservice->grf_base, pservice->mode_ctrl, &raw); + + if (data->mode == VCODEC_RUNNING_MODE_HEVC) + regmap_write(pservice->grf_base, pservice->mode_ctrl, + raw | bits | (bits << 16)); + else + regmap_write(pservice->grf_base, pservice->mode_ctrl, + (raw & (~bits)) | (bits << 16)); +#else raw = readl_relaxed(pservice->grf_base + pservice->mode_ctrl / 4); if (data->mode == VCODEC_RUNNING_MODE_HEVC) writel_relaxed(raw | bits | (bits << 16), @@ -529,10 +547,13 @@ static void vcodec_enter_mode(struct vpu_subdev_data *data) else writel_relaxed((raw & (~bits)) | (bits << 16), pservice->grf_base + pservice->mode_ctrl / 4); +#endif #if defined(CONFIG_VCODEC_MMU) if (data->mmu_dev && !test_bit(MMU_ACTIVATED, &data->state)) { set_bit(MMU_ACTIVATED, &data->state); - rockchip_iovmm_activate(data->dev); + BUG_ON(!pservice->enabled); + if (pservice->enabled) + rockchip_iovmm_activate(data->dev); } #endif pservice->prev_mode = pservice->curr_mode; @@ -610,8 +631,9 @@ static void vpu_put_clk(struct vpu_service_info *pservice) #endif } -static void vpu_reset(struct vpu_service_info *pservice) +static void vpu_reset(struct vpu_subdev_data *data) { + struct vpu_service_info *pservice = data->pservice; #if defined(CONFIG_ARCH_RK29) clk_disable(aclk_ddr_vepu); cru_set_soft_reset(SOFT_RST_CPU_VODEC_A2A_AHB, true); @@ -640,6 +662,15 @@ static void vpu_reset(struct vpu_service_info *pservice) pservice->reg_codec = NULL; pservice->reg_pproc = NULL; pservice->reg_resev = NULL; + +#if defined(CONFIG_VCODEC_MMU) + if (data->mmu_dev && !test_bit(MMU_ACTIVATED, &data->state)) { + set_bit(MMU_ACTIVATED, &data->state); + BUG_ON(!pservice->enabled); + if (pservice->enabled) + rockchip_iovmm_activate(data->dev); + } +#endif } static void reg_deinit(struct vpu_subdev_data *data, vpu_reg *reg); @@ -919,8 +950,11 @@ static int vcodec_bufid_to_iova(struct vpu_subdev_data *data, u8 *tbl, if (ext_inf != NULL && ext_inf->magic == EXTRA_INFO_MAGIC) { for (i=0; icnt; i++) { - vpu_debug(3, "reg[%d] + offset %d\n", ext_inf->elem[i].index, ext_inf->elem[i].offset); - reg->reg[ext_inf->elem[i].index] += ext_inf->elem[i].offset; + vpu_debug(3, "reg[%d] + offset %d\n", + ext_inf->elem[i].index, + ext_inf->elem[i].offset); + reg->reg[ext_inf->elem[i].index] += + ext_inf->elem[i].offset; } } @@ -996,7 +1030,7 @@ static int vcodec_reg_address_translate(struct vpu_subdev_data *data, #endif static vpu_reg *reg_init(struct vpu_subdev_data *data, - vpu_session *session, void __user *src, unsigned long size) + vpu_session *session, void __user *src, u32 size) { struct vpu_service_info *pservice = data->pservice; int extra_size = 0; @@ -1187,9 +1221,8 @@ static void reg_from_run_to_done(struct vpu_subdev_data *data, } vcodec_exit_mode(pservice); - if (irq_reg != -1) { + if (irq_reg != -1) reg->reg[irq_reg] = pservice->irq_status; - } atomic_sub(1, ®->session->task_running); atomic_sub(1, &pservice->total_running); @@ -1201,9 +1234,8 @@ static void reg_from_run_to_done(struct vpu_subdev_data *data, static void vpu_service_set_freq(struct vpu_service_info *pservice, vpu_reg *reg) { VPU_FREQ curr = atomic_read(&pservice->freq_status); - if (curr == reg->freq) { - return ; - } + if (curr == reg->freq) + return; atomic_set(&pservice->freq_status, reg->freq); switch (reg->freq) { case VPU_FREQ_200M : { @@ -1225,11 +1257,10 @@ static void vpu_service_set_freq(struct vpu_service_info *pservice, vpu_reg *reg clk_set_rate(pservice->aclk_vcodec, 600*MHZ); } break; default : { - if (soc_is_rk2928g()) { + if (soc_is_rk2928g()) clk_set_rate(pservice->aclk_vcodec, 400*MHZ); - } else { + else clk_set_rate(pservice->aclk_vcodec, 300*MHZ); - } } break; } } @@ -1372,9 +1403,8 @@ static void try_set_reg(struct vpu_subdev_data *data) case VPU_DEC : { if (NULL == pservice->reg_codec) can_set = 1; - if (pservice->auto_freq && (NULL != pservice->reg_pproc)) { + if (pservice->auto_freq && (NULL != pservice->reg_pproc)) can_set = 0; - } } break; case VPU_PP : { if (NULL == pservice->reg_codec) { @@ -1384,9 +1414,8 @@ static void try_set_reg(struct vpu_subdev_data *data) if ((VPU_DEC == pservice->reg_codec->type) && (NULL == pservice->reg_pproc)) can_set = 1; /* can not charge frequency when vpu is working */ - if (pservice->auto_freq) { + if (pservice->auto_freq) can_set = 0; - } } } break; case VPU_DEC_PP : { @@ -1452,13 +1481,13 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, struct vpu_service_info *pservice = data->pservice; vpu_session *session = (vpu_session *)filp->private_data; vpu_debug_enter(); - vpu_debug(3, "cmd %x, VPU_IOC_SET_CLIENT_TYPE %x\n", cmd, VPU_IOC_SET_CLIENT_TYPE); + vpu_debug(3, "cmd %x, VPU_IOC_SET_CLIENT_TYPE %x\n", cmd, (u32)VPU_IOC_SET_CLIENT_TYPE); if (NULL == session) return -EINVAL; switch (cmd) { case VPU_IOC_SET_CLIENT_TYPE : { - session->type = (VPU_CLIENT_TYPE)arg; + session->type = (enum VPU_CLIENT_TYPE)arg; break; } case VPU_IOC_GET_HW_FUSE_STATUS : { @@ -1470,7 +1499,7 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, if (VPU_ENC != session->type) { if (copy_to_user((void __user *)req.req, &pservice->dec_config, - sizeof(VPUHwDecConfig_t))) { + sizeof(struct vpu_dec_config))) { vpu_err("error: VPU_IOC_GET_HW_FUSE_STATUS copy_to_user failed type %d\n", session->type); return -EFAULT; @@ -1478,7 +1507,7 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, } else { if (copy_to_user((void __user *)req.req, &pservice->enc_config, - sizeof(VPUHwEncConfig_t))) { + sizeof(struct vpu_enc_config ))) { vpu_err("error: VPU_IOC_GET_HW_FUSE_STATUS copy_to_user failed type %d\n", session->type); return -EFAULT; @@ -1538,7 +1567,7 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, atomic_set(&session->task_running, 0); atomic_sub(task_running, &pservice->total_running); printk("%d task is running but not return, reset hardware...", task_running); - vpu_reset(pservice); + vpu_reset(data); printk("done\n"); } vpu_service_session_clear(data, session); @@ -1574,6 +1603,144 @@ static long vpu_service_ioctl(struct file *filp, unsigned int cmd, return 0; } +#ifdef CONFIG_COMPAT +static long compat_vpu_service_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct vpu_subdev_data *data = + container_of(filp->f_dentry->d_inode->i_cdev, + struct vpu_subdev_data, cdev); + struct vpu_service_info *pservice = data->pservice; + vpu_session *session = (vpu_session *)filp->private_data; + vpu_debug_enter(); + vpu_debug(3, "cmd %x, COMPAT_VPU_IOC_SET_CLIENT_TYPE %x\n", cmd, + (u32)COMPAT_VPU_IOC_SET_CLIENT_TYPE); + if (NULL == session) + return -EINVAL; + + switch (cmd) { + case COMPAT_VPU_IOC_SET_CLIENT_TYPE : { + session->type = (enum VPU_CLIENT_TYPE)arg; + break; + } + case COMPAT_VPU_IOC_GET_HW_FUSE_STATUS : { + vpu_request req; + if (copy_from_user(&req, compat_ptr((compat_uptr_t)arg), + sizeof(vpu_request))) { + vpu_err("error: VPU_IOC_GET_HW_FUSE_STATUS" + " copy_from_user failed\n"); + return -EFAULT; + } else { + if (VPU_ENC != session->type) { + if (copy_to_user(compat_ptr((compat_uptr_t)req.req), + &pservice->dec_config, + sizeof(struct vpu_dec_config))) { + vpu_err("error: VPU_IOC_GET_HW_FUSE_STATUS " + "copy_to_user failed type %d\n", + session->type); + return -EFAULT; + } + } else { + if (copy_to_user(compat_ptr((compat_uptr_t)req.req), + &pservice->enc_config, + sizeof(struct vpu_enc_config ))) { + vpu_err("error: VPU_IOC_GET_HW_FUSE_STATUS" + " copy_to_user failed type %d\n", + session->type); + return -EFAULT; + } + } + } + + break; + } + case COMPAT_VPU_IOC_SET_REG : { + vpu_request req; + vpu_reg *reg; + if (copy_from_user(&req, compat_ptr((compat_uptr_t)arg), + sizeof(vpu_request))) { + vpu_err("VPU_IOC_SET_REG copy_from_user failed\n"); + return -EFAULT; + } + reg = reg_init(data, session, + compat_ptr((compat_uptr_t)req.req), req.size); + if (NULL == reg) { + return -EFAULT; + } else { + mutex_lock(&pservice->lock); + try_set_reg(data); + mutex_unlock(&pservice->lock); + } + + break; + } + case COMPAT_VPU_IOC_GET_REG : { + vpu_request req; + vpu_reg *reg; + if (copy_from_user(&req, compat_ptr((compat_uptr_t)arg), + sizeof(vpu_request))) { + vpu_err("VPU_IOC_GET_REG copy_from_user failed\n"); + return -EFAULT; + } else { + int ret = wait_event_timeout(session->wait, !list_empty(&session->done), VPU_TIMEOUT_DELAY); + if (!list_empty(&session->done)) { + if (ret < 0) { + vpu_err("warning: pid %d wait task sucess but wait_evernt ret %d\n", session->pid, ret); + } + ret = 0; + } else { + if (unlikely(ret < 0)) { + vpu_err("error: pid %d wait task ret %d\n", session->pid, ret); + } else if (0 == ret) { + vpu_err("error: pid %d wait %d task done timeout\n", session->pid, atomic_read(&session->task_running)); + ret = -ETIMEDOUT; + } + } + if (ret < 0) { + int task_running = atomic_read(&session->task_running); + mutex_lock(&pservice->lock); + vpu_service_dump(pservice); + if (task_running) { + atomic_set(&session->task_running, 0); + atomic_sub(task_running, &pservice->total_running); + printk("%d task is running but not return, reset hardware...", task_running); + vpu_reset(data); + printk("done\n"); + } + vpu_service_session_clear(data, session); + mutex_unlock(&pservice->lock); + return ret; + } + } + mutex_lock(&pservice->lock); + reg = list_entry(session->done.next, vpu_reg, session_link); + return_reg(data, reg, compat_ptr((compat_uptr_t)req.req)); + mutex_unlock(&pservice->lock); + break; + } + case COMPAT_VPU_IOC_PROBE_IOMMU_STATUS : { + int iommu_enable = 0; + +#if defined(CONFIG_VCODEC_MMU) + iommu_enable = data->mmu_dev ? 1 : 0; +#endif + + if (copy_to_user(compat_ptr((compat_uptr_t)arg), &iommu_enable, sizeof(int))) { + vpu_err("error: VPU_IOC_PROBE_IOMMU_STATUS copy_to_user failed\n"); + return -EFAULT; + } + break; + } + default : { + vpu_err("error: unknow vpu service ioctl cmd %x\n", cmd); + break; + } + } + vpu_debug_leave(); + return 0; +} +#endif + static int vpu_service_check_hw(struct vpu_subdev_data *data, u32 hw_addr) { int ret = -EINVAL, i = 0; @@ -1659,6 +1826,9 @@ static const struct file_operations vpu_service_fops = { .unlocked_ioctl = vpu_service_ioctl, .open = vpu_service_open, .release = vpu_service_release, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_vpu_service_ioctl, +#endif //.fasync = vpu_service_fasync, }; @@ -1710,13 +1880,15 @@ int vcodec_sysmmu_fault_hdl(struct device *dev, unsigned long fault_addr, unsigned int status) { struct platform_device *pdev; + struct vpu_subdev_data *data; struct vpu_service_info *pservice; vpu_debug_enter(); pdev = container_of(dev, struct platform_device, dev); - pservice = platform_get_drvdata(pdev); + data = platform_get_drvdata(pdev); + pservice = data->pservice; if (pservice->reg_codec) { struct vcodec_mem_region *mem, *n; @@ -1732,7 +1904,7 @@ int vcodec_sysmmu_fault_hdl(struct device *dev, pr_alert("vcodec, page fault occur, reset hw\n"); pservice->reg_codec->reg[101] = 1; - vpu_reset(pservice); + vpu_reset(data); } return 0; @@ -1768,7 +1940,7 @@ static int vcodec_subdev_probe(struct platform_device *pdev, data->dev = dev; of_property_read_string(np, "name", (const char**)&name); - of_property_read_u32(np, "dev_mode", &data->mode); + of_property_read_u32(np, "dev_mode", (u32*)&data->mode); dev_set_name(dev, name); if (pservice->reg_base == 0) { @@ -1887,6 +2059,18 @@ static int vcodec_subdev_probe(struct platform_device *pdev, INIT_LIST_HEAD(&data->lnk_service); list_add_tail(&data->lnk_service, &pservice->subdev_list); + +#ifdef CONFIG_DEBUG_FS + data->debugfs_dir = + vcodec_debugfs_create_device_dir((char*)dev_name(dev), parent); + if (data->debugfs_dir == NULL) + vpu_err("create debugfs dir %s failed\n", dev_name(dev)); + + data->debugfs_file_regs = + debugfs_create_file("regs", 0664, + data->debugfs_dir, data, + &debug_vcodec_fops); +#endif return 0; err: if (data->irq_enc > 0) @@ -1914,6 +2098,11 @@ static void vcodec_subdev_remove(struct vpu_subdev_data *data) free_irq(data->irq_enc, (void *)&data); free_irq(data->irq_dec, (void *)&data); + +#ifdef CONFIG_DEBUG_FS + debugfs_remove(data->debugfs_file_regs); + debugfs_remove(data->debugfs_dir); +#endif } static void vcodec_read_property(struct device_node *np, @@ -1929,7 +2118,11 @@ static void vcodec_read_property(struct device_node *np, of_property_read_u32(np, "mode_bit", &pservice->mode_bit); of_property_read_u32(np, "mode_ctrl", &pservice->mode_ctrl); } - pservice->grf_base = RK_GRF_VIRT;/*syscon_regmap_lookup_by_phandle(np, "rockchip,grf");*/ +#ifdef CONFIG_REGMAP + pservice->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); +#else + pservice->grf_base = (u32*)RK_GRF_VIRT; +#endif if (IS_ERR(pservice->grf_base)) { vpu_err("can't find vpu grf property\n"); return; @@ -2023,18 +2216,6 @@ static int vcodec_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, pservice); -#ifdef CONFIG_DEBUG_FS - pservice->debugfs_dir = - vcodec_debugfs_create_device_dir((char*)dev_name(dev), parent); - if (pservice->debugfs_dir == NULL) - vpu_err("create debugfs dir %s failed\n", dev_name(dev)); - - pservice->debugfs_file_regs = - debugfs_create_file("regs", 0664, - pservice->debugfs_dir, pservice, - &debug_vcodec_fops); -#endif - vpu_service_power_off(pservice); pr_info("init success\n"); @@ -2068,11 +2249,6 @@ static int vcodec_remove(struct platform_device *pdev) vpu_put_clk(pservice); wake_lock_destroy(&pservice->wake_lock); -#ifdef CONFIG_DEBUG_FS - debugfs_remove(pservice->debugfs_file_regs); - debugfs_remove(pservice->debugfs_dir); -#endif - return 0; } @@ -2100,13 +2276,13 @@ static struct platform_driver vcodec_driver = { static void get_hw_info(struct vpu_subdev_data *data) { struct vpu_service_info *pservice = data->pservice; - VPUHwDecConfig_t *dec = &pservice->dec_config; - VPUHwEncConfig_t *enc = &pservice->enc_config; + struct vpu_dec_config *dec = &pservice->dec_config; + struct vpu_enc_config *enc = &pservice->enc_config; if (data->mode == VCODEC_RUNNING_MODE_VPU) { u32 configReg = data->dec_dev.hwregs[VPU_DEC_HWCFG0]; u32 asicID = data->dec_dev.hwregs[0]; - dec->h264Support = (configReg >> DWL_H264_E) & 0x3U; + dec->h264_support = (configReg >> DWL_H264_E) & 0x3U; dec->jpegSupport = (configReg >> DWL_JPEG_E) & 0x01U; if (dec->jpegSupport && ((configReg >> DWL_PJPEG_E) & 0x01U)) dec->jpegSupport = JPEG_PROGRESSIVE; @@ -2642,7 +2818,7 @@ static int hevc_test_case0(vpu_service_info *pservice) atomic_set(&session.task_running, 0); atomic_sub(task_running, &pservice->total_running); printk("%d task is running but not return, reset hardware...", task_running); - vpu_reset(pservice); + vpu_reset(data); printk("done\n"); } vpu_service_session_clear(pservice, &session); diff --git a/arch/arm/mach-rockchip/vcodec_service.h b/arch/arm/mach-rockchip/vcodec_service.h index 1b0ca2a3be53..70fa21f3056d 100644 --- a/arch/arm/mach-rockchip/vcodec_service.h +++ b/arch/arm/mach-rockchip/vcodec_service.h @@ -35,58 +35,70 @@ #define VPU_IOC_PROBE_IOMMU_STATUS _IOR(VPU_IOC_MAGIC, 5, unsigned long) -typedef enum VPU_CLIENT_TYPE { - VPU_ENC = 0x0, - VPU_DEC = 0x1, - VPU_PP = 0x2, - VPU_DEC_PP = 0x3, - VPU_TYPE_BUTT , +#ifdef CONFIG_COMPAT +#define COMPAT_VPU_IOC_SET_CLIENT_TYPE _IOW(VPU_IOC_MAGIC, 1, u32) +#define COMPAT_VPU_IOC_GET_HW_FUSE_STATUS _IOW(VPU_IOC_MAGIC, 2, u32) -} VPU_CLIENT_TYPE; +#define COMPAT_VPU_IOC_SET_REG _IOW(VPU_IOC_MAGIC, 3, u32) +#define COMPAT_VPU_IOC_GET_REG _IOW(VPU_IOC_MAGIC, 4, u32) + +#define COMPAT_VPU_IOC_PROBE_IOMMU_STATUS _IOR(VPU_IOC_MAGIC, 5, u32) +#endif + +enum VPU_CLIENT_TYPE { + VPU_ENC = 0x0, + VPU_DEC = 0x1, + VPU_PP = 0x2, + VPU_DEC_PP = 0x3, + VPU_TYPE_BUTT , +}; /* Hardware decoder configuration description */ -typedef struct VPUHwDecConfig { - unsigned long maxDecPicWidth; /* Maximum video decoding width supported */ - unsigned long maxPpOutPicWidth; /* Maximum output width of Post-Processor */ - unsigned long h264Support; /* HW supports h.264 */ - unsigned long jpegSupport; /* HW supports JPEG */ - unsigned long mpeg4Support; /* HW supports MPEG-4 */ - unsigned long customMpeg4Support; /* HW supports custom MPEG-4 features */ - unsigned long vc1Support; /* HW supports VC-1 Simple */ - unsigned long mpeg2Support; /* HW supports MPEG-2 */ - unsigned long ppSupport; /* HW supports post-processor */ - unsigned long ppConfig; /* HW post-processor functions bitmask */ - unsigned long sorensonSparkSupport; /* HW supports Sorenson Spark */ - unsigned long refBufSupport; /* HW supports reference picture buffering */ - unsigned long vp6Support; /* HW supports VP6 */ - unsigned long vp7Support; /* HW supports VP7 */ - unsigned long vp8Support; /* HW supports VP8 */ - unsigned long avsSupport; /* HW supports AVS */ - unsigned long jpegESupport; /* HW supports JPEG extensions */ - unsigned long rvSupport; /* HW supports REAL */ - unsigned long mvcSupport; /* HW supports H264 MVC extension */ -} VPUHwDecConfig_t; +struct vpu_dec_config { + u32 maxDecPicWidth; /* Maximum video decoding width supported */ + u32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */ + u32 h264_support; /* HW supports h.264 */ + u32 jpegSupport; /* HW supports JPEG */ + u32 mpeg4Support; /* HW supports MPEG-4 */ + u32 customMpeg4Support; /* HW supports custom MPEG-4 features */ + u32 vc1Support; /* HW supports VC-1 Simple */ + u32 mpeg2Support; /* HW supports MPEG-2 */ + u32 ppSupport; /* HW supports post-processor */ + u32 ppConfig; /* HW post-processor functions bitmask */ + u32 sorensonSparkSupport; /* HW supports Sorenson Spark */ + u32 refBufSupport; /* HW supports reference picture buffering */ + u32 vp6Support; /* HW supports VP6 */ + u32 vp7Support; /* HW supports VP7 */ + u32 vp8Support; /* HW supports VP8 */ + u32 avsSupport; /* HW supports AVS */ + u32 jpegESupport; /* HW supports JPEG extensions */ + u32 rvSupport; /* HW supports REAL */ + u32 mvcSupport; /* HW supports H264 MVC extension */ +}; /* Hardware encoder configuration description */ -typedef struct VPUHwEndConfig -{ - unsigned long maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */ - unsigned long h264Enabled; /* HW supports H.264 */ - unsigned long jpegEnabled; /* HW supports JPEG */ - unsigned long mpeg4Enabled; /* HW supports MPEG-4 */ - unsigned long vsEnabled; /* HW supports video stabilization */ - unsigned long rgbEnabled; /* HW supports RGB input */ - unsigned long reg_size; - unsigned long reserv[2]; /* reverved */ -} VPUHwEncConfig_t; - -typedef struct VPUHwCfgReq -{ - unsigned long *cfg; - unsigned long size; -} VPUHwCfgReq_t; +struct vpu_enc_config { + u32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */ + u32 h264Enabled; /* HW supports H.264 */ + u32 jpegEnabled; /* HW supports JPEG */ + u32 mpeg4Enabled; /* HW supports MPEG-4 */ + u32 vsEnabled; /* HW supports video stabilization */ + u32 rgbEnabled; /* HW supports RGB input */ + u32 reg_size; + u32 reserv[2]; /* reverved */ +}; + +union vpu_config { + struct vpu_dec_config vpu_dec_conf; + struct vpu_enc_config vpu_enc_conf; +}; + +struct VPUHwCfgReq_t { + u32 *cfg; + u32 size; +}; #define DWL_MPEG2_E 31 /* 1 bit */ #define DWL_VC1_E 29 /* 2 bits */ @@ -232,29 +244,27 @@ typedef struct VPUHwCfgReq #define VPU_PP_HW_SYNTH_CFG 40 #define VPU_PP_HW_FUSE_CFG 41 -typedef struct VPUHwFuseStatus -{ - u32 h264SupportFuse; /* HW supports h.264 */ - u32 mpeg4SupportFuse; /* HW supports MPEG-4 */ - u32 mpeg2SupportFuse; /* HW supports MPEG-2 */ - u32 sorensonSparkSupportFuse; /* HW supports Sorenson Spark */ - u32 jpegSupportFuse; /* HW supports JPEG */ - u32 vp6SupportFuse; /* HW supports VP6 */ - u32 vp7SupportFuse; /* HW supports VP6 */ - u32 vp8SupportFuse; /* HW supports VP6 */ - u32 vc1SupportFuse; /* HW supports VC-1 Simple */ - u32 jpegProgSupportFuse; /* HW supports Progressive JPEG */ - u32 ppSupportFuse; /* HW supports post-processor */ - u32 ppConfigFuse; /* HW post-processor functions bitmask */ - u32 maxDecPicWidthFuse; /* Maximum video decoding width supported */ - u32 maxPpOutPicWidthFuse; /* Maximum output width of Post-Processor */ - u32 refBufSupportFuse; /* HW supports reference picture buffering */ - u32 avsSupportFuse; /* one of the AVS values defined above */ - u32 rvSupportFuse; /* one of the REAL values defined above */ - u32 mvcSupportFuse; - u32 customMpeg4SupportFuse; /* Fuse for custom MPEG-4 */ - -} VPUHwFuseStatus_t; +struct VPUHwFuseStatus_t { + u32 h264SupportFuse; /* HW supports h.264 */ + u32 mpeg4SupportFuse; /* HW supports MPEG-4 */ + u32 mpeg2SupportFuse; /* HW supports MPEG-2 */ + u32 sorensonSparkSupportFuse; /* HW supports Sorenson Spark */ + u32 jpegSupportFuse; /* HW supports JPEG */ + u32 vp6SupportFuse; /* HW supports VP6 */ + u32 vp7SupportFuse; /* HW supports VP6 */ + u32 vp8SupportFuse; /* HW supports VP6 */ + u32 vc1SupportFuse; /* HW supports VC-1 Simple */ + u32 jpegProgSupportFuse; /* HW supports Progressive JPEG */ + u32 ppSupportFuse; /* HW supports post-processor */ + u32 ppConfigFuse; /* HW post-processor functions bitmask */ + u32 maxDecPicWidthFuse; /* Maximum video decoding width supported */ + u32 maxPpOutPicWidthFuse; /* Maximum output width of Post-Processor */ + u32 refBufSupportFuse; /* HW supports reference picture buffering */ + u32 avsSupportFuse; /* one of the AVS values defined above */ + u32 rvSupportFuse; /* one of the REAL values defined above */ + u32 mvcSupportFuse; + u32 customMpeg4SupportFuse; /* Fuse for custom MPEG-4 */ +}; #endif