From 766e5dbd772edcd2bde090144bef2074989a480f Mon Sep 17 00:00:00 2001 From: Huang Jiachai Date: Thu, 10 Nov 2016 14:35:13 +0800 Subject: [PATCH] video: rockchip: fb: add api to enable mirror for VR Change-Id: Ic9a6409f0243896021eb94df3600cdc2fc3db637 Signed-off-by: Huang Jiachai --- drivers/video/rockchip/lcdc/rk322x_lcdc.c | 9 +++++++ drivers/video/rockchip/lcdc/rk3288_lcdc.c | 28 ++++++++++++++++++++++ drivers/video/rockchip/rkfb_sysfs.c | 29 ++++++++++++++++++++++- include/linux/rk_fb.h | 3 ++- 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/video/rockchip/lcdc/rk322x_lcdc.c b/drivers/video/rockchip/lcdc/rk322x_lcdc.c index 7a9b67d7a1f7..93c996a79e0e 100644 --- a/drivers/video/rockchip/lcdc/rk322x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk322x_lcdc.c @@ -4820,6 +4820,7 @@ static int vop_extern_func(struct rk_lcdc_driver *dev_drv, int cmd) { struct vop_device *vop_dev = container_of(dev_drv, struct vop_device, driver); + u64 val; if (unlikely(!vop_dev->clk_on)) { pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); @@ -4830,6 +4831,14 @@ static int vop_extern_func(struct rk_lcdc_driver *dev_drv, int cmd) case UPDATE_CABC_PWM: vop_cfg_done(vop_dev); break; + case SET_DSP_MIRROR: + val = V_DSP_X_MIR_EN(dev_drv->cur_screen->x_mirror) | + V_DSP_Y_MIR_EN(dev_drv->cur_screen->y_mirror); + vop_msk_reg(vop_dev, DSP_CTRL0, val); + pr_info("%s: xmirror: %d, ymirror: %d\n", + __func__, dev_drv->cur_screen->x_mirror, + dev_drv->cur_screen->y_mirror); + break; default: break; } diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.c b/drivers/video/rockchip/lcdc/rk3288_lcdc.c index 1f300c4d2bff..870d22f678da 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.c @@ -3865,6 +3865,34 @@ static struct rk_lcdc_win lcdc_win[] = { }, }; +static int rk3288_lcdc_extern_func(struct rk_lcdc_driver *dev_drv, int cmd) +{ + struct lcdc_device *lcdc_dev = + container_of(dev_drv, struct lcdc_device, driver); + u32 mask, val; + + if (unlikely(!vop_dev->clk_on)) { + pr_info("%s,clk_on = %d\n", __func__, vop_dev->clk_on); + return 0; + } + + switch (cmd) { + case SET_DSP_MIRROR: + mask = m_DSP_X_MIR_EN | m_DSP_Y_MIR_EN; + val = v_DSP_X_MIR_EN(screen->x_mirror) | + v_DSP_Y_MIR_EN(screen->y_mirror); + lcdc_msk_reg(lcdc_dev, DSP_CTRL0, mask, val); + pr_info("%s: xmirror: %d, ymirror: %d\n", + __func__, dev_drv->cur_screen->x_mirror, + dev_drv->cur_screen->y_mirror); + break; + default: + break; + } + + return 0; +} + static struct rk_lcdc_drv_ops lcdc_drv_ops = { .open = rk3288_lcdc_open, .win_direct_en = rk3288_lcdc_win_direct_en, diff --git a/drivers/video/rockchip/rkfb_sysfs.c b/drivers/video/rockchip/rkfb_sysfs.c index 894ed23cd7b8..4cfc84ee36cb 100644 --- a/drivers/video/rockchip/rkfb_sysfs.c +++ b/drivers/video/rockchip/rkfb_sysfs.c @@ -110,6 +110,32 @@ static ssize_t show_screen_info(struct device *dev, fps, screen->type, screen->mode.vmode); } +static ssize_t set_screen_info(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct fb_info *fbi = dev_get_drvdata(dev); + struct rk_fb_par *fb_par = (struct rk_fb_par *)fbi->par; + struct rk_lcdc_driver *dev_drv = fb_par->lcdc_drv; + int xmirror = 0, ymirror = 0, ret = 0, rotate = 0; + + ret = kstrtoint(buf, 0, &rotate); + if (ret) + return ret; + xmirror = !!(rotate & X_MIRROR); + ymirror = !!(rotate & Y_MIRROR); + dev_drv->cur_screen->x_mirror = xmirror; + dev_drv->cur_screen->y_mirror = ymirror; + mutex_lock(&dev_drv->output_lock); + mutex_lock(&dev_drv->win_config); + if (dev_drv->ops->extern_func) + dev_drv->ops->extern_func(dev_drv, SET_DSP_MIRROR); + mutex_unlock(&dev_drv->win_config); + mutex_unlock(&dev_drv->output_lock); + + return count; +} + static ssize_t show_disp_info(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1262,7 +1288,8 @@ static struct device_attribute rkfb_attrs[] = { __ATTR(disp_info, S_IRUGO, show_disp_info, NULL), __ATTR(dump_buf, S_IRUGO | S_IWUSR, show_dump_buffer, set_dump_buffer), __ATTR(dsp_buf, S_IRUGO | S_IWUSR, show_dsp_buffer, set_dsp_buffer), - __ATTR(screen_info, S_IRUGO, show_screen_info, NULL), + __ATTR(screen_info, S_IRUGO | S_IWUSR, + show_screen_info, set_screen_info), __ATTR(dual_mode, S_IRUGO, show_dual_mode, NULL), __ATTR(enable, S_IRUGO | S_IWUSR, show_fb_state, set_fb_state), __ATTR(overlay, S_IRUGO | S_IWUSR, show_overlay, set_overlay), diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index d91f7a2ec2a6..d7634a83817f 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -279,7 +279,8 @@ typedef enum { GET_PAGE_FAULT = 0x0, CLR_PAGE_FAULT = 0x1, UNMASK_PAGE_FAULT = 0x2, - UPDATE_CABC_PWM = 0x3 + UPDATE_CABC_PWM = 0x3, + SET_DSP_MIRROR = 0x4 } extern_func; enum rk_vop_feature { -- 2.34.1