Re: [PATCH] OMAP: DSS2: GFX FIFO UNDERFLOW issue fixed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2010-03-22 at 14:09 +0100, ext hvaibhav@xxxxxx wrote:
> From: Vaibhav Hiremath <hvaibhav@xxxxxx>
> 
> In case of 720P with 90/270 degree rotation, the system reports
> GFX_FIFO_UNDERFLOW error which usually happens if DSS DMA is not able to fill
> the FIFO as per requirement.
> 
> In TRM (section 11.2.6.1.3), where is has been clearly mentioned that,
> 
> "To improve the performance on 90 degree rotation, split the data access on
> write side and not read side."
> 
> That means, read should always happen on 0 degree and write should go to
> respective rotation view.
> 

With this patch my db test app (from
git://gitorious.org/linux-omap-dss2/omapfb-tests.git) shows a lot of
tearing when rotation != 0. I tested this on 3430SDP using the LCD.

 Tomi


> Signed-off-by: Vaibhav Hiremath <hvaibhav@xxxxxx>
> ---
>  drivers/video/omap2/omapfb/omapfb-main.c |   85 +++++++++++++++++++----------
>  1 files changed, 56 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
> index 4a76917..fea6b08 100644
> --- a/drivers/video/omap2/omapfb/omapfb-main.c
> +++ b/drivers/video/omap2/omapfb/omapfb-main.c
> @@ -184,6 +184,11 @@ static unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot)
>  static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
>  {
>  	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
> +		if (rot == FB_ROTATE_CW)
> +			rot = FB_ROTATE_CCW;
> +		else if (rot == FB_ROTATE_CCW)
> +			rot = FB_ROTATE_CW;
> +
>  		return ofbi->region.vrfb.paddr[rot]
>  			+ omapfb_get_vrfb_offset(ofbi, rot);
>  	} else {
> @@ -191,20 +196,32 @@ static u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot)
>  	}
>  }
>  
> -static u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi)
> +static u32 omapfb_get_region_paddr(struct omapfb_info *ofbi, int rot)
>  {
> -	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
> -		return ofbi->region.vrfb.paddr[0];
> -	else
> +	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
> +		if (rot == FB_ROTATE_CW)
> +			rot = FB_ROTATE_CCW;
> +		else if (rot == FB_ROTATE_CCW)
> +			rot = FB_ROTATE_CW;
> +
> +		return ofbi->region.vrfb.paddr[rot];
> +	} else {
>  		return ofbi->region.paddr;
> +	}
>  }
>  
> -static void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi)
> +static void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi, int rot)
>  {
> -	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
> -		return ofbi->region.vrfb.vaddr[0];
> -	else
> +	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
> +		if (rot == FB_ROTATE_CW)
> +			rot = FB_ROTATE_CCW;
> +		else if (rot == FB_ROTATE_CCW)
> +			rot = FB_ROTATE_CW;
> +
> +		return ofbi->region.vrfb.vaddr[rot];
> +	} else {
>  		return ofbi->region.vaddr;
> +	}
>  }
>  
>  static struct omapfb_colormode omapfb_colormodes[] = {
> @@ -503,7 +520,7 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
>  	unsigned bytespp;
>  	bool yuv_mode;
>  	enum omap_color_mode mode;
> -	int r;
> +	int r, rotation = var->rotate;
>  	bool reconf;
>  
>  	if (!rg->size || ofbi->rotation_type != OMAP_DSS_ROT_VRFB)
> @@ -511,6 +528,11 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
>  
>  	DBG("setup_vrfb_rotation\n");
>  
> +	if (rotation == FB_ROTATE_CW)
> +		rotation = FB_ROTATE_CCW;
> +	else if (rotation == FB_ROTATE_CCW)
> +		rotation = FB_ROTATE_CW;
> +
>  	r = fb_mode_to_dss_mode(var, &mode);
>  	if (r)
>  		return r;
> @@ -534,32 +556,35 @@ static int setup_vrfb_rotation(struct fb_info *fbi)
>  			vrfb->yres != var->yres_virtual)
>  		reconf = true;
>  
> -	if (vrfb->vaddr[0] && reconf) {
> +	if (vrfb->vaddr[rotation] && reconf) {
>  		fbi->screen_base = NULL;
>  		fix->smem_start = 0;
>  		fix->smem_len = 0;
> -		iounmap(vrfb->vaddr[0]);
> -		vrfb->vaddr[0] = NULL;
> +		iounmap(vrfb->vaddr[rotation]);
> +		vrfb->vaddr[rotation] = NULL;
>  		DBG("setup_vrfb_rotation: reset fb\n");
>  	}
>  
> -	if (vrfb->vaddr[0])
> +	if (vrfb->vaddr[rotation])
>  		return 0;
>  
> -	omap_vrfb_setup(&rg->vrfb, rg->paddr,
> -			var->xres_virtual,
> -			var->yres_virtual,
> -			bytespp, yuv_mode);
> +	if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW)
> +		omap_vrfb_setup(&rg->vrfb, rg->paddr,
> +				var->yres_virtual, var->xres_virtual,
> +				bytespp, yuv_mode);
> +	else
> +		omap_vrfb_setup(&rg->vrfb, rg->paddr,
> +				var->xres_virtual, var->yres_virtual,
> +				bytespp, yuv_mode);
>  
> -	/* Now one can ioremap the 0 angle view */
> -	r = omap_vrfb_map_angle(vrfb, var->yres_virtual, 0);
> +	/* Now one can ioremap the rotation angle view */
> +	r = omap_vrfb_map_angle(vrfb, var->yres_virtual, rotation);
>  	if (r)
>  		return r;
> -
>  	/* used by open/write in fbmem.c */
> -	fbi->screen_base = ofbi->region.vrfb.vaddr[0];
> +	fbi->screen_base = ofbi->region.vrfb.vaddr[rotation];
>  
> -	fix->smem_start = ofbi->region.vrfb.paddr[0];
> +	fix->smem_start = ofbi->region.vrfb.paddr[rotation];
>  
>  	switch (var->nonstd) {
>  	case OMAPFB_COLOR_YUV422:
> @@ -603,7 +628,8 @@ void set_fb_fix(struct fb_info *fbi)
>  	DBG("set_fb_fix\n");
>  
>  	/* used by open/write in fbmem.c */
> -	fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
> +	fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi,
> +			var->rotate);
>  
>  	/* used by mmap in fbmem.c */
>  	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
> @@ -626,7 +652,7 @@ void set_fb_fix(struct fb_info *fbi)
>  		fix->smem_len = rg->size;
>  	}
>  
> -	fix->smem_start = omapfb_get_region_paddr(ofbi);
> +	fix->smem_start = omapfb_get_region_paddr(ofbi, var->rotate);
>  
>  	fix->type = FB_TYPE_PACKED_PIXELS;
>  
> @@ -862,15 +888,15 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
>  
> 
>  	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
> -		data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation);
> +		data_start_p = omapfb_get_region_rot_paddr(ofbi, 0);
>  		data_start_v = NULL;
>  	} else {
> -		data_start_p = omapfb_get_region_paddr(ofbi);
> -		data_start_v = omapfb_get_region_vaddr(ofbi);
> +		data_start_p = omapfb_get_region_paddr(ofbi, 0);
> +		data_start_v = omapfb_get_region_vaddr(ofbi, 0);
>  	}
>  
>  	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
> -		offset = calc_rotation_offset_vrfb(var, fix, rotation);
> +		offset = calc_rotation_offset_vrfb(var, fix, 0);
>  	else
>  		offset = calc_rotation_offset_dma(var, fix, rotation);
>  
> @@ -1078,6 +1104,7 @@ static struct vm_operations_struct mmap_user_ops = {
>  static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
>  {
>  	struct omapfb_info *ofbi = FB2OFB(fbi);
> +	struct fb_var_screeninfo *var = &fbi->var;
>  	struct fb_fix_screeninfo *fix = &fbi->fix;
>  	unsigned long off;
>  	unsigned long start;
> @@ -1089,7 +1116,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
>  		return -EINVAL;
>  	off = vma->vm_pgoff << PAGE_SHIFT;
>  
> -	start = omapfb_get_region_paddr(ofbi);
> +	start = omapfb_get_region_paddr(ofbi, var->rotate);
>  	len = fix->smem_len;
>  	if (off >= len)
>  		return -EINVAL;


--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux