From patchwork Tue Apr 7 19:00:44 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tim Yamin X-Patchwork-Id: 16938 X-Patchwork-Delegate: tomi.valkeinen@nokia.com Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n37J0qVc023293 for ; Tue, 7 Apr 2009 19:00:52 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753717AbZDGTAt (ORCPT ); Tue, 7 Apr 2009 15:00:49 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753441AbZDGTAt (ORCPT ); Tue, 7 Apr 2009 15:00:49 -0400 Received: from mail-bw0-f169.google.com ([209.85.218.169]:50234 "EHLO mail-bw0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754030AbZDGTAr (ORCPT ); Tue, 7 Apr 2009 15:00:47 -0400 Received: by bwz17 with SMTP id 17so2445787bwz.37 for ; Tue, 07 Apr 2009 12:00:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:in-reply-to :references:date:x-google-sender-auth:message-id:subject:from:to:cc :content-type; bh=hK8+dmzjPqRUu7vqEIBuy1B4x7UiTCixH+EH370ZIZ4=; b=JEl+mvUpAID1GnmGnAa8CpHF24nJczBJRnEOLSD23um1ih/qJuDGYSd4zL+CfVwdf9 IhxIRoYrKQa0H2gmAJdqWUvX2Ey6LLpKR4d5WprWI5ZXPpVysXHs8K8uH4a4VXg5izIR UAcw6nsDc4fTHn0aKEpMvtEWMZh6uNSc8UvaQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type; b=EHBYSW4W94KzJKXO7tTne8tUl/p+yLUrjaEq82ZUvYk+kVGf3L+sLHcuPmCciPRnVq 3e2k0sWAy9bA07f126XAYFfbOt6MsIOJnYbm+SMziWO4hCMAie20GpWXlW1lbEP1sxd1 mAETgzxUkj89gcP8YqaLOj95eXU+MJXmm22WY= MIME-Version: 1.0 Received: by 10.223.116.195 with SMTP id n3mr226707faq.12.1239130844955; Tue, 07 Apr 2009 12:00:44 -0700 (PDT) In-Reply-To: <5A47E75E594F054BAF48C5E4FC4B92AB02FB10317D@dbde02.ent.ti.com> References: <1239078602.16520.59.camel@localhost> <5A47E75E594F054BAF48C5E4FC4B92AB02FB10317D@dbde02.ent.ti.com> Date: Tue, 7 Apr 2009 12:00:44 -0700 X-Google-Sender-Auth: 791bcce7e07f4ebc Message-ID: <792f5f410904071200h1dae9024v1f2d9cbd4f1bbebc@mail.gmail.com> Subject: Re: YUV rotation support for DSS2 - 2.6.29 [WAS Re: Hello Tomi Valkeinen, I have some questions about dss2 driver.] From: Tim Yamin To: "Shah, Hardik" Cc: "gregoire@gentil.com" , "tomi.valkeinen@nokia.com" , "linux-omap@vger.kernel.org" , "beagleboard@googlegroups.com" Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org Hi Hardik / Tomi, > [Shah, Hardik] I have also patched the DSS to support the DSS YUV rotation.  Here the rotation type is passed to know the type of rotation required by driver.  I have also modified the FBDEV driver to use this patch.  Please find the both patches.  I have tested it on the old master of tomi. Commit id is 4261fafc4fdc0730b3d4dd83c036d8be09ec8575.  I am planning to rebase it on the latest master soon. I have tested the FBDEV driver with different rotation and resolution settings. I've merged my changes with your patches and rebased against master, please find the new patch attached. > [Shah, Hardik] In past I saw setting the FIFO size eliminates this problem.  I have some FIFO setting can you please try this out and let me know the result. > FIFO_HIGH_THRES = 0x3FC and GFX_FIFO_LOW_THRES = 0x3BC.  This I tried in on OMAP3. Tried this (see attached patch) but does not help -- still getting these errors as soon as I try to play a video: omapdss DISPC error: VID1_FIFO_UNDERFLOW, disabling VID1 omapdss DISPC error: SYNC_LOST, disabling LCD The FIFOs are configured as follows: omapdss DISPC: fifo(0) size 1024, low/high old 3008/3071, new 956/1020 omapdss DISPC: fifo(1) size 1024, low/high old 956/1020, new 956/1020 Cheers, Tim From 826edf9b2b9af7b9bc32f4363724af174911175c Mon Sep 17 00:00:00 2001 From: Tim Yamin Date: Tue, 7 Apr 2009 11:52:35 -0700 Subject: [PATCH] DSS2: Add YUV VRFB rotation support This is a rebased version of Hardik Shah's patch with a few additional tweaks from me. Signed-off-by: Tim Yamin --- arch/arm/plat-omap/include/mach/display.h | 6 ++ arch/arm/plat-omap/vrfb.c | 4 +- drivers/video/omap2/dss/dispc.c | 87 ++++++++++++++++++++++++++-- drivers/video/omap2/dss/dss.h | 1 + drivers/video/omap2/dss/manager.c | 1 + drivers/video/omap2/omapfb/omapfb-main.c | 66 +++++++++++----------- drivers/video/omap2/omapfb/omapfb.h | 7 +-- 7 files changed, 126 insertions(+), 46 deletions(-) diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h index 6b702c7..b0a6272 100644 --- a/arch/arm/plat-omap/include/mach/display.h +++ b/arch/arm/plat-omap/include/mach/display.h @@ -341,6 +341,11 @@ enum omap_dss_overlay_managers { struct omap_overlay_manager; +enum omap_dss_rotation_type { + OMAP_DSS_ROT_DMA = 0, + OMAP_DSS_ROT_VRFB = 1, +}; + struct omap_overlay_info { bool enabled; @@ -351,6 +356,7 @@ struct omap_overlay_info { u16 height; enum omap_color_mode color_mode; u8 rotation; + enum omap_dss_rotation_type rotation_type; bool mirror; u16 pos_x; diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c index 7e0f8fc..77aa9a7 100644 --- a/arch/arm/plat-omap/vrfb.c +++ b/arch/arm/plat-omap/vrfb.c @@ -61,8 +61,10 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, width, height, bytespp); if (bytespp == 4) + { pixel_size_exp = 2; - else if (bytespp == 2) + width >>= 1; + } else if (bytespp == 2) pixel_size_exp = 1; else BUG(); diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index ae7be3d..b1dbb79 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1106,7 +1106,7 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, case 0: vidrot = 0; break; case 1: vidrot = 1; break; case 2: vidrot = 2; break; - case 3: vidrot = 1; break; + case 3: vidrot = 3; break; } } @@ -1134,7 +1134,70 @@ static s32 pixinc(int pixels, u8 ps) BUG(); } -static void calc_rotation_offset(u8 rotation, bool mirror, +static void calc_vrfb_rotation_offset(u8 rotation, bool mirror, + u16 screen_width, + u16 width, u16 height, + enum omap_color_mode color_mode, bool fieldmode, + unsigned *offset0, unsigned *offset1, + s32 *row_inc, s32 *pix_inc) +{ + u8 ps; + + switch (color_mode) { + case OMAP_DSS_COLOR_RGB16: + case OMAP_DSS_COLOR_ARGB16: + ps = 2; + break; + + case OMAP_DSS_COLOR_RGB24P: + ps = 3; + break; + + case OMAP_DSS_COLOR_RGB24U: + case OMAP_DSS_COLOR_ARGB32: + case OMAP_DSS_COLOR_RGBA32: + case OMAP_DSS_COLOR_RGBX32: + case OMAP_DSS_COLOR_YUV2: + case OMAP_DSS_COLOR_UYVY: + ps = 4; + break; + + default: + BUG(); + return; + } + + DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width, + width, height); + switch (rotation + mirror * 4) { + case 0: + case 2: + /* + * If the pixel format is YUV or UYVY divide the width + * of the image by 2. + */ + if (color_mode == OMAP_DSS_COLOR_YUV2 || + color_mode == OMAP_DSS_COLOR_UYVY) + width = width >> 1; + case 1: + case 3: + *offset0 = 0; + if (fieldmode) + *offset1 = screen_width * ps; + else + *offset1 = 0; + + *row_inc = pixinc(1 + (screen_width - width) + + (fieldmode ? screen_width : 0), + ps); + *pix_inc = pixinc(1, ps); + break; + default: + BUG(); + } +} + +static void calc_dma_rotation_offset(u8 rotation, bool mirror, u16 screen_width, u16 width, u16 height, enum omap_color_mode color_mode, bool fieldmode, @@ -1357,6 +1420,7 @@ static int _dispc_setup_plane(enum omap_plane plane, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool ilace, + enum omap_dss_rotation_type rotation_type, u8 rotation, int mirror) { const int maxdownscale = cpu_is_omap34xx() ? 4 : 2; @@ -1463,10 +1527,16 @@ static int _dispc_setup_plane(enum omap_plane plane, return -EINVAL; } - calc_rotation_offset(rotation, mirror, - screen_width, width, frame_height, color_mode, - fieldmode, - &offset0, &offset1, &row_inc, &pix_inc); + if (rotation_type == OMAP_DSS_ROT_DMA) + calc_dma_rotation_offset(rotation, mirror, + screen_width, width, height, color_mode, + fieldmode, + &offset0, &offset1, &row_inc, &pix_inc); + else + calc_vrfb_rotation_offset(rotation, mirror, + screen_width, width, height, color_mode, + fieldmode, + &offset0, &offset1, &row_inc, &pix_inc); DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n", offset0, offset1, row_inc, pix_inc); @@ -2879,6 +2949,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool ilace, + enum omap_dss_rotation_type rotation_type, u8 rotation, bool mirror) { int r = 0; @@ -2899,6 +2970,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out, width, height, out_width, out_height, color_mode, ilace, + rotation_type, rotation, mirror); enable_clocks(0); @@ -3112,7 +3184,8 @@ void dispc_setup_partial_planes(struct omap_display *display, pw, ph, pow, poh, pi->color_mode, 0, - pi->rotation, // XXX rotation probably wrong + pi->rotation_type, + pi->rotation, pi->mirror); dispc_enable_plane(ovl->id, 1); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 0be42b6..c722eee 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -269,6 +269,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out, u16 out_width, u16 out_height, enum omap_color_mode color_mode, bool ilace, + enum omap_dss_rotation_type rotation_type, u8 rotation, bool mirror); void dispc_go(enum omap_channel channel); diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index b0fee80..8ca0bbb 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -395,6 +395,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) outh, ovl->info.color_mode, ilace, + ovl->info.rotation_type, ovl->info.rotation, ovl->info.mirror); diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 12ce0c3..8327681 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -176,15 +176,9 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot) static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi) { - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) { - unsigned offset; - int rot; - - rot = ofbi->rotation; - - offset = omapfb_get_vrfb_offset(ofbi, rot); - - return ofbi->region.vrfb.paddr[rot] + offset; + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + return ofbi->region.vrfb.paddr[ofbi->rotation] + + omapfb_get_vrfb_offset(ofbi, ofbi->rotation); } else { return ofbi->region.paddr; } @@ -192,7 +186,7 @@ static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi) u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) { - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) return ofbi->region.vrfb.paddr[0]; else return ofbi->region.paddr; @@ -200,7 +194,7 @@ u32 omapfb_get_region_paddr(struct omapfb_info *ofbi) void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi) { - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) return ofbi->region.vrfb.vaddr[0]; else return ofbi->region.vaddr; @@ -383,7 +377,7 @@ void set_fb_fix(struct fb_info *fbi) fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi); /* used by mmap in fbmem.c */ - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) fix->line_length = (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3; else @@ -419,11 +413,21 @@ void set_fb_fix(struct fb_info *fbi) fix->xpanstep = 1; fix->ypanstep = 1; - if (rg->size) { - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) - omap_vrfb_setup(&rg->vrfb, rg->paddr, - var->xres_virtual, var->yres_virtual, - var->bits_per_pixel >> 3); + if (rg->size && ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { + switch(var->nonstd) + { + case OMAPFB_COLOR_YUV422: + case OMAPFB_COLOR_YUV420: + case OMAPFB_COLOR_YUY422: + omap_vrfb_setup(&rg->vrfb, rg->paddr, + var->xres_virtual, var->yres_virtual, + var->bits_per_pixel >> 2); + break; + default: + omap_vrfb_setup(&rg->vrfb, rg->paddr, + var->xres_virtual, var->yres_virtual, + var->bits_per_pixel >> 3); + } } } @@ -512,7 +516,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) if (var->yres > var->yres_virtual) var->yres = var->yres_virtual; - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) line_size = OMAP_VRFB_LINE_LEN * bytespp; else line_size = var->xres_virtual * bytespp; @@ -534,7 +538,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) if (line_size * var->yres_virtual > max_frame_size) { DBG("can't fit FB into memory, reducing x\n"); - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) return -EINVAL; var->xres_virtual = max_frame_size / var->yres_virtual / @@ -657,7 +661,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, struct omap_overlay_info info; int xres, yres; int screen_width; - int rot, mirror; + int mirror; DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id, posx, posy, outw, outh); @@ -673,7 +677,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, offset = ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel) >> 3; - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) { + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { data_start_p = omapfb_get_region_rot_paddr(ofbi); data_start_v = NULL; } else { @@ -696,13 +700,10 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, ovl->get_overlay_info(ovl, &info); - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) { - rot = 0; + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) mirror = 0; - } else { - rot = ofbi->rotation; + else mirror = ofbi->mirror; - } info.paddr = data_start_p; info.vaddr = data_start_v; @@ -710,7 +711,8 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, info.width = xres; info.height = yres; info.color_mode = mode; - info.rotation = rot; + info.rotation_type = ofbi->rotation_type; + info.rotation = ofbi->rotation; info.mirror = mirror; info.pos_x = posx; @@ -1106,7 +1108,7 @@ static void omapfb_free_fbmem(struct fb_info *fbi) if (rg->vaddr) iounmap(rg->vaddr); - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) { + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { /* unmap the 0 angle rotation */ if (rg->vrfb.vaddr[0]) { iounmap(rg->vrfb.vaddr[0]); @@ -1166,7 +1168,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size, return -ENOMEM; } - if (ofbi->rotation_type != OMAPFB_ROT_VRFB) { + if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) { vaddr = ioremap_wc(paddr, size); if (!vaddr) { @@ -1245,7 +1247,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size, display->get_resolution(display, &w, &h); - if (ofbi->rotation_type == OMAPFB_ROT_VRFB) { + if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { #ifdef DEBUG int oldw = w, oldh = h; #endif @@ -1602,8 +1604,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) ofbi->id = i; /* assign these early, so that fb alloc can use them */ - ofbi->rotation_type = def_vrfb ? OMAPFB_ROT_VRFB : - OMAPFB_ROT_DMA; + ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : + OMAP_DSS_ROT_DMA; ofbi->rotation = def_rotate; ofbi->mirror = def_mirror; diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index 65e9e6e..88e7675 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h @@ -51,11 +51,6 @@ struct omapfb2_mem_region { bool map; /* kernel mapped by the driver */ }; -enum omapfb_rotation_type { - OMAPFB_ROT_DMA = 0, - OMAPFB_ROT_VRFB = 1, -}; - /* appended to fb_info */ struct omapfb_info { int id; @@ -64,7 +59,7 @@ struct omapfb_info { int num_overlays; struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB]; struct omapfb2_device *fbdev; - enum omapfb_rotation_type rotation_type; + enum omap_dss_rotation_type rotation_type; u8 rotation; bool mirror; }; -- 1.5.6.3