From acd18af93ad3b99e6769b917fe5b549dc1bfc468 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 28 Sep 2012 12:42:28 +0300 Subject: OMAPDSS: add omapdss_version Add new enum, omapdss_version, that is used to tell which DSS hardware version the SoC has. This enum is initialized during platform init, and passed in the platform data to omapdss driver. Note that the versions are not "continuous", that is, you cannot check if the version is less or greater than something, but you need to check for exact version match. In other words, this is invalid: /* test if DSS is 3630 or earlier */ if (ver <= OMAPDSS_VER_OMAP3630) ... Signed-off-by: Tomi Valkeinen --- arch/arm/mach-omap2/display.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 1011995f150a..28f508724a56 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -284,6 +284,35 @@ err: return ERR_PTR(r); } +static enum omapdss_version __init omap_display_get_version(void) +{ + if (cpu_is_omap24xx()) + return OMAPDSS_VER_OMAP24xx; + else if (cpu_is_omap3630()) + return OMAPDSS_VER_OMAP3630; + else if (cpu_is_omap34xx()) { + if (soc_is_am35xx()) { + return OMAPDSS_VER_AM35xx; + } else { + if (omap_rev() < OMAP3430_REV_ES3_0) + return OMAPDSS_VER_OMAP34xx_ES1; + else + return OMAPDSS_VER_OMAP34xx_ES3; + } + } else if (omap_rev() == OMAP4430_REV_ES1_0) + return OMAPDSS_VER_OMAP4430_ES1; + else if (omap_rev() == OMAP4430_REV_ES2_0 || + omap_rev() == OMAP4430_REV_ES2_1 || + omap_rev() == OMAP4430_REV_ES2_2) + return OMAPDSS_VER_OMAP4430_ES2; + else if (cpu_is_omap44xx()) + return OMAPDSS_VER_OMAP4; + else if (soc_is_omap54xx()) + return OMAPDSS_VER_OMAP5; + else + return OMAPDSS_VER_UNKNOWN; +} + int __init omap_display_init(struct omap_dss_board_info *board_data) { int r = 0; @@ -291,9 +320,18 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) int i, oh_count; const struct omap_dss_hwmod_data *curr_dss_hwmod; struct platform_device *dss_pdev; + enum omapdss_version ver; /* create omapdss device */ + ver = omap_display_get_version(); + + if (ver == OMAPDSS_VER_UNKNOWN) { + pr_err("DSS not supported on this SoC\n"); + return -ENODEV; + } + + board_data->version = ver; board_data->dsi_enable_pads = omap_dsi_enable_pads; board_data->dsi_disable_pads = omap_dsi_disable_pads; board_data->get_context_loss_count = omap_pm_get_dev_context_loss_count; -- cgit v1.2.3 From 406c8563a7b07ce91b1310536948477c7a8755de Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 8 Oct 2012 14:35:44 +0300 Subject: OMAP: VRFB: convert vrfb to platform device This patch converts vrfb library into a platform device, in an effort to remove omap dependencies. The platform device is registered in arch/arm/plat-omap/fb.c and assigned resources depending on whether running on omap2 or omap3. The vrfb driver will parse those resources and use them to access vrfb configuration registers and the vrfb virtual rotation areas. Signed-off-by: Tomi Valkeinen Cc: Tony Lindgren --- arch/arm/plat-omap/fb.c | 61 ++++++++++++++++++++++ drivers/video/omap2/vrfb.c | 124 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 165 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index bcbb9d5dc293..f868caeedfd6 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c @@ -33,6 +33,67 @@ #include #include +#include + +#ifdef CONFIG_OMAP2_VRFB + +/* + * The first memory resource is the register region for VRFB, + * the rest are VRFB virtual memory areas for each VRFB context. + */ + +static const struct resource omap2_vrfb_resources[] = { + DEFINE_RES_MEM_NAMED(0x68008000u, 0x40, "vrfb-regs"), + DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"), + DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"), + DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"), + DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"), +}; + +static const struct resource omap3_vrfb_resources[] = { + DEFINE_RES_MEM_NAMED(0x6C000180u, 0xc0, "vrfb-regs"), + DEFINE_RES_MEM_NAMED(0x70000000u, 0x4000000, "vrfb-area-0"), + DEFINE_RES_MEM_NAMED(0x74000000u, 0x4000000, "vrfb-area-1"), + DEFINE_RES_MEM_NAMED(0x78000000u, 0x4000000, "vrfb-area-2"), + DEFINE_RES_MEM_NAMED(0x7c000000u, 0x4000000, "vrfb-area-3"), + DEFINE_RES_MEM_NAMED(0xe0000000u, 0x4000000, "vrfb-area-4"), + DEFINE_RES_MEM_NAMED(0xe4000000u, 0x4000000, "vrfb-area-5"), + DEFINE_RES_MEM_NAMED(0xe8000000u, 0x4000000, "vrfb-area-6"), + DEFINE_RES_MEM_NAMED(0xec000000u, 0x4000000, "vrfb-area-7"), + DEFINE_RES_MEM_NAMED(0xf0000000u, 0x4000000, "vrfb-area-8"), + DEFINE_RES_MEM_NAMED(0xf4000000u, 0x4000000, "vrfb-area-9"), + DEFINE_RES_MEM_NAMED(0xf8000000u, 0x4000000, "vrfb-area-10"), + DEFINE_RES_MEM_NAMED(0xfc000000u, 0x4000000, "vrfb-area-11"), +}; + +static int __init omap_init_vrfb(void) +{ + struct platform_device *pdev; + const struct resource *res; + unsigned int num_res; + + if (cpu_is_omap24xx()) { + res = omap2_vrfb_resources; + num_res = ARRAY_SIZE(omap2_vrfb_resources); + } else if (cpu_is_omap34xx()) { + res = omap3_vrfb_resources; + num_res = ARRAY_SIZE(omap3_vrfb_resources); + } else { + return 0; + } + + pdev = platform_device_register_resndata(NULL, "omapvrfb", -1, + res, num_res, NULL, 0); + + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + else + return 0; +} + +arch_initcall(omap_init_vrfb); +#endif + #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE) static bool omapfb_lcd_configured; diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/omap2/vrfb.c index 7e990220ad2a..fda45cc10d48 100644 --- a/drivers/video/omap2/vrfb.c +++ b/drivers/video/omap2/vrfb.c @@ -26,9 +26,9 @@ #include #include #include +#include #include -#include #ifdef DEBUG #define DBG(format, ...) pr_debug("VRFB: " format, ## __VA_ARGS__) @@ -36,10 +36,10 @@ #define DBG(format, ...) #endif -#define SMS_ROT_VIRT_BASE(context, rot) \ - (((context >= 4) ? 0xD0000000 : 0x70000000) \ - + (0x4000000 * (context)) \ - + (0x1000000 * (rot))) +#define SMS_ROT_CONTROL(context) (0x0 + 0x10 * context) +#define SMS_ROT_SIZE(context) (0x4 + 0x10 * context) +#define SMS_ROT_PHYSICAL_BA(context) (0x8 + 0x10 * context) +#define SMS_ROT_VIRT_BASE(rot) (0x1000000 * (rot)) #define OMAP_VRFB_SIZE (2048 * 2048 * 4) @@ -53,10 +53,16 @@ #define SMS_PW_OFFSET 4 #define SMS_PS_OFFSET 0 -#define VRFB_NUM_CTXS 12 /* bitmap of reserved contexts */ static unsigned long ctx_map; +struct vrfb_ctx { + u32 base; + u32 physical_ba; + u32 control; + u32 size; +}; + static DEFINE_MUTEX(ctx_lock); /* @@ -65,17 +71,32 @@ static DEFINE_MUTEX(ctx_lock); * 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 void __iomem *vrfb_base; + +static int num_ctxs; +static struct vrfb_ctx *ctxs; + +static void omap2_sms_write_rot_control(u32 val, unsigned ctx) +{ + __raw_writel(val, vrfb_base + SMS_ROT_CONTROL(ctx)); +} + +static void omap2_sms_write_rot_size(u32 val, unsigned ctx) +{ + __raw_writel(val, vrfb_base + SMS_ROT_SIZE(ctx)); +} + +static void omap2_sms_write_rot_physical_ba(u32 val, unsigned ctx) +{ + __raw_writel(val, vrfb_base + SMS_ROT_PHYSICAL_BA(ctx)); +} static inline void restore_hw_context(int ctx) { - omap2_sms_write_rot_control(vrfb_hw_context[ctx].control, ctx); - omap2_sms_write_rot_size(vrfb_hw_context[ctx].size, ctx); - omap2_sms_write_rot_physical_ba(vrfb_hw_context[ctx].physical_ba, ctx); + omap2_sms_write_rot_control(ctxs[ctx].control, ctx); + omap2_sms_write_rot_size(ctxs[ctx].size, ctx); + omap2_sms_write_rot_physical_ba(ctxs[ctx].physical_ba, ctx); } static u32 get_image_width_roundup(u16 width, u8 bytespp) @@ -196,9 +217,9 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, 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; + ctxs[ctx].physical_ba = paddr; + ctxs[ctx].size = size; + ctxs[ctx].control = control; omap2_sms_write_rot_physical_ba(paddr, ctx); omap2_sms_write_rot_size(size, ctx); @@ -274,11 +295,11 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb) mutex_lock(&ctx_lock); - for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx) + for (ctx = 0; ctx < num_ctxs; ++ctx) if ((ctx_map & (1 << ctx)) == 0) break; - if (ctx == VRFB_NUM_CTXS) { + if (ctx == num_ctxs) { pr_err("vrfb: no free contexts\n"); r = -EBUSY; goto out; @@ -293,7 +314,7 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb) vrfb->context = ctx; for (rot = 0; rot < 4; ++rot) { - paddr = SMS_ROT_VIRT_BASE(ctx, rot); + paddr = ctxs[ctx].base + SMS_ROT_VIRT_BASE(rot); if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) { pr_err("vrfb: failed to reserve VRFB " "area for ctx %d, rotation %d\n", @@ -314,3 +335,66 @@ out: return r; } EXPORT_SYMBOL(omap_vrfb_request_ctx); + +static int __init vrfb_probe(struct platform_device *pdev) +{ + struct resource *mem; + int i; + + /* first resource is the register res, the rest are vrfb contexts */ + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "can't get vrfb base address\n"); + return -EINVAL; + } + + vrfb_base = devm_request_and_ioremap(&pdev->dev, mem); + if (!vrfb_base) { + dev_err(&pdev->dev, "can't ioremap vrfb memory\n"); + return -ENOMEM; + } + + num_ctxs = pdev->num_resources - 1; + + ctxs = devm_kzalloc(&pdev->dev, + sizeof(struct vrfb_ctx) * num_ctxs, + GFP_KERNEL); + + if (!ctxs) + return -ENOMEM; + + for (i = 0; i < num_ctxs; ++i) { + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i); + if (!mem) { + dev_err(&pdev->dev, "can't get vrfb ctx %d address\n", + i); + return -EINVAL; + } + + ctxs[i].base = mem->start; + } + + return 0; +} + +static struct platform_driver vrfb_driver = { + .driver.name = "omapvrfb", +}; + +static int __init vrfb_init(void) +{ + return platform_driver_probe(&vrfb_driver, &vrfb_probe); +} + +static void __exit vrfb_exit(void) +{ + platform_driver_unregister(&vrfb_driver); +} + +module_init(vrfb_init); +module_exit(vrfb_exit); + +MODULE_AUTHOR("Tomi Valkeinen "); +MODULE_DESCRIPTION("OMAP VRFB"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 6a1c9f6d19180cdbb603e5b77bd7b57d01260664 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 8 Oct 2012 14:52:24 +0300 Subject: OMAP: move arch/arm/plat-omap/include/plat/vrfb.h Now that vrfb driver is not omap dependent anymore, we can move vrfb.h from arch/arm/plat-omap/include/plat to include/video/omapvrfb.h. Signed-off-by: Tomi Valkeinen Cc: Tony Lindgren Cc: Vaibhav Hiremath --- arch/arm/plat-omap/include/plat/vrfb.h | 66 ---------------------------- drivers/media/platform/omap/omap_vout.c | 2 +- drivers/media/platform/omap/omap_vout_vrfb.c | 2 +- drivers/media/platform/omap/omap_voutdef.h | 2 +- drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +- drivers/video/omap2/omapfb/omapfb-main.c | 2 +- drivers/video/omap2/omapfb/omapfb-sysfs.c | 2 +- drivers/video/omap2/vrfb.c | 2 +- include/video/omapvrfb.h | 66 ++++++++++++++++++++++++++++ 9 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 arch/arm/plat-omap/include/plat/vrfb.h create mode 100644 include/video/omapvrfb.h (limited to 'arch') diff --git a/arch/arm/plat-omap/include/plat/vrfb.h b/arch/arm/plat-omap/include/plat/vrfb.h deleted file mode 100644 index 3792bdea2f6d..000000000000 --- a/arch/arm/plat-omap/include/plat/vrfb.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * VRFB Rotation Engine - * - * Copyright (C) 2009 Nokia Corporation - * Author: Tomi Valkeinen - * - * 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 xres; - u16 yres; - u16 xoffset; - u16 yoffset; - u8 bytespp; - bool yuv_mode; -}; - -#ifdef CONFIG_OMAP2_VRFB -extern int omap_vrfb_request_ctx(struct vrfb *vrfb); -extern void omap_vrfb_release_ctx(struct vrfb *vrfb); -extern void omap_vrfb_adjust_size(u16 *width, u16 *height, - u8 bytespp); -extern u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp); -extern u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp); -extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, - u16 width, u16 height, - unsigned bytespp, bool yuv_mode); -extern int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot); -extern void omap_vrfb_restore_context(void); - -#else -static inline int omap_vrfb_request_ctx(struct vrfb *vrfb) { return 0; } -static inline void omap_vrfb_release_ctx(struct vrfb *vrfb) {} -static inline void omap_vrfb_adjust_size(u16 *width, u16 *height, - u8 bytespp) {} -static inline u32 omap_vrfb_min_phys_size(u16 width, u16 height, u8 bytespp) - { return 0; } -static inline u16 omap_vrfb_max_height(u32 phys_size, u16 width, u8 bytespp) - { return 0; } -static inline void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, - u16 width, u16 height, unsigned bytespp, bool yuv_mode) {} -static inline int omap_vrfb_map_angle(struct vrfb *vrfb, u16 height, u8 rot) - { return 0; } -static inline void omap_vrfb_restore_context(void) {} -#endif -#endif /* __VRFB_H */ diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index a3b1a34c896d..3ff94a30fde4 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -46,7 +46,7 @@ #include #include -#include +#include