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-rc3 2/5] pxafb: add shared framebuffer interface
Date: Fri, 30 May 2008 08:28:47 -0400 [thread overview]
Message-ID: <1212150530-14941-3-git-send-email-jayakumar.lkml@gmail.com> (raw)
In-Reply-To: <1212150530-14941-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 clkdev entry in pxafb_mach_info so that a driver can pass in the
correct struct device owner for the LCDCLK.
- adding custom_xfer_div entry so that a driver can have custom sized
transfers. For example, the metronome controller uses 16 bit AMLCD
transfers but actually has 3 bit pixels in 8 bit containers.
- 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>
---
arch/arm/mach-pxa/devices.c | 2 +
drivers/video/pxafb.c | 46 ++++++++++++++++++++++++++++++++-----
include/asm-arm/arch-pxa/pxafb.h | 9 +++++++
3 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index d6c05b6..b72b73a 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -130,6 +130,8 @@ struct platform_device pxa_device_fb = {
void __init set_pxa_fb_info(struct pxafb_mach_info *info)
{
+ if (!info->clkdev)
+ info->clkdev = &pxa_device_fb.dev;
pxa_register_device(&pxa_device_fb, info);
}
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index a4bb733..2a574ad 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 */
@@ -775,10 +777,15 @@ 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;
+
+ if (inf->custom_xfer_div)
+ pix_per_line /= inf->custom_xfer_div;
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);
@@ -819,6 +826,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)) {
@@ -878,6 +886,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
fbi->reg_lccr3 |= pxafb_bpp_to_lccr3(var);
nbytes = var->yres * fbi->fb.fix.line_length;
+ if (inf->custom_xfer_div)
+ nbytes /= inf->custom_xfer_div;
if ((fbi->lccr0 & LCCR0_SDS) == LCCR0_Dual) {
nbytes = nbytes / 2;
@@ -1246,14 +1256,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);
@@ -1280,6 +1293,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;
@@ -1290,6 +1310,7 @@ static void pxafb_decode_mode_info(struct pxafb_info *fbi,
unsigned int num_modes)
{
unsigned int i, smemlen;
+ struct pxafb_mach_info *inf = fbi->dev->platform_data;
pxafb_setmode(&fbi->fb.var, &modes[0]);
@@ -1297,6 +1318,8 @@ static void pxafb_decode_mode_info(struct pxafb_info *fbi,
smemlen = modes[i].xres * modes[i].yres * modes[i].bpp / 8;
if (smemlen > fbi->fb.fix.smem_len)
fbi->fb.fix.smem_len = smemlen;
+ if (inf->custom_xfer_div)
+ smemlen /= inf->custom_xfer_div;
}
}
@@ -1360,7 +1383,7 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
memset(fbi, 0, sizeof(struct pxafb_info));
fbi->dev = dev;
- fbi->clk = clk_get(dev, "LCDCLK");
+ fbi->clk = clk_get(inf->clkdev, "LCDCLK");
if (IS_ERR(fbi->clk)) {
kfree(fbi);
return NULL;
@@ -1701,8 +1724,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);
+ ret = -ENODEV;
+ 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;
@@ -1770,6 +1797,8 @@ failed_free_io:
failed_free_mem:
dma_free_writecombine(&dev->dev, fbi->map_size,
fbi->map_cpu, fbi->map_dma);
+ if (inf->unshare_video_mem)
+ inf->unshare_video_mem(inf->extra_data);
failed:
platform_set_drvdata(dev, NULL);
kfree(fbi);
@@ -1783,6 +1812,7 @@ static int __devexit pxafb_remove(struct platform_device *dev)
int irq;
if (fbi) {
+ struct pxafb_mach_info *inf;
struct fb_info *info = &fbi->fb;
irq = platform_get_irq(dev, 0);
@@ -1792,7 +1822,9 @@ static int __devexit pxafb_remove(struct platform_device *dev)
release_mem_region(r->start, r->end - r->start + 1);
iounmap(fbi->mmio_base);
-
+ 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);
fb_dealloc_cmap(&info->cmap);
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index bbd2239..c703633 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -138,9 +138,18 @@ struct pxafb_mach_info {
* All other bits in LCCR4 should be left alone.
*/
u_int lccr4;
+ unsigned int custom_xfer_div; /* divides the pixel transfer */
+ /* 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)(unsigned char *, dma_addr_t, struct module *,
+ void *);
+ void (*unshare_video_mem)(void *);
+ struct device *clkdev;
};
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: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
next prev parent reply other threads:[~2008-05-30 13:26 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-30 12:28 [RFC 2.6.26-rc3 0/5] am200epd, pxafb, metronomefb changes Jaya Kumar
2008-05-30 12:28 ` [RFC 2.6.26-rc3 1/5] pxafb: module unloading support Jaya Kumar
2008-05-30 17:04 ` Krzysztof Helt
2008-05-31 1:02 ` Jaya Kumar
2008-05-30 12:28 ` Jaya Kumar [this message]
2008-05-30 17:10 ` [RFC 2.6.26-rc3 2/5] pxafb: add shared framebuffer interface Krzysztof Helt
2008-05-31 0:49 ` Jaya Kumar
2008-05-30 12:28 ` [RFC 2.6.26-rc3 3/5] gumstix: conversion to MFP support and add bluetooth support Jaya Kumar
2008-05-30 12:28 ` [RFC 2.6.26-rc3 4/5] am200epd: remove am200epd platform device driver Jaya Kumar
2008-05-30 12:28 ` [RFC 2.6.26-rc3 5/5] am200epd: add mach-pxa support for am200epd Jaya Kumar
-- strict thread matches above, loose matches on Subject: below --
2008-05-31 4:41 [RFC 2.6.26-rc3 0/5] am200epd, pxafb, metronomefb changes v2 Jaya Kumar
2008-05-31 4:41 ` [RFC 2.6.26-rc3 2/5] pxafb: add shared framebuffer interface 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=1212150530-14941-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).