diff options
Diffstat (limited to 'recipes/linux/linux-omap-pm/dss2/0065-VRFB-add-suspend-resume-functionality.patch')
-rw-r--r-- | recipes/linux/linux-omap-pm/dss2/0065-VRFB-add-suspend-resume-functionality.patch | 216 |
1 files changed, 0 insertions, 216 deletions
diff --git a/recipes/linux/linux-omap-pm/dss2/0065-VRFB-add-suspend-resume-functionality.patch b/recipes/linux/linux-omap-pm/dss2/0065-VRFB-add-suspend-resume-functionality.patch deleted file mode 100644 index 17f959cb27..0000000000 --- a/recipes/linux/linux-omap-pm/dss2/0065-VRFB-add-suspend-resume-functionality.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 1269429fe6ddd6e5f15e3b4edb4fc2bcd6fc0410 Mon Sep 17 00:00:00 2001 -From: Imre Deak <imre.deak@nokia.com> -Date: Tue, 5 May 2009 11:16:13 +0200 -Subject: [PATCH 65/69] VRFB: add suspend/resume functionality - -At the moment the VRFB context is restored at each core power domain -OFF->ON transition. This is not optimal since the VRFB might be unused -temporarily for example when the screen is blanked. Add a suspend / -resume function to mark these unused periods during which we'll avoid -thea the context restore. - -Use atomic bitops for ctx_map for consistency. - -Signed-off-by: Imre Deak <imre.deak@nokia.com> ---- - arch/arm/plat-omap/include/mach/vrfb.h | 2 + - arch/arm/plat-omap/vrfb.c | 75 ++++++++++++++++++++++++----- - drivers/video/omap2/omapfb/omapfb-main.c | 28 +++++++++++ - 3 files changed, 92 insertions(+), 13 deletions(-) - -diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h -index ee6c062..9647d82 100644 ---- a/arch/arm/plat-omap/include/mach/vrfb.h -+++ b/arch/arm/plat-omap/include/mach/vrfb.h -@@ -39,6 +39,8 @@ struct vrfb - - 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, -diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c -index 289fc8a..29f04e2 100644 ---- a/arch/arm/plat-omap/vrfb.c -+++ b/arch/arm/plat-omap/vrfb.c -@@ -1,7 +1,9 @@ - #include <linux/kernel.h> - #include <linux/module.h> - #include <linux/ioport.h> -+ - #include <asm/io.h> -+#include <asm/bitops.h> - - #include <mach/io.h> - #include <mach/vrfb.h> -@@ -37,7 +39,9 @@ - - #define VRFB_NUM_CTXS 12 - /* bitmap of reserved contexts */ --static unsigned ctx_map; -+static unsigned long ctx_map; -+/* bitmap of contexts for which we have to keep the HW context valid */ -+static unsigned long ctx_map_active; - - /* - * Access to this happens from client drivers or the PM core after wake-up. -@@ -51,18 +55,23 @@ struct { - u32 size; - } vrfb_hw_context[VRFB_NUM_CTXS]; - -+static void inline 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)); -+} -+ - void omap_vrfb_restore_context(void) - { - int i; -+ unsigned long map = ctx_map_active; - -- for (i = 0; i < VRFB_NUM_CTXS; i++) { -- /* Restore only the active contexts */ -- if (!(ctx_map & (1 << i))) -- continue; -- omap_writel(vrfb_hw_context[i].control, SMS_ROT_CONTROL(i)); -- omap_writel(vrfb_hw_context[i].size, SMS_ROT_SIZE(i)); -- omap_writel(vrfb_hw_context[i].physical_ba, -- SMS_ROT_PHYSICAL_BA(i)); -+ for (i = ffs(map); i; i = ffs(map)) { -+ /* i=1..32 */ -+ i--; -+ map &= ~(1 << i); -+ restore_hw_context(i); - } - } - -@@ -156,13 +165,20 @@ EXPORT_SYMBOL(omap_vrfb_setup); - void omap_vrfb_release_ctx(struct vrfb *vrfb) - { - int rot; -+ int ctx = vrfb->context; - -- if (vrfb->context == 0xff) -+ if (ctx == 0xff) - return; - -- DBG("release ctx %d\n", vrfb->context); -+ DBG("release ctx %d\n", ctx); - -- ctx_map &= ~(1 << vrfb->context); -+ if (!(ctx_map & (1 << ctx))) { -+ BUG(); -+ return; -+ } -+ WARN_ON(!(ctx_map_active & (1 << ctx))); -+ clear_bit(ctx, &ctx_map_active); -+ clear_bit(ctx, &ctx_map); - - for (rot = 0; rot < 4; ++rot) { - if(vrfb->paddr[rot]) { -@@ -194,7 +210,9 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb) - - DBG("found free ctx %d\n", ctx); - -- ctx_map |= 1 << ctx; -+ set_bit(ctx, &ctx_map); -+ WARN_ON(ctx_map_active & (1 << ctx)); -+ set_bit(ctx, &ctx_map_active); - - memset(vrfb, 0, sizeof(*vrfb)); - -@@ -219,3 +237,34 @@ int omap_vrfb_request_ctx(struct vrfb *vrfb) - } - EXPORT_SYMBOL(omap_vrfb_request_ctx); - -+void omap_vrfb_suspend_ctx(struct vrfb *vrfb) -+{ -+ DBG("suspend ctx %d\n", vrfb->context); -+ if (vrfb->context >= VRFB_NUM_CTXS || -+ (!(1 << vrfb->context) & ctx_map_active)) { -+ BUG(); -+ return; -+ } -+ clear_bit(vrfb->context, &ctx_map_active); -+} -+EXPORT_SYMBOL(omap_vrfb_suspend_ctx); -+ -+void omap_vrfb_resume_ctx(struct vrfb *vrfb) -+{ -+ DBG("resume ctx %d\n", vrfb->context); -+ if (vrfb->context >= VRFB_NUM_CTXS || -+ ((1 << vrfb->context) & ctx_map_active)) { -+ BUG(); -+ return; -+ } -+ /* -+ * 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); -+} -+EXPORT_SYMBOL(omap_vrfb_resume_ctx); -+ -diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c -index 76e7c6c..4bb74b7 100644 ---- a/drivers/video/omap2/omapfb/omapfb-main.c -+++ b/drivers/video/omap2/omapfb/omapfb-main.c -@@ -1036,6 +1036,30 @@ static int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) - return 0; - } - -+static void omapfb_vrfb_suspend_all(struct omapfb2_device *fbdev) -+{ -+ int i; -+ -+ for (i = 0; i < fbdev->num_fbs; i++) { -+ struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); -+ -+ if (ofbi->region.vrfb.vaddr[0]) -+ omap_vrfb_suspend_ctx(&ofbi->region.vrfb); -+ } -+} -+ -+static void omapfb_vrfb_resume_all(struct omapfb2_device *fbdev) -+{ -+ int i; -+ -+ for (i = 0; i < fbdev->num_fbs; i++) { -+ struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); -+ -+ if (ofbi->region.vrfb.vaddr[0]) -+ omap_vrfb_resume_ctx(&ofbi->region.vrfb); -+ } -+} -+ - static int omapfb_blank(int blank, struct fb_info *fbi) - { - struct omapfb_info *ofbi = FB2OFB(fbi); -@@ -1051,6 +1075,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi) - if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) - goto exit; - -+ omapfb_vrfb_resume_all(fbdev); -+ - if (display->resume) - r = display->resume(display); - -@@ -1073,6 +1099,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi) - if (display->suspend) - r = display->suspend(display); - -+ omapfb_vrfb_suspend_all(fbdev); -+ - break; - - default: --- -1.6.2.4 - |