From: Tony Lindgren <tony@atomide.com>
To: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Cc: linux-fbdev-devel@lists.sourceforge.net, linux-omap@vger.kernel.org
Subject: Re: [PATCH 04/15] OMAP: Add support for VRFB rotation engine
Date: Wed, 5 Aug 2009 17:31:41 +0300 [thread overview]
Message-ID: <20090805143141.GI7374@atomide.com> (raw)
In-Reply-To: <1249481741-14008-5-git-send-email-tomi.valkeinen@nokia.com>
* Tomi Valkeinen <tomi.valkeinen@nokia.com> [090805 17:19]:
> VRFB rotation engine is a block in OMAP2/3 that offers 12 independent
> contexts that can be used for framebuffer rotation.
>
> Each context has a backend area of real memory, where it stores the
> pixels in undisclosed format. This memory is offered to users via 4
> virtual memory areas, which see the same memory area in different
> rotation angles (0, 90, 180 and 270 degrees).
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
> ---
> arch/arm/plat-omap/Kconfig | 3 +
> arch/arm/plat-omap/Makefile | 1 +
> arch/arm/plat-omap/include/mach/vrfb.h | 46 +++++
> arch/arm/plat-omap/vrfb.c | 281 ++++++++++++++++++++++++++++++++
> 4 files changed, 331 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/plat-omap/include/mach/vrfb.h
> create mode 100644 arch/arm/plat-omap/vrfb.c
>
> diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
> index ca06037..2d6ae55 100644
> --- a/arch/arm/plat-omap/Kconfig
> +++ b/arch/arm/plat-omap/Kconfig
> @@ -186,6 +186,9 @@ config OMAP_SERIAL_WAKE
> config OMAP2_VRAM
> bool
>
> +config OMAP2_VRFB
> + bool
> +
> endmenu
>
> endif
> diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
> index 0472bbe..462edf3 100644
> --- a/arch/arm/plat-omap/Makefile
> +++ b/arch/arm/plat-omap/Makefile
> @@ -26,3 +26,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
> obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
>
> obj-$(CONFIG_OMAP2_VRAM) += vram.o
> +obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
Can you please place this file under drivers/video?
> diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h
> new file mode 100644
> index 0000000..8790612
> --- /dev/null
> +++ b/arch/arm/plat-omap/include/mach/vrfb.h
> @@ -0,0 +1,46 @@
> +/*
> + * VRFB Rotation Engine
> + *
> + * Copyright (C) 2009 Nokia Corporation
> + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.,
> + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +#ifndef __OMAP_VRFB_H__
> +#define __OMAP_VRFB_H__
> +
> +#define OMAP_VRFB_LINE_LEN 2048
> +
> +struct vrfb {
> + u8 context;
> + void __iomem *vaddr[4];
> + unsigned long paddr[4];
> + u16 xoffset;
> + u16 yoffset;
> + u8 bytespp;
> +};
> +
> +extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
> +extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
> +extern void omap_vrfb_suspend_ctx(struct vrfb *vrfb);
> +extern void omap_vrfb_resume_ctx(struct vrfb *vrfb);
> +extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
> + u8 bytespp);
> +extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
> + u16 width, u16 height,
> + unsigned bytespp, bool yuv_mode);
> +extern void omap_vrfb_restore_context(void);
> +
> +#endif /* __VRFB_H */
> diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
> new file mode 100644
> index 0000000..240058f
> --- /dev/null
> +++ b/arch/arm/plat-omap/vrfb.c
> @@ -0,0 +1,281 @@
> +/*
> + * VRFB Rotation Engine
> + *
> + * Copyright (C) 2009 Nokia Corporation
> + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.,
> + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/ioport.h>
> +#include <linux/io.h>
> +#include <linux/bitops.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/io.h>
> +#include <mach/vrfb.h>
> +/*#define DEBUG*/
> +
> +#ifdef DEBUG
> +#define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__)
> +#else
> +#define DBG(format, ...)
> +#endif
> +
> +#define SMS_ROT_VIRT_BASE(context, rot) \
> + (((context >= 4) ? 0xD0000000 : 0x70000000) \
> + + (0x4000000 * (context)) \
> + + (0x1000000 * (rot)))
> +
> +#define OMAP_VRFB_SIZE (2048 * 2048 * 4)
> +
> +#define VRFB_PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */
> +#define VRFB_PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */
> +#define VRFB_PAGE_WIDTH (1 << VRFB_PAGE_WIDTH_EXP)
> +#define VRFB_PAGE_HEIGHT (1 << VRFB_PAGE_HEIGHT_EXP)
> +#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 OMAP_SMS_BASE 0x6C000000
> +#define SMS_ROT_CONTROL(context) (OMAP_SMS_BASE + 0x180 + 0x10 * context)
> +#define SMS_ROT_SIZE(context) (OMAP_SMS_BASE + 0x184 + 0x10 * context)
> +#define SMS_ROT_PHYSICAL_BA(context) (OMAP_SMS_BASE + 0x188 + 0x10 * context)
> +
> +#define VRFB_NUM_CTXS 12
> +/* bitmap of reserved contexts */
> +static unsigned long ctx_map;
> +/* bitmap of contexts for which we have to keep the HW context valid */
> +static unsigned long ctx_map_active;
> +
> +static DEFINE_MUTEX(ctx_lock);
> +
> +/*
> + * Access to this happens from client drivers or the PM core after wake-up.
> + * For the first case we require locking at the driver level, for the second
> + * we don't need locking, since no drivers will run until after the wake-up
> + * has finished.
> + */
> +static struct {
> + u32 physical_ba;
> + u32 control;
> + u32 size;
> +} vrfb_hw_context[VRFB_NUM_CTXS];
> +
> +static inline void restore_hw_context(int ctx)
> +{
> + omap_writel(vrfb_hw_context[ctx].control, SMS_ROT_CONTROL(ctx));
> + omap_writel(vrfb_hw_context[ctx].size, SMS_ROT_SIZE(ctx));
> + omap_writel(vrfb_hw_context[ctx].physical_ba, SMS_ROT_PHYSICAL_BA(ctx));
> +}
Please use ioremap + and readl/writel instead of omap_read/write for all new code.
Otherwise we'll have harder time to reclaim more address space for kernel
as discussed earlier on linux-omap list.
> +
> +void omap_vrfb_restore_context(void)
> +{
> + int i;
> + unsigned long map = ctx_map_active;
> +
> + for (i = ffs(map); i; i = ffs(map)) {
> + /* i=1..32 */
> + i--;
> + map &= ~(1 << i);
> + restore_hw_context(i);
> + }
> +}
> +
> +void omap_vrfb_adjust_size(u16 *width, u16 *height,
> + u8 bytespp)
> +{
> + *width = ALIGN(*width * bytespp, VRFB_PAGE_WIDTH) / bytespp;
> + *height = ALIGN(*height, VRFB_PAGE_HEIGHT);
> +}
> +EXPORT_SYMBOL(omap_vrfb_adjust_size);
> +
> +void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
> + u16 width, u16 height,
> + unsigned bytespp, bool yuv_mode)
> +{
> + unsigned pixel_size_exp;
> + u16 vrfb_width;
> + u16 vrfb_height;
> + u8 ctx = vrfb->context;
> + u32 size;
> + u32 control;
> +
> + DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr,
> + width, height, color_mode);
> +
> + /* For YUV2 and UYVY modes VRFB needs to handle pixels a bit
> + * differently. See TRM. */
> + if (yuv_mode) {
> + bytespp *= 2;
> + width /= 2;
> + }
> +
> + if (bytespp == 4)
> + pixel_size_exp = 2;
> + else if (bytespp == 2)
> + pixel_size_exp = 1;
> + else
> + BUG();
> +
> + vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp;
> + vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT);
> +
> + DBG("vrfb w %u, h %u bytespp %d\n", vrfb_width, vrfb_height, bytespp);
> +
> + size = vrfb_width << SMS_IMAGEWIDTH_OFFSET;
> + size |= vrfb_height << SMS_IMAGEHEIGHT_OFFSET;
> +
> + control = pixel_size_exp << SMS_PS_OFFSET;
> + control |= VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET;
> + control |= VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET;
> +
> + vrfb_hw_context[ctx].physical_ba = paddr;
> + vrfb_hw_context[ctx].size = size;
> + vrfb_hw_context[ctx].control = control;
> +
> + omap_writel(paddr, SMS_ROT_PHYSICAL_BA(ctx));
> + omap_writel(size, SMS_ROT_SIZE(ctx));
> + omap_writel(control, SMS_ROT_CONTROL(ctx));
> +
> + DBG("vrfb offset pixels %d, %d\n",
> + vrfb_width - width, vrfb_height - height);
> +
> + vrfb->xoffset = vrfb_width - width;
> + vrfb->yoffset = vrfb_height - height;
> + vrfb->bytespp = bytespp;
> +}
> +EXPORT_SYMBOL(omap_vrfb_setup);
> +
> +void omap_vrfb_release_ctx(struct vrfb *vrfb)
> +{
> + int rot;
> + int ctx = vrfb->context;
> +
> + if (ctx == 0xff)
> + return;
> +
> + DBG("release ctx %d\n", ctx);
> +
> + mutex_lock(&ctx_lock);
> +
> + BUG_ON(!(ctx_map & (1 << ctx)));
> +
> + clear_bit(ctx, &ctx_map_active);
> + clear_bit(ctx, &ctx_map);
> +
> + for (rot = 0; rot < 4; ++rot) {
> + if (vrfb->paddr[rot]) {
> + release_mem_region(vrfb->paddr[rot], OMAP_VRFB_SIZE);
> + vrfb->paddr[rot] = 0;
> + }
> + }
> +
> + vrfb->context = 0xff;
> +
> + mutex_unlock(&ctx_lock);
> +}
> +EXPORT_SYMBOL(omap_vrfb_release_ctx);
> +
> +int omap_vrfb_request_ctx(struct vrfb *vrfb)
> +{
> + int rot;
> + u32 paddr;
> + u8 ctx;
> + int r;
> +
> + DBG("request ctx\n");
> +
> + mutex_lock(&ctx_lock);
> +
> + for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
> + if ((ctx_map & (1 << ctx)) == 0)
> + break;
> +
> + if (ctx == VRFB_NUM_CTXS) {
> + pr_err("vrfb: no free contexts\n");
> + r = -EBUSY;
> + goto out;
> + }
> +
> + DBG("found free ctx %d\n", ctx);
> +
> + set_bit(ctx, &ctx_map);
> + WARN_ON(ctx_map_active & (1 << ctx));
> + set_bit(ctx, &ctx_map_active);
> +
> + memset(vrfb, 0, sizeof(*vrfb));
> +
> + vrfb->context = ctx;
> +
> + for (rot = 0; rot < 4; ++rot) {
> + paddr = SMS_ROT_VIRT_BASE(ctx, rot);
> + if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) {
> + pr_err("vrfb: failed to reserve VRFB "
> + "area for ctx %d, rotation %d\n",
> + ctx, rot * 90);
> + omap_vrfb_release_ctx(vrfb);
> + r = -ENOMEM;
> + goto out;
> + }
> +
> + vrfb->paddr[rot] = paddr;
> +
> + DBG("VRFB %d/%d: %lx\n", ctx, rot*90, vrfb->paddr[rot]);
> + }
> +
> + r = 0;
> +out:
> + mutex_unlock(&ctx_lock);
> + return r;
> +}
> +EXPORT_SYMBOL(omap_vrfb_request_ctx);
> +
> +void omap_vrfb_suspend_ctx(struct vrfb *vrfb)
> +{
> + DBG("suspend ctx %d\n", vrfb->context);
> + mutex_lock(&ctx_lock);
> +
> + BUG_ON(vrfb->context >= VRFB_NUM_CTXS);
> + BUG_ON(!((1 << vrfb->context) & ctx_map_active));
> +
> + clear_bit(vrfb->context, &ctx_map_active);
> + mutex_unlock(&ctx_lock);
> +}
> +EXPORT_SYMBOL(omap_vrfb_suspend_ctx);
> +
> +void omap_vrfb_resume_ctx(struct vrfb *vrfb)
> +{
> + DBG("resume ctx %d\n", vrfb->context);
> + mutex_lock(&ctx_lock);
> +
> + BUG_ON(vrfb->context >= VRFB_NUM_CTXS);
> + BUG_ON((1 << vrfb->context) & ctx_map_active);
> +
> + /*
> + * omap_vrfb_restore_context is normally called by the core domain
> + * save / restore logic, but since this VRFB context was suspended
> + * those calls didn't actually restore the context and now we might
> + * have an invalid context. Do an explicit restore here.
> + */
> + restore_hw_context(vrfb->context);
> + set_bit(vrfb->context, &ctx_map_active);
> + mutex_unlock(&ctx_lock);
> +}
> +EXPORT_SYMBOL(omap_vrfb_resume_ctx);
> +
> --
> 1.6.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2009-08-05 14:31 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-05 14:15 [PATCH 00/15] OMAP: DSS intro Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 01/15] OMAP: OMAPFB: split omapfb.h Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 02/15] OMAP: OMAPFB: add omapdss device Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 03/15] OMAP: Add VRAM manager Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 04/15] OMAP: Add support for VRFB rotation engine Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 05/15] OMAP: DSS2: Documentation for DSS2 Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 06/15] OMAP: DSS2: Display Subsystem Driver core Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 07/15] OMAP: DSS2: VENC driver Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 08/15] OMAP: DSS2: RFBI driver Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 09/15] OMAP: DSS2: SDI driver Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 10/15] OMAP: DSS2: DSI driver Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 11/15] OMAP: DSS2: omapfb driver Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 12/15] OMAP: DSS2: Add panel drivers Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 13/15] OMAP: SDP: Enable DSS2 for OMAP3 SDP board Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 14/15] OMAP: Beagle: Enable DSS2 for Beagle board Tomi Valkeinen
2009-08-05 14:15 ` [PATCH 15/15] OMAP: Overo: Enable DSS2 for Overo Tomi Valkeinen
2009-08-05 14:44 ` Tony Lindgren
2009-08-05 14:43 ` [PATCH 14/15] OMAP: Beagle: Enable DSS2 for Beagle board Tony Lindgren
2009-08-05 14:40 ` [PATCH 13/15] OMAP: SDP: Enable DSS2 for OMAP3 SDP board Tony Lindgren
2009-08-05 14:48 ` Tomi Valkeinen
2009-08-07 11:50 ` [PATCH 12/15] OMAP: DSS2: Add panel drivers Roger Quadros
2009-08-07 11:47 ` [PATCH 11/15] OMAP: DSS2: omapfb driver Roger Quadros
2009-08-07 11:52 ` Tomi Valkeinen
2009-08-07 11:54 ` Roger Quadros
2009-08-05 15:04 ` [PATCH 10/15] OMAP: DSS2: DSI driver Tony Lindgren
2009-08-05 14:59 ` [PATCH 09/15] OMAP: DSS2: SDI driver Tony Lindgren
2009-08-05 14:49 ` [PATCH 08/15] OMAP: DSS2: RFBI driver Tony Lindgren
2009-08-05 14:47 ` [PATCH 07/15] OMAP: DSS2: VENC driver Tony Lindgren
2009-08-05 14:31 ` Tony Lindgren [this message]
2009-08-07 8:33 ` [PATCH 04/15] OMAP: Add support for VRFB rotation engine Tomi Valkeinen
2009-08-05 14:33 ` [PATCH 03/15] OMAP: Add VRAM manager Tony Lindgren
2009-08-05 14:32 ` [PATCH 02/15] OMAP: OMAPFB: add omapdss device Tony Lindgren
2009-08-05 14:32 ` [PATCH 01/15] OMAP: OMAPFB: split omapfb.h Tony Lindgren
2009-08-07 11:17 ` [PATCH 00/15] OMAP: DSS intro Roger Quadros
2009-08-07 11:24 ` Tomi Valkeinen
2009-08-07 11:27 ` Roger Quadros
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=20090805143141.GI7374@atomide.com \
--to=tony@atomide.com \
--cc=linux-fbdev-devel@lists.sourceforge.net \
--cc=linux-omap@vger.kernel.org \
--cc=tomi.valkeinen@nokia.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).