On Mon, 21 Apr 2008 15:40:02 +0530, "arun c" <arunedarath@xxxxxxxxxxxxxxxxxxxx> wrote: > Hi all, > > I am resending the patch with changes as suggested by felipe balbi > > I also have attached the patch with this mail.( because i think my email > program > introduces some unnecessary formatting stuff into patch) Just a tip in this case: $ git send-email --from "arun <arunedarath@xxxxxxxxxxxxxxxxxxxx>" \ --to linux-omap@xxxxxxxxxxxxxxx <patchfile> If you have a series you can put it into one directory and issue: $ git send-email --from "arun <arunedarath@xxxxxxxxxxxxxxxxxxxx>" \ --to linux-omap@xxxxxxxxxxxxxxx <directory> > > ######################################## > > From 8d3405d3388bb8daef285ba1adf5f582e27dab91 Mon Sep 17 00:00:00 2001 > From: arun <arunedarath@xxxxxxxxxxxxxxxxxxxx> > Date: Mon, 21 Apr 2008 14:49:29 +0530 > Subject: [PATCH] This patch adds VRFB based rotation support to omapfb > > The features are: > > a) Processor and applications writes to VRFB0 space and the display > controller reads from different VRFB space according to degree of > rotation. > > b) Pass video=omapfb:rotate:<degree> to see the penguin rotate. > > c) Clean up code is not implemented as of now(like unmapping the VRFB > regions) Your missing a Signed-off-by here, could you please and answer to the patch and add such a line ? > --- > drivers/video/omap/dispc.c | 205 > ++++++++++++++++++++++++++++++++++++++ > drivers/video/omap/omapfb_main.c | 23 +++-- > 2 files changed, 220 insertions(+), 8 deletions(-) > > diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c > index 4c055a2..f7d4acd 100644 > --- a/drivers/video/omap/dispc.c > +++ b/drivers/video/omap/dispc.c > @@ -148,6 +148,43 @@ > #define RESMAP_MASK(_page_nr) \ > (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1))) > > +/* Rotation using VRFB */ > +#define ROTATION_TEST 1 > +#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 OMAP_SMS_BASE (0x6C000000) > +#define SMS_ROT0_PHYSICAL_BA(context) __REG32(OMAP_SMS_BASE + 0x188 \ > + + 0x10 * context) > +#define SMS_ROT_CONTROL(context) __REG32(OMAP_SMS_BASE + 0x180 \ > + + 0x10 * context) > +#define SMS_ROT0_SIZE(context) __REG32(OMAP_SMS_BASE + 0x184 \ > + + 0x10 * context) > + > +dma_addr_t save_paddr; > +unsigned long save_vaddr; > +unsigned long save_offset; > +int vrfb_rotation; > + > +static struct { > + dma_addr_t paddr[4]; > + unsigned long vaddr[4]; > + u32 xoffset; > + u32 yoffset; > +} vrfb; > + > +static int omap2_disp_set_vrfb(u32 width, u32 height, u32 > bytes_per_pixel); > + > struct resmap { > unsigned long start; > unsigned page_cnt; > @@ -449,6 +486,7 @@ static int omap_dispc_setup_plane(int plane, int > channel_out, > > if ((unsigned)plane > dispc.mem_desc.region_cnt) > return -EINVAL; > + save_offset = offset; > paddr = dispc.mem_desc.region[plane].paddr + offset; > enable_lcd_clocks(1); > r = _setup_plane(plane, channel_out, paddr, > @@ -458,6 +496,111 @@ static int omap_dispc_setup_plane(int plane, int > channel_out, > return r; > } > > +static inline u32 > +calc_vrfb_div(u32 img_side, u32 page_exp) > +{ > + u32 div; > + div = img_side / page_exp; > + if ((div * page_exp) < img_side) > + return div + 1; > + else > + return div; > +} > + > +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; > + int div; > + u32 vrfb_width; > + u32 vrfb_height; > + > + page_width_exp = PAGE_WIDTH_EXP; > + page_height_exp = PAGE_HEIGHT_EXP; > + pixel_size_exp = bytes_per_pixel >> 1; > + > + div = calc_vrfb_div(width * bytes_per_pixel, 1 << page_width_exp); > + vrfb_width = (div * (1 << page_width_exp)) / bytes_per_pixel; > + > + div = calc_vrfb_div(height, 1 << page_height_exp); > + vrfb_height = div * (1 << page_height_exp); > + > + SMS_ROT0_PHYSICAL_BA(context) = save_paddr; > + SMS_ROT0_SIZE(context) = 0; > + SMS_ROT0_SIZE(context) |= (vrfb_width << SMS_IMAGEWIDTH_OFFSET) > + | (vrfb_height << SMS_IMAGEHEIGHT_OFFSET); > + SMS_ROT_CONTROL(context) = 0; > + SMS_ROT_CONTROL(context) |= pixel_size_exp << SMS_PS_OFFSET > + | page_width_exp << SMS_PW_OFFSET > + | page_height_exp << SMS_PH_OFFSET; > + > + vrfb.xoffset = vrfb_width - width; > + vrfb.yoffset = vrfb_height - height; > + return 0; > +} > + > +static int omap_dispc_set_rotate(int angle) > +{ > + const u32 ba_reg[] = { DISPC_GFX_BA0 }; > + const u32 ri_reg[] = { DISPC_GFX_ROW_INC }; > + const u32 pi_reg[] = { DISPC_GFX_PIXEL_INC }; > + int width, height; > + u32 addr_base; > + u32 Bpp; > + > + if (vrfb_rotation != 1) > + return 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; > + > + enable_lcd_clocks(1); > + > + switch (angle) { > + case 0: > + omap2_disp_set_vrfb(width, height, Bpp); > + addr_base = SMS_ROT_VIRT_BASE(0, 0) + save_offset; > + dispc_write_reg(ba_reg[0], addr_base); > + dispc_write_reg(pi_reg[0], 1); > + dispc_write_reg(ri_reg[0], (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 90: > + omap2_disp_set_vrfb(height, width, Bpp); > + addr_base = SMS_ROT_VIRT_BASE(0, 90) + save_offset > + + vrfb.yoffset * Bpp; > + > + dispc_write_reg(ba_reg[0], addr_base); > + dispc_write_reg(pi_reg[0], 1); > + dispc_write_reg(ri_reg[0], (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 180: > + omap2_disp_set_vrfb(width, height, Bpp); > + addr_base = SMS_ROT_VIRT_BASE(0, 180) + save_offset > + + vrfb.xoffset * Bpp > + + ROT_LINE_LENGTH * vrfb.yoffset * Bpp; > + > + dispc_write_reg(ba_reg[0], addr_base); > + dispc_write_reg(pi_reg[0], 1); > + dispc_write_reg(ri_reg[0], (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + case 270: > + omap2_disp_set_vrfb(height, width, Bpp); > + addr_base = SMS_ROT_VIRT_BASE(0, 270) + save_offset > + + ROT_LINE_LENGTH * vrfb.xoffset * Bpp; > + > + dispc_write_reg(ba_reg[0], addr_base); > + dispc_write_reg(pi_reg[0], 1); > + dispc_write_reg(ri_reg[0], (ROT_LINE_LENGTH - width) * Bpp + 1); > + break; > + } > + > + MOD_REG_FLD(DISPC_CONTROL, 0x20, 0); /* Sets & clears the GOLCD bit */ > + 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; > @@ -1422,9 +1565,70 @@ static int omap_dispc_init(struct omapfb_device > *fbdev, int ext_mode, > if ((r = alloc_palette_ram()) < 0) > goto fail2; > > +#ifdef ROTATION_TEST > + memset(&vrfb, 0, sizeof(vrfb)); > + vrfb_rotation = 1; > + 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"); > + vrfb_rotation++; > + } > + > + if (!request_mem_region(vrfb.paddr[1], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB90 area\n"); > + vrfb_rotation++; > + } > + > + if (!request_mem_region(vrfb.paddr[2], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB180 area\n"); > + vrfb_rotation++; > + } > + > + if (!request_mem_region(vrfb.paddr[3], > + req_vram->region[0].size, "omapfb")) { > + printk(KERN_ERR "omapfb: can't reserve VRFB270 area\n"); > + vrfb_rotation++; > + } > + > + 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"); > + vrfb_rotation++; > + } > +#endif > + > if ((r = setup_fbmem(req_vram)) < 0) > goto fail3; > > + if (vrfb_rotation == 1) { > + save_paddr = dispc.mem_desc.region[0].paddr; > + save_vaddr = (unsigned long)dispc.mem_desc.region[0].vaddr; > + > + dispc.mem_desc.region[0].vaddr = (void *)vrfb.vaddr[0]; > + dispc.mem_desc.region[0].paddr = vrfb.paddr[0]; > + dispc.fbdev->mem_desc.region[0].vaddr = > + (void *)vrfb.vaddr[0]; > + > + dispc.fbdev->mem_desc.region[0].paddr = vrfb.paddr[0]; > + omap2_disp_set_vrfb(panel->x_res, panel->y_res, > + panel->bpp / 8); > + } > + > if (!skip_init) { > for (i = 0; i < dispc.mem_desc.region_cnt; i++) { > memset(dispc.mem_desc.region[i].vaddr, 0, > @@ -1503,4 +1707,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/omapfb_main.c > b/drivers/video/omap/omapfb_main.c > index 418ed9f..2a9500b 100644 > --- a/drivers/video/omap/omapfb_main.c > +++ b/drivers/video/omap/omapfb_main.c > @@ -32,6 +32,8 @@ > #include <asm/arch/omapfb.h> > > #define MODULE_NAME "omapfb" > +#define ROTATION_TEST 1 > +#define ROT_LINE_LENGTH 2048 > > static unsigned int def_accel; > static unsigned long def_vram[OMAPFB_PLANE_NUM]; > @@ -422,7 +424,11 @@ static void set_fb_fix(struct fb_info *fbi) > break; > } > fix->accel = FB_ACCEL_OMAP1610; > +#ifdef ROTATION_TEST > + fix->line_length = ROT_LINE_LENGTH * bpp / 8; > +#else > fix->line_length = var->xres_virtual * bpp / 8; > +#endif > } > > static int set_color_mode(struct omapfb_plane_struct *plane, > @@ -495,13 +501,14 @@ static int set_fb_var(struct fb_info *fbi, > 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; > @@ -509,10 +516,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; > @@ -1715,7 +1718,11 @@ static int omapfb_do_probe(struct platform_device > *pdev, > > pr_info("omapfb: configured for panel %s\n", fbdev->panel->name); > > +#ifdef ROTATION_TEST > + def_vxres = ROT_LINE_LENGTH; > +#else > def_vxres = def_vxres ? : fbdev->panel->x_res; > +#endif > def_vyres = def_vyres ? : fbdev->panel->y_res; > > init_state++; > -- > 1.5.3.4 > > > > Regards, > Arun c -- Best Regards, Felipe Balbi http://felipebalbi.com me@xxxxxxxxxxxxxxx -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html