From 482644bbb2e168002d8a004d1553f5da994276c2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Tue, 5 May 2009 09:05:12 +0300 Subject: [PATCH 059/146] DSS2: VRFB: save / restore context The VRFB is part of the SMS and supplied by the core power domain; do the context saving while VRFB is configured and restore it along with the rest of the domain context. This patch only implements the restore functionality, but not the actual call to the restore. That belongs to PM functionality. --- arch/arm/plat-omap/include/mach/vrfb.h | 1 + arch/arm/plat-omap/vrfb.c | 50 ++++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h index 12c7fab..ee6c062 100644 --- a/arch/arm/plat-omap/include/mach/vrfb.h +++ b/arch/arm/plat-omap/include/mach/vrfb.h @@ -44,5 +44,6 @@ extern void omap_vrfb_adjust_size(u16 *width, u16 *height, extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, u16 width, u16 height, enum omap_color_mode color_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 index 2ae0d68..649803e 100644 --- a/arch/arm/plat-omap/vrfb.c +++ b/arch/arm/plat-omap/vrfb.c @@ -39,6 +39,33 @@ /* bitmap of reserved contexts */ static unsigned ctx_map; +/* + * 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. + */ +struct { + u32 physical_ba; + u32 control; + u32 size; +} vrfb_hw_context[VRFB_NUM_CTXS]; + +void omap_vrfb_restore_context(void) +{ + int i; + + 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)); + } +} + void omap_vrfb_adjust_size(u16 *width, u16 *height, u8 bytespp) { @@ -56,6 +83,8 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, u16 vrfb_height; u8 ctx = vrfb->context; u8 bytespp; + u32 size; + u32 control; DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr, width, height, bytespp); @@ -100,15 +129,20 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr, DBG("vrfb w %u, h %u\n", vrfb_width, vrfb_height); + 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((vrfb_width << SMS_IMAGEWIDTH_OFFSET) | - (vrfb_height << SMS_IMAGEHEIGHT_OFFSET), - SMS_ROT_SIZE(ctx)); - - omap_writel(pixel_size_exp << SMS_PS_OFFSET | - VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET | - VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET, - SMS_ROT_CONTROL(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); -- 1.6.2.4