* omap-sdp3430_Rotation patch @ 2008-09-12 12:00 rajesh k 2008-09-12 12:26 ` Felipe Balbi 2008-09-15 9:48 ` arun c 0 siblings, 2 replies; 11+ messages in thread From: rajesh k @ 2008-09-12 12:00 UTC (permalink / raw) To: linux-omap; +Cc: krajesh >From Rajesh K krajesh<krajesh@ti.com> OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP 3430 This patch provides rotation support OMAP SDP 3430. You will have to append video=omapfb:rotate=0 parameters to your u-boot arguments to get this working. This supports 0,90,180 and 270 degree rotations. Signed-off-by: Rajesh K < krajesh@ti.com > Iqbal shareef < iqbal@ti.com > --- arch/arm/plat-omap/include/mach/omapfb.h | 2 +- drivers/video/omap/dispc.c | 167 +++++++++++++++++++++++++++++- drivers/video/omap/dispc.h | 31 ++++++ drivers/video/omap/omapfb_main.c | 27 +++--- 4 files changed, 208 insertions(+), 19 deletions(-) diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h index a4a84f3..6abc327 100644 --- a/arch/arm/plat-omap/include/mach/omapfb.h +++ b/arch/arm/plat-omap/include/mach/omapfb.h @@ -306,7 +306,7 @@ struct lcd_ctrl { int screen_width, int pos_x, int pos_y, int width, int height, int color_mode); - int (*set_rotate) (int angle); + int (*set_rotate) (int plane, int angle); int (*setup_mem) (int plane, size_t size, int mem_type, unsigned long *paddr); int (*mmap) (struct fb_info *info, diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index ce4c4de..f882db4 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -24,11 +24,9 @@ #include <linux/vmalloc.h> #include <linux/clk.h> #include <linux/io.h> - #include <mach/sram.h> #include <mach/omapfb.h> #include <mach/board.h> - #include "dispc.h" #define MODULE_NAME "dispc" @@ -149,6 +147,20 @@ #define RESMAP_MASK(_page_nr) \ (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) +dma_addr_t save_paddr; +unsigned long save_vaddr; + +struct { + dma_addr_t paddr[4]; + unsigned long vaddr[4]; + u32 xoffset; + u32 yoffset; + unsigned long size_val; + unsigned long control_val; +} vrfb; + +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); + struct resmap { unsigned long start; unsigned page_cnt; @@ -459,6 +471,108 @@ static int omap_dispc_setup_plane(int plane, int channel_out, return r; } +/* +* function: pages_per_side : Will provide page height & width +* @ img_side : img_side +* @ page_exp : page_exp +* Return Value: Will return an integer. +*/ +static inline u32 +pages_per_side(u32 img_side, u32 page_exp) +{ + return (u32) (img_side + (1<<page_exp) - 1) >> page_exp; +} + +/* +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine +* which will supports rotations of 0,90,180,270 degrees. +* @width: Width of the image +* @height : height of the image +* @bytes_per_pixel : color depth of the image +* return value : will return an integer value +*/ +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) +{ + int page_width_exp, page_height_exp, pixel_size_exp; + int context = 0; + vrfb.size_val = 0; + vrfb.control_val = 0; + pixel_size_exp = bytes_per_pixel >> 1; + page_width_exp = PAGE_WIDTH_EXP; + page_height_exp = PAGE_HEIGHT_EXP; + width = ((1<<page_width_exp) * + (pages_per_side(width * bytes_per_pixel, + page_width_exp))) >> pixel_size_exp; + height = (1<<page_height_exp) * + (pages_per_side(height, page_height_exp)); + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); + __raw_writel(0, SMS_ROT0_SIZE(context)); + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| + (height << SMS_IMAGEHEIGHT_OFFSET); + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); + __raw_writel(0, SMS_ROT_CONTROL(context)); + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET + | page_height_exp << SMS_PH_OFFSET; + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); + return 0; +} + +/* +* omap_dispc_set_rotate : configuring rotation registers based on angle. +* @ plane: graphics or video pipe line +* @ angle: Rotation angle. +* Return Value: Returns an integer. +*/ +int omap_dispc_set_rotate(int plane, int angle) +{ + int width, height; + u32 addr_base; + u32 Bpp; + width = dispc.fbdev->fb_info[0]->var.xres; + height = dispc.fbdev->fb_info[0]->var.yres; + Bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; + if (plane == OMAPFB_PLANE_GFX) { + enable_lcd_clocks(1); + /* clear GOLCD bit */ + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); + omap2_disp_set_vrfb(width, height, Bpp); + switch (angle) { + case 0: + addr_base = vrfb.paddr[0]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - width) * Bpp + 1); + break; + case 90: + addr_base = vrfb.paddr[1]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - height) * Bpp + 1); + break; + case 180: + addr_base = vrfb.paddr[2]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - width) * Bpp + 1); + break; + case 270: + addr_base = vrfb.paddr[3]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - height) * Bpp + 1); + break; + } + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); + enable_lcd_clocks(0); + } + return 0; +} + static void write_firh_reg(int plane, int reg, u32 value) { u32 base; @@ -1340,6 +1454,49 @@ static void cleanup_fbmem(void) } } +static void omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) +{ + memset(&vrfb, 0, sizeof(vrfb)); + vrfb.paddr[0] = SMS_ROT_VIRT_BASE(0, 0); + vrfb.paddr[1] = SMS_ROT_VIRT_BASE(0, 90); + vrfb.paddr[2] = SMS_ROT_VIRT_BASE(0, 180); + vrfb.paddr[3] = SMS_ROT_VIRT_BASE(0, 270); + + if (!request_mem_region(vrfb.paddr[0], + req_vram->region[0].size, "omapfb")) { + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); + } + + if (!request_mem_region(vrfb.paddr[1], + req_vram->region[0].size, "omapfb")) { + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); + } + + if (!request_mem_region(vrfb.paddr[2], + req_vram->region[0].size, "omapfb")) { + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); + } + + if (!request_mem_region(vrfb.paddr[3], + req_vram->region[0].size, "omapfb")) { + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); + } + + vrfb.vaddr[0] = (unsigned long)ioremap(vrfb.paddr[0], + req_vram->region[0].size); + vrfb.vaddr[1] = (unsigned long)ioremap(vrfb.paddr[1], + req_vram->region[0].size); + vrfb.vaddr[2] = (unsigned long)ioremap(vrfb.paddr[2], + req_vram->region[0].size); + vrfb.vaddr[3] = (unsigned long)ioremap(vrfb.paddr[3], + req_vram->region[0].size); + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) + || (!vrfb.vaddr[3])) { + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); + } + +} + static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, struct omapfb_mem_desc *req_vram) { @@ -1425,10 +1582,11 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, if ((r = alloc_palette_ram()) < 0) goto fail2; - + omap2_alloc_vrfb_mem(req_vram); if ((r = setup_fbmem(req_vram)) < 0) goto fail3; - + save_paddr = dispc.mem_desc.region[0].paddr; + dispc.fbdev->mem_desc.region[0].vaddr = (void *)vrfb.vaddr[0]; if (!skip_init) { for (i = 0; i < dispc.mem_desc.region_cnt; i++) { memset(dispc.mem_desc.region[i].vaddr, 0, @@ -1507,4 +1665,5 @@ const struct lcd_ctrl omap2_int_ctrl = { .set_color_key = omap_dispc_set_color_key, .get_color_key = omap_dispc_get_color_key, .mmap = omap_dispc_mmap_user, + .set_rotate = omap_dispc_set_rotate, }; diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h index ef720a7..5f470b4 100644 --- a/drivers/video/omap/dispc.h +++ b/drivers/video/omap/dispc.h @@ -2,6 +2,7 @@ #define _DISPC_H #include <linux/interrupt.h> +#include <mach/hardware.h> #define DISPC_PLANE_GFX 0 #define DISPC_PLANE_VID1 1 @@ -32,6 +33,36 @@ #define DISPC_TFT_DATA_LINES_18 2 #define DISPC_TFT_DATA_LINES_24 3 +/* Rotation using VRFB */ +#define SMS_ROT_VIRT_BASE(context, degree) (0x70000000 \ + | 0x4000000 * (context) \ + | 0x1000000 * (degree/90)) +#define VRFB_SIZE (2048 * 640 * (16/8)) +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ +#define SMS_IMAGEHEIGHT_OFFSET 16 +#define SMS_IMAGEWIDTH_OFFSET 0 +#define SMS_PH_OFFSET 8 +#define SMS_PW_OFFSET 4 +#define SMS_PS_OFFSET 0 +#define ROT_LINE_LENGTH 2048 + +#define DSS_REG_BASE 0x48050000 +#define DISPC_REG_OFFSET 0x00000400 +#define DISPC_BASE 0x48050400 +#define OMAP_SMS_BASE (0x6C000000) +#define DISPC_GFX_BA0 0x0080 +#define DISPC_GFX_ROW_INC 0x00AC +#define DISPC_GFX_PIXEL_INC 0x00B0 +#define DISPC_CONTROL 0x0040 + +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ + + 0x10 * context) +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ + + 0x10 * context) +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ + + 0x10 * context) + extern void omap_dispc_set_lcd_size(int width, int height); extern void omap_dispc_enable_lcd_out(int enable); diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index d176a2c..92d571c 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -36,6 +36,7 @@ #define MODULE_NAME "omapfb" +#define ROT_LINE_LENGTH 2048 static unsigned int def_accel; static unsigned long def_vram[OMAPFB_PLANE_NUM]; static unsigned int def_vram_cnt; @@ -219,10 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) if (r < 0) return r; - if (fbdev->ctrl->set_rotate != NULL) - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) + if (fbdev->ctrl->set_rotate != NULL) { + r = fbdev->ctrl->set_rotate(0, var->rotate); + if (r < 0) return r; - + } if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) r = fbdev->ctrl->set_scale(plane->idx, var->xres, var->yres, @@ -425,7 +427,7 @@ static void set_fb_fix(struct fb_info *fbi) break; } fix->accel = FB_ACCEL_OMAP1610; - fix->line_length = var->xres_virtual * bpp / 8; + fix->line_length = ROT_LINE_LENGTH * bpp / 8; } static int set_color_mode(struct omapfb_plane_struct *plane, @@ -497,14 +499,14 @@ static int set_fb_var(struct fb_info *fbi, bpp = var->bits_per_pixel; if (plane->color_mode == OMAPFB_COLOR_RGB444) bpp = 16; - + xres_min = OMAPFB_PLANE_XRES_MIN; + xres_max = panel->x_res; + yres_min = OMAPFB_PLANE_YRES_MIN; + yres_max = panel->y_res; switch (var->rotate) { case 0: case 180: - xres_min = OMAPFB_PLANE_XRES_MIN; - xres_max = panel->x_res; - yres_min = OMAPFB_PLANE_YRES_MIN; - yres_max = panel->y_res; + if (cpu_is_omap15xx()) { var->xres = panel->x_res; var->yres = panel->y_res; @@ -512,10 +514,7 @@ static int set_fb_var(struct fb_info *fbi, break; case 90: case 270: - xres_min = OMAPFB_PLANE_YRES_MIN; - xres_max = panel->y_res; - yres_min = OMAPFB_PLANE_XRES_MIN; - yres_max = panel->x_res; + if (cpu_is_omap15xx()) { var->xres = panel->y_res; var->yres = panel->x_res; @@ -1718,7 +1717,7 @@ static int omapfb_do_probe(struct platform_device *pdev, pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); - def_vxres = def_vxres ? : fbdev->panel->x_res; + def_vxres = ROT_LINE_LENGTH; def_vyres = def_vyres ? : fbdev->panel->y_res; init_state++; -- 1.5.3.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: omap-sdp3430_Rotation patch 2008-09-12 12:00 omap-sdp3430_Rotation patch rajesh k @ 2008-09-12 12:26 ` Felipe Balbi 2008-09-15 9:48 ` arun c 1 sibling, 0 replies; 11+ messages in thread From: Felipe Balbi @ 2008-09-12 12:26 UTC (permalink / raw) To: ext rajesh k; +Cc: linux-omap, krajesh Generally the code is difficult to read. A bit of coding style would help. A few comments below. On Fri, Sep 12, 2008 at 05:00:21AM -0700, ext rajesh k wrote: > >From Rajesh K krajesh<krajesh@ti.com> > > OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP 3430 > > This patch provides rotation support OMAP SDP 3430. You will have to append > video=omapfb:rotate=0 parameters to your u-boot arguments to get this working. > This supports 0,90,180 and 270 degree rotations. > > Signed-off-by: Rajesh K < krajesh@ti.com > > Iqbal shareef < iqbal@ti.com > > --- > arch/arm/plat-omap/include/mach/omapfb.h | 2 +- > drivers/video/omap/dispc.c | 167 +++++++++++++++++++++++++++++- > drivers/video/omap/dispc.h | 31 ++++++ > drivers/video/omap/omapfb_main.c | 27 +++--- > 4 files changed, 208 insertions(+), 19 deletions(-) > > diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h > index a4a84f3..6abc327 100644 > --- a/arch/arm/plat-omap/include/mach/omapfb.h > +++ b/arch/arm/plat-omap/include/mach/omapfb.h > @@ -306,7 +306,7 @@ struct lcd_ctrl { > int screen_width, > int pos_x, int pos_y, int width, > int height, int color_mode); > - int (*set_rotate) (int angle); > + int (*set_rotate) (int plane, int angle); > int (*setup_mem) (int plane, size_t size, > int mem_type, unsigned long *paddr); > int (*mmap) (struct fb_info *info, > diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c > index ce4c4de..f882db4 100644 > --- a/drivers/video/omap/dispc.c > +++ b/drivers/video/omap/dispc.c > @@ -24,11 +24,9 @@ > #include <linux/vmalloc.h> > #include <linux/clk.h> > #include <linux/io.h> > - > #include <mach/sram.h> > #include <mach/omapfb.h> > #include <mach/board.h> > - > #include "dispc.h" > > #define MODULE_NAME "dispc" > @@ -149,6 +147,20 @@ > #define RESMAP_MASK(_page_nr) \ > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > +dma_addr_t save_paddr; > +unsigned long save_vaddr; > + > +struct { > + dma_addr_t paddr[4]; > + unsigned long vaddr[4]; > + u32 xoffset; > + u32 yoffset; > + unsigned long size_val; > + unsigned long control_val; > +} vrfb; > + > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); > + > struct resmap { > unsigned long start; > unsigned page_cnt; > @@ -459,6 +471,108 @@ static int omap_dispc_setup_plane(int plane, int channel_out, > return r; > } > > +/* > +* function: pages_per_side : Will provide page height & width > +* @ img_side : img_side > +* @ page_exp : page_exp > +* Return Value: Will return an integer. > +*/ should be: /** * pages_per_side - Will provide page height & width * * @img_side : image side (or whatever you meant here :-p) * @page_exp : page exp (what does that exp stand for ?) * * Return 0 on success or a negative errno. */ > +static inline u32 > +pages_per_side(u32 img_side, u32 page_exp) These fit in one line: static inline u32 pages_per_side(u32 img_side, u32 page_exp) > +{ > + return (u32) (img_side + (1<<page_exp) - 1) >> page_exp; add spaces arroun << > +/* > +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine > +* which will supports rotations of 0,90,180,270 degrees. > +* @width: Width of the image > +* @height : height of the image > +* @bytes_per_pixel : color depth of the image > +* return value : will return an integer value > +*/ Fix this comment according to the above. > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) > +{ > + int page_width_exp, page_height_exp, pixel_size_exp; > + int context = 0; > + vrfb.size_val = 0; > + vrfb.control_val = 0; > + pixel_size_exp = bytes_per_pixel >> 1; > + page_width_exp = PAGE_WIDTH_EXP; > + page_height_exp = PAGE_HEIGHT_EXP; add a blank line here to separete variable declaration and function body. > + width = ((1<<page_width_exp) * spaces around << > + (pages_per_side(width * bytes_per_pixel, > + page_width_exp))) >> pixel_size_exp; > + height = (1<<page_height_exp) * > + (pages_per_side(height, page_height_exp)); > + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); > + __raw_writel(0, SMS_ROT0_SIZE(context)); > + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| > + (height << SMS_IMAGEHEIGHT_OFFSET); > + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); > + __raw_writel(0, SMS_ROT_CONTROL(context)); > + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET > + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET > + | page_height_exp << SMS_PH_OFFSET; > + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); add blank line here. > + return 0; > +} > + > +/* > +* omap_dispc_set_rotate : configuring rotation registers based on angle. > +* @ plane: graphics or video pipe line > +* @ angle: Rotation angle. > +* Return Value: Returns an integer. > +*/ fix comment. > +int omap_dispc_set_rotate(int plane, int angle) > +{ > + int width, height; > + u32 addr_base; > + u32 Bpp; > + width = dispc.fbdev->fb_info[0]->var.xres; > + height = dispc.fbdev->fb_info[0]->var.yres; > + Bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; avoid CaMeLCaSe, everything should be lower case. Add a blank line here as well. > + if (plane == OMAPFB_PLANE_GFX) { > + enable_lcd_clocks(1); > + /* clear GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); > + omap2_disp_set_vrfb(width, height, Bpp); > + switch (angle) { > + case 0: > + addr_base = vrfb.paddr[0]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 90: > + addr_base = vrfb.paddr[1]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * Bpp + 1); > + break; > + case 180: > + addr_base = vrfb.paddr[2]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 270: > + addr_base = vrfb.paddr[3]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * Bpp + 1); > + break; > + } > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); > + enable_lcd_clocks(0); > + } add a blank line here. > +static void omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) > +{ > + memset(&vrfb, 0, sizeof(vrfb)); > + vrfb.paddr[0] = SMS_ROT_VIRT_BASE(0, 0); > + vrfb.paddr[1] = SMS_ROT_VIRT_BASE(0, 90); > + vrfb.paddr[2] = SMS_ROT_VIRT_BASE(0, 180); > + vrfb.paddr[3] = SMS_ROT_VIRT_BASE(0, 270); > + > + if (!request_mem_region(vrfb.paddr[0], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[1], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[2], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[3], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); > + } > + > + vrfb.vaddr[0] = (unsigned long)ioremap(vrfb.paddr[0], > + req_vram->region[0].size); > + vrfb.vaddr[1] = (unsigned long)ioremap(vrfb.paddr[1], > + req_vram->region[0].size); > + vrfb.vaddr[2] = (unsigned long)ioremap(vrfb.paddr[2], > + req_vram->region[0].size); > + vrfb.vaddr[3] = (unsigned long)ioremap(vrfb.paddr[3], > + req_vram->region[0].size); > + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) > + || (!vrfb.vaddr[3])) { > + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); > + } no brackets for one line if() -- balbi ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: omap-sdp3430_Rotation patch 2008-09-12 12:00 omap-sdp3430_Rotation patch rajesh k 2008-09-12 12:26 ` Felipe Balbi @ 2008-09-15 9:48 ` arun c 2008-09-16 4:41 ` K, Rajesh 2008-10-06 4:24 ` Rajesh 1 sibling, 2 replies; 11+ messages in thread From: arun c @ 2008-09-15 9:48 UTC (permalink / raw) To: hirajeshk; +Cc: linux-omap@vger.kernel.org Hi, On Fri, Sep 12, 2008 at 8:00 AM, rajesh k <hirajeshk@yahoo.com> wrote: > From Rajesh K krajesh<krajesh@ti.com> > > OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP 3430 This comment is wrong, if you add rotation support to omapfb it will affect all the hardwres(omap2&3) which uses fbdev. > > This patch provides rotation support OMAP SDP 3430. You will have to append > video=omapfb:rotate=0 parameters to your u-boot arguments to get this working. > This supports 0,90,180 and 270 degree rotations. > Same here > Signed-off-by: Rajesh K < krajesh@ti.com > > Iqbal shareef < iqbal@ti.com > > --- > arch/arm/plat-omap/include/mach/omapfb.h | 2 +- > drivers/video/omap/dispc.c | 167 +++++++++++++++++++++++++++++- > drivers/video/omap/dispc.h | 31 ++++++ > drivers/video/omap/omapfb_main.c | 27 +++--- > 4 files changed, 208 insertions(+), 19 deletions(-) > > diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h > index a4a84f3..6abc327 100644 > --- a/arch/arm/plat-omap/include/mach/omapfb.h > +++ b/arch/arm/plat-omap/include/mach/omapfb.h > @@ -306,7 +306,7 @@ struct lcd_ctrl { > int screen_width, > int pos_x, int pos_y, int width, > int height, int color_mode); > - int (*set_rotate) (int angle); > + int (*set_rotate) (int plane, int angle); > int (*setup_mem) (int plane, size_t size, > int mem_type, unsigned long *paddr); > int (*mmap) (struct fb_info *info, > diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c > index ce4c4de..f882db4 100644 > --- a/drivers/video/omap/dispc.c > +++ b/drivers/video/omap/dispc.c > @@ -24,11 +24,9 @@ > #include <linux/vmalloc.h> > #include <linux/clk.h> > #include <linux/io.h> > - > #include <mach/sram.h> > #include <mach/omapfb.h> > #include <mach/board.h> > - > #include "dispc.h" > > #define MODULE_NAME "dispc" > @@ -149,6 +147,20 @@ > #define RESMAP_MASK(_page_nr) \ > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > +dma_addr_t save_paddr; > +unsigned long save_vaddr; > + > +struct { > + dma_addr_t paddr[4]; > + unsigned long vaddr[4]; > + u32 xoffset; > + u32 yoffset; > + unsigned long size_val; > + unsigned long control_val; > +} vrfb; > + > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); > + > struct resmap { > unsigned long start; > unsigned page_cnt; > @@ -459,6 +471,108 @@ static int omap_dispc_setup_plane(int plane, int channel_out, > return r; > } > > +/* > +* function: pages_per_side : Will provide page height & width > +* @ img_side : img_side > +* @ page_exp : page_exp > +* Return Value: Will return an integer. > +*/ > +static inline u32 > +pages_per_side(u32 img_side, u32 page_exp) > +{ > + return (u32) (img_side + (1<<page_exp) - 1) >> page_exp; > +} > + > +/* > +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine > +* which will supports rotations of 0,90,180,270 degrees. > +* @width: Width of the image > +* @height : height of the image > +* @bytes_per_pixel : color depth of the image > +* return value : will return an integer value > +*/ > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) > +{ > + int page_width_exp, page_height_exp, pixel_size_exp; > + int context = 0; > + vrfb.size_val = 0; > + vrfb.control_val = 0; > + pixel_size_exp = bytes_per_pixel >> 1; > + page_width_exp = PAGE_WIDTH_EXP; > + page_height_exp = PAGE_HEIGHT_EXP; > + width = ((1<<page_width_exp) * > + (pages_per_side(width * bytes_per_pixel, > + page_width_exp))) >> pixel_size_exp; > + height = (1<<page_height_exp) * > + (pages_per_side(height, page_height_exp)); > + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); > + __raw_writel(0, SMS_ROT0_SIZE(context)); > + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| > + (height << SMS_IMAGEHEIGHT_OFFSET); > + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); > + __raw_writel(0, SMS_ROT_CONTROL(context)); > + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET > + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET > + | page_height_exp << SMS_PH_OFFSET; > + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); > + return 0; > +} > + > +/* > +* omap_dispc_set_rotate : configuring rotation registers based on angle. > +* @ plane: graphics or video pipe line > +* @ angle: Rotation angle. > +* Return Value: Returns an integer. > +*/ > +int omap_dispc_set_rotate(int plane, int angle) > +{ > + int width, height; > + u32 addr_base; > + u32 Bpp; > + width = dispc.fbdev->fb_info[0]->var.xres; > + height = dispc.fbdev->fb_info[0]->var.yres; > + Bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; > + if (plane == OMAPFB_PLANE_GFX) { > + enable_lcd_clocks(1); > + /* clear GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); > + omap2_disp_set_vrfb(width, height, Bpp); > + switch (angle) { > + case 0: > + addr_base = vrfb.paddr[0]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 90: > + addr_base = vrfb.paddr[1]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * Bpp + 1); > + break; > + case 180: > + addr_base = vrfb.paddr[2]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 270: > + addr_base = vrfb.paddr[3]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * Bpp + 1); > + break; > + } > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); > + enable_lcd_clocks(0); > + } > + return 0; > +} > + > static void write_firh_reg(int plane, int reg, u32 value) > { > u32 base; > @@ -1340,6 +1454,49 @@ static void cleanup_fbmem(void) > } > } > > +static void omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) > +{ > + memset(&vrfb, 0, sizeof(vrfb)); > + vrfb.paddr[0] = SMS_ROT_VIRT_BASE(0, 0); > + vrfb.paddr[1] = SMS_ROT_VIRT_BASE(0, 90); > + vrfb.paddr[2] = SMS_ROT_VIRT_BASE(0, 180); > + vrfb.paddr[3] = SMS_ROT_VIRT_BASE(0, 270); > + > + if (!request_mem_region(vrfb.paddr[0], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[1], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[2], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[3], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); > + } > + > + vrfb.vaddr[0] = (unsigned long)ioremap(vrfb.paddr[0], > + req_vram->region[0].size); > + vrfb.vaddr[1] = (unsigned long)ioremap(vrfb.paddr[1], > + req_vram->region[0].size); > + vrfb.vaddr[2] = (unsigned long)ioremap(vrfb.paddr[2], > + req_vram->region[0].size); > + vrfb.vaddr[3] = (unsigned long)ioremap(vrfb.paddr[3], > + req_vram->region[0].size); > + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) > + || (!vrfb.vaddr[3])) { > + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); > + } > + > +} > + > static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > struct omapfb_mem_desc *req_vram) > { > @@ -1425,10 +1582,11 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > > if ((r = alloc_palette_ram()) < 0) > goto fail2; > - > + omap2_alloc_vrfb_mem(req_vram); What if allocation fails?? > if ((r = setup_fbmem(req_vram)) < 0) > goto fail3; > - > + save_paddr = dispc.mem_desc.region[0].paddr; > + dispc.fbdev->mem_desc.region[0].vaddr = (void *)vrfb.vaddr[0]; > if (!skip_init) { > for (i = 0; i < dispc.mem_desc.region_cnt; i++) { > memset(dispc.mem_desc.region[i].vaddr, 0, > @@ -1507,4 +1665,5 @@ const struct lcd_ctrl omap2_int_ctrl = { > .set_color_key = omap_dispc_set_color_key, > .get_color_key = omap_dispc_get_color_key, > .mmap = omap_dispc_mmap_user, > + .set_rotate = omap_dispc_set_rotate, > }; > diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h > index ef720a7..5f470b4 100644 > --- a/drivers/video/omap/dispc.h > +++ b/drivers/video/omap/dispc.h > @@ -2,6 +2,7 @@ > #define _DISPC_H > > #include <linux/interrupt.h> > +#include <mach/hardware.h> > > #define DISPC_PLANE_GFX 0 > #define DISPC_PLANE_VID1 1 > @@ -32,6 +33,36 @@ > #define DISPC_TFT_DATA_LINES_18 2 > #define DISPC_TFT_DATA_LINES_24 3 > > +/* Rotation using VRFB */ > +#define SMS_ROT_VIRT_BASE(context, degree) (0x70000000 \ > + | 0x4000000 * (context) \ > + | 0x1000000 * (degree/90)) > +#define VRFB_SIZE (2048 * 640 * (16/8)) The static declaration of VRFB_SIZE will make it impossible to use on hardwares using diffrent bpp(other than 16) > +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ > +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ > +#define SMS_IMAGEHEIGHT_OFFSET 16 > +#define SMS_IMAGEWIDTH_OFFSET 0 > +#define SMS_PH_OFFSET 8 > +#define SMS_PW_OFFSET 4 > +#define SMS_PS_OFFSET 0 > +#define ROT_LINE_LENGTH 2048 > + > +#define DSS_REG_BASE 0x48050000 > +#define DISPC_REG_OFFSET 0x00000400 > +#define DISPC_BASE 0x48050400 > +#define OMAP_SMS_BASE (0x6C000000) > +#define DISPC_GFX_BA0 0x0080 > +#define DISPC_GFX_ROW_INC 0x00AC > +#define DISPC_GFX_PIXEL_INC 0x00B0 > +#define DISPC_CONTROL 0x0040 > + > +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ > + + 0x10 * context) > +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ > + + 0x10 * context) > +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ > + + 0x10 * context) > + > extern void omap_dispc_set_lcd_size(int width, int height); > > extern void omap_dispc_enable_lcd_out(int enable); > diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c > index d176a2c..92d571c 100644 > --- a/drivers/video/omap/omapfb_main.c > +++ b/drivers/video/omap/omapfb_main.c > @@ -36,6 +36,7 @@ > > #define MODULE_NAME "omapfb" > > +#define ROT_LINE_LENGTH 2048 > static unsigned int def_accel; > static unsigned long def_vram[OMAPFB_PLANE_NUM]; > static unsigned int def_vram_cnt; > @@ -219,10 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) > if (r < 0) > return r; > > - if (fbdev->ctrl->set_rotate != NULL) > - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) > + if (fbdev->ctrl->set_rotate != NULL) { > + r = fbdev->ctrl->set_rotate(0, var->rotate); > + if (r < 0) > return r; > - > + } > if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) > r = fbdev->ctrl->set_scale(plane->idx, > var->xres, var->yres, > @@ -425,7 +427,7 @@ static void set_fb_fix(struct fb_info *fbi) > break; > } > fix->accel = FB_ACCEL_OMAP1610; > - fix->line_length = var->xres_virtual * bpp / 8; > + fix->line_length = ROT_LINE_LENGTH * bpp / 8; > } > > static int set_color_mode(struct omapfb_plane_struct *plane, > @@ -497,14 +499,14 @@ static int set_fb_var(struct fb_info *fbi, > bpp = var->bits_per_pixel; > if (plane->color_mode == OMAPFB_COLOR_RGB444) > bpp = 16; > - > + xres_min = OMAPFB_PLANE_XRES_MIN; > + xres_max = panel->x_res; > + yres_min = OMAPFB_PLANE_YRES_MIN; > + yres_max = panel->y_res; > switch (var->rotate) { > case 0: > case 180: > - xres_min = OMAPFB_PLANE_XRES_MIN; > - xres_max = panel->x_res; > - yres_min = OMAPFB_PLANE_YRES_MIN; > - yres_max = panel->y_res; > + > if (cpu_is_omap15xx()) { > var->xres = panel->x_res; > var->yres = panel->y_res; > @@ -512,10 +514,7 @@ static int set_fb_var(struct fb_info *fbi, > break; > case 90: > case 270: > - xres_min = OMAPFB_PLANE_YRES_MIN; > - xres_max = panel->y_res; > - yres_min = OMAPFB_PLANE_XRES_MIN; > - yres_max = panel->x_res; > + > if (cpu_is_omap15xx()) { > var->xres = panel->y_res; > var->yres = panel->x_res; > @@ -1718,7 +1717,7 @@ static int omapfb_do_probe(struct platform_device *pdev, > > pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); > > - def_vxres = def_vxres ? : fbdev->panel->x_res; > + def_vxres = ROT_LINE_LENGTH; > def_vyres = def_vyres ? : fbdev->panel->y_res; > > init_state++; > -- Finally you did not provide a choice to boot with rotation (uses huge framebuffer) and with out rotation (normal boot for hardwares which don't want rotation). Regards, Arun C ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: omap-sdp3430_Rotation patch 2008-09-15 9:48 ` arun c @ 2008-09-16 4:41 ` K, Rajesh 2008-09-16 5:10 ` arun c 2008-09-16 7:41 ` Russell King - ARM Linux 2008-10-06 4:24 ` Rajesh 1 sibling, 2 replies; 11+ messages in thread From: K, Rajesh @ 2008-09-16 4:41 UTC (permalink / raw) To: arun c, hirajeshk@yahoo.com; +Cc: linux-omap@vger.kernel.org ~Rajesh.K 9731600339 ________________________________________ From: linux-omap-owner@vger.kernel.org [linux-omap-owner@vger.kernel.org] On Behalf Of arun c [arun.edarath@gmail.com] Sent: Monday, September 15, 2008 3:18 PM To: hirajeshk@yahoo.com Cc: linux-omap@vger.kernel.org Subject: Re: omap-sdp3430_Rotation patch Hi, On Fri, Sep 12, 2008 at 8:00 AM, rajesh k <hirajeshk@yahoo.com> wrote: > From Rajesh K krajesh<krajesh@ti.com> > > OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP 3430 >>This comment is wrong, if you add rotation support to omapfb it >>will affect all the hardwres(omap2&3) which uses fbdev. Agree.Its true > > This patch provides rotation support OMAP SDP 3430. You will have to append > video=omapfb:rotate=0 parameters to your u-boot arguments to get this working. > This supports 0,90,180 and 270 degree rotations. > >>Same here Agree.Its true > Signed-off-by: Rajesh K < krajesh@ti.com > > Iqbal shareef < iqbal@ti.com > > --- > arch/arm/plat-omap/include/mach/omapfb.h | 2 +- > drivers/video/omap/dispc.c | 167 +++++++++++++++++++++++++++++- > drivers/video/omap/dispc.h | 31 ++++++ > drivers/video/omap/omapfb_main.c | 27 +++--- > 4 files changed, 208 insertions(+), 19 deletions(-) > > diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h > index a4a84f3..6abc327 100644 > --- a/arch/arm/plat-omap/include/mach/omapfb.h > +++ b/arch/arm/plat-omap/include/mach/omapfb.h > @@ -306,7 +306,7 @@ struct lcd_ctrl { > int screen_width, > int pos_x, int pos_y, int width, > int height, int color_mode); > - int (*set_rotate) (int angle); > + int (*set_rotate) (int plane, int angle); > int (*setup_mem) (int plane, size_t size, > int mem_type, unsigned long *paddr); > int (*mmap) (struct fb_info *info, > diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c > index ce4c4de..f882db4 100644 > --- a/drivers/video/omap/dispc.c > +++ b/drivers/video/omap/dispc.c > @@ -24,11 +24,9 @@ > #include <linux/vmalloc.h> > #include <linux/clk.h> > #include <linux/io.h> > - > #include <mach/sram.h> > #include <mach/omapfb.h> > #include <mach/board.h> > - > #include "dispc.h" > > #define MODULE_NAME "dispc" > @@ -149,6 +147,20 @@ > #define RESMAP_MASK(_page_nr) \ > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > +dma_addr_t save_paddr; > +unsigned long save_vaddr; > + > +struct { > + dma_addr_t paddr[4]; > + unsigned long vaddr[4]; > + u32 xoffset; > + u32 yoffset; > + unsigned long size_val; > + unsigned long control_val; > +} vrfb; > + > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); > + > struct resmap { > unsigned long start; > unsigned page_cnt; > @@ -459,6 +471,108 @@ static int omap_dispc_setup_plane(int plane, int channel_out, > return r; > } > > +/* > +* function: pages_per_side : Will provide page height & width > +* @ img_side : img_side > +* @ page_exp : page_exp > +* Return Value: Will return an integer. > +*/ > +static inline u32 > +pages_per_side(u32 img_side, u32 page_exp) > +{ > + return (u32) (img_side + (1<<page_exp) - 1) >> page_exp; > +} > + > +/* > +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine > +* which will supports rotations of 0,90,180,270 degrees. > +* @width: Width of the image > +* @height : height of the image > +* @bytes_per_pixel : color depth of the image > +* return value : will return an integer value > +*/ > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) > +{ > + int page_width_exp, page_height_exp, pixel_size_exp; > + int context = 0; > + vrfb.size_val = 0; > + vrfb.control_val = 0; > + pixel_size_exp = bytes_per_pixel >> 1; > + page_width_exp = PAGE_WIDTH_EXP; > + page_height_exp = PAGE_HEIGHT_EXP; > + width = ((1<<page_width_exp) * > + (pages_per_side(width * bytes_per_pixel, > + page_width_exp))) >> pixel_size_exp; > + height = (1<<page_height_exp) * > + (pages_per_side(height, page_height_exp)); > + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); > + __raw_writel(0, SMS_ROT0_SIZE(context)); > + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| > + (height << SMS_IMAGEHEIGHT_OFFSET); > + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); > + __raw_writel(0, SMS_ROT_CONTROL(context)); > + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET > + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET > + | page_height_exp << SMS_PH_OFFSET; > + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); > + return 0; > +} > + > +/* > +* omap_dispc_set_rotate : configuring rotation registers based on angle. > +* @ plane: graphics or video pipe line > +* @ angle: Rotation angle. > +* Return Value: Returns an integer. > +*/ > +int omap_dispc_set_rotate(int plane, int angle) > +{ > + int width, height; > + u32 addr_base; > + u32 Bpp; > + width = dispc.fbdev->fb_info[0]->var.xres; > + height = dispc.fbdev->fb_info[0]->var.yres; > + Bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; > + if (plane == OMAPFB_PLANE_GFX) { > + enable_lcd_clocks(1); > + /* clear GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); > + omap2_disp_set_vrfb(width, height, Bpp); > + switch (angle) { > + case 0: > + addr_base = vrfb.paddr[0]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 90: > + addr_base = vrfb.paddr[1]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * Bpp + 1); > + break; > + case 180: > + addr_base = vrfb.paddr[2]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 270: > + addr_base = vrfb.paddr[3]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * Bpp + 1); > + break; > + } > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); > + enable_lcd_clocks(0); > + } > + return 0; > +} > + > static void write_firh_reg(int plane, int reg, u32 value) > { > u32 base; > @@ -1340,6 +1454,49 @@ static void cleanup_fbmem(void) > } > } > > +static void omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) > +{ > + memset(&vrfb, 0, sizeof(vrfb)); > + vrfb.paddr[0] = SMS_ROT_VIRT_BASE(0, 0); > + vrfb.paddr[1] = SMS_ROT_VIRT_BASE(0, 90); > + vrfb.paddr[2] = SMS_ROT_VIRT_BASE(0, 180); > + vrfb.paddr[3] = SMS_ROT_VIRT_BASE(0, 270); > + > + if (!request_mem_region(vrfb.paddr[0], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[1], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[2], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[3], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); > + } > + > + vrfb.vaddr[0] = (unsigned long)ioremap(vrfb.paddr[0], > + req_vram->region[0].size); > + vrfb.vaddr[1] = (unsigned long)ioremap(vrfb.paddr[1], > + req_vram->region[0].size); > + vrfb.vaddr[2] = (unsigned long)ioremap(vrfb.paddr[2], > + req_vram->region[0].size); > + vrfb.vaddr[3] = (unsigned long)ioremap(vrfb.paddr[3], > + req_vram->region[0].size); > + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) > + || (!vrfb.vaddr[3])) { > + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); > + } > + > +} > + > static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > struct omapfb_mem_desc *req_vram) > { > @@ -1425,10 +1582,11 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > > if ((r = alloc_palette_ram()) < 0) > goto fail2; > - > + omap2_alloc_vrfb_mem(req_vram); What if allocation fails?? > if ((r = setup_fbmem(req_vram)) < 0) > goto fail3; > - > + save_paddr = dispc.mem_desc.region[0].paddr; > + dispc.fbdev->mem_desc.region[0].vaddr = (void *)vrfb.vaddr[0]; > if (!skip_init) { > for (i = 0; i < dispc.mem_desc.region_cnt; i++) { > memset(dispc.mem_desc.region[i].vaddr, 0, > @@ -1507,4 +1665,5 @@ const struct lcd_ctrl omap2_int_ctrl = { > .set_color_key = omap_dispc_set_color_key, > .get_color_key = omap_dispc_get_color_key, > .mmap = omap_dispc_mmap_user, > + .set_rotate = omap_dispc_set_rotate, > }; > diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h > index ef720a7..5f470b4 100644 > --- a/drivers/video/omap/dispc.h > +++ b/drivers/video/omap/dispc.h > @@ -2,6 +2,7 @@ > #define _DISPC_H > > #include <linux/interrupt.h> > +#include <mach/hardware.h> > > #define DISPC_PLANE_GFX 0 > #define DISPC_PLANE_VID1 1 > @@ -32,6 +33,36 @@ > #define DISPC_TFT_DATA_LINES_18 2 > #define DISPC_TFT_DATA_LINES_24 3 > > +/* Rotation using VRFB */ > +#define SMS_ROT_VIRT_BASE(context, degree) (0x70000000 \ > + | 0x4000000 * (context) \ > + | 0x1000000 * (degree/90)) > +#define VRFB_SIZE (2048 * 640 * (16/8)) The static declaration of VRFB_SIZE will make it impossible to use on hardwares using diffrent bpp(other than 16) > +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ > +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ > +#define SMS_IMAGEHEIGHT_OFFSET 16 > +#define SMS_IMAGEWIDTH_OFFSET 0 > +#define SMS_PH_OFFSET 8 > +#define SMS_PW_OFFSET 4 > +#define SMS_PS_OFFSET 0 > +#define ROT_LINE_LENGTH 2048 > + > +#define DSS_REG_BASE 0x48050000 > +#define DISPC_REG_OFFSET 0x00000400 > +#define DISPC_BASE 0x48050400 > +#define OMAP_SMS_BASE (0x6C000000) > +#define DISPC_GFX_BA0 0x0080 > +#define DISPC_GFX_ROW_INC 0x00AC > +#define DISPC_GFX_PIXEL_INC 0x00B0 > +#define DISPC_CONTROL 0x0040 > + > +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ > + + 0x10 * context) > +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ > + + 0x10 * context) > +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ > + + 0x10 * context) > + > extern void omap_dispc_set_lcd_size(int width, int height); > > extern void omap_dispc_enable_lcd_out(int enable); > diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c > index d176a2c..92d571c 100644 > --- a/drivers/video/omap/omapfb_main.c > +++ b/drivers/video/omap/omapfb_main.c > @@ -36,6 +36,7 @@ > > #define MODULE_NAME "omapfb" > > +#define ROT_LINE_LENGTH 2048 > static unsigned int def_accel; > static unsigned long def_vram[OMAPFB_PLANE_NUM]; > static unsigned int def_vram_cnt; > @@ -219,10 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) > if (r < 0) > return r; > > - if (fbdev->ctrl->set_rotate != NULL) > - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) > + if (fbdev->ctrl->set_rotate != NULL) { > + r = fbdev->ctrl->set_rotate(0, var->rotate); > + if (r < 0) > return r; > - > + } > if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) > r = fbdev->ctrl->set_scale(plane->idx, > var->xres, var->yres, > @@ -425,7 +427,7 @@ static void set_fb_fix(struct fb_info *fbi) > break; > } > fix->accel = FB_ACCEL_OMAP1610; > - fix->line_length = var->xres_virtual * bpp / 8; > + fix->line_length = ROT_LINE_LENGTH * bpp / 8; > } > > static int set_color_mode(struct omapfb_plane_struct *plane, > @@ -497,14 +499,14 @@ static int set_fb_var(struct fb_info *fbi, > bpp = var->bits_per_pixel; > if (plane->color_mode == OMAPFB_COLOR_RGB444) > bpp = 16; > - > + xres_min = OMAPFB_PLANE_XRES_MIN; > + xres_max = panel->x_res; > + yres_min = OMAPFB_PLANE_YRES_MIN; > + yres_max = panel->y_res; > switch (var->rotate) { > case 0: > case 180: > - xres_min = OMAPFB_PLANE_XRES_MIN; > - xres_max = panel->x_res; > - yres_min = OMAPFB_PLANE_YRES_MIN; > - yres_max = panel->y_res; > + > if (cpu_is_omap15xx()) { > var->xres = panel->x_res; > var->yres = panel->y_res; > @@ -512,10 +514,7 @@ static int set_fb_var(struct fb_info *fbi, > break; > case 90: > case 270: > - xres_min = OMAPFB_PLANE_YRES_MIN; > - xres_max = panel->y_res; > - yres_min = OMAPFB_PLANE_XRES_MIN; > - yres_max = panel->x_res; > + > if (cpu_is_omap15xx()) { > var->xres = panel->y_res; > var->yres = panel->x_res; > @@ -1718,7 +1717,7 @@ static int omapfb_do_probe(struct platform_device *pdev, > > pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); > > - def_vxres = def_vxres ? : fbdev->panel->x_res; > + def_vxres = ROT_LINE_LENGTH; > def_vyres = def_vyres ? : fbdev->panel->y_res; > > init_state++; > -- >>Finally you did not provide a choice to boot with rotation (uses huge >>framebuffer) >>and with out rotation (normal boot for hardwares which don't want rotation). If you see my comment in the patch, I had mentioned that you need pass "video=omapfb:rotate=0 parameters to your u-boot arguments to get rotation working". With out boot params(normal boot), Rotation feature will not be enabled. Regards, Arun C -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: omap-sdp3430_Rotation patch 2008-09-16 4:41 ` K, Rajesh @ 2008-09-16 5:10 ` arun c 2008-09-16 7:41 ` Russell King - ARM Linux 1 sibling, 0 replies; 11+ messages in thread From: arun c @ 2008-09-16 5:10 UTC (permalink / raw) To: K, Rajesh; +Cc: linux-omap@vger.kernel.org Hi , On Tue, Sep 16, 2008 at 12:41 AM, K, Rajesh <krajesh@ti.com> wrote: > > > > ~Rajesh.K > 9731600339 > ________________________________________ > From: linux-omap-owner@vger.kernel.org [linux-omap-owner@vger.kernel.org] On Behalf Of arun c [arun.edarath@gmail.com] > Sent: Monday, September 15, 2008 3:18 PM > To: hirajeshk@yahoo.com > Cc: linux-omap@vger.kernel.org > Subject: Re: omap-sdp3430_Rotation patch > > Hi, > > On Fri, Sep 12, 2008 at 8:00 AM, rajesh k <hirajeshk@yahoo.com> wrote: >> From Rajesh K krajesh<krajesh@ti.com> >> >> OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP 3430 >>>This comment is wrong, if you add rotation support to omapfb it >>>will affect all the hardwres(omap2&3) which uses fbdev. > Agree.Its true > >> >> This patch provides rotation support OMAP SDP 3430. You will have to append >> video=omapfb:rotate=0 parameters to your u-boot arguments to get this working. >> This supports 0,90,180 and 270 degree rotations. >> >>>Same here > Agree.Its true > >> Signed-off-by: Rajesh K < krajesh@ti.com > >> Iqbal shareef < iqbal@ti.com > >> --- >> arch/arm/plat-omap/include/mach/omapfb.h | 2 +- >> drivers/video/omap/dispc.c | 167 +++++++++++++++++++++++++++++- >> drivers/video/omap/dispc.h | 31 ++++++ >> drivers/video/omap/omapfb_main.c | 27 +++--- >> 4 files changed, 208 insertions(+), 19 deletions(-) >> >> diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h >> index a4a84f3..6abc327 100644 >> --- a/arch/arm/plat-omap/include/mach/omapfb.h >> +++ b/arch/arm/plat-omap/include/mach/omapfb.h >> @@ -306,7 +306,7 @@ struct lcd_ctrl { >> int screen_width, >> int pos_x, int pos_y, int width, >> int height, int color_mode); >> - int (*set_rotate) (int angle); >> + int (*set_rotate) (int plane, int angle); >> int (*setup_mem) (int plane, size_t size, >> int mem_type, unsigned long *paddr); >> int (*mmap) (struct fb_info *info, >> diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c >> index ce4c4de..f882db4 100644 >> --- a/drivers/video/omap/dispc.c >> +++ b/drivers/video/omap/dispc.c >> @@ -24,11 +24,9 @@ >> #include <linux/vmalloc.h> >> #include <linux/clk.h> >> #include <linux/io.h> >> - >> #include <mach/sram.h> >> #include <mach/omapfb.h> >> #include <mach/board.h> >> - >> #include "dispc.h" >> >> #define MODULE_NAME "dispc" >> @@ -149,6 +147,20 @@ >> #define RESMAP_MASK(_page_nr) \ >> (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) >> >> +dma_addr_t save_paddr; >> +unsigned long save_vaddr; >> + >> +struct { >> + dma_addr_t paddr[4]; >> + unsigned long vaddr[4]; >> + u32 xoffset; >> + u32 yoffset; >> + unsigned long size_val; >> + unsigned long control_val; >> +} vrfb; >> + >> +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); >> + >> struct resmap { >> unsigned long start; >> unsigned page_cnt; >> @@ -459,6 +471,108 @@ static int omap_dispc_setup_plane(int plane, int channel_out, >> return r; >> } >> >> +/* >> +* function: pages_per_side : Will provide page height & width >> +* @ img_side : img_side >> +* @ page_exp : page_exp >> +* Return Value: Will return an integer. >> +*/ >> +static inline u32 >> +pages_per_side(u32 img_side, u32 page_exp) >> +{ >> + return (u32) (img_side + (1<<page_exp) - 1) >> page_exp; >> +} >> + >> +/* >> +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine >> +* which will supports rotations of 0,90,180,270 degrees. >> +* @width: Width of the image >> +* @height : height of the image >> +* @bytes_per_pixel : color depth of the image >> +* return value : will return an integer value >> +*/ >> +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) >> +{ >> + int page_width_exp, page_height_exp, pixel_size_exp; >> + int context = 0; >> + vrfb.size_val = 0; >> + vrfb.control_val = 0; >> + pixel_size_exp = bytes_per_pixel >> 1; >> + page_width_exp = PAGE_WIDTH_EXP; >> + page_height_exp = PAGE_HEIGHT_EXP; >> + width = ((1<<page_width_exp) * >> + (pages_per_side(width * bytes_per_pixel, >> + page_width_exp))) >> pixel_size_exp; >> + height = (1<<page_height_exp) * >> + (pages_per_side(height, page_height_exp)); >> + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); >> + __raw_writel(0, SMS_ROT0_SIZE(context)); >> + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| >> + (height << SMS_IMAGEHEIGHT_OFFSET); >> + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); >> + __raw_writel(0, SMS_ROT_CONTROL(context)); >> + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET >> + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET >> + | page_height_exp << SMS_PH_OFFSET; >> + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); >> + return 0; >> +} >> + >> +/* >> +* omap_dispc_set_rotate : configuring rotation registers based on angle. >> +* @ plane: graphics or video pipe line >> +* @ angle: Rotation angle. >> +* Return Value: Returns an integer. >> +*/ >> +int omap_dispc_set_rotate(int plane, int angle) >> +{ >> + int width, height; >> + u32 addr_base; >> + u32 Bpp; >> + width = dispc.fbdev->fb_info[0]->var.xres; >> + height = dispc.fbdev->fb_info[0]->var.yres; >> + Bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; >> + if (plane == OMAPFB_PLANE_GFX) { >> + enable_lcd_clocks(1); >> + /* clear GOLCD bit */ >> + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); >> + omap2_disp_set_vrfb(width, height, Bpp); >> + switch (angle) { >> + case 0: >> + addr_base = vrfb.paddr[0]; >> + dispc_write_reg(DISPC_GFX_BA0, addr_base); >> + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); >> + dispc_write_reg(DISPC_GFX_ROW_INC, >> + (ROT_LINE_LENGTH - width) * Bpp + 1); >> + break; >> + case 90: >> + addr_base = vrfb.paddr[1]; >> + dispc_write_reg(DISPC_GFX_BA0, addr_base); >> + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); >> + dispc_write_reg(DISPC_GFX_ROW_INC, >> + (ROT_LINE_LENGTH - height) * Bpp + 1); >> + break; >> + case 180: >> + addr_base = vrfb.paddr[2]; >> + dispc_write_reg(DISPC_GFX_BA0, addr_base); >> + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); >> + dispc_write_reg(DISPC_GFX_ROW_INC, >> + (ROT_LINE_LENGTH - width) * Bpp + 1); >> + break; >> + case 270: >> + addr_base = vrfb.paddr[3]; >> + dispc_write_reg(DISPC_GFX_BA0, addr_base); >> + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); >> + dispc_write_reg(DISPC_GFX_ROW_INC, >> + (ROT_LINE_LENGTH - height) * Bpp + 1); >> + break; >> + } >> + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); >> + enable_lcd_clocks(0); >> + } >> + return 0; >> +} >> + >> static void write_firh_reg(int plane, int reg, u32 value) >> { >> u32 base; >> @@ -1340,6 +1454,49 @@ static void cleanup_fbmem(void) >> } >> } >> >> +static void omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) >> +{ >> + memset(&vrfb, 0, sizeof(vrfb)); >> + vrfb.paddr[0] = SMS_ROT_VIRT_BASE(0, 0); >> + vrfb.paddr[1] = SMS_ROT_VIRT_BASE(0, 90); >> + vrfb.paddr[2] = SMS_ROT_VIRT_BASE(0, 180); >> + vrfb.paddr[3] = SMS_ROT_VIRT_BASE(0, 270); >> + >> + if (!request_mem_region(vrfb.paddr[0], >> + req_vram->region[0].size, "omapfb")) { >> + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); >> + } >> + >> + if (!request_mem_region(vrfb.paddr[1], >> + req_vram->region[0].size, "omapfb")) { >> + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); >> + } >> + >> + if (!request_mem_region(vrfb.paddr[2], >> + req_vram->region[0].size, "omapfb")) { >> + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); >> + } >> + >> + if (!request_mem_region(vrfb.paddr[3], >> + req_vram->region[0].size, "omapfb")) { >> + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); >> + } >> + >> + vrfb.vaddr[0] = (unsigned long)ioremap(vrfb.paddr[0], >> + req_vram->region[0].size); >> + vrfb.vaddr[1] = (unsigned long)ioremap(vrfb.paddr[1], >> + req_vram->region[0].size); >> + vrfb.vaddr[2] = (unsigned long)ioremap(vrfb.paddr[2], >> + req_vram->region[0].size); >> + vrfb.vaddr[3] = (unsigned long)ioremap(vrfb.paddr[3], >> + req_vram->region[0].size); >> + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) >> + || (!vrfb.vaddr[3])) { >> + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); >> + } >> + >> +} >> + >> static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, >> struct omapfb_mem_desc *req_vram) >> { >> @@ -1425,10 +1582,11 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, >> >> if ((r = alloc_palette_ram()) < 0) >> goto fail2; >> - >> + omap2_alloc_vrfb_mem(req_vram); > What if allocation fails?? > >> if ((r = setup_fbmem(req_vram)) < 0) >> goto fail3; >> - >> + save_paddr = dispc.mem_desc.region[0].paddr; >> + dispc.fbdev->mem_desc.region[0].vaddr = (void *)vrfb.vaddr[0]; >> if (!skip_init) { >> for (i = 0; i < dispc.mem_desc.region_cnt; i++) { >> memset(dispc.mem_desc.region[i].vaddr, 0, >> @@ -1507,4 +1665,5 @@ const struct lcd_ctrl omap2_int_ctrl = { >> .set_color_key = omap_dispc_set_color_key, >> .get_color_key = omap_dispc_get_color_key, >> .mmap = omap_dispc_mmap_user, >> + .set_rotate = omap_dispc_set_rotate, >> }; >> diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h >> index ef720a7..5f470b4 100644 >> --- a/drivers/video/omap/dispc.h >> +++ b/drivers/video/omap/dispc.h >> @@ -2,6 +2,7 @@ >> #define _DISPC_H >> >> #include <linux/interrupt.h> >> +#include <mach/hardware.h> >> >> #define DISPC_PLANE_GFX 0 >> #define DISPC_PLANE_VID1 1 >> @@ -32,6 +33,36 @@ >> #define DISPC_TFT_DATA_LINES_18 2 >> #define DISPC_TFT_DATA_LINES_24 3 >> >> +/* Rotation using VRFB */ >> +#define SMS_ROT_VIRT_BASE(context, degree) (0x70000000 \ >> + | 0x4000000 * (context) \ >> + | 0x1000000 * (degree/90)) >> +#define VRFB_SIZE (2048 * 640 * (16/8)) > > The static declaration of VRFB_SIZE will make it impossible to > use on hardwares using diffrent bpp(other than 16) > > >> +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ >> +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ >> +#define SMS_IMAGEHEIGHT_OFFSET 16 >> +#define SMS_IMAGEWIDTH_OFFSET 0 >> +#define SMS_PH_OFFSET 8 >> +#define SMS_PW_OFFSET 4 >> +#define SMS_PS_OFFSET 0 >> +#define ROT_LINE_LENGTH 2048 >> + >> +#define DSS_REG_BASE 0x48050000 >> +#define DISPC_REG_OFFSET 0x00000400 >> +#define DISPC_BASE 0x48050400 >> +#define OMAP_SMS_BASE (0x6C000000) >> +#define DISPC_GFX_BA0 0x0080 >> +#define DISPC_GFX_ROW_INC 0x00AC >> +#define DISPC_GFX_PIXEL_INC 0x00B0 >> +#define DISPC_CONTROL 0x0040 >> + >> +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ >> + + 0x10 * context) >> +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ >> + + 0x10 * context) >> +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ >> + + 0x10 * context) >> + >> extern void omap_dispc_set_lcd_size(int width, int height); >> >> extern void omap_dispc_enable_lcd_out(int enable); >> diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c >> index d176a2c..92d571c 100644 >> --- a/drivers/video/omap/omapfb_main.c >> +++ b/drivers/video/omap/omapfb_main.c >> @@ -36,6 +36,7 @@ >> >> #define MODULE_NAME "omapfb" >> >> +#define ROT_LINE_LENGTH 2048 >> static unsigned int def_accel; >> static unsigned long def_vram[OMAPFB_PLANE_NUM]; >> static unsigned int def_vram_cnt; >> @@ -219,10 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) >> if (r < 0) >> return r; >> >> - if (fbdev->ctrl->set_rotate != NULL) >> - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) >> + if (fbdev->ctrl->set_rotate != NULL) { >> + r = fbdev->ctrl->set_rotate(0, var->rotate); >> + if (r < 0) >> return r; >> - >> + } >> if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) >> r = fbdev->ctrl->set_scale(plane->idx, >> var->xres, var->yres, >> @@ -425,7 +427,7 @@ static void set_fb_fix(struct fb_info *fbi) >> break; >> } >> fix->accel = FB_ACCEL_OMAP1610; >> - fix->line_length = var->xres_virtual * bpp / 8; >> + fix->line_length = ROT_LINE_LENGTH * bpp / 8; >> } >> >> static int set_color_mode(struct omapfb_plane_struct *plane, >> @@ -497,14 +499,14 @@ static int set_fb_var(struct fb_info *fbi, >> bpp = var->bits_per_pixel; >> if (plane->color_mode == OMAPFB_COLOR_RGB444) >> bpp = 16; >> - >> + xres_min = OMAPFB_PLANE_XRES_MIN; >> + xres_max = panel->x_res; >> + yres_min = OMAPFB_PLANE_YRES_MIN; >> + yres_max = panel->y_res; >> switch (var->rotate) { >> case 0: >> case 180: >> - xres_min = OMAPFB_PLANE_XRES_MIN; >> - xres_max = panel->x_res; >> - yres_min = OMAPFB_PLANE_YRES_MIN; >> - yres_max = panel->y_res; >> + >> if (cpu_is_omap15xx()) { >> var->xres = panel->x_res; >> var->yres = panel->y_res; >> @@ -512,10 +514,7 @@ static int set_fb_var(struct fb_info *fbi, >> break; >> case 90: >> case 270: >> - xres_min = OMAPFB_PLANE_YRES_MIN; >> - xres_max = panel->y_res; >> - yres_min = OMAPFB_PLANE_XRES_MIN; >> - yres_max = panel->x_res; >> + >> if (cpu_is_omap15xx()) { >> var->xres = panel->y_res; >> var->yres = panel->x_res; >> @@ -1718,7 +1717,7 @@ static int omapfb_do_probe(struct platform_device *pdev, >> >> pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); >> >> - def_vxres = def_vxres ? : fbdev->panel->x_res; >> + def_vxres = ROT_LINE_LENGTH; >> def_vyres = def_vyres ? : fbdev->panel->y_res; >> >> init_state++; >> -- >>>Finally you did not provide a choice to boot with rotation (uses huge >>>framebuffer) >>>and with out rotation (normal boot for hardwares which don't want rotation). > > If you see my comment in the patch, I had mentioned that you need pass > "video=omapfb:rotate=0 parameters to your u-boot arguments to get rotation working". > With out boot params(normal boot), Rotation feature will not be enabled. > I didn't mean booting with zero degree or some other angle. I mean booting with rotation feature and without that feature. See your patch, you are doing all the rotation related setup ( Allocating large fb, line_length=2048, VRFB initialization) independent of the parameter passed in the bootargs. > > Regards, > Arun C > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: omap-sdp3430_Rotation patch 2008-09-16 4:41 ` K, Rajesh 2008-09-16 5:10 ` arun c @ 2008-09-16 7:41 ` Russell King - ARM Linux 2008-09-17 15:43 ` [PATCH] " nskamat 1 sibling, 1 reply; 11+ messages in thread From: Russell King - ARM Linux @ 2008-09-16 7:41 UTC (permalink / raw) To: K, Rajesh; +Cc: arun c, hirajeshk@yahoo.com, linux-omap@vger.kernel.org On Tue, Sep 16, 2008 at 10:11:26AM +0530, K, Rajesh wrote: > > @@ -149,6 +147,20 @@ > > #define RESMAP_MASK(_page_nr) \ > > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > > > +dma_addr_t save_paddr; See comment about paddr[]. > > +unsigned long save_vaddr; Virtual addresses should be pointer like. > > + > > +struct { > > + dma_addr_t paddr[4]; These are physical addresses. Please make them 'unsigned long' or resource_size_t, not dma_addr_t. > > + unsigned long vaddr[4]; Ditto. > > + u32 xoffset; > > + u32 yoffset; > > + unsigned long size_val; > > + unsigned long control_val; > > +} vrfb; > > + > > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); > > + > > struct resmap { > > unsigned long start; > > unsigned page_cnt; > > @@ -459,6 +471,108 @@ static int omap_dispc_setup_plane(int plane, int channel_out, > > return r; > > } > > > > +/* > > +* function: pages_per_side : Will provide page height & width > > +* @ img_side : img_side > > +* @ page_exp : page_exp > > +* Return Value: Will return an integer. > > +*/ > > +static inline u32 > > +pages_per_side(u32 img_side, u32 page_exp) > > +{ > > + return (u32) (img_side + (1<<page_exp) - 1) >> page_exp; Unnecessary cast. > > +} > > + > > +/* > > +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine > > +* which will supports rotations of 0,90,180,270 degrees. > > +* @width: Width of the image > > +* @height : height of the image > > +* @bytes_per_pixel : color depth of the image > > +* return value : will return an integer value > > +*/ > > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) > > +{ > > + int page_width_exp, page_height_exp, pixel_size_exp; > > + int context = 0; > > + vrfb.size_val = 0; > > + vrfb.control_val = 0; > > + pixel_size_exp = bytes_per_pixel >> 1; > > + page_width_exp = PAGE_WIDTH_EXP; > > + page_height_exp = PAGE_HEIGHT_EXP; > > + width = ((1<<page_width_exp) * > > + (pages_per_side(width * bytes_per_pixel, > > + page_width_exp))) >> pixel_size_exp; > > + height = (1<<page_height_exp) * > > + (pages_per_side(height, page_height_exp)); > > + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); > > + __raw_writel(0, SMS_ROT0_SIZE(context)); > > + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| > > + (height << SMS_IMAGEHEIGHT_OFFSET); > > + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); > > + __raw_writel(0, SMS_ROT_CONTROL(context)); > > + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET > > + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET > > + | page_height_exp << SMS_PH_OFFSET; > > + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); > > + return 0; > > +} > > + > > +/* > > +* omap_dispc_set_rotate : configuring rotation registers based on angle. > > +* @ plane: graphics or video pipe line > > +* @ angle: Rotation angle. > > +* Return Value: Returns an integer. > > +*/ > > +int omap_dispc_set_rotate(int plane, int angle) > > +{ > > + int width, height; > > + u32 addr_base; > > + u32 Bpp; Lower case variable names please. > > + width = dispc.fbdev->fb_info[0]->var.xres; > > + height = dispc.fbdev->fb_info[0]->var.yres; > > + Bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; > > + if (plane == OMAPFB_PLANE_GFX) { > > + enable_lcd_clocks(1); > > + /* clear GOLCD bit */ > > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); > > + omap2_disp_set_vrfb(width, height, Bpp); > > + switch (angle) { > > + case 0: > > + addr_base = vrfb.paddr[0]; > > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > > + dispc_write_reg(DISPC_GFX_ROW_INC, > > + (ROT_LINE_LENGTH - width) * Bpp + 1); > > + break; > > + case 90: > > + addr_base = vrfb.paddr[1]; > > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > > + dispc_write_reg(DISPC_GFX_ROW_INC, > > + (ROT_LINE_LENGTH - height) * Bpp + 1); > > + break; > > + case 180: > > + addr_base = vrfb.paddr[2]; > > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > > + dispc_write_reg(DISPC_GFX_ROW_INC, > > + (ROT_LINE_LENGTH - width) * Bpp + 1); > > + break; > > + case 270: > > + addr_base = vrfb.paddr[3]; > > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > > + dispc_write_reg(DISPC_GFX_ROW_INC, > > + (ROT_LINE_LENGTH - height) * Bpp + 1); > > + break; > > + } > > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); > > + enable_lcd_clocks(0); > > + } > > + return 0; > > +} > > + > > static void write_firh_reg(int plane, int reg, u32 value) > > { > > u32 base; > > @@ -1340,6 +1454,49 @@ static void cleanup_fbmem(void) > > } > > } > > > > +static void omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) > > +{ > > + memset(&vrfb, 0, sizeof(vrfb)); > > + vrfb.paddr[0] = SMS_ROT_VIRT_BASE(0, 0); > > + vrfb.paddr[1] = SMS_ROT_VIRT_BASE(0, 90); > > + vrfb.paddr[2] = SMS_ROT_VIRT_BASE(0, 180); > > + vrfb.paddr[3] = SMS_ROT_VIRT_BASE(0, 270); > > + > > + if (!request_mem_region(vrfb.paddr[0], > > + req_vram->region[0].size, "omapfb")) { > > + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); > > + } > > + > > + if (!request_mem_region(vrfb.paddr[1], > > + req_vram->region[0].size, "omapfb")) { > > + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); > > + } > > + > > + if (!request_mem_region(vrfb.paddr[2], > > + req_vram->region[0].size, "omapfb")) { > > + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); > > + } > > + > > + if (!request_mem_region(vrfb.paddr[3], > > + req_vram->region[0].size, "omapfb")) { > > + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); > > + } > > + > > + vrfb.vaddr[0] = (unsigned long)ioremap(vrfb.paddr[0], > > + req_vram->region[0].size); > > + vrfb.vaddr[1] = (unsigned long)ioremap(vrfb.paddr[1], > > + req_vram->region[0].size); > > + vrfb.vaddr[2] = (unsigned long)ioremap(vrfb.paddr[2], > > + req_vram->region[0].size); > > + vrfb.vaddr[3] = (unsigned long)ioremap(vrfb.paddr[3], > > + req_vram->region[0].size); You should never need to cast the return value from ioremap. > > + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) > > + || (!vrfb.vaddr[3])) { > > + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); > > + } > > + > > +} > > + > > static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > > struct omapfb_mem_desc *req_vram) > > { > > @@ -1425,10 +1582,11 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > > > > if ((r = alloc_palette_ram()) < 0) > > goto fail2; > > - > > + omap2_alloc_vrfb_mem(req_vram); > What if allocation fails?? > > > if ((r = setup_fbmem(req_vram)) < 0) > > goto fail3; > > - > > + save_paddr = dispc.mem_desc.region[0].paddr; > > + dispc.fbdev->mem_desc.region[0].vaddr = (void *)vrfb.vaddr[0]; This cast screams that you're doing something wrong (as identified above). > > if (!skip_init) { > > for (i = 0; i < dispc.mem_desc.region_cnt; i++) { > > memset(dispc.mem_desc.region[i].vaddr, 0, > > @@ -1507,4 +1665,5 @@ const struct lcd_ctrl omap2_int_ctrl = { > > .set_color_key = omap_dispc_set_color_key, > > .get_color_key = omap_dispc_get_color_key, > > .mmap = omap_dispc_mmap_user, > > + .set_rotate = omap_dispc_set_rotate, > > }; > > diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h > > index ef720a7..5f470b4 100644 > > --- a/drivers/video/omap/dispc.h > > +++ b/drivers/video/omap/dispc.h > > @@ -2,6 +2,7 @@ > > #define _DISPC_H > > > > #include <linux/interrupt.h> > > +#include <mach/hardware.h> > > > > #define DISPC_PLANE_GFX 0 > > #define DISPC_PLANE_VID1 1 > > @@ -32,6 +33,36 @@ > > #define DISPC_TFT_DATA_LINES_18 2 > > #define DISPC_TFT_DATA_LINES_24 3 > > > > +/* Rotation using VRFB */ > > +#define SMS_ROT_VIRT_BASE(context, degree) (0x70000000 \ > > + | 0x4000000 * (context) \ > > + | 0x1000000 * (degree/90)) This can't be a virtual address for a kernel driver. It's in the middle of userspace. Luckily it isn't, and it's just that you've got a confusing name for the macro. Please change the name. > > +#define VRFB_SIZE (2048 * 640 * (16/8)) > > The static declaration of VRFB_SIZE will make it impossible to > use on hardwares using diffrent bpp(other than 16) > > > > +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ > > +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ > > +#define SMS_IMAGEHEIGHT_OFFSET 16 > > +#define SMS_IMAGEWIDTH_OFFSET 0 > > +#define SMS_PH_OFFSET 8 > > +#define SMS_PW_OFFSET 4 > > +#define SMS_PS_OFFSET 0 > > +#define ROT_LINE_LENGTH 2048 > > + > > +#define DSS_REG_BASE 0x48050000 > > +#define DISPC_REG_OFFSET 0x00000400 > > +#define DISPC_BASE 0x48050400 > > +#define OMAP_SMS_BASE (0x6C000000) > > +#define DISPC_GFX_BA0 0x0080 > > +#define DISPC_GFX_ROW_INC 0x00AC > > +#define DISPC_GFX_PIXEL_INC 0x00B0 > > +#define DISPC_CONTROL 0x0040 > > + > > +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ > > + + 0x10 * context) > > +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ > > + + 0x10 * context) > > +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ > > + + 0x10 * context) > > + > > extern void omap_dispc_set_lcd_size(int width, int height); > > > > extern void omap_dispc_enable_lcd_out(int enable); > > diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c > > index d176a2c..92d571c 100644 > > --- a/drivers/video/omap/omapfb_main.c > > +++ b/drivers/video/omap/omapfb_main.c > > @@ -36,6 +36,7 @@ > > > > #define MODULE_NAME "omapfb" > > > > +#define ROT_LINE_LENGTH 2048 > > static unsigned int def_accel; > > static unsigned long def_vram[OMAPFB_PLANE_NUM]; > > static unsigned int def_vram_cnt; > > @@ -219,10 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) > > if (r < 0) > > return r; > > > > - if (fbdev->ctrl->set_rotate != NULL) > > - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) > > + if (fbdev->ctrl->set_rotate != NULL) { > > + r = fbdev->ctrl->set_rotate(0, var->rotate); > > + if (r < 0) > > return r; > > - > > + } > > if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) > > r = fbdev->ctrl->set_scale(plane->idx, > > var->xres, var->yres, > > @@ -425,7 +427,7 @@ static void set_fb_fix(struct fb_info *fbi) > > break; > > } > > fix->accel = FB_ACCEL_OMAP1610; > > - fix->line_length = var->xres_virtual * bpp / 8; > > + fix->line_length = ROT_LINE_LENGTH * bpp / 8; > > } > > > > static int set_color_mode(struct omapfb_plane_struct *plane, > > @@ -497,14 +499,14 @@ static int set_fb_var(struct fb_info *fbi, > > bpp = var->bits_per_pixel; > > if (plane->color_mode == OMAPFB_COLOR_RGB444) > > bpp = 16; > > - > > + xres_min = OMAPFB_PLANE_XRES_MIN; > > + xres_max = panel->x_res; > > + yres_min = OMAPFB_PLANE_YRES_MIN; > > + yres_max = panel->y_res; Use tabs instead of spaces for code indentation. > > switch (var->rotate) { > > case 0: > > case 180: > > - xres_min = OMAPFB_PLANE_XRES_MIN; > > - xres_max = panel->x_res; > > - yres_min = OMAPFB_PLANE_YRES_MIN; > > - yres_max = panel->y_res; > > + > > if (cpu_is_omap15xx()) { > > var->xres = panel->x_res; > > var->yres = panel->y_res; > > @@ -512,10 +514,7 @@ static int set_fb_var(struct fb_info *fbi, > > break; > > case 90: > > case 270: > > - xres_min = OMAPFB_PLANE_YRES_MIN; > > - xres_max = panel->y_res; > > - yres_min = OMAPFB_PLANE_XRES_MIN; > > - yres_max = panel->x_res; > > + > > if (cpu_is_omap15xx()) { > > var->xres = panel->y_res; > > var->yres = panel->x_res; > > @@ -1718,7 +1717,7 @@ static int omapfb_do_probe(struct platform_device *pdev, > > > > pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); > > > > - def_vxres = def_vxres ? : fbdev->panel->x_res; > > + def_vxres = ROT_LINE_LENGTH; > > def_vyres = def_vyres ? : fbdev->panel->y_res; > > > > init_state++; > > -- > >>Finally you did not provide a choice to boot with rotation (uses huge > >>framebuffer) > >>and with out rotation (normal boot for hardwares which don't want rotation). > > If you see my comment in the patch, I had mentioned that you need pass > "video=omapfb:rotate=0 parameters to your u-boot arguments to get rotation working". > With out boot params(normal boot), Rotation feature will not be enabled. > > > Regards, > Arun C > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] Re: omap-sdp3430_Rotation patch 2008-09-16 7:41 ` Russell King - ARM Linux @ 2008-09-17 15:43 ` nskamat 2008-09-18 5:29 ` arun c 0 siblings, 1 reply; 11+ messages in thread From: nskamat @ 2008-09-17 15:43 UTC (permalink / raw) To: linux-omap; +Cc: Rajesh K, Iqbal Shareef From: Rajesh K <krajesh@ti.com> OMAP FBDEV: VRFB framebuffer rotation support This patch provides rotation support for OMAP2/3. You will have to append video=omapfb:rotation=0 parameters to your u-boot arguments to get this working. This supports 0,90,180 and 270 degree rotations. Signed-off-by: Rajesh K <krajesh@ti.com> Signed-off-by: Iqbal Shareef <iqbal@ti.com> --- arch/arm/plat-omap/include/mach/omapfb.h | 4 +- drivers/video/omap/dispc.c | 189 +++++++++++++++++++++++++++++- drivers/video/omap/dispc.h | 33 +++++- drivers/video/omap/omapfb_main.c | 32 +++--- 4 files changed, 236 insertions(+), 22 deletions(-) diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h index a4a84f3..338a11d 100644 --- a/arch/arm/plat-omap/include/mach/omapfb.h +++ b/arch/arm/plat-omap/include/mach/omapfb.h @@ -277,7 +277,7 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, struct omapfb_mem_region { dma_addr_t paddr; - void *vaddr; + void __iomem *vaddr; unsigned long size; u8 type; /* OMAPFB_PLANE_MEM_* */ unsigned alloc:1; /* allocated by the driver */ @@ -306,7 +306,7 @@ struct lcd_ctrl { int screen_width, int pos_x, int pos_y, int width, int height, int color_mode); - int (*set_rotate) (int angle); + int (*set_rotate) (int plane, int angle); int (*setup_mem) (int plane, size_t size, int mem_type, unsigned long *paddr); int (*mmap) (struct fb_info *info, diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index ce4c4de..1f5a7a5 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -149,12 +149,25 @@ #define RESMAP_MASK(_page_nr) \ (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) +unsigned long save_paddr; +unsigned long save_vaddr; + struct resmap { unsigned long start; unsigned page_cnt; unsigned long *map; }; +struct { + unsigned long paddr[4]; + void __iomem *vaddr[4]; + u32 xoffset; + u32 yoffset; + unsigned long size_val; + unsigned long control_val; +} vrfb; + +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); static struct { void __iomem *base; @@ -459,6 +472,170 @@ static int omap_dispc_setup_plane(int plane, int channel_out, return r; } +/* +* pages_per_side : Will provide pages per side +* @ img_side : img_side +* @ page_exp : page_exponential +* Return Value: Returns pages per side value. +*/ + +static inline u32 pages_per_side(u32 img_side, u32 page_exp) +{ + return (img_side + (1<<page_exp) - 1) >> page_exp; +} + +/* +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine +* which will supports rotations of 0,90,180,270 degrees. +* @width: Width of the image +* @height : height of the image +* @bytes_per_pixel : color depth of the image +* return value : None +*/ + +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) +{ + int page_width_exp, page_height_exp, pixel_size_exp; + int context = 0; + vrfb.size_val = 0; + vrfb.control_val = 0; + pixel_size_exp = bytes_per_pixel >> 1; + page_width_exp = PAGE_WIDTH_EXP; + page_height_exp = PAGE_HEIGHT_EXP; + + width = ((1<<page_width_exp) * + (pages_per_side(width * bytes_per_pixel, + page_width_exp))) >> pixel_size_exp; + height = (1<<page_height_exp) * + (pages_per_side(height, page_height_exp)); + + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); + __raw_writel(0, SMS_ROT0_SIZE(context)); + + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| + (height << SMS_IMAGEHEIGHT_OFFSET); + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); + __raw_writel(0, SMS_ROT_CONTROL(context)); + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET + | page_height_exp << SMS_PH_OFFSET; + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); +} + +/* +* omap_dispc_set_rotate : configuring rotation registers based on angle. +* @ plane: graphics or video pipe line +* @ angle: Rotation angle. +* Return Value: Returns 0 on success + Returns -1 if it fails. +*/ + +int omap_dispc_set_rotate(int plane, int angle) +{ + int width, height; + u32 addr_base; + u32 bpp; + int r = 0; + + width = dispc.fbdev->fb_info[0]->var.xres; + height = dispc.fbdev->fb_info[0]->var.yres; + bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; + + if (plane == OMAPFB_PLANE_GFX) { + enable_lcd_clocks(1); + /* clear GOLCD bit */ + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); + if (rotation == 1) { + omap2_disp_set_vrfb(width, height, bpp); + switch (angle) { + case 0: + addr_base = vrfb.paddr[0]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - width) * bpp + 1); + break; + case 90: + addr_base = vrfb.paddr[1]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - height) * bpp + 1); + break; + case 180: + addr_base = vrfb.paddr[2]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - width) * bpp + 1); + break; + case 270: + addr_base = vrfb.paddr[3]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - height) * bpp + 1); + break; + } + } else { + return r; + } + /* set GOLCD bit */ + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); + enable_lcd_clocks(0); + } + return r; +} + +static int omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) +{ + int r = 0; + memset(&vrfb, 0, sizeof(vrfb)); + vrfb.paddr[0] = SMS_ROT_BASE_ADDR(0, 0); + vrfb.paddr[1] = SMS_ROT_BASE_ADDR(0, 90); + vrfb.paddr[2] = SMS_ROT_BASE_ADDR(0, 180); + vrfb.paddr[3] = SMS_ROT_BASE_ADDR(0, 270); + + if (!request_mem_region(vrfb.paddr[0], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); + } + + if (!request_mem_region(vrfb.paddr[1], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); + } + + if (!request_mem_region(vrfb.paddr[2], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserveVRFB180 area\n"); + } + + if (!request_mem_region(vrfb.paddr[3], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); + } + + vrfb.vaddr[0] = ioremap(vrfb.paddr[0], + req_vram->region[0].size); + vrfb.vaddr[1] = ioremap(vrfb.paddr[1], + req_vram->region[0].size); + vrfb.vaddr[2] = ioremap(vrfb.paddr[2], + req_vram->region[0].size); + vrfb.vaddr[3] = ioremap(vrfb.paddr[3], + req_vram->region[0].size); + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) + || (!vrfb.vaddr[3])) { + r = -1; + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); + } + return r; +} + static void write_firh_reg(int plane, int reg, u32 value) { u32 base; @@ -1425,10 +1602,16 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, if ((r = alloc_palette_ram()) < 0) goto fail2; - + if (rotation == 1) { + if (omap2_alloc_vrfb_mem(req_vram) < 0) + printk(KERN_ERR "VRFB memory allocation failed"); + } if ((r = setup_fbmem(req_vram)) < 0) goto fail3; - + if (rotation == 1) { + save_paddr = dispc.mem_desc.region[0].paddr; + dispc.fbdev->mem_desc.region[0].vaddr = vrfb.vaddr[0]; + } if (!skip_init) { for (i = 0; i < dispc.mem_desc.region_cnt; i++) { memset(dispc.mem_desc.region[i].vaddr, 0, @@ -1478,7 +1661,6 @@ fail0: static void omap_dispc_cleanup(void) { int i; - omap_dispc_set_update_mode(OMAPFB_UPDATE_DISABLED); /* This will also disable clocks that are on */ for (i = 0; i < dispc.mem_desc.region_cnt; i++) @@ -1507,4 +1689,5 @@ const struct lcd_ctrl omap2_int_ctrl = { .set_color_key = omap_dispc_set_color_key, .get_color_key = omap_dispc_get_color_key, .mmap = omap_dispc_mmap_user, + .set_rotate = omap_dispc_set_rotate, }; diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h index ef720a7..506e4c6 100644 --- a/drivers/video/omap/dispc.h +++ b/drivers/video/omap/dispc.h @@ -2,7 +2,7 @@ #define _DISPC_H #include <linux/interrupt.h> - +#include <mach/hardware.h> #define DISPC_PLANE_GFX 0 #define DISPC_PLANE_VID1 1 #define DISPC_PLANE_VID2 2 @@ -32,6 +32,37 @@ #define DISPC_TFT_DATA_LINES_18 2 #define DISPC_TFT_DATA_LINES_24 3 +/* Rotation using VRFB */ +extern int rotation; +#define SMS_ROT_BASE_ADDR(context, degree) (0x70000000 \ + | 0x4000000 * (context) \ + | 0x1000000 * (degree/90)) +#define BITS_PER_PIXEL 16 /* RGB value */ +#define VRFB_SIZE (2048 * 640 * (BITS_PER_PIXEL/8)) +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ +#define SMS_IMAGEHEIGHT_OFFSET 16 +#define SMS_IMAGEWIDTH_OFFSET 0 +#define SMS_PH_OFFSET 8 +#define SMS_PW_OFFSET 4 +#define SMS_PS_OFFSET 0 +#define ROT_LINE_LENGTH 2048 + +#define DSS_REG_BASE 0x48050000 +#define DISPC_REG_OFFSET 0x00000400 +#define DISPC_BASE 0x48050400 +#define OMAP_SMS_BASE (0x6C000000) +#define DISPC_GFX_BA0 0x0080 +#define DISPC_GFX_ROW_INC 0x00AC +#define DISPC_GFX_PIXEL_INC 0x00B0 +#define DISPC_CONTROL 0x0040 + +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ + + 0x10 * context) +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ + + 0x10 * context) +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ + + 0x10 * context) extern void omap_dispc_set_lcd_size(int width, int height); extern void omap_dispc_enable_lcd_out(int enable); diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index d176a2c..1d2ceb8 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -35,7 +35,8 @@ #include "dispc.h" #define MODULE_NAME "omapfb" - +int rotation = -1; +#define ROT_LINE_LENGTH 2048 static unsigned int def_accel; static unsigned long def_vram[OMAPFB_PLANE_NUM]; static unsigned int def_vram_cnt; @@ -219,9 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) if (r < 0) return r; - if (fbdev->ctrl->set_rotate != NULL) - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) + if (fbdev->ctrl->set_rotate != NULL) { + r = fbdev->ctrl->set_rotate(0, var->rotate); + if (r < 0) return r; + } if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) r = fbdev->ctrl->set_scale(plane->idx, @@ -425,7 +428,7 @@ static void set_fb_fix(struct fb_info *fbi) break; } fix->accel = FB_ACCEL_OMAP1610; - fix->line_length = var->xres_virtual * bpp / 8; + fix->line_length = ROT_LINE_LENGTH * bpp / 8; } static int set_color_mode(struct omapfb_plane_struct *plane, @@ -497,14 +500,13 @@ static int set_fb_var(struct fb_info *fbi, bpp = var->bits_per_pixel; if (plane->color_mode == OMAPFB_COLOR_RGB444) bpp = 16; - + xres_min = OMAPFB_PLANE_XRES_MIN; + xres_max = panel->x_res; + yres_min = OMAPFB_PLANE_YRES_MIN; + yres_max = panel->y_res; switch (var->rotate) { case 0: case 180: - xres_min = OMAPFB_PLANE_XRES_MIN; - xres_max = panel->x_res; - yres_min = OMAPFB_PLANE_YRES_MIN; - yres_max = panel->y_res; if (cpu_is_omap15xx()) { var->xres = panel->x_res; var->yres = panel->y_res; @@ -512,10 +514,6 @@ static int set_fb_var(struct fb_info *fbi, break; case 90: case 270: - xres_min = OMAPFB_PLANE_YRES_MIN; - xres_max = panel->y_res; - yres_min = OMAPFB_PLANE_XRES_MIN; - yres_max = panel->x_res; if (cpu_is_omap15xx()) { var->xres = panel->y_res; var->yres = panel->x_res; @@ -1718,7 +1716,7 @@ static int omapfb_do_probe(struct platform_device *pdev, pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); - def_vxres = def_vxres ? : fbdev->panel->x_res; + def_vxres = ROT_LINE_LENGTH; def_vyres = def_vyres ? : fbdev->panel->y_res; init_state++; @@ -1909,8 +1907,10 @@ static int __init omapfb_setup(char *options) def_vxres = simple_strtoul(this_opt + 6, NULL, 0); else if (!strncmp(this_opt, "vyres:", 6)) def_vyres = simple_strtoul(this_opt + 6, NULL, 0); - else if (!strncmp(this_opt, "rotate:", 7)) - def_rotate = (simple_strtoul(this_opt + 7, NULL, 0)); + else if (!strncmp(this_opt, "rotation=", 9)) { + rotation = 1; + def_rotate = (simple_strtoul(this_opt + 9, NULL, 0)); + } else if (!strncmp(this_opt, "mirror:", 7)) def_mirror = (simple_strtoul(this_opt + 7, NULL, 0)); else if (!strncmp(this_opt, "manual_update", 13)) -- 1.5.3.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] Re: omap-sdp3430_Rotation patch 2008-09-17 15:43 ` [PATCH] " nskamat @ 2008-09-18 5:29 ` arun c 2008-09-18 8:50 ` Russell King - ARM Linux 0 siblings, 1 reply; 11+ messages in thread From: arun c @ 2008-09-18 5:29 UTC (permalink / raw) To: nskamat; +Cc: linux-omap, Rajesh K, Iqbal Shareef Hi, On Wed, Sep 17, 2008 at 11:43 AM, <nskamat@ti.com> wrote: > From: Rajesh K <krajesh@ti.com> > > OMAP FBDEV: VRFB framebuffer rotation support > > This patch provides rotation support for OMAP2/3. You will have to append > video=omapfb:rotation=0 parameters to your u-boot arguments to get this > working. This supports 0,90,180 and 270 degree rotations. > > Signed-off-by: Rajesh K <krajesh@ti.com> > Signed-off-by: Iqbal Shareef <iqbal@ti.com> > --- > arch/arm/plat-omap/include/mach/omapfb.h | 4 +- > drivers/video/omap/dispc.c | 189 +++++++++++++++++++++++++++++- > drivers/video/omap/dispc.h | 33 +++++- > drivers/video/omap/omapfb_main.c | 32 +++--- > 4 files changed, 236 insertions(+), 22 deletions(-) > > diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h > index a4a84f3..338a11d 100644 > --- a/arch/arm/plat-omap/include/mach/omapfb.h > +++ b/arch/arm/plat-omap/include/mach/omapfb.h > @@ -277,7 +277,7 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, > > struct omapfb_mem_region { > dma_addr_t paddr; > - void *vaddr; > + void __iomem *vaddr; > unsigned long size; > u8 type; /* OMAPFB_PLANE_MEM_* */ > unsigned alloc:1; /* allocated by the driver */ > @@ -306,7 +306,7 @@ struct lcd_ctrl { > int screen_width, > int pos_x, int pos_y, int width, > int height, int color_mode); > - int (*set_rotate) (int angle); > + int (*set_rotate) (int plane, int angle); > int (*setup_mem) (int plane, size_t size, > int mem_type, unsigned long *paddr); > int (*mmap) (struct fb_info *info, > diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c > index ce4c4de..1f5a7a5 100644 > --- a/drivers/video/omap/dispc.c > +++ b/drivers/video/omap/dispc.c > @@ -149,12 +149,25 @@ > #define RESMAP_MASK(_page_nr) \ > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > +unsigned long save_paddr; sav_vaddr is defined but nowhere used. > +unsigned long save_vaddr; > + > struct resmap { > unsigned long start; > unsigned page_cnt; > unsigned long *map; > }; > > +struct { > + unsigned long paddr[4]; > + void __iomem *vaddr[4]; > + u32 xoffset; > + u32 yoffset; > + unsigned long size_val; > + unsigned long control_val; > +} vrfb; > + > +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); > static struct { > void __iomem *base; > > @@ -459,6 +472,170 @@ static int omap_dispc_setup_plane(int plane, int channel_out, > return r; > } > > +/* > +* pages_per_side : Will provide pages per side > +* @ img_side : img_side > +* @ page_exp : page_exponential > +* Return Value: Returns pages per side value. > +*/ > + > +static inline u32 pages_per_side(u32 img_side, u32 page_exp) > +{ > + return (img_side + (1<<page_exp) - 1) >> page_exp; > +} > + > +/* > +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine > +* which will supports rotations of 0,90,180,270 degrees. > +* @width: Width of the image > +* @height : height of the image > +* @bytes_per_pixel : color depth of the image > +* return value : None > +*/ > + > +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) > +{ > + int page_width_exp, page_height_exp, pixel_size_exp; > + int context = 0; > + vrfb.size_val = 0; > + vrfb.control_val = 0; > + pixel_size_exp = bytes_per_pixel >> 1; > + page_width_exp = PAGE_WIDTH_EXP; > + page_height_exp = PAGE_HEIGHT_EXP; > + > + width = ((1<<page_width_exp) * > + (pages_per_side(width * bytes_per_pixel, > + page_width_exp))) >> pixel_size_exp; > + height = (1<<page_height_exp) * > + (pages_per_side(height, page_height_exp)); > + > + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); > + __raw_writel(0, SMS_ROT0_SIZE(context)); > + > + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| > + (height << SMS_IMAGEHEIGHT_OFFSET); > + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); > + __raw_writel(0, SMS_ROT_CONTROL(context)); > + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET > + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET > + | page_height_exp << SMS_PH_OFFSET; > + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); > +} > + > +/* > +* omap_dispc_set_rotate : configuring rotation registers based on angle. > +* @ plane: graphics or video pipe line > +* @ angle: Rotation angle. > +* Return Value: Returns 0 on success > + Returns -1 if it fails. > +*/ > + > +int omap_dispc_set_rotate(int plane, int angle) > +{ > + int width, height; > + u32 addr_base; > + u32 bpp; > + int r = 0; > + > + width = dispc.fbdev->fb_info[0]->var.xres; > + height = dispc.fbdev->fb_info[0]->var.yres; > + bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; > + > + if (plane == OMAPFB_PLANE_GFX) { > + enable_lcd_clocks(1); > + /* clear GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); > + if (rotation == 1) { > + omap2_disp_set_vrfb(width, height, bpp); > + switch (angle) { > + case 0: > + addr_base = vrfb.paddr[0]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * bpp + 1); > + break; > + case 90: > + addr_base = vrfb.paddr[1]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * bpp + 1); > + break; > + case 180: > + addr_base = vrfb.paddr[2]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * bpp + 1); > + break; > + case 270: > + addr_base = vrfb.paddr[3]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * bpp + 1); > + break; > + } > + } else { > + return r; > + } > + /* set GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); > + enable_lcd_clocks(0); > + } > + return r; > +} > + > +static int omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) > +{ > + int r = 0; > + memset(&vrfb, 0, sizeof(vrfb)); > + vrfb.paddr[0] = SMS_ROT_BASE_ADDR(0, 0); > + vrfb.paddr[1] = SMS_ROT_BASE_ADDR(0, 90); > + vrfb.paddr[2] = SMS_ROT_BASE_ADDR(0, 180); > + vrfb.paddr[3] = SMS_ROT_BASE_ADDR(0, 270); > + > + if (!request_mem_region(vrfb.paddr[0], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[1], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[2], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserveVRFB180 area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[3], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); > + } > + > + vrfb.vaddr[0] = ioremap(vrfb.paddr[0], > + req_vram->region[0].size); > + vrfb.vaddr[1] = ioremap(vrfb.paddr[1], > + req_vram->region[0].size); > + vrfb.vaddr[2] = ioremap(vrfb.paddr[2], > + req_vram->region[0].size); > + vrfb.vaddr[3] = ioremap(vrfb.paddr[3], > + req_vram->region[0].size); > + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) > + || (!vrfb.vaddr[3])) { > + r = -1; > + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); > + } > + return r; > +} > + > static void write_firh_reg(int plane, int reg, u32 value) > { > u32 base; > @@ -1425,10 +1602,16 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, > > if ((r = alloc_palette_ram()) < 0) > goto fail2; > - > + if (rotation == 1) { > + if (omap2_alloc_vrfb_mem(req_vram) < 0) > + printk(KERN_ERR "VRFB memory allocation failed"); > + } > if ((r = setup_fbmem(req_vram)) < 0) > goto fail3; > - > + if (rotation == 1) { > + save_paddr = dispc.mem_desc.region[0].paddr; Here you are missing these save_vaddr = dispc.mem_desc.region[0].vaddr; dispc.mem_desc.region[0].vaddr = vrfb.vaddr[0]; dispc.mem_desc.region[0].paddr = vrfb.paddr[0]; dispc.fbdev->mem_desc.region[0].paddr = vrfb.paddr[0]; Because set_fb_fix will be using those to fill up struct fb_fix_screeninfo see below rg = &plane->fbdev->mem_desc.region[plane->idx]; fbi->screen_base = (char __iomem *)rg->vaddr; fix->smem_start = rg->paddr; fix->smem_len = rg->size; > + dispc.fbdev->mem_desc.region[0].vaddr = vrfb.vaddr[0]; > + } > if (!skip_init) { > for (i = 0; i < dispc.mem_desc.region_cnt; i++) { > memset(dispc.mem_desc.region[i].vaddr, 0, > @@ -1478,7 +1661,6 @@ fail0: > static void omap_dispc_cleanup(void) > { > int i; > - > omap_dispc_set_update_mode(OMAPFB_UPDATE_DISABLED); > /* This will also disable clocks that are on */ > for (i = 0; i < dispc.mem_desc.region_cnt; i++) > @@ -1507,4 +1689,5 @@ const struct lcd_ctrl omap2_int_ctrl = { > .set_color_key = omap_dispc_set_color_key, > .get_color_key = omap_dispc_get_color_key, > .mmap = omap_dispc_mmap_user, > + .set_rotate = omap_dispc_set_rotate, > }; > diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h > index ef720a7..506e4c6 100644 > --- a/drivers/video/omap/dispc.h > +++ b/drivers/video/omap/dispc.h > @@ -2,7 +2,7 @@ > #define _DISPC_H > > #include <linux/interrupt.h> > - > +#include <mach/hardware.h> > #define DISPC_PLANE_GFX 0 > #define DISPC_PLANE_VID1 1 > #define DISPC_PLANE_VID2 2 > @@ -32,6 +32,37 @@ > #define DISPC_TFT_DATA_LINES_18 2 > #define DISPC_TFT_DATA_LINES_24 3 > > +/* Rotation using VRFB */ > +extern int rotation; > +#define SMS_ROT_BASE_ADDR(context, degree) (0x70000000 \ > + | 0x4000000 * (context) \ > + | 0x1000000 * (degree/90)) > +#define BITS_PER_PIXEL 16 /* RGB value */ > +#define VRFB_SIZE (2048 * 640 * (BITS_PER_PIXEL/8)) VRFB_SIZE deifned but not used > +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ > +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ > +#define SMS_IMAGEHEIGHT_OFFSET 16 > +#define SMS_IMAGEWIDTH_OFFSET 0 > +#define SMS_PH_OFFSET 8 > +#define SMS_PW_OFFSET 4 > +#define SMS_PS_OFFSET 0 > +#define ROT_LINE_LENGTH 2048 > + > +#define DSS_REG_BASE 0x48050000 > +#define DISPC_REG_OFFSET 0x00000400 > +#define DISPC_BASE 0x48050400 > +#define OMAP_SMS_BASE (0x6C000000) > +#define DISPC_GFX_BA0 0x0080 > +#define DISPC_GFX_ROW_INC 0x00AC > +#define DISPC_GFX_PIXEL_INC 0x00B0 > +#define DISPC_CONTROL 0x0040 > + > +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ > + + 0x10 * context) > +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ > + + 0x10 * context) > +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ > + + 0x10 * context) > extern void omap_dispc_set_lcd_size(int width, int height); > > extern void omap_dispc_enable_lcd_out(int enable); > diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c > index d176a2c..1d2ceb8 100644 > --- a/drivers/video/omap/omapfb_main.c > +++ b/drivers/video/omap/omapfb_main.c > @@ -35,7 +35,8 @@ > #include "dispc.h" > > #define MODULE_NAME "omapfb" > - > +int rotation = -1; > +#define ROT_LINE_LENGTH 2048 > static unsigned int def_accel; > static unsigned long def_vram[OMAPFB_PLANE_NUM]; > static unsigned int def_vram_cnt; > @@ -219,9 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) > if (r < 0) > return r; > > - if (fbdev->ctrl->set_rotate != NULL) > - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) > + if (fbdev->ctrl->set_rotate != NULL) { > + r = fbdev->ctrl->set_rotate(0, var->rotate); > + if (r < 0) > return r; > + } > > if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) > r = fbdev->ctrl->set_scale(plane->idx, > @@ -425,7 +428,7 @@ static void set_fb_fix(struct fb_info *fbi) > break; > } > fix->accel = FB_ACCEL_OMAP1610; > - fix->line_length = var->xres_virtual * bpp / 8; > + fix->line_length = ROT_LINE_LENGTH * bpp / 8; or if (rotation) fix->line_length = ROT_LINE_LENGTH * bpp / 8; else fix->line_length = var->xres_virtual * bpp / 8; > } > > static int set_color_mode(struct omapfb_plane_struct *plane, > @@ -497,14 +500,13 @@ static int set_fb_var(struct fb_info *fbi, > bpp = var->bits_per_pixel; > if (plane->color_mode == OMAPFB_COLOR_RGB444) > bpp = 16; > - > + xres_min = OMAPFB_PLANE_XRES_MIN; > + xres_max = panel->x_res; > + yres_min = OMAPFB_PLANE_YRES_MIN; > + yres_max = panel->y_res; > switch (var->rotate) { > case 0: > case 180: > - xres_min = OMAPFB_PLANE_XRES_MIN; > - xres_max = panel->x_res; > - yres_min = OMAPFB_PLANE_YRES_MIN; > - yres_max = panel->y_res; > if (cpu_is_omap15xx()) { > var->xres = panel->x_res; > var->yres = panel->y_res; > @@ -512,10 +514,6 @@ static int set_fb_var(struct fb_info *fbi, > break; > case 90: > case 270: > - xres_min = OMAPFB_PLANE_YRES_MIN; > - xres_max = panel->y_res; > - yres_min = OMAPFB_PLANE_XRES_MIN; > - yres_max = panel->x_res; > if (cpu_is_omap15xx()) { > var->xres = panel->y_res; > var->yres = panel->x_res; > @@ -1718,7 +1716,7 @@ static int omapfb_do_probe(struct platform_device *pdev, > > pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); > > - def_vxres = def_vxres ? : fbdev->panel->x_res; > + def_vxres = ROT_LINE_LENGTH; Or if (rotation) def_vxres = ROT_LINE_LENGTH; else def_vxres = def_vxres ? : fbdev->panel->x_res; > def_vyres = def_vyres ? : fbdev->panel->y_res; > > init_state++; > @@ -1909,8 +1907,10 @@ static int __init omapfb_setup(char *options) > def_vxres = simple_strtoul(this_opt + 6, NULL, 0); > else if (!strncmp(this_opt, "vyres:", 6)) > def_vyres = simple_strtoul(this_opt + 6, NULL, 0); > - else if (!strncmp(this_opt, "rotate:", 7)) > - def_rotate = (simple_strtoul(this_opt + 7, NULL, 0)); > + else if (!strncmp(this_opt, "rotation=", 9)) { > + rotation = 1; > + def_rotate = (simple_strtoul(this_opt + 9, NULL, 0)); > + } > else if (!strncmp(this_opt, "mirror:", 7)) > def_mirror = (simple_strtoul(this_opt + 7, NULL, 0)); > else if (!strncmp(this_opt, "manual_update", 13)) > -- > 1.5.3.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Re: omap-sdp3430_Rotation patch 2008-09-18 5:29 ` arun c @ 2008-09-18 8:50 ` Russell King - ARM Linux 0 siblings, 0 replies; 11+ messages in thread From: Russell King - ARM Linux @ 2008-09-18 8:50 UTC (permalink / raw) To: arun c; +Cc: nskamat, linux-omap, Rajesh K, Iqbal Shareef On Thu, Sep 18, 2008 at 01:29:24AM -0400, arun c wrote: > Because set_fb_fix will be using those to fill up struct fb_fix_screeninfo > > see below > > rg = &plane->fbdev->mem_desc.region[plane->idx]; > fbi->screen_base = (char __iomem *)rg->vaddr; You should get rid of that cast. Remember: casts are bad news when overused. Only use casts when you really have no other alternative and you're sure that you should be doing what you're trying to do. (Eg, I've recently seen someone casting a platform device structure to its platform data - and the cast there clearly shouted out "wrong" - they didn't actually want to be doing that.) > > diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h > > index ef720a7..506e4c6 100644 > > --- a/drivers/video/omap/dispc.h > > +++ b/drivers/video/omap/dispc.h > > @@ -2,7 +2,7 @@ > > #define _DISPC_H > > > > #include <linux/interrupt.h> > > - > > +#include <mach/hardware.h> Could do with keeping the blank line after the #include statements. > > #define DISPC_PLANE_GFX 0 > > #define DISPC_PLANE_VID1 1 > > #define DISPC_PLANE_VID2 2 > > @@ -32,6 +32,37 @@ > > #define DISPC_TFT_DATA_LINES_18 2 > > #define DISPC_TFT_DATA_LINES_24 3 > > > > +/* Rotation using VRFB */ > > +extern int rotation; > > +#define SMS_ROT_BASE_ADDR(context, degree) (0x70000000 \ > > + | 0x4000000 * (context) \ > > + | 0x1000000 * (degree/90)) > > +#define BITS_PER_PIXEL 16 /* RGB value */ > > +#define VRFB_SIZE (2048 * 640 * (BITS_PER_PIXEL/8)) > > VRFB_SIZE deifned but not used > > > +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ > > +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ > > +#define SMS_IMAGEHEIGHT_OFFSET 16 > > +#define SMS_IMAGEWIDTH_OFFSET 0 > > +#define SMS_PH_OFFSET 8 > > +#define SMS_PW_OFFSET 4 > > +#define SMS_PS_OFFSET 0 > > +#define ROT_LINE_LENGTH 2048 > > + > > +#define DSS_REG_BASE 0x48050000 > > +#define DISPC_REG_OFFSET 0x00000400 > > +#define DISPC_BASE 0x48050400 > > +#define OMAP_SMS_BASE (0x6C000000) > > +#define DISPC_GFX_BA0 0x0080 > > +#define DISPC_GFX_ROW_INC 0x00AC > > +#define DISPC_GFX_PIXEL_INC 0x00B0 > > +#define DISPC_CONTROL 0x0040 > > + > > +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ > > + + 0x10 * context) > > +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ > > + + 0x10 * context) > > +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ > > + + 0x10 * context) > > extern void omap_dispc_set_lcd_size(int width, int height); > > > > extern void omap_dispc_enable_lcd_out(int enable); > > diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c > > index d176a2c..1d2ceb8 100644 > > --- a/drivers/video/omap/omapfb_main.c > > +++ b/drivers/video/omap/omapfb_main.c > > @@ -35,7 +35,8 @@ > > #include "dispc.h" > > > > #define MODULE_NAME "omapfb" > > - > > +int rotation = -1; Bad name for a public variable. > > - def_vxres = def_vxres ? : fbdev->panel->x_res; > > + def_vxres = ROT_LINE_LENGTH; > Or > if (rotation) > def_vxres = ROT_LINE_LENGTH; > else > def_vxres = def_vxres ? : fbdev->panel->x_res; Please avoid using foo ? : bar - although legal, please write it more clearly as "foo ? foo : bar", or in this case: if (rotation) def_vxres = ROT_LINE_LENGTH; else if (!def_vxres) def_vxres = fbdev->panel->x_res; Ditto for def_vyres. ^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: omap-sdp3430_Rotation patch 2008-09-15 9:48 ` arun c 2008-09-16 4:41 ` K, Rajesh @ 2008-10-06 4:24 ` Rajesh 2008-10-06 5:43 ` arun c 1 sibling, 1 reply; 11+ messages in thread From: Rajesh @ 2008-10-06 4:24 UTC (permalink / raw) To: 'arun c'; +Cc: linux-omap Thanks for giving me the comments.I have incorporated all the comments and sending the complete patch for review ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >From Rajesh K krajesh<krajesh@ti.com> OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP This patch provides rotation support OMAP SDP. You will have to append video=omapfb:rotate=0 parameters to your u-boot arguments to get this working. This supports 0,90,180 and 270 degree rotations. Signed-off-by: Rajesh K < krajesh@ti.com > Signed-off-by: Iqbal shareef < iqbal@ti.com > --- arch/arm/plat-omap/include/mach/omapfb.h | 4 +- drivers/video/omap/dispc.c | 193 +++++++++++++++++++++++++++++- drivers/video/omap/dispc.h | 29 +++++ drivers/video/omap/omapfb_main.c | 37 ++++--- 4 files changed, 243 insertions(+), 20 deletions(-) diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h index a4a84f3..338a11d 100644 --- a/arch/arm/plat-omap/include/mach/omapfb.h +++ b/arch/arm/plat-omap/include/mach/omapfb.h @@ -277,7 +277,7 @@ typedef int (*omapfb_notifier_callback_t)(struct notifier_block *, struct omapfb_mem_region { dma_addr_t paddr; - void *vaddr; + void __iomem *vaddr; unsigned long size; u8 type; /* OMAPFB_PLANE_MEM_* */ unsigned alloc:1; /* allocated by the driver */ @@ -306,7 +306,7 @@ struct lcd_ctrl { int screen_width, int pos_x, int pos_y, int width, int height, int color_mode); - int (*set_rotate) (int angle); + int (*set_rotate) (int plane, int angle); int (*setup_mem) (int plane, size_t size, int mem_type, unsigned long *paddr); int (*mmap) (struct fb_info *info, diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index ce4c4de..94c96dd 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -149,12 +149,25 @@ #define RESMAP_MASK(_page_nr) \ (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) +unsigned long save_paddr; +unsigned long save_vaddr; + struct resmap { unsigned long start; unsigned page_cnt; unsigned long *map; }; +struct { + unsigned long paddr[4]; + void __iomem *vaddr[4]; + u32 xoffset; + u32 yoffset; + unsigned long size_val; + unsigned long control_val; +} vrfb; + +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel); static struct { void __iomem *base; @@ -459,6 +472,170 @@ static int omap_dispc_setup_plane(int plane, int channel_out, return r; } +/* +* pages_per_side : Will provide pages per side +* @ img_side : img_side +* @ page_exp : page_exponential +* Return Value: Returns pages per side value. +*/ + +static inline u32 pages_per_side(u32 img_side, u32 page_exp) +{ + return (img_side + (1<<page_exp) - 1) >> page_exp; +} + +/* +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation engine +* which will supports rotations of 0,90,180,270 degrees. +* @width: Width of the image +* @height : height of the image +* @bytes_per_pixel : color depth of the image +* return value : None +*/ + +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) +{ + int page_width_exp, page_height_exp, pixel_size_exp; + int context = 0; + vrfb.size_val = 0; + vrfb.control_val = 0; + pixel_size_exp = bytes_per_pixel >> 1; + page_width_exp = PAGE_WIDTH_EXP; + page_height_exp = PAGE_HEIGHT_EXP; + + width = ((1<<page_width_exp) * + (pages_per_side(width * bytes_per_pixel, + page_width_exp))) >> pixel_size_exp; + height = (1<<page_height_exp) * + (pages_per_side(height, page_height_exp)); + + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); + __raw_writel(0, SMS_ROT0_SIZE(context)); + + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| + (height << SMS_IMAGEHEIGHT_OFFSET); + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); + __raw_writel(0, SMS_ROT_CONTROL(context)); + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET + | page_height_exp << SMS_PH_OFFSET; + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); +} + +/* +* omap_dispc_set_rotate : configuring rotation registers based on angle. +* @ plane: graphics or video pipe line +* @ angle: Rotation angle. +* Return Value: Returns 0 on success + Returns -1 if it fails. +*/ + +int omap_dispc_set_rotate(int plane, int angle) +{ + int width, height; + u32 addr_base; + u32 bpp; + int r = 0; + + width = dispc.fbdev->fb_info[0]->var.xres; + height = dispc.fbdev->fb_info[0]->var.yres; + bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; + + if (plane == OMAPFB_PLANE_GFX) { + enable_lcd_clocks(1); + /* clear GOLCD bit */ + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); + if (omapfb_dispc_rotation == 1) { + omap2_disp_set_vrfb(width, height, bpp); + switch (angle) { + case 0: + addr_base = vrfb.paddr[0]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - width) * bpp + 1); + break; + case 90: + addr_base = vrfb.paddr[1]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - height) * bpp + 1); + break; + case 180: + addr_base = vrfb.paddr[2]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - width) * bpp + 1); + break; + case 270: + addr_base = vrfb.paddr[3]; + dispc_write_reg(DISPC_GFX_BA0, addr_base); + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); + dispc_write_reg(DISPC_GFX_ROW_INC, + (ROT_LINE_LENGTH - height) * bpp + 1); + break; + } + } else { + return r; + } + /* set GOLCD bit */ + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); + enable_lcd_clocks(0); + } + return r; +} + +static int omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) +{ + int r = 0; + memset(&vrfb, 0, sizeof(vrfb)); + vrfb.paddr[0] = SMS_ROT_BASE_ADDR(0, 0); + vrfb.paddr[1] = SMS_ROT_BASE_ADDR(0, 90); + vrfb.paddr[2] = SMS_ROT_BASE_ADDR(0, 180); + vrfb.paddr[3] = SMS_ROT_BASE_ADDR(0, 270); + + if (!request_mem_region(vrfb.paddr[0], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserve VRFB0 area\n"); + } + + if (!request_mem_region(vrfb.paddr[1], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); + } + + if (!request_mem_region(vrfb.paddr[2], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserveVRFB180 area\n"); + } + + if (!request_mem_region(vrfb.paddr[3], + req_vram->region[0].size, "omapfb")) { + r = -1; + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); + } + + vrfb.vaddr[0] = ioremap(vrfb.paddr[0], + req_vram->region[0].size); + vrfb.vaddr[1] = ioremap(vrfb.paddr[1], + req_vram->region[0].size); + vrfb.vaddr[2] = ioremap(vrfb.paddr[2], + req_vram->region[0].size); + vrfb.vaddr[3] = ioremap(vrfb.paddr[3], + req_vram->region[0].size); + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) + || (!vrfb.vaddr[3])) { + r = -1; + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); + } + return r; +} + static void write_firh_reg(int plane, int reg, u32 value) { u32 base; @@ -1425,10 +1602,20 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode, if ((r = alloc_palette_ram()) < 0) goto fail2; - + if (omapfb_dispc_rotation == 1) { + if (omap2_alloc_vrfb_mem(req_vram) < 0) + printk(KERN_ERR "VRFB memory allocation failed"); + } if ((r = setup_fbmem(req_vram)) < 0) goto fail3; - + if (omapfb_dispc_rotation == 1) { + save_paddr = dispc.mem_desc.region[0].paddr; + save_vaddr = dispc.mem_desc.region[0].vaddr; + dispc.mem_desc.region[0].vaddr = vrfb.vaddr[0]; + dispc.mem_desc.region[0].paddr = vrfb.paddr[0]; + dispc.fbdev->mem_desc.region[0].paddr = vrfb.paddr[0]; + dispc.fbdev->mem_desc.region[0].vaddr = vrfb.vaddr[0]; + } if (!skip_init) { for (i = 0; i < dispc.mem_desc.region_cnt; i++) { memset(dispc.mem_desc.region[i].vaddr, 0, @@ -1478,7 +1665,6 @@ fail0: static void omap_dispc_cleanup(void) { int i; - omap_dispc_set_update_mode(OMAPFB_UPDATE_DISABLED); /* This will also disable clocks that are on */ for (i = 0; i < dispc.mem_desc.region_cnt; i++) @@ -1507,4 +1693,5 @@ const struct lcd_ctrl omap2_int_ctrl = { .set_color_key = omap_dispc_set_color_key, .get_color_key = omap_dispc_get_color_key, .mmap = omap_dispc_mmap_user, + .set_rotate = omap_dispc_set_rotate, }; diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h index ef720a7..5b29e6f 100644 --- a/drivers/video/omap/dispc.h +++ b/drivers/video/omap/dispc.h @@ -32,6 +32,35 @@ #define DISPC_TFT_DATA_LINES_18 2 #define DISPC_TFT_DATA_LINES_24 3 +/* Rotation using VRFB */ +extern int omapfb_dispc_rotation; +#define SMS_ROT_BASE_ADDR(context, degree) (0x70000000 \ + | 0x4000000 * (context) \ + | 0x1000000 * (degree/90)) +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ +#define SMS_IMAGEHEIGHT_OFFSET 16 +#define SMS_IMAGEWIDTH_OFFSET 0 +#define SMS_PH_OFFSET 8 +#define SMS_PW_OFFSET 4 +#define SMS_PS_OFFSET 0 +#define ROT_LINE_LENGTH 2048 + +#define DSS_REG_BASE 0x48050000 +#define DISPC_REG_OFFSET 0x00000400 +#define DISPC_BASE 0x48050400 +#define OMAP_SMS_BASE (0x6C000000) +#define DISPC_GFX_BA0 0x0080 +#define DISPC_GFX_ROW_INC 0x00AC +#define DISPC_GFX_PIXEL_INC 0x00B0 +#define DISPC_CONTROL 0x0040 + +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x188 \ + + 0x10 * context) +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x180 \ + + 0x10 * context) +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + 0x184 \ + + 0x10 * context) extern void omap_dispc_set_lcd_size(int width, int height); extern void omap_dispc_enable_lcd_out(int enable); diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index d176a2c..8f2746c 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -35,7 +35,8 @@ #include "dispc.h" #define MODULE_NAME "omapfb" - +int omapfb_dispc_rotation = -1; +#define ROT_LINE_LENGTH 2048 static unsigned int def_accel; static unsigned long def_vram[OMAPFB_PLANE_NUM]; static unsigned int def_vram_cnt; @@ -219,9 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) if (r < 0) return r; - if (fbdev->ctrl->set_rotate != NULL) - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) + if (fbdev->ctrl->set_rotate != NULL) { + r = fbdev->ctrl->set_rotate(0, var->rotate); + if (r < 0) return r; + } if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) r = fbdev->ctrl->set_scale(plane->idx, @@ -425,7 +428,10 @@ static void set_fb_fix(struct fb_info *fbi) break; } fix->accel = FB_ACCEL_OMAP1610; - fix->line_length = var->xres_virtual * bpp / 8; + if (omapfb_dispc_rotation) + fix->line_length = ROT_LINE_LENGTH * bpp / 8; + else if (!omapfb_dispc_rotation) + fix->line_length = var->xres_virtual * bpp / 8; } static int set_color_mode(struct omapfb_plane_struct *plane, @@ -497,14 +503,13 @@ static int set_fb_var(struct fb_info *fbi, bpp = var->bits_per_pixel; if (plane->color_mode == OMAPFB_COLOR_RGB444) bpp = 16; - + xres_min = OMAPFB_PLANE_XRES_MIN; + xres_max = panel->x_res; + yres_min = OMAPFB_PLANE_YRES_MIN; + yres_max = panel->y_res; switch (var->rotate) { case 0: case 180: - xres_min = OMAPFB_PLANE_XRES_MIN; - xres_max = panel->x_res; - yres_min = OMAPFB_PLANE_YRES_MIN; - yres_max = panel->y_res; if (cpu_is_omap15xx()) { var->xres = panel->x_res; var->yres = panel->y_res; @@ -512,10 +517,6 @@ static int set_fb_var(struct fb_info *fbi, break; case 90: case 270: - xres_min = OMAPFB_PLANE_YRES_MIN; - xres_max = panel->y_res; - yres_min = OMAPFB_PLANE_XRES_MIN; - yres_max = panel->x_res; if (cpu_is_omap15xx()) { var->xres = panel->y_res; var->yres = panel->x_res; @@ -1718,7 +1719,11 @@ static int omapfb_do_probe(struct platform_device *pdev, pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); - def_vxres = def_vxres ? : fbdev->panel->x_res; + if (omapfb_dispc_rotation) + def_vxres = ROT_LINE_LENGTH; + else if (!omapfb_dispc_rotation) + def_vxres = def_vxres ? : fbdev->panel->x_res; + def_vyres = def_vyres ? : fbdev->panel->y_res; init_state++; @@ -1909,8 +1914,10 @@ static int __init omapfb_setup(char *options) def_vxres = simple_strtoul(this_opt + 6, NULL, 0); else if (!strncmp(this_opt, "vyres:", 6)) def_vyres = simple_strtoul(this_opt + 6, NULL, 0); - else if (!strncmp(this_opt, "rotate:", 7)) + else if (!strncmp(this_opt, "rotate=", 7)) { + omapfb_dispc_rotation = 1; def_rotate = (simple_strtoul(this_opt + 7, NULL, 0)); + } else if (!strncmp(this_opt, "mirror:", 7)) def_mirror = (simple_strtoul(this_opt + 7, NULL, 0)); else if (!strncmp(this_opt, "manual_update", 13)) -- 1.5.3.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: omap-sdp3430_Rotation patch 2008-10-06 4:24 ` Rajesh @ 2008-10-06 5:43 ` arun c 0 siblings, 0 replies; 11+ messages in thread From: arun c @ 2008-10-06 5:43 UTC (permalink / raw) To: Rajesh; +Cc: linux-omap@vger.kernel.org Hi Rajesh, On Mon, Oct 6, 2008 at 9:54 AM, Rajesh <krajesh@ti.com> wrote: > > Thanks for giving me the comments.I have incorporated all the comments > and sending the complete patch for review > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > > From Rajesh K krajesh<krajesh@ti.com> > As I said earlier rotation is not for a particular board it will affect all omap2/3 boards, so better change this describtion. > OMAP FBDEV: VRFB framebuffer rotation support for OMAP SDP > > This patch provides rotation support OMAP SDP. You will have to append > video=omapfb:rotate=0 parameters to your u-boot arguments to get this > working. > This supports 0,90,180 and 270 degree rotations. > > Signed-off-by: Rajesh K < krajesh@ti.com > > Signed-off-by: Iqbal shareef < iqbal@ti.com > > > --- > arch/arm/plat-omap/include/mach/omapfb.h | 4 +- > drivers/video/omap/dispc.c | 193 > +++++++++++++++++++++++++++++- > drivers/video/omap/dispc.h | 29 +++++ > drivers/video/omap/omapfb_main.c | 37 ++++--- > 4 files changed, 243 insertions(+), 20 deletions(-) > > diff --git a/arch/arm/plat-omap/include/mach/omapfb.h > b/arch/arm/plat-omap/include/mach/omapfb.h > index a4a84f3..338a11d 100644 > --- a/arch/arm/plat-omap/include/mach/omapfb.h > +++ b/arch/arm/plat-omap/include/mach/omapfb.h > @@ -277,7 +277,7 @@ typedef int (*omapfb_notifier_callback_t)(struct > notifier_block *, > > struct omapfb_mem_region { > dma_addr_t paddr; > - void *vaddr; > + void __iomem *vaddr; > unsigned long size; > u8 type; /* OMAPFB_PLANE_MEM_* */ > unsigned alloc:1; /* allocated by the driver */ > @@ -306,7 +306,7 @@ struct lcd_ctrl { > int screen_width, > int pos_x, int pos_y, int width, > int height, int color_mode); > - int (*set_rotate) (int angle); > + int (*set_rotate) (int plane, int angle); > int (*setup_mem) (int plane, size_t size, > int mem_type, unsigned long > *paddr); > int (*mmap) (struct fb_info *info, > diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c > index ce4c4de..94c96dd 100644 > --- a/drivers/video/omap/dispc.c > +++ b/drivers/video/omap/dispc.c > @@ -149,12 +149,25 @@ > #define RESMAP_MASK(_page_nr) \ > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > +unsigned long save_paddr; > +unsigned long save_vaddr; > + > struct resmap { > unsigned long start; > unsigned page_cnt; > unsigned long *map; > }; > > +struct { > + unsigned long paddr[4]; > + void __iomem *vaddr[4]; > + u32 xoffset; > + u32 yoffset; > + unsigned long size_val; > + unsigned long control_val; > +} vrfb; > + > +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 > bytes_per_pixel); > static struct { > void __iomem *base; > > @@ -459,6 +472,170 @@ static int omap_dispc_setup_plane(int plane, int > channel_out, > return r; > } > > +/* > +* pages_per_side : Will provide pages per side > +* @ img_side : img_side > +* @ page_exp : page_exponential > +* Return Value: Returns pages per side value. > +*/ > + > +static inline u32 pages_per_side(u32 img_side, u32 page_exp) > +{ > + return (img_side + (1<<page_exp) - 1) >> page_exp; > +} > + > +/* > +* omap2_disp_set_vrfb : Will configure VRFB Support.Its a rotation > engine > +* which will supports rotations of 0,90,180,270 degrees. > +* @width: Width of the image > +* @height : height of the image > +* @bytes_per_pixel : color depth of the image > +* return value : None > +*/ > + > +static void omap2_disp_set_vrfb(u32 width, u32 height, u32 bytes_per_pixel) > +{ > + int page_width_exp, page_height_exp, pixel_size_exp; > + int context = 0; > + vrfb.size_val = 0; > + vrfb.control_val = 0; > + pixel_size_exp = bytes_per_pixel >> 1; > + page_width_exp = PAGE_WIDTH_EXP; > + page_height_exp = PAGE_HEIGHT_EXP; > + > + width = ((1<<page_width_exp) * > + (pages_per_side(width * bytes_per_pixel, > + page_width_exp))) >> pixel_size_exp; > + height = (1<<page_height_exp) * > + (pages_per_side(height, page_height_exp)); > + > + __raw_writel(save_paddr, SMS_ROT0_PHYSICAL_BA(context)); > + __raw_writel(0, SMS_ROT0_SIZE(context)); > + > + vrfb.size_val |= (width << SMS_IMAGEWIDTH_OFFSET)| > + (height << SMS_IMAGEHEIGHT_OFFSET); > + __raw_writel(vrfb.size_val, SMS_ROT0_SIZE(context)); > + __raw_writel(0, SMS_ROT_CONTROL(context)); > + vrfb.control_val |= pixel_size_exp << SMS_PS_OFFSET > + | (page_width_exp - pixel_size_exp) << SMS_PW_OFFSET > + | page_height_exp << SMS_PH_OFFSET; > + __raw_writel(vrfb.control_val, SMS_ROT_CONTROL(context)); > +} > + > +/* > +* omap_dispc_set_rotate : configuring rotation registers based on > angle. > +* @ plane: graphics or video pipe line > +* @ angle: Rotation angle. > +* Return Value: Returns 0 on success > + Returns -1 if it fails. > +*/ > + > +int omap_dispc_set_rotate(int plane, int angle) > +{ > + int width, height; > + u32 addr_base; > + u32 bpp; > + int r = 0; > + > + width = dispc.fbdev->fb_info[0]->var.xres; > + height = dispc.fbdev->fb_info[0]->var.yres; > + bpp = dispc.fbdev->fb_info[0]->var.bits_per_pixel / 8; > + > + if (plane == OMAPFB_PLANE_GFX) { > + enable_lcd_clocks(1); > + /* clear GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); > + if (omapfb_dispc_rotation == 1) { > + omap2_disp_set_vrfb(width, height, bpp); > + switch (angle) { > + case 0: > + addr_base = vrfb.paddr[0]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * bpp + > 1); > + break; > + case 90: > + addr_base = vrfb.paddr[1]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * bpp + > 1); > + break; > + case 180: > + addr_base = vrfb.paddr[2]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - width) * bpp + > 1); > + break; > + case 270: > + addr_base = vrfb.paddr[3]; > + dispc_write_reg(DISPC_GFX_BA0, addr_base); > + dispc_write_reg(DISPC_GFX_PIXEL_INC, 1); > + dispc_write_reg(DISPC_GFX_ROW_INC, > + (ROT_LINE_LENGTH - height) * bpp + > 1); > + break; > + } > + } else { > + return r; > + } > + /* set GOLCD bit */ > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0x20); > + enable_lcd_clocks(0); > + } > + return r; > +} > + > +static int omap2_alloc_vrfb_mem(struct omapfb_mem_desc *req_vram) > +{ > + int r = 0; > + memset(&vrfb, 0, sizeof(vrfb)); > + vrfb.paddr[0] = SMS_ROT_BASE_ADDR(0, 0); > + vrfb.paddr[1] = SMS_ROT_BASE_ADDR(0, 90); > + vrfb.paddr[2] = SMS_ROT_BASE_ADDR(0, 180); > + vrfb.paddr[3] = SMS_ROT_BASE_ADDR(0, 270); > + > + if (!request_mem_region(vrfb.paddr[0], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserve VRFB0 > area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[1], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserve VRFB90 > area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[2], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserveVRFB180 > area\n"); > + } > + > + if (!request_mem_region(vrfb.paddr[3], > + req_vram->region[0].size, "omapfb")) { > + r = -1; > + printk(KERN_ERR "omapfb: can't reserve VRFB270 > area\n"); > + } > + > + vrfb.vaddr[0] = ioremap(vrfb.paddr[0], > + req_vram->region[0].size); > + vrfb.vaddr[1] = ioremap(vrfb.paddr[1], > + req_vram->region[0].size); > + vrfb.vaddr[2] = ioremap(vrfb.paddr[2], > + req_vram->region[0].size); > + vrfb.vaddr[3] = ioremap(vrfb.paddr[3], > + req_vram->region[0].size); > + if ((!vrfb.vaddr[0]) || (!vrfb.vaddr[1]) || (!vrfb.vaddr[2]) > + || (!vrfb.vaddr[3])) { > + r = -1; > + printk(KERN_ERR "omapfb: can't map rotated view(s)\n"); > + } > + return r; > +} > + > static void write_firh_reg(int plane, int reg, u32 value) > { > u32 base; > @@ -1425,10 +1602,20 @@ static int omap_dispc_init(struct omapfb_device > *fbdev, int ext_mode, > > if ((r = alloc_palette_ram()) < 0) > goto fail2; > - > + if (omapfb_dispc_rotation == 1) { > + if (omap2_alloc_vrfb_mem(req_vram) < 0) > + printk(KERN_ERR "VRFB memory allocation failed"); > + } > if ((r = setup_fbmem(req_vram)) < 0) > goto fail3; > - > + if (omapfb_dispc_rotation == 1) { > + save_paddr = dispc.mem_desc.region[0].paddr; > + save_vaddr = dispc.mem_desc.region[0].vaddr; > + dispc.mem_desc.region[0].vaddr = vrfb.vaddr[0]; > + dispc.mem_desc.region[0].paddr = vrfb.paddr[0]; > + dispc.fbdev->mem_desc.region[0].paddr = vrfb.paddr[0]; > + dispc.fbdev->mem_desc.region[0].vaddr = vrfb.vaddr[0]; > + } > if (!skip_init) { > for (i = 0; i < dispc.mem_desc.region_cnt; i++) { > memset(dispc.mem_desc.region[i].vaddr, 0, > @@ -1478,7 +1665,6 @@ fail0: > static void omap_dispc_cleanup(void) > { > int i; > - > omap_dispc_set_update_mode(OMAPFB_UPDATE_DISABLED); > /* This will also disable clocks that are on */ > for (i = 0; i < dispc.mem_desc.region_cnt; i++) > @@ -1507,4 +1693,5 @@ const struct lcd_ctrl omap2_int_ctrl = { > .set_color_key = omap_dispc_set_color_key, > .get_color_key = omap_dispc_get_color_key, > .mmap = omap_dispc_mmap_user, > + .set_rotate = omap_dispc_set_rotate, > }; > diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h > index ef720a7..5b29e6f 100644 > --- a/drivers/video/omap/dispc.h > +++ b/drivers/video/omap/dispc.h > @@ -32,6 +32,35 @@ > #define DISPC_TFT_DATA_LINES_18 2 > #define DISPC_TFT_DATA_LINES_24 3 > > +/* Rotation using VRFB */ > +extern int omapfb_dispc_rotation; > +#define SMS_ROT_BASE_ADDR(context, degree) (0x70000000 \ > + | 0x4000000 * (context) \ > + | 0x1000000 * (degree/90)) > +#define PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */ > +#define PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */ > +#define SMS_IMAGEHEIGHT_OFFSET 16 > +#define SMS_IMAGEWIDTH_OFFSET 0 > +#define SMS_PH_OFFSET 8 > +#define SMS_PW_OFFSET 4 > +#define SMS_PS_OFFSET 0 > +#define ROT_LINE_LENGTH 2048 > + > + > +#define DSS_REG_BASE 0x48050000 > +#define DISPC_REG_OFFSET 0x00000400 > +#define DISPC_BASE 0x48050400 > +#define OMAP_SMS_BASE (0x6C000000) > +#define DISPC_GFX_BA0 0x0080 > +#define DISPC_GFX_ROW_INC 0x00AC > +#define DISPC_GFX_PIXEL_INC 0x00B0 > +#define DISPC_CONTROL 0x0040 > + > +#define SMS_ROT0_PHYSICAL_BA(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + > 0x188 \ > + + 0x10 * context) > +#define SMS_ROT_CONTROL(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + > 0x180 \ > + + 0x10 * context) > +#define SMS_ROT0_SIZE(context) OMAP2_IO_ADDRESS(OMAP_SMS_BASE + > 0x184 \ > + + 0x10 * context) > extern void omap_dispc_set_lcd_size(int width, int height); > > extern void omap_dispc_enable_lcd_out(int enable); > diff --git a/drivers/video/omap/omapfb_main.c > b/drivers/video/omap/omapfb_main.c > index d176a2c..8f2746c 100644 > --- a/drivers/video/omap/omapfb_main.c > +++ b/drivers/video/omap/omapfb_main.c > @@ -35,7 +35,8 @@ > #include "dispc.h" > > #define MODULE_NAME "omapfb" > - > +int omapfb_dispc_rotation = -1; > +#define ROT_LINE_LENGTH 2048 > static unsigned int def_accel; > static unsigned long def_vram[OMAPFB_PLANE_NUM]; > static unsigned int def_vram_cnt; > @@ -219,9 +220,11 @@ static int ctrl_change_mode(struct fb_info *fbi) > if (r < 0) > return r; > > - if (fbdev->ctrl->set_rotate != NULL) > - if((r = fbdev->ctrl->set_rotate(var->rotate)) < 0) > + if (fbdev->ctrl->set_rotate != NULL) { > + r = fbdev->ctrl->set_rotate(0, var->rotate); > + if (r < 0) > return r; > + } > > if ((fbdev->ctrl->set_scale != NULL) && (plane->idx > 0)) > r = fbdev->ctrl->set_scale(plane->idx, > @@ -425,7 +428,10 @@ static void set_fb_fix(struct fb_info *fbi) > break; > } > fix->accel = FB_ACCEL_OMAP1610; > - fix->line_length = var->xres_virtual * bpp / 8; > + if (omapfb_dispc_rotation) > + fix->line_length = ROT_LINE_LENGTH * bpp / 8; > + else if (!omapfb_dispc_rotation) > + fix->line_length = var->xres_virtual * bpp / 8; > } > > static int set_color_mode(struct omapfb_plane_struct *plane, > @@ -497,14 +503,13 @@ static int set_fb_var(struct fb_info *fbi, > bpp = var->bits_per_pixel; > if (plane->color_mode == OMAPFB_COLOR_RGB444) > bpp = 16; > - > + xres_min = OMAPFB_PLANE_XRES_MIN; > + xres_max = panel->x_res; > + yres_min = OMAPFB_PLANE_YRES_MIN; > + yres_max = panel->y_res; > switch (var->rotate) { > case 0: > case 180: > - xres_min = OMAPFB_PLANE_XRES_MIN; > - xres_max = panel->x_res; > - yres_min = OMAPFB_PLANE_YRES_MIN; > - yres_max = panel->y_res; > if (cpu_is_omap15xx()) { > var->xres = panel->x_res; > var->yres = panel->y_res; > @@ -512,10 +517,6 @@ static int set_fb_var(struct fb_info *fbi, > break; > case 90: > case 270: > - xres_min = OMAPFB_PLANE_YRES_MIN; > - xres_max = panel->y_res; > - yres_min = OMAPFB_PLANE_XRES_MIN; > - yres_max = panel->x_res; > if (cpu_is_omap15xx()) { > var->xres = panel->y_res; > var->yres = panel->x_res; > @@ -1718,7 +1719,11 @@ static int omapfb_do_probe(struct platform_device > *pdev, > > pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); > > - def_vxres = def_vxres ? : fbdev->panel->x_res; > + if (omapfb_dispc_rotation) > + def_vxres = ROT_LINE_LENGTH; > + else if (!omapfb_dispc_rotation) > + def_vxres = def_vxres ? : fbdev->panel->x_res; > + > def_vyres = def_vyres ? : fbdev->panel->y_res; > > init_state++; > @@ -1909,8 +1914,10 @@ static int __init omapfb_setup(char *options) > def_vxres = simple_strtoul(this_opt + 6, NULL, 0); > else if (!strncmp(this_opt, "vyres:", 6)) > def_vyres = simple_strtoul(this_opt + 6, NULL, 0); > - else if (!strncmp(this_opt, "rotate:", 7)) > + else if (!strncmp(this_opt, "rotate=", 7)) { > + omapfb_dispc_rotation = 1; > def_rotate = (simple_strtoul(this_opt + 7, NULL, > 0)); > + } > else if (!strncmp(this_opt, "mirror:", 7)) > def_mirror = (simple_strtoul(this_opt + 7, NULL, > 0)); > else if (!strncmp(this_opt, "manual_update", 13)) > -- > 1.5.3.2 > > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-10-06 5:43 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-09-12 12:00 omap-sdp3430_Rotation patch rajesh k 2008-09-12 12:26 ` Felipe Balbi 2008-09-15 9:48 ` arun c 2008-09-16 4:41 ` K, Rajesh 2008-09-16 5:10 ` arun c 2008-09-16 7:41 ` Russell King - ARM Linux 2008-09-17 15:43 ` [PATCH] " nskamat 2008-09-18 5:29 ` arun c 2008-09-18 8:50 ` Russell King - ARM Linux 2008-10-06 4:24 ` Rajesh 2008-10-06 5:43 ` arun c
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox