All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] video: add PXA3xx accelerator ID
       [not found]             ` <4A63E08F.4090409@gmail.com>
@ 2009-07-20 10:14               ` Daniel Mack
       [not found]               ` <20090720102239.GA3809@buzzloop.caiaq.de>
  1 sibling, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2009-07-20 10:14 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Daniel Mack, Eric Miao, linux-fbdev-devel, Dennis Oliver Kropp,
	Sven Neumann

Add ID 99 for PXA3xx frame buffers and use it in pxafb when running on a
pxa with acceleration enabled.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Eric Miao <eric.miao@marvell.com>
Cc: linux-fbdev-devel@lists.sourceforge.net
Cc: Dennis Oliver Kropp <dok@directfb.org>
Cc: Sven Neumann <s.neumann@raumfeld.com>
---
 drivers/video/pxafb.c |    5 +++++
 include/linux/fb.h    |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 3951cc5..922ed8a 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -2083,6 +2083,11 @@ static int __devinit pxafb_probe(struct platform_device *dev)
 		goto failed;
 	}
 
+#ifdef CONFIG_PXA3XX_GCU
+	if (cpu_is_pxa3xx())
+		fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
+#endif
+
 	fbi->backlight_power = inf->pxafb_backlight_power;
 	fbi->lcd_power = inf->pxafb_lcd_power;
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f847df9..a34bdf5 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -133,6 +133,7 @@ struct dentry;
 #define FB_ACCEL_NEOMAGIC_NM2230 96	/* NeoMagic NM2230              */
 #define FB_ACCEL_NEOMAGIC_NM2360 97	/* NeoMagic NM2360              */
 #define FB_ACCEL_NEOMAGIC_NM2380 98	/* NeoMagic NM2380              */
+#define FB_ACCEL_PXA3XX		 99	/* PXA3xx			*/
 
 #define FB_ACCEL_SAVAGE4        0x80	/* S3 Savage4                   */
 #define FB_ACCEL_SAVAGE3D       0x81	/* S3 Savage3D                  */
-- 
1.6.3.1


-------------------------------------------------------------------
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel
FAQ:        http://www.arm.linux.org.uk/mailinglists/faq.php
Etiquette:  http://www.arm.linux.org.uk/mailinglists/etiquette.php

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 4/4] video: add driver for PXA3xx 2D graphics accelerator
       [not found]                       ` <20090722120433.GA9464@buzzloop.caiaq.de>
@ 2009-09-02 21:24                           ` Daniel Mack
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2009-09-02 21:24 UTC (permalink / raw)
  To: Krzysztof Helt
  Cc: Sven Neumann, linux-fbdev-devel, dok, linux-arm-kernel, Eric Miao

On Wed, Jul 22, 2009 at 02:04:33PM +0200, Daniel Mack wrote:
> On Mon, Jul 20, 2009 at 10:45:35PM +0800, Eric Miao wrote:
> > Daniel Mack wrote:
> > >> Cool - I'll find a time slot to test this, and maybe someone else wants to
> > >> have a try either. Thanks.
> > > 
> > > Will that accelerator ID patch (the one I sent today) go thru your
> > > channel or are the fbdev people supposed to pick it?
> > > 
> > 
> > Better to go through fbdev people - or at least I need an Ack before it
> > goes through my tree.
> > 
> > Krzysztof Cc'ed.
> 
> Krzysztof,
> 
> resending this because I don't known whether you got the first copy of
> that patch.

I'm sending this patch for the the forth time now, this time with the
fbdev-devel list copied. Maybe that helps.

This is fairly simple, but it's blocking the pxa3xx-gcu driver to be
merged.

Any feedback is appreciated.

Thanks,
Daniel

From 8b200756251e3dcdc91d506e9dbc9846ccaa91d3 Mon Sep 17 00:00:00 2001
From: Daniel Mack <daniel@caiaq.de>
Date: Mon, 20 Jul 2009 11:18:43 +0200
Subject: [PATCH] video: add PXA3xx accelerator ID

Add ID 99 for PXA3xx frame buffers and use it in pxafb when running on a
pxa with acceleration enabled.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Eric Miao <eric.miao@marvell.com>
Cc: linux-fbdev-devel@lists.sourceforge.net
Cc: Dennis Oliver Kropp <dok@directfb.org>
Cc: Sven Neumann <s.neumann@raumfeld.com>
---
 drivers/video/pxafb.c |    5 +++++
 include/linux/fb.h    |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 3951cc5..922ed8a 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -2083,6 +2083,11 @@ static int __devinit pxafb_probe(struct platform_device *dev)
 		goto failed;
 	}
 
+#ifdef CONFIG_PXA3XX_GCU
+	if (cpu_is_pxa3xx())
+		fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
+#endif
+
 	fbi->backlight_power = inf->pxafb_backlight_power;
 	fbi->lcd_power = inf->pxafb_lcd_power;
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f847df9..a34bdf5 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -133,6 +133,7 @@ struct dentry;
 #define FB_ACCEL_NEOMAGIC_NM2230 96	/* NeoMagic NM2230              */
 #define FB_ACCEL_NEOMAGIC_NM2360 97	/* NeoMagic NM2360              */
 #define FB_ACCEL_NEOMAGIC_NM2380 98	/* NeoMagic NM2380              */
+#define FB_ACCEL_PXA3XX		 99	/* PXA3xx			*/
 
 #define FB_ACCEL_SAVAGE4        0x80	/* S3 Savage4                   */
 #define FB_ACCEL_SAVAGE3D       0x81	/* S3 Savage3D                  */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] video: add driver for PXA3xx 2D graphics accelerator
@ 2009-09-02 21:24                           ` Daniel Mack
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2009-09-02 21:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 22, 2009 at 02:04:33PM +0200, Daniel Mack wrote:
> On Mon, Jul 20, 2009 at 10:45:35PM +0800, Eric Miao wrote:
> > Daniel Mack wrote:
> > >> Cool - I'll find a time slot to test this, and maybe someone else wants to
> > >> have a try either. Thanks.
> > > 
> > > Will that accelerator ID patch (the one I sent today) go thru your
> > > channel or are the fbdev people supposed to pick it?
> > > 
> > 
> > Better to go through fbdev people - or at least I need an Ack before it
> > goes through my tree.
> > 
> > Krzysztof Cc'ed.
> 
> Krzysztof,
> 
> resending this because I don't known whether you got the first copy of
> that patch.

I'm sending this patch for the the forth time now, this time with the
fbdev-devel list copied. Maybe that helps.

This is fairly simple, but it's blocking the pxa3xx-gcu driver to be
merged.

Any feedback is appreciated.

Thanks,
Daniel

>From 8b200756251e3dcdc91d506e9dbc9846ccaa91d3 Mon Sep 17 00:00:00 2001
From: Daniel Mack <daniel@caiaq.de>
Date: Mon, 20 Jul 2009 11:18:43 +0200
Subject: [PATCH] video: add PXA3xx accelerator ID

Add ID 99 for PXA3xx frame buffers and use it in pxafb when running on a
pxa with acceleration enabled.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Cc: Eric Miao <eric.miao@marvell.com>
Cc: linux-fbdev-devel at lists.sourceforge.net
Cc: Dennis Oliver Kropp <dok@directfb.org>
Cc: Sven Neumann <s.neumann@raumfeld.com>
---
 drivers/video/pxafb.c |    5 +++++
 include/linux/fb.h    |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 3951cc5..922ed8a 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -2083,6 +2083,11 @@ static int __devinit pxafb_probe(struct platform_device *dev)
 		goto failed;
 	}
 
+#ifdef CONFIG_PXA3XX_GCU
+	if (cpu_is_pxa3xx())
+		fbi->fb.fix.accel = FB_ACCEL_PXA3XX;
+#endif
+
 	fbi->backlight_power = inf->pxafb_backlight_power;
 	fbi->lcd_power = inf->pxafb_lcd_power;
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f847df9..a34bdf5 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -133,6 +133,7 @@ struct dentry;
 #define FB_ACCEL_NEOMAGIC_NM2230 96	/* NeoMagic NM2230              */
 #define FB_ACCEL_NEOMAGIC_NM2360 97	/* NeoMagic NM2360              */
 #define FB_ACCEL_NEOMAGIC_NM2380 98	/* NeoMagic NM2380              */
+#define FB_ACCEL_PXA3XX		 99	/* PXA3xx			*/
 
 #define FB_ACCEL_SAVAGE4        0x80	/* S3 Savage4                   */
 #define FB_ACCEL_SAVAGE3D       0x81	/* S3 Savage3D                  */
-- 
1.6.3.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 4/4] video: add driver for PXA3xx 2D graphics accelerator
       [not found]       ` <1247159091-28697-5-git-send-email-daniel@caiaq.de>
       [not found]         ` <4A56F02D.1000007@gmail.com>
@ 2010-02-25 16:05         ` Daniel Mack
  2010-04-18  7:46           ` Daniel Mack
  1 sibling, 1 reply; 5+ messages in thread
From: Daniel Mack @ 2010-02-25 16:05 UTC (permalink / raw)
  To: linux-arm-kernel

(now used the new AKML address)

Hi,

Was anyone able to give that driver a try?
Haojian, you wanted to have a look IIRC?

I would appreciate seeing this in .35 if possible.

Daniel


On Thu, Jul 09, 2009 at 07:04:51PM +0200, Daniel Mack wrote:
> This adds a driver for the the 2D graphics accelerator found on PXA3xx
> processors. Only resource mapping, interrupt handling and a simple ioctl
> handler is done by the kernel part, the rest of the logic is implemented
> in DirectFB userspace.
> 
> Graphic applications benefit for line drawing, blend, and rectangle and
> triangle filling operations.
> 
> Measurements on a PXA303 using the df_dok benchmarking tool follow,
> where the value in square brackets show the CPU usage during that test.
> 
> Without accelerator:
> 
>   Fill Rectangle                                 3.007 secs (  175.922 MPixel/sec) [100.3%]
>   Fill Rectangles [10]                           3.178 secs (  182.696 MPixel/sec) [100.0%]
>   Fill Triangles                                 3.023 secs (   99.232 MPixel/sec) [100.3%]
>   Blit                                           3.082 secs (   39.770 MPixel/sec) [100.0%]
>   Blit 180                                       3.115 secs (   28.994 MPixel/sec) [100.3%]
>   Blit with format conversion                    3.078 secs (   18.863 MPixel/sec) [100.0%]
> 
> With accelerator:
> 
>   Fill Rectangle                                 4.377 secs (*  88.433 MPixel/sec) [  5.9%]
>   Fill Rectangles [10]                           5.176 secs (*  87.245 MPixel/sec) [  0.5%]
>   Fill Triangles                                 3.025 secs (   87.437 MPixel/sec) [ 46.6%]
>   Blit                                          12.177 secs (*  22.250 MPixel/sec) [  1.3%]
>   Blit 180                                       8.421 secs (*  32.175 MPixel/sec) [  4.9%]
>   Blit with format conversion                    8.216 secs (*  40.045 MPixel/sec) [  2.5%]
> 
> Signed-off-by: Daniel Mack <daniel@caiaq.de>
> Cc: Denis Oliver Kropp <dok@directfb.org>
> ---
>  drivers/video/Kconfig      |   10 +
>  drivers/video/Makefile     |    1 +
>  drivers/video/pxa3xx-gcu.c |  591 ++++++++++++++++++++++++++++++++++++++++++++
>  drivers/video/pxa3xx-gcu.h |   49 ++++
>  4 files changed, 651 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/video/pxa3xx-gcu.c
>  create mode 100644 drivers/video/pxa3xx-gcu.h
> 
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index 8afcf08..6ad0a1c 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -1817,6 +1817,16 @@ config FB_PXA_PARAMETERS
>  
>  	  <file:Documentation/fb/pxafb.txt> describes the available parameters.
>  
> +config PXA3XX_GCU
> +	tristate "PXA3xx 2D graphics accelerator driver"
> +	depends on FB_PXA
> +	help
> +	  Kernelspace driver for the 2D graphics controller unit (GCU)
> +	  found on PXA3xx processors. There is a counterpart driver in the
> +	  DirectFB suite, see http://www.directfb.org/
> +
> +	  If you compile this as a module, it will be called pxa3xx_gcu.
> +
>  config FB_MBX
>  	tristate "2700G LCD framebuffer support"
>  	depends on FB && ARCH_PXA
> diff --git a/drivers/video/Makefile b/drivers/video/Makefile
> index 01a819f..ffe382c 100644
> --- a/drivers/video/Makefile
> +++ b/drivers/video/Makefile
> @@ -98,6 +98,7 @@ obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o
>  obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o
>  obj-$(CONFIG_FB_PXA)		  += pxafb.o
>  obj-$(CONFIG_FB_PXA168)		  += pxa168fb.o
> +obj-$(CONFIG_PXA3XX_GCU)	  += pxa3xx-gcu.o
>  obj-$(CONFIG_FB_W100)		  += w100fb.o
>  obj-$(CONFIG_FB_TMIO)		  += tmiofb.o
>  obj-$(CONFIG_FB_AU1100)		  += au1100fb.o
> diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
> new file mode 100644
> index 0000000..224faf7
> --- /dev/null
> +++ b/drivers/video/pxa3xx-gcu.c
> @@ -0,0 +1,591 @@
> +/*
> + *  pxa3xx-gc.c - Linux kernel module for PXA3xx graphics controllers
> + *
> + *  This driver needs a DirectFB counterpart in user space, communication
> + *  is handled via mmap()ed memory areas and an ioctl.
> + *
> + *  Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
> + *  Copyright (c) 2009 Janine Kropp <nin@directfb.org>
> + *  Copyright (c) 2009 Denis Oliver Kropp <dok@directfb.org>
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; if not, write to the Free Software
> + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +/*
> + * WARNING: This controller is attached to System Bus 2 of the PXA which
> + * needs its arbiter to be enabled explictly (CKENB & 1<<9).
> + * There is currently no way to do this from Linux, so you need to teach
> + * your bootloader for now.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/version.h>
> +
> +#include <linux/platform_device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/miscdevice.h>
> +#include <linux/interrupt.h>
> +#include <linux/spinlock.h>
> +#include <linux/uaccess.h>
> +#include <linux/ioctl.h>
> +#include <linux/delay.h>
> +#include <linux/sched.h>
> +#include <linux/clk.h>
> +#include <linux/fs.h>
> +#include <linux/io.h>
> +
> +#include "pxa3xx-gcu.h"
> +
> +#define DRV_NAME	"pxa3xx-gcu"
> +#define MISCDEV_MINOR	197
> +
> +#define REG_GCCR	0x00
> +#define GCCR_SYNC_CLR	(1 << 9)
> +#define GCCR_BP_RST	(1 << 8)
> +#define GCCR_ABORT	(1 << 6)
> +#define GCCR_STOP	(1 << 4)
> +
> +#define REG_GCISCR	0x04
> +#define REG_GCIECR	0x08
> +#define REG_GCRBBR	0x20
> +#define REG_GCRBLR	0x24
> +#define REG_GCRBHR	0x28
> +#define REG_GCRBTR	0x2C
> +#define REG_GCRBEXHR	0x30
> +
> +#define IE_EOB		(1 << 0)
> +#define IE_EEOB		(1 << 5)
> +#define IE_ALL		0xff
> +
> +#define SHARED_SIZE	PAGE_ALIGN(sizeof(struct pxa3xx_gcu_shared))
> +
> +/* #define PXA3XX_GCU_DEBUG */
> +/* #define PXA3XX_GCU_DEBUG_TIMER */
> +
> +#ifdef PXA3XX_GCU_DEBUG
> +#define QDUMP(msg)	\
> +	do {						\
> +		QPRINT(priv, KERN_DEBUG, msg);		\
> +	} while (0)
> +#else
> +#define QDUMP(msg)	do {} while (0)
> +#endif
> +
> +#define QERROR(msg)	\
> +	do {						\
> +		QPRINT(priv, KERN_ERR, msg);		\
> +	} while (0)
> +
> +struct pxa3xx_gcu_priv {
> +	void __iomem		*mmio_base;
> +	struct clk		*clk;
> +	struct pxa3xx_gcu_shared	*shared;
> +	dma_addr_t		 shared_phys;
> +	struct resource		*resource_mem;
> +	struct miscdevice	 misc_dev;
> +	struct file_operations	 misc_fops;
> +	wait_queue_head_t	 wait_idle;
> +	wait_queue_head_t	 wait_next;
> +	spinlock_t		 spinlock;
> +	struct timeval 		 base_time;
> +};
> +
> +static inline unsigned long
> +gc_readl(struct pxa3xx_gcu_priv *priv, unsigned int off)
> +{
> +	return __raw_readl(priv->mmio_base + off);
> +}
> +
> +static inline void
> +gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val)
> +{
> +	__raw_writel(val, priv->mmio_base + off);
> +}
> +
> +#define QPRINT(priv, level, msg)					\
> +	do {								\
> +		struct timeval tv;					\
> +		struct pxa3xx_gcu_shared *shared = priv->shared;	\
> +		u32 base = gc_readl(priv, REG_GCRBBR);			\
> +									\
> +		do_gettimeofday(&tv);					\
> +									\
> +		printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, "	\
> +			"hw %5d-%5d, next %5d-%5d, %svalid, STATUS "	\
> +			"0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, "	\
> +			"T %5ld)\n",					\
> +			tv.tv_sec - priv->base_time.tv_sec,		\
> +			tv.tv_usec / 1000, tv.tv_usec % 1000,		\
> +			__func__, msg,					\
> +			shared->hw_running ? "running" : "   idle",	\
> +			shared->hw_start,				\
> +			shared->hw_end,					\
> +			shared->next_start,				\
> +			shared->next_end,				\
> +			shared->next_valid ? "  " : "in",		\
> +			gc_readl(priv, REG_GCISCR),			\
> +			gc_readl(priv, REG_GCRBBR),			\
> +			gc_readl(priv, REG_GCRBLR),			\
> +			(gc_readl(priv, REG_GCRBEXHR) - base) / 4,	\
> +			(gc_readl(priv, REG_GCRBHR) - base) / 4,	\
> +			(gc_readl(priv, REG_GCRBTR) - base) / 4);	\
> +	} while (0)
> +
> +static void pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv)
> +{
> +	QDUMP("RESET");
> +
> +	/* disable interrupts */
> +	gc_writel(priv, REG_GCIECR, 0);
> +
> +	/* reset hardware */
> +	gc_writel(priv, REG_GCCR, GCCR_ABORT);
> +	gc_writel(priv, REG_GCCR, 0);
> +
> +	memset(priv->shared, 0, SHARED_SIZE);
> +	priv->shared->buffer_phys = priv->shared_phys;
> +	priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC;
> +
> +	do_gettimeofday(&priv->base_time);
> +
> +	/* set up the ring buffer pointers */
> +	gc_writel(priv, REG_GCRBLR, 0);
> +	gc_writel(priv, REG_GCRBBR, priv->shared_phys);
> +	gc_writel(priv, REG_GCRBTR, priv->shared_phys);
> +
> +	/* enable all IRQs except EOB */
> +	gc_writel(priv, REG_GCIECR, IE_ALL & ~IE_EOB);
> +}
> +
> +static void pxa3xx_gcu_start(struct pxa3xx_gcu_priv *priv)
> +{
> +	struct pxa3xx_gcu_shared	*sh = priv->shared;
> +
> +	QDUMP("Start");
> +
> +	gc_writel(priv, REG_GCRBLR, 0);
> +
> +	/* ring base address */
> +	gc_writel(priv, REG_GCRBBR, sh->buffer_phys + sh->hw_start * 4);
> +
> +	/* ring tail address */
> +	gc_writel(priv, REG_GCRBTR, sh->buffer_phys + sh->hw_end * 4);
> +
> +	/* ring length */
> +	gc_writel(priv, REG_GCRBLR,
> +		((sh->hw_end - sh->hw_start + 63) & ~63) * 4);
> +}
> +
> +static irqreturn_t pxa3xx_gcu_handle_irq(int irq, void *ctx)
> +{
> +	struct pxa3xx_gcu_priv *priv = ctx;
> +	struct pxa3xx_gcu_shared *shared = priv->shared;
> +	u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL;
> +
> +	if (!status)
> +		return IRQ_NONE;
> +
> +	QDUMP("-Interrupt");
> +
> +	spin_lock(&priv->spinlock);
> +
> +	shared->num_interrupts++;
> +
> +	if (status & IE_EEOB) {
> +		QDUMP(" [EEOB]");
> +
> +		/* next_valid means user space is not in the process of
> +		 * extending the buffer, so we can safely access the
> +		 * contents. */
> +		if (shared->next_valid &&
> +		    shared->next_start != shared->next_end) {
> +			shared->hw_start = shared->next_start;
> +			shared->hw_end = shared->next_end;
> +			shared->next_start = (shared->hw_end + 63) & ~63;
> +			shared->next_end = shared->next_start;
> +			shared->num_words += shared->hw_end - shared->hw_start;
> +			shared->num_starts++;
> +
> +			pxa3xx_gcu_start(priv);
> +
> +			wake_up_all(&priv->wait_next);
> +		} else {
> +			/* There is no more data prepared by the userspace.
> +			 * Set hw_running = 0 and wait for the next userspace
> +			 * kick-off */
> +			shared->num_idle++;
> +			shared->hw_running = 0;
> +
> +			QDUMP(" '-> Idle.");
> +
> +			/* set ring buffer length to zero */
> +			gc_writel(priv, REG_GCRBLR, 0);
> +
> +			wake_up_all(&priv->wait_next);
> +			wake_up_all(&priv->wait_idle);
> +		}
> +
> +		shared->num_done++;
> +	} else
> +		QERROR(" [???]");
> +
> +	/* Clear the interrupt */
> +	gc_writel(priv, REG_GCISCR, status);
> +	spin_unlock(&priv->spinlock);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int
> +pxa3xx_gcu_wait_idle(struct pxa3xx_gcu_priv *priv)
> +{
> +	int ret = 0;
> +
> +	QDUMP("Waiting for idle...");
> +
> +	while (priv->shared->hw_running) {
> +		int num = priv->shared->num_interrupts;
> +		u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);
> +
> +		ret = wait_event_interruptible_timeout(priv->wait_idle,
> +					!priv->shared->hw_running, HZ/4);
> +
> +		if (ret < 0)
> +			break;
> +
> +		if (ret > 0)
> +			continue;
> +
> +		if (gc_readl(priv, REG_GCRBEXHR) == rbexhr &&
> +		    priv->shared->num_interrupts == num) {
> +			QERROR("TIMEOUT");
> +			ret = -ETIMEDOUT;
> +			break;
> +		}
> +	}
> +
> +	QDUMP("done");
> +
> +	return ret;
> +}
> +
> +static int
> +pxa3xx_gcu_wait_next(struct pxa3xx_gcu_priv *priv)
> +{
> +	int ret = 0;
> +	int num = priv->shared->num_interrupts;
> +
> +	QDUMP("Waiting for next...");
> +
> +	while (priv->shared->hw_running &&
> +	       num == priv->shared->num_interrupts) {
> +		u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);
> +
> +		ret = wait_event_interruptible_timeout(priv->wait_next,
> +			(!priv->shared->hw_running ||
> +			 num != priv->shared->num_interrupts), HZ/4);
> +
> +		if (ret < 0)
> +			break;
> +
> +		if (ret > 0)
> +			continue;
> +
> +		if (gc_readl(priv, REG_GCRBEXHR) == rbexhr) {
> +			QERROR("TIMEOUT");
> +			ret = -ETIMEDOUT;
> +			break;
> +		}
> +	}
> +
> +	QDUMP("done");
> +
> +	return ret;
> +}
> +
> +/* Misc device layer */
> +
> +static int
> +pxa3xx_gcu_misc_ioctl(struct inode *inode, struct file *filp,
> +		 unsigned int cmd, unsigned long arg)
> +{
> +	unsigned long flags;
> +	struct pxa3xx_gcu_priv *priv =
> +		container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
> +
> +	switch (cmd) {
> +	case PXA3XX_GCU_IOCTL_RESET:
> +		spin_lock_irqsave(&priv->spinlock, flags);
> +		pxa3xx_gcu_reset(priv);
> +		spin_unlock_irqrestore(&priv->spinlock, flags);
> +		return 0;
> +
> +	case PXA3XX_GCU_IOCTL_START:
> +		spin_lock_irqsave(&priv->spinlock, flags);
> +		pxa3xx_gcu_start(priv);
> +		spin_unlock_irqrestore(&priv->spinlock, flags);
> +		return 0;
> +
> +	case PXA3XX_GCU_IOCTL_WAIT_IDLE:
> +		/* Does not need to be atomic. There's a lock in user space,
> +		 * but anyhow, this is just for statistics. */
> +		priv->shared->num_wait_idle++;
> +		return pxa3xx_gcu_wait_idle(priv);
> +
> +	case PXA3XX_GCU_IOCTL_WAIT_NEXT:
> +		/* Does not need to be atomic. There's a lock in user space,
> +		 * but anyhow, this is just for statistics. */
> +		priv->shared->num_wait_next++;
> +		return pxa3xx_gcu_wait_next(priv);
> +	}
> +
> +	return -ENOSYS;
> +}
> +
> +static int
> +pxa3xx_gcu_misc_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> +	unsigned int size = vma->vm_end - vma->vm_start;
> +	struct pxa3xx_gcu_priv *priv =
> +		container_of(filp->f_op, struct pxa3xx_gcu_priv, misc_fops);
> +
> +	switch (vma->vm_pgoff) {
> +	case 0:
> +		/* hand out the shared data area */
> +		if (size != SHARED_SIZE)
> +			return -EINVAL;
> +
> +		return dma_mmap_coherent(NULL, vma,
> +			priv->shared, priv->shared_phys, size);
> +
> +	case SHARED_SIZE >> PAGE_SHIFT:
> +		/* hand out the MMIO base for direct register access
> +		 * from userspace */
> +		if (size != resource_size(priv->resource_mem))
> +			return -EINVAL;
> +
> +		vma->vm_flags |= VM_IO;
> +		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> +
> +		return io_remap_pfn_range(vma, vma->vm_start,
> +				priv->resource_mem->start >> PAGE_SHIFT,
> +				size, vma->vm_page_prot);
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +
> +#ifdef PXA3XX_GCU_DEBUG_TIMER
> +static struct timer_list pxa3xx_gcu_debug_timer;
> +
> +static void pxa3xx_gcu_debug_timedout(unsigned long ptr)
> +{
> +	struct pxa3xx_gcu_priv *priv = (struct pxa3xx_gcu_priv *) ptr;
> +
> +	QERROR("Timer DUMP");
> +
> +	/* init the timer structure */
> +	init_timer(&pxa3xx_gcu_debug_timer);
> +	pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout;
> +	pxa3xx_gcu_debug_timer.data = ptr;
> +	pxa3xx_gcu_debug_timer.expires = jiffies + 5*HZ; /* one second */
> +
> +	add_timer(&pxa3xx_gcu_debug_timer);
> +}
> +
> +static void pxa3xx_gcu_init_debug_timer(void)
> +{
> +	pxa3xx_gcu_debug_timedout((unsigned long) &pxa3xx_gcu_debug_timer);
> +}
> +#else
> +static inline void pxa3xx_gcu_init_debug_timer(void) {}
> +#endif
> +
> +static int __devinit pxa3xx_gcu_probe(struct platform_device *dev)
> +{
> +	int ret, irq;
> +	struct resource *r;
> +	struct pxa3xx_gcu_priv *priv;
> +
> +	priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	init_waitqueue_head(&priv->wait_idle);
> +	init_waitqueue_head(&priv->wait_next);
> +	spin_lock_init(&priv->spinlock);
> +
> +	/* we allocate the misc device structure as part of our own allocation,
> +	 * so we can get a pointer to our priv structure later on with
> +	 * container_of(). This isn't really necessary as we have a fixed minor
> +	 * number anyway, but this is to avoid statics. */
> +
> +	priv->misc_fops.owner	= THIS_MODULE;
> +	priv->misc_fops.ioctl	= pxa3xx_gcu_misc_ioctl;
> +	priv->misc_fops.mmap	= pxa3xx_gcu_misc_mmap;
> +
> +	priv->misc_dev.minor	= MISCDEV_MINOR,
> +	priv->misc_dev.name	= DRV_NAME,
> +	priv->misc_dev.fops	= &priv->misc_fops,
> +
> +	/* register misc device */
> +	ret = misc_register(&priv->misc_dev);
> +	if (ret < 0) {
> +		dev_err(&dev->dev, "misc_register() for minor %d failed\n",
> +			MISCDEV_MINOR);
> +		goto err_free_priv;
> +	}
> +
> +	/* handle IO resources */
> +	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
> +	if (r == NULL) {
> +		dev_err(&dev->dev, "no I/O memory resource defined\n");
> +		ret = -ENODEV;
> +		goto err_misc_deregister;
> +	}
> +
> +	if (!request_mem_region(r->start, resource_size(r), dev->name)) {
> +		dev_err(&dev->dev, "failed to request I/O memory\n");
> +		ret = -EBUSY;
> +		goto err_misc_deregister;
> +	}
> +
> +	priv->mmio_base = ioremap_nocache(r->start, resource_size(r));
> +	if (!priv->mmio_base) {
> +		dev_err(&dev->dev, "failed to map I/O memory\n");
> +		ret = -EBUSY;
> +		goto err_free_mem_region;
> +	}
> +
> +	/* allocate dma memory */
> +	priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE,
> +					  &priv->shared_phys, GFP_KERNEL);
> +
> +	if (!priv->shared) {
> +		dev_err(&dev->dev, "failed to allocate DMA memory\n");
> +		ret = -ENOMEM;
> +		goto err_free_io;
> +	}
> +
> +	/* enable the clock */
> +	priv->clk = clk_get(&dev->dev, NULL);
> +	if (IS_ERR(priv->clk)) {
> +		dev_err(&dev->dev, "failed to get clock\n");
> +		ret = -ENODEV;
> +		goto err_free_dma;
> +	}
> +
> +	ret = clk_enable(priv->clk);
> +	if (ret < 0) {
> +		dev_err(&dev->dev, "failed to enable clock\n");
> +		goto err_put_clk;
> +	}
> +
> +	/* request the IRQ */
> +	irq = platform_get_irq(dev, 0);
> +	if (irq < 0) {
> +		dev_err(&dev->dev, "no IRQ defined\n");
> +		ret = -ENODEV;
> +		goto err_put_clk;
> +	}
> +
> +	ret = request_irq(irq, pxa3xx_gcu_handle_irq,
> +			  IRQF_DISABLED, DRV_NAME, priv);
> +	if (ret) {
> +		dev_err(&dev->dev, "request_irq failed\n");
> +		ret = -EBUSY;
> +		goto err_put_clk;
> +	}
> +
> +	platform_set_drvdata(dev, priv);
> +	priv->resource_mem = r;
> +	pxa3xx_gcu_reset(priv);
> +	pxa3xx_gcu_init_debug_timer();
> +
> +	dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
> +			(void *) r->start, (void *) priv->shared_phys,
> +			SHARED_SIZE, irq);
> +	return 0;
> +
> +err_put_clk:
> +	clk_put(priv->clk);
> +
> +err_free_dma:
> +	dma_free_coherent(&dev->dev, SHARED_SIZE,
> +			priv->shared, priv->shared_phys);
> +
> +err_free_io:
> +	iounmap(priv->mmio_base);
> +	clk_disable(priv->clk);
> +
> +err_free_mem_region:
> +	release_mem_region(r->start, resource_size(r));
> +
> +err_misc_deregister:
> +	misc_deregister(&priv->misc_dev);
> +
> +err_free_priv:
> +	platform_set_drvdata(dev, NULL);
> +	kfree(priv);
> +	return ret;
> +}
> +
> +static int __devexit pxa3xx_gcu_remove(struct platform_device *dev)
> +{
> +	struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev);
> +	struct resource *r = priv->resource_mem;
> +
> +	misc_deregister(&priv->misc_dev);
> +	dma_free_coherent(&dev->dev, SHARED_SIZE,
> +			priv->shared, priv->shared_phys);
> +	iounmap(priv->mmio_base);
> +	release_mem_region(r->start, resource_size(r));
> +	platform_set_drvdata(dev, NULL);
> +	clk_disable(priv->clk);
> +	kfree(priv);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver pxa3xx_gcu_driver = {
> +	.probe	  = pxa3xx_gcu_probe,
> +	.remove	 = __devexit_p(pxa3xx_gcu_remove),
> +	.driver	 = {
> +		.owner  = THIS_MODULE,
> +		.name   = DRV_NAME,
> +	},
> +};
> +
> +static int __init pxa3xx_gcu_init(void)
> +{
> +	return platform_driver_register(&pxa3xx_gcu_driver);
> +}
> +
> +static void __exit pxa3xx_gcu_exit(void)
> +{
> +	platform_driver_unregister(&pxa3xx_gcu_driver);
> +}
> +
> +module_init(pxa3xx_gcu_init);
> +module_exit(pxa3xx_gcu_exit);
> +
> +MODULE_DESCRIPTION("PXA3xx graphics controller unit driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS_MISCDEV(MISCDEV_MINOR);
> +MODULE_AUTHOR("Janine Kropp <nin@directfb.org>, "
> +		"Denis Oliver Kropp <dok@directfb.org>, "
> +		"Daniel Mack <daniel@caiaq.de>");
> +
> diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/pxa3xx-gcu.h
> new file mode 100644
> index 0000000..18d8e43
> --- /dev/null
> +++ b/drivers/video/pxa3xx-gcu.h
> @@ -0,0 +1,49 @@
> +#ifndef __PXA3XX_GCU_H__
> +#define __PXA3XX_GCU_H__
> +
> +#include <linux/types.h>
> +
> +/* Number of 32bit words in display list (ring buffer). */
> +#define PXA3XX_GCU_BUFFER_WORDS  ((256 * 1024 - 256) / 4)
> +
> +/* To be increased when breaking the ABI */
> +#define PXA3XX_GCU_SHARED_MAGIC  0x30000001
> +
> +struct pxa3xx_gcu_shared {
> +	u32            buffer[PXA3XX_GCU_BUFFER_WORDS];
> +
> +	bool           hw_running;
> +	int            hw_start;
> +	int            hw_end;
> +
> +	int            next_start;
> +	int            next_end;
> +	int            next_valid;
> +
> +	unsigned long  buffer_phys;
> +
> +	unsigned int   num_words;
> +	unsigned int   num_starts;
> +	unsigned int   num_done;
> +	unsigned int   num_interrupts;
> +	unsigned int   num_wait_idle;
> +	unsigned int   num_wait_next;
> +	unsigned int   num_idle;
> +
> +	u32            magic;
> +};
> +
> +struct pxa3xx_gcu_register {
> +	u32		address;	/* in */
> +	u32		value;		/* in/out */
> +};
> +
> +/* Initialization and synchronization.
> + * Hardware is started from user space via MMIO or via ioctl. */
> +#define PXA3XX_GCU_IOCTL_RESET		_IO('G', 0)
> +#define PXA3XX_GCU_IOCTL_START		_IO('G', 1)
> +#define PXA3XX_GCU_IOCTL_WAIT_IDLE	_IO('G', 2)
> +#define PXA3XX_GCU_IOCTL_WAIT_NEXT	_IO('G', 3)
> +
> +#endif /* __PXA3XX_GCU_H__ */
> +
> -- 
> 1.6.3.1
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/4] video: add driver for PXA3xx 2D graphics accelerator
  2010-02-25 16:05         ` Daniel Mack
@ 2010-04-18  7:46           ` Daniel Mack
  0 siblings, 0 replies; 5+ messages in thread
From: Daniel Mack @ 2010-04-18  7:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

this patch keeps on lurking around in tree since many months, and I
would still like to push that to mainline. Is anyone interested to give
some feedback on this? Below is a rebased version that applies to and
compiles with Linus' current git HEAD.

Thanks,
Daniel


On Thu, Feb 25, 2010 at 05:05:58PM +0100, Daniel Mack wrote:
> Was anyone able to give that driver a try?
> Haojian, you wanted to have a look IIRC?
> 
> I would appreciate seeing this in .35 if possible.
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-04-18  7:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1247159091-28697-1-git-send-email-daniel@caiaq.de>
     [not found] ` <1247159091-28697-2-git-send-email-daniel@caiaq.de>
     [not found]   ` <1247159091-28697-3-git-send-email-daniel@caiaq.de>
     [not found]     ` <1247159091-28697-4-git-send-email-daniel@caiaq.de>
     [not found]       ` <1247159091-28697-5-git-send-email-daniel@caiaq.de>
     [not found]         ` <4A56F02D.1000007@gmail.com>
     [not found]           ` <20090718080736.GL13236@buzzloop.caiaq.de>
     [not found]             ` <4A63E08F.4090409@gmail.com>
2009-07-20 10:14               ` [PATCH] video: add PXA3xx accelerator ID Daniel Mack
     [not found]               ` <20090720102239.GA3809@buzzloop.caiaq.de>
     [not found]                 ` <4A645A38.1080008@gmail.com>
     [not found]                   ` <20090720134703.GE19257@buzzloop.caiaq.de>
     [not found]                     ` <4A64830F.2020701@gmail.com>
     [not found]                       ` <20090722120433.GA9464@buzzloop.caiaq.de>
2009-09-02 21:24                         ` [PATCH 4/4] video: add driver for PXA3xx 2D graphics accelerator Daniel Mack
2009-09-02 21:24                           ` Daniel Mack
2010-02-25 16:05         ` Daniel Mack
2010-04-18  7:46           ` Daniel Mack

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.