Re: [PATCH] This patch adds VRFB based rotation support to omapfb

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

 




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

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

  Powered by Linux