aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux/linux-omap-pm-2.6.29/dss2/0061-DSS2-VRFB-save-restore-context.patch
blob: a0b694736b6655f1758a362d571cb6a5af4cfc13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
From e58576ceca922bfe4c793e6f77a873c4ea14f768 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Tue, 5 May 2009 09:05:12 +0300
Subject: [PATCH 61/69] 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