All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jaya Kumar <jayakumar.lkml@gmail.com>
To: ymiao3@marvell.com
Cc: Jaya Kumar <jayakumar.lkml@gmail.com>,
	linux-fbdev-devel@lists.sourceforge.net,
	linux-arm-kernel@lists.arm.linux.org.uk
Subject: [RFC 2.6.26-rc9 1/5] pxafb: add shared framebuffer interface
Date: Sat, 26 Jul 2008 00:32:50 -0400	[thread overview]
Message-ID: <1217046774-13080-2-git-send-email-jayakumar.lkml@gmail.com> (raw)
In-Reply-To: <1217046774-13080-1-git-send-email-jayakumar.lkml@gmail.com>

These changes are to make it possible for a secondary driver to share the
pxafb framebuffer. The changes include:
- adding custom_lccr_bpp entry so that a driver can set a specific
  transfer width on the AMLCD bus while using a separate bits per pixel for
  its actual framebuffer.
- adding extra_video_mem entry so that a driver can tell pxafb of its
  additional needs.
- adding share_video_mem/unshare_video_mem callbacks to notify the secondary
  driver of the framebuffer address, to allow refcounting, and to cleanup on
  completion.

Signed-off-by: Jaya Kumar <jayakumar.lkml@gmail.com>
---
 drivers/video/pxafb.c            |   65 +++++++++++++++++++++++++++++++++-----
 include/asm-arm/arch-pxa/pxafb.h |    8 +++++
 2 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index bb25143..54e0ad1 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -57,6 +57,8 @@
  */
 #define DEBUG_VAR 1
 
+static struct platform_driver pxafb_driver;
+
 #include "pxafb.h"
 
 /* Bits which should not be set in machine configuration structures */
@@ -218,9 +220,25 @@ pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
  *  pxafb_bpp_to_lccr3():
  *    Convert a bits per pixel value to the correct bit pattern for LCCR3
  */
-static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var)
+static int pxafb_bpp_to_lccr3(struct fb_var_screeninfo *var,
+				struct pxafb_mach_info *inf)
 {
 	int ret = 0;
+
+	/* this is to support devices that have customized
+	 * bpp settings for LCCR that are independent from
+	 * the actual bpp used in the framebuffer.
+	 */
+	if (inf->custom_lccr_bpp) {
+		switch (inf->custom_lccr_bpp) {
+		case 1:  ret = LCCR3_1BPP; break;
+		case 2:  ret = LCCR3_2BPP; break;
+		case 4:  ret = LCCR3_4BPP; break;
+		case 8:  ret = LCCR3_8BPP; break;
+		case 16: ret = LCCR3_16BPP; break;
+		}
+		return ret;
+	}
 	switch (var->bits_per_pixel) {
 	case 1:  ret = LCCR3_1BPP; break;
 	case 2:  ret = LCCR3_2BPP; break;
@@ -826,10 +844,22 @@ int pxafb_smart_flush(struct fb_info *info)
 static void setup_parallel_timing(struct pxafb_info *fbi,
 				  struct fb_var_screeninfo *var)
 {
+	struct pxafb_mach_info *inf = fbi->dev->platform_data;
 	unsigned int lines_per_panel, pcd = get_pcd(fbi, var->pixclock);
+	unsigned int pix_per_line = var->xres;
+
+	/*
+	 * We can have a device that needs a different width for its AMLCD
+	 * transfers than its framebuffer's bits per pixel. So we need to
+	 * divide down the x resolution. Eg: 800 pixels at 8bpp is the fb.
+	 * The device uses 16-bit xfers so the desired result is:
+	 * 800 pixels / ( 16 bit xfer / 8bpp ) = 400 pixels per line
+	 */
+	if (inf->custom_lccr_bpp)
+		pix_per_line /= (inf->custom_lccr_bpp / var->bits_per_pixel);
 
 	fbi->reg_lccr1 =
-		LCCR1_DisWdth(var->xres) +
+		LCCR1_DisWdth(pix_per_line) +
 		LCCR1_HorSnchWdth(var->hsync_len) +
 		LCCR1_BegLnDel(var->left_margin) +
 		LCCR1_EndLnDel(var->right_margin);
@@ -870,6 +900,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
 {
 	u_long flags;
 	size_t nbytes;
+	struct pxafb_mach_info *inf = fbi->dev->platform_data;
 
 #if DEBUG_VAR
 	if (!(fbi->lccr0 & LCCR0_LCDT)) {
@@ -928,7 +959,7 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
 		(LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM |
 		 LCCR0_QDM | LCCR0_BM  | LCCR0_OUM);
 
-	fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);
+	fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var, inf);
 
 	nbytes = var->yres * fbi->fb.fix.line_length;
 
@@ -1304,14 +1335,17 @@ static int pxafb_resume(struct platform_device *dev)
  *      cache.  Once this area is remapped, all virtual memory
  *      access to the video memory should occur at the new region.
  */
-static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi)
+static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi,
+						struct pxafb_mach_info *inf)
 {
+	int ret;
 	/*
 	 * We reserve one page for the palette, plus the size
 	 * of the framebuffer.
 	 */
 	fbi->video_offset = PAGE_ALIGN(sizeof(struct pxafb_dma_buff));
-	fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + fbi->video_offset);
+	fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + fbi->video_offset +
+					inf->extra_video_mem);
 	fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
 					      &fbi->map_dma, GFP_KERNEL);
 
@@ -1340,6 +1374,13 @@ static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi)
 		fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff;
 		fbi->n_smart_cmds = 0;
 #endif
+		if (inf->share_video_mem) {
+			ret = inf->share_video_mem(fbi->fb.screen_base,
+				fbi->screen_dma, pxafb_driver.driver.owner,
+				inf->extra_data);
+			if (ret)
+				return ret;
+		}
 	}
 
 	return fbi->map_cpu ? 0 : -ENOMEM;
@@ -1761,10 +1802,12 @@ static int __devinit pxafb_probe(struct platform_device *dev)
 	}
 
 	/* Initialize video memory */
-	ret = pxafb_map_video_memory(fbi);
-	if (ret) {
+	ret = pxafb_map_video_memory(fbi, inf);
+	if (ret == -ENODEV) {
+		dev_err(&dev->dev, "Failed device binding: %d\n", ret);
+		goto failed_free_mem;
+	} else if (ret) {
 		dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret);
-		ret = -ENOMEM;
 		goto failed_free_io;
 	}
 
@@ -1836,6 +1879,8 @@ failed_free_cmap:
 failed_free_irq:
 	free_irq(irq, fbi);
 failed_free_mem:
+	if (inf->unshare_video_mem)
+		inf->unshare_video_mem(inf->extra_data);
 	dma_free_writecombine(&dev->dev, fbi->map_size,
 			fbi->map_cpu, fbi->map_dma);
 failed_free_io:
@@ -1856,6 +1901,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
 	struct resource *r;
 	int irq;
 	struct fb_info *info;
+	struct pxafb_mach_info *inf;
 
 	if (!fbi)
 		return 0;
@@ -1872,6 +1918,9 @@ static int __devexit pxafb_remove(struct platform_device *dev)
 	irq = platform_get_irq(dev, 0);
 	free_irq(irq, fbi);
 
+	inf = dev->dev.platform_data;
+	if (inf->unshare_video_mem)
+		inf->unshare_video_mem(inf->extra_data);
 	dma_free_writecombine(&dev->dev, fbi->map_size,
 					fbi->map_cpu, fbi->map_dma);
 
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index daf018d..c8c3e84 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -139,9 +139,17 @@ struct pxafb_mach_info {
 	 * All other bits in LCCR4 should be left alone.
 	 */
 	u_int		lccr4;
+	unsigned int	custom_lccr_bpp; /* custom bpp setting */
+	/* size of extra mem needed for secondary driver */
+	unsigned int	extra_video_mem;
+	void		*extra_data; /* extra data for secondary */
 	void (*pxafb_backlight_power)(int);
 	void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
 	void (*smart_update)(struct fb_info *);
+	/* share_video_mem allows client drivers to get our framebuffer */
+	int (*share_video_mem)(char __iomem *, dma_addr_t, struct module *,
+				void *);
+	void (*unshare_video_mem)(void *);
 };
 void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
 void set_pxa_fb_parent(struct device *parent_dev);
-- 
1.5.3.6


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

  reply	other threads:[~2008-07-26  5:29 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-26  4:32 [RFC 2.6.26-rc9 0/5] am200epd, pxafb, metronomefb changes v7 Jaya Kumar
2008-07-26  4:32 ` Jaya Kumar [this message]
2008-07-29 15:28   ` [RFC 2.6.26-rc9 1/5] pxafb: add shared framebuffer interface Krzysztof Helt
2008-07-29 16:39     ` Jaya Kumar
2008-07-26  4:32 ` [RFC 2.6.26-rc9 2/5] gumstix: conversion to MFP support and add bluetooth support Jaya Kumar
2008-07-26  4:32 ` [RFC 2.6.26-rc9 3/5] am200epd: convert to shared fb and use gpio api Jaya Kumar
2008-07-30  2:45   ` Eric Miao
2008-07-26  4:32 ` [RFC 2.6.26-rc9 4/5] metronomefb: convert printk to dev_dbg/err messages Jaya Kumar
2008-07-30  2:50   ` Eric Miao
2008-07-30  3:18     ` Jaya Kumar
2008-07-26  4:32 ` [RFC 2.6.26-rc9 5/5] metronomefb: changes to use separate framebuffer Jaya Kumar
  -- strict thread matches above, loose matches on Subject: below --
2008-07-20  6:10 [RFC 2.6.26-rc9 0/5] am200epd, pxafb, metronomefb changes v6 Jaya Kumar
2008-07-20  6:10 ` [RFC 2.6.26-rc9 1/5] pxafb: add shared framebuffer interface Jaya Kumar
2008-07-21 11:11   ` Russell King - ARM Linux
2008-07-21 12:32     ` Jaya Kumar
2008-07-26  3:30       ` Jaya Kumar
2008-07-30  2:41         ` Eric Miao
2008-07-30  3:10           ` Jaya Kumar
2008-07-13 13:26 [RFC 2.6.26-rc9 0/5] am200epd, pxafb, metronomefb changes v5 Jaya Kumar
2008-07-13 13:26 ` [RFC 2.6.26-rc9 1/5] pxafb: add shared framebuffer interface Jaya Kumar
2008-07-16  7:00   ` eric miao
2008-07-16  8:59     ` Jaya Kumar
2008-07-16  9:08       ` eric miao
2008-07-16 11:10         ` Jaya Kumar
2008-07-16  9:38       ` Russell King - ARM Linux
2008-07-16 11:18         ` Jaya Kumar
2008-07-20  2:41           ` Jaya Kumar
2008-07-21  2:10             ` eric miao
2008-07-21  3:38               ` Jaya Kumar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1217046774-13080-2-git-send-email-jayakumar.lkml@gmail.com \
    --to=jayakumar.lkml@gmail.com \
    --cc=linux-arm-kernel@lists.arm.linux.org.uk \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    --cc=ymiao3@marvell.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.