From: Alpha Lin Date: Tue, 6 Jan 2015 06:24:01 +0000 (+0800) Subject: rk3368: iep driver compatible for both 32bits and 64bits userspace application. X-Git-Tag: firefly_0821_release~4158^2~456 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=d7b502ca4eaecc473e50d4915200eefd29552fc1;p=firefly-linux-kernel-4.4.55.git rk3368: iep driver compatible for both 32bits and 64bits userspace application. Signed-off-by: Alpha Lin --- diff --git a/drivers/video/rockchip/iep/iep.h b/drivers/video/rockchip/iep/iep.h index 4f46de9d30fc..8f5554fb5ce1 100644 --- a/drivers/video/rockchip/iep/iep.h +++ b/drivers/video/rockchip/iep/iep.h @@ -3,20 +3,50 @@ #define IEP_IOC_MAGIC 'i' -#define IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, unsigned long) -#define IEP_SET_PARAMETER_DEINTERLACE _IOW(IEP_IOC_MAGIC, 2, unsigned long) -#define IEP_SET_PARAMETER_ENHANCE _IOW(IEP_IOC_MAGIC, 3, unsigned long) -#define IEP_SET_PARAMETER_CONVERT _IOW(IEP_IOC_MAGIC, 4, unsigned long) -#define IEP_SET_PARAMETER_SCALE _IOW(IEP_IOC_MAGIC, 5, unsigned long) -#define IEP_GET_RESULT_SYNC _IOW(IEP_IOC_MAGIC, 6, unsigned long) -#define IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, unsigned long) -#define IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, unsigned long) -#define IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, unsigned long) +#define IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, unsigned long) +#define IEP_SET_PARAMETER_DEINTERLACE _IOW(IEP_IOC_MAGIC, 2, unsigned long) +#define IEP_SET_PARAMETER_ENHANCE _IOW(IEP_IOC_MAGIC, 3, unsigned long) +#define IEP_SET_PARAMETER_CONVERT _IOW(IEP_IOC_MAGIC, 4, unsigned long) +#define IEP_SET_PARAMETER_SCALE _IOW(IEP_IOC_MAGIC, 5, unsigned long) +#define IEP_GET_RESULT_SYNC _IOW(IEP_IOC_MAGIC, 6, unsigned long) +#define IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, unsigned long) +#define IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, unsigned long) +#define IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, unsigned long) + +#ifdef CONFIG_COMPAT +#define COMPAT_IEP_SET_PARAMETER_REQ _IOW(IEP_IOC_MAGIC, 1, u32) +#define COMPAT_IEP_SET_PARAMETER_DEINTERLACE _IOW(IEP_IOC_MAGIC, 2, u32) +#define COMPAT_IEP_SET_PARAMETER_ENHANCE _IOW(IEP_IOC_MAGIC, 3, u32) +#define COMPAT_IEP_SET_PARAMETER_CONVERT _IOW(IEP_IOC_MAGIC, 4, u32) +#define COMPAT_IEP_SET_PARAMETER_SCALE _IOW(IEP_IOC_MAGIC, 5, u32) +#define COMPAT_IEP_GET_RESULT_SYNC _IOW(IEP_IOC_MAGIC, 6, u32) +#define COMPAT_IEP_GET_RESULT_ASYNC _IOW(IEP_IOC_MAGIC, 7, u32) +#define COMPAT_IEP_SET_PARAMETER _IOW(IEP_IOC_MAGIC, 8, u32) +#define COMPAT_IEP_RELEASE_CURRENT_TASK _IOW(IEP_IOC_MAGIC, 9, u32) +#endif /* Driver information */ #define DRIVER_DESC "IEP Device Driver" #define DRIVER_NAME "iep" +#define DEBUG +#ifdef DEBUG +#define iep_debug(level, fmt, args...) \ + do { \ + if (debug >= level) \ + pr_info("%s:%d: " fmt, \ + __func__, __LINE__, ##args); \ + } while (0) +#else +#define iep_debug(level, fmt, args...) +#endif + +#define iep_debug_enter() vpu_debug(4, "enter\n") +#define iep_debug_leave() vpu_debug(4, "leave\n") + +#define iep_err(fmt, args...) \ + pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) + /* Logging */ #define IEP_DEBUG 0 #if IEP_DEBUG @@ -120,22 +150,22 @@ enum { struct iep_img { - unsigned short act_w; // act_width - unsigned short act_h; // act_height - signed short x_off; // x offset for the vir,word unit - signed short y_off; // y offset for the vir,word unit - - unsigned short vir_w; //unit :pix - unsigned short vir_h; //unit :pix - unsigned int format; - unsigned int *mem_addr; - unsigned int *uv_addr; - unsigned int *v_addr; - - unsigned char rb_swap;//not be used - unsigned char uv_swap;//not be used - - unsigned char alpha_swap;//not be used + u16 act_w; /* act_width */ + u16 act_h; /* act_height */ + s16 x_off; /* x offset for the vir,word unit */ + s16 y_off; /* y offset for the vir,word unit */ + + u16 vir_w; /* unit :pix */ + u16 vir_h; /* unit :pix */ + u32 format; + u32 mem_addr; + u32 uv_addr; + u32 v_addr; + + u8 rb_swap; /* not be used */ + u8 uv_swap; /* not be used */ + + u8 alpha_swap; /* not be used */ }; @@ -164,20 +194,20 @@ struct IEP_MSG { u8 yuv2rgb_clip_en; u8 lcdc_path_en; - int off_x; - int off_y; - int width; - int height; - int layer; + s32 off_x; + s32 off_y; + s32 width; + s32 height; + s32 layer; u8 yuv_3D_denoise_en; /* yuv color enhance */ u8 yuv_enhance_en; - int sat_con_int; - int contrast_int; - int cos_hue_int; - int sin_hue_int; + s32 sat_con_int; + s32 contrast_int; + s32 cos_hue_int; + s32 sin_hue_int; s8 yuv_enh_brightness; /*-32iep_base); */ #ifdef IEP_CLK_ENABLE - clk_prepare_enable(iep_drvdata1->pd_iep); + if (iep_drvdata1->pd_iep) + clk_prepare_enable(iep_drvdata1->pd_iep); clk_prepare_enable(iep_drvdata1->aclk_iep); clk_prepare_enable(iep_drvdata1->hclk_iep); #endif @@ -262,7 +265,8 @@ static void iep_power_off(void) #ifdef IEP_CLK_ENABLE clk_disable_unprepare(iep_drvdata1->aclk_iep); clk_disable_unprepare(iep_drvdata1->hclk_iep); - clk_disable_unprepare(iep_drvdata1->pd_iep); + if (iep_drvdata1->pd_iep) + clk_disable_unprepare(iep_drvdata1->pd_iep); #endif wake_unlock(&iep_drvdata1->wake_lock); @@ -791,12 +795,88 @@ static long iep_ioctl(struct file *filp, uint32_t cmd, unsigned long arg) return ret; } +#ifdef CONFIG_COMPAT +static long compat_iep_ioctl(struct file *filp, uint32_t cmd, + unsigned long arg) +{ + int ret = 0; + iep_session *session = (iep_session *)filp->private_data; + + if (NULL == session) { + IEP_ERR("%s [%d] iep thread session is null\n", + __func__, __LINE__); + return -EINVAL; + } + + mutex_lock(&iep_service.mutex); + + switch (cmd) { + case COMPAT_IEP_SET_PARAMETER: + { + struct IEP_MSG *msg; + + msg = kzalloc(sizeof(*msg), GFP_KERNEL); + + if (msg) { + if (copy_from_user + (msg, compat_ptr((compat_uptr_t)arg), + sizeof(struct IEP_MSG))) { + IEP_ERR("copy_from_user failure\n"); + ret = -EFAULT; + } + } + + if (ret == 0) { + if (atomic_read(&iep_service.waitcnt) < 10) { +#if defined(CONFIG_IEP_IOMMU) + iep_power_on(); +#endif + iep_config(session, msg); + atomic_inc(&iep_service.waitcnt); + } else { + IEP_ERR("iep task queue full\n"); + ret = -EFAULT; + } + } + + /** REGISTER CONFIG must accord to Timing When DPI mode + * enable */ + if (!iep_drvdata1->dpi_mode) + iep_try_set_reg(); + kfree(msg); + } + break; + case COMPAT_IEP_GET_RESULT_SYNC: + if (0 > iep_get_result_sync(session)) + ret = -ETIMEDOUT; + break; + case COMPAT_IEP_GET_RESULT_ASYNC: + iep_get_result_async(session); + break; + case COMPAT_IEP_RELEASE_CURRENT_TASK: + iep_del_running_list_timeout(); + iep_try_set_reg(); + iep_try_start_frm(); + break; + default: + IEP_ERR("unknown ioctl cmd!\n"); + ret = -EINVAL; + } + mutex_unlock(&iep_service.mutex); + + return ret; +} +#endif + struct file_operations iep_fops = { .owner = THIS_MODULE, .open = iep_open, .release = iep_release, .poll = iep_poll, .unlocked_ioctl = iep_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_iep_ioctl, +#endif }; static struct miscdevice iep_dev = { @@ -909,7 +989,7 @@ static int iep_drv_probe(struct platform_device *pdev) data->pd_iep = devm_clk_get(&pdev->dev, "pd_iep"); if (IS_ERR(data->pd_iep)) { IEP_ERR("failed to find iep power down clock source.\n"); - goto err_clock; + data->pd_iep = NULL; } data->aclk_iep = devm_clk_get(&pdev->dev, "aclk_iep"); @@ -1013,7 +1093,9 @@ err_irq: } err_ioremap: wake_lock_destroy(&data->wake_lock); +#ifdef IEP_CLK_ENABLE err_clock: +#endif return ret; }