From a99d6b4e096c61a409ca39d8d8ae39b411f6fd3a Mon Sep 17 00:00:00 2001 From: Mark Yao Date: Tue, 5 Jan 2016 16:07:53 +0800 Subject: [PATCH] video: rockchip_fb: support ymirror for uboot logo Now only find rk322x and rk3368 support do ymirror in windows. Change-Id: Iba49d64bb51db8fb35e6b21cab8aeba23dbd52b6 Signed-off-by: Mark Yao --- drivers/video/rockchip/lcdc/rk312x_lcdc.c | 6 ++++-- drivers/video/rockchip/lcdc/rk3288_lcdc.c | 6 ++++-- drivers/video/rockchip/lcdc/rk3368_lcdc.c | 12 ++++++++---- drivers/video/rockchip/rk_fb.c | 21 +++++++++++++++------ drivers/video/rockchip/rkfb_sysfs.c | 4 +++- include/linux/rk_fb.h | 5 +++-- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/drivers/video/rockchip/lcdc/rk312x_lcdc.c b/drivers/video/rockchip/lcdc/rk312x_lcdc.c index c1db0e58be49..f8cb796a2a4e 100755 --- a/drivers/video/rockchip/lcdc/rk312x_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk312x_lcdc.c @@ -1128,7 +1128,8 @@ static void rk312x_lcdc_select_bcsh(struct rk_lcdc_driver *dev_drv, } static int rk312x_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, - u16 *yact, int *format, u32 *dsp_addr) + u16 *yact, int *format, u32 *dsp_addr, + int *ymirror) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); @@ -1151,7 +1152,8 @@ static int rk312x_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, } static int rk312x_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, - int format, u16 xact, u16 yact, u16 xvir) + int format, u16 xact, u16 yact, u16 xvir, + int ymirror) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.c b/drivers/video/rockchip/lcdc/rk3288_lcdc.c index 7e594a70aef6..8cd84a4d984a 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.c @@ -1158,7 +1158,8 @@ static void rk3288_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv) } static int rk3288_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, - u16 *yact, int *format, u32 *dsp_addr) + u16 *yact, int *format, u32 *dsp_addr, + int *ymirror) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); @@ -1180,7 +1181,8 @@ static int rk3288_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, } static int rk3288_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, - int format, u16 xact, u16 yact, u16 xvir) + int format, u16 xact, u16 yact, u16 xvir, + int ymirror) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); diff --git a/drivers/video/rockchip/lcdc/rk3368_lcdc.c b/drivers/video/rockchip/lcdc/rk3368_lcdc.c index a2259e525934..307c1599abb5 100644 --- a/drivers/video/rockchip/lcdc/rk3368_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3368_lcdc.c @@ -1805,7 +1805,8 @@ static void rk3368_lcdc_bcsh_path_sel(struct rk_lcdc_driver *dev_drv) } static int rk3368_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, - u16 *yact, int *format, u32 *dsp_addr) + u16 *yact, int *format, u32 *dsp_addr, + int *ymirror) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); @@ -1819,6 +1820,7 @@ static int rk3368_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, val = lcdc_readl(lcdc_dev, WIN0_CTRL0); *format = (val & m_WIN0_DATA_FMT) >> 1; + *ymirror = (val & m_WIN0_Y_MIRROR) >> 22; *dsp_addr = lcdc_readl(lcdc_dev, WIN0_YRGB_MST); spin_unlock(&lcdc_dev->reg_lock); @@ -1827,15 +1829,17 @@ static int rk3368_get_dspbuf_info(struct rk_lcdc_driver *dev_drv, u16 *xact, } static int rk3368_post_dspbuf(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, - int format, u16 xact, u16 yact, u16 xvir) + int format, u16 xact, u16 yact, u16 xvir, + int ymirror) { struct lcdc_device *lcdc_dev = container_of(dev_drv, struct lcdc_device, driver); u32 val, mask; int swap = (format == RGB888) ? 1 : 0; - mask = m_WIN0_DATA_FMT | m_WIN0_RB_SWAP; - val = v_WIN0_DATA_FMT(format) | v_WIN0_RB_SWAP(swap); + mask = m_WIN0_DATA_FMT | m_WIN0_RB_SWAP | m_WIN0_Y_MIRROR; + val = v_WIN0_DATA_FMT(format) | v_WIN0_RB_SWAP(swap) | + v_WIN0_Y_MIRROR(ymirror); lcdc_msk_reg(lcdc_dev, WIN0_CTRL0, mask, val); lcdc_msk_reg(lcdc_dev, WIN0_VIR, m_WIN0_VIR_STRIDE, diff --git a/drivers/video/rockchip/rk_fb.c b/drivers/video/rockchip/rk_fb.c index 7c0462c18cfa..82fa78426fd6 100644 --- a/drivers/video/rockchip/rk_fb.c +++ b/drivers/video/rockchip/rk_fb.c @@ -4143,13 +4143,14 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv, phys_addr_t start = uboot_logo_base + uboot_logo_offset; unsigned int size = uboot_logo_size - uboot_logo_offset; unsigned int nr_pages; + int ymirror = 0; struct page **pages; char *vaddr; int i = 0; if (dev_drv->ops->get_dspbuf_info) dev_drv->ops->get_dspbuf_info(dev_drv, &xact, - &yact, &format, &dsp_addr); + &yact, &format, &dsp_addr, &ymirror); nr_pages = size >> PAGE_SHIFT; pages = kzalloc(sizeof(struct page) * nr_pages, GFP_KERNEL); @@ -4188,7 +4189,8 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv, dev_drv->ops->post_dspbuf(dev_drv, main_fbi->fix.smem_start, rk_fb_data_fmt(0, bits), - width, height, width * bits >> 5); + width, height, width * bits >> 5, + ymirror); } if (dev_drv->iommu_enabled) { rk_fb_poll_wait_frame_complete(); @@ -4201,19 +4203,24 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv, } else if (dev_drv->uboot_logo && uboot_logo_base) { u32 start = uboot_logo_base; u32 start_base = start; - int logo_len, i = 0; + int logo_len, i=0; + int y_mirror = 0; unsigned int nr_pages; struct page **pages; char *vaddr; dev_drv->ops->get_dspbuf_info(dev_drv, &xact, - &yact, &format, &start); + &yact, &format, + &start, + &y_mirror); logo_len = rk_fb_pixel_width(format) * xact * yact >> 3; if (logo_len > uboot_logo_size || logo_len > main_fbi->fix.smem_len) { pr_err("logo size > uboot reserve buffer size\n"); return -1; } + if (y_mirror) + start -= logo_len; nr_pages = uboot_logo_size >> PAGE_SHIFT; pages = kzalloc(sizeof(struct page) * nr_pages, @@ -4239,9 +4246,11 @@ int rk_fb_register(struct rk_lcdc_driver *dev_drv, if (dev_drv->ops->wait_frame_start) dev_drv->ops->wait_frame_start(dev_drv, 0); dev_drv->ops->post_dspbuf(dev_drv, - main_fbi->fix.smem_start, + main_fbi->fix.smem_start + + (y_mirror ? logo_len : 0), format, xact, yact, - xact * rk_fb_pixel_width(format) >> 5); + xact * rk_fb_pixel_width(format) >> 5, + y_mirror); if (dev_drv->iommu_enabled) { rk_fb_poll_wait_frame_complete(); if (dev_drv->ops->mmu_en) diff --git a/drivers/video/rockchip/rkfb_sysfs.c b/drivers/video/rockchip/rkfb_sysfs.c index 2554aa370232..99e2dcf4c462 100644 --- a/drivers/video/rockchip/rkfb_sysfs.c +++ b/drivers/video/rockchip/rkfb_sysfs.c @@ -411,12 +411,14 @@ static ssize_t set_dump_buffer(struct device *dev, u16 xact, yact; int data_format; u32 dsp_addr; + int ymirror; mutex_unlock(&dev_drv->front_lock); if (dev_drv->ops->get_dspbuf_info) dev_drv->ops->get_dspbuf_info(dev_drv, &xact, - &yact, &data_format, &dsp_addr); + &yact, &data_format, &dsp_addr, + &ymirror); dump_win(NULL, NULL, dsp_addr, xact, yact, data_format, 0, 0, 0, is_bmp, false); diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 42ee6d35e0e5..40931041b5ac 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -458,9 +458,10 @@ struct rk_lcdc_drv_ops { int (*load_screen) (struct rk_lcdc_driver *dev_drv, bool initscreen); int (*get_dspbuf_info) (struct rk_lcdc_driver *dev_drv, u16 *xact, u16 *yact, int *format, - u32 *dsp_addr); + u32 *dsp_addr, int *ymirror); int (*post_dspbuf)(struct rk_lcdc_driver *dev_drv, u32 rgb_mst, - int format, u16 xact, u16 yact, u16 xvir); + int format, u16 xact, u16 yact, u16 xvir, + int ymirror); int (*get_win_state) (struct rk_lcdc_driver *dev_drv, int layer_id, int area_id); int (*ovl_mgr) (struct rk_lcdc_driver *dev_drv, int swap, bool set); /*overlay manager*/ -- 2.34.1