aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.24/1299-glamo_fb-Implement-screen-blanking.patch
blob: 3004a832efe19dba9643c9627ac19193bbae0cc1 (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
From a2ef813d2f439a3e9f377d33a2e5baad098afb7e Mon Sep 17 00:00:00 2001
From: Harald Welte <laforge@openmoko.org>
Date: Wed, 8 Oct 2008 21:36:23 +0100
Subject: [PATCH] glamo_fb: Implement screen blanking

This patch implements fb_blank() for the glamo-fb driver, which switches off
the pixel clock (DCLK) for power saving.

We currently delay the actual pixel clock switch until we enter
FB_BLANK_POWERDOWN, since the backlight fade is slow and we don't want the
user to see artefacts on the screen while the backlight is fading out.

So since the X server first sends FB_BLANK_{V,H}SYNC_SUSPEND, we start the
backlight fade here, and only once we get FB_BLANK_POWERDOWN the pixel clock is
disabled.

There are no measurements yet, but the power savings should be double, since
there is no longer any  generation of the high-frequency LCM signals, and
there are no video-related SDRAM accesses anymore.

Signed-off-by: Harald Welte <laforge@openmoko.org>
---
 drivers/mfd/glamo/glamo-core.c |   32 ++++++++++++++++++++++++++++++++
 drivers/mfd/glamo/glamo-core.h |    6 ++++++
 drivers/mfd/glamo/glamo-fb.c   |   29 ++++++++++++++++++++++++++++-
 3 files changed, 66 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index 2619c5f..58ee3e2 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -524,6 +524,38 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
 }
 EXPORT_SYMBOL_GPL(glamo_engine_disable);
 
+static const u_int16_t engine_clock_regs[__NUM_GLAMO_ENGINES] = {
+	[GLAMO_ENGINE_LCD]	= GLAMO_REG_CLOCK_LCD,
+	[GLAMO_ENGINE_MMC]	= GLAMO_REG_CLOCK_MMC,
+	[GLAMO_ENGINE_ISP]	= GLAMO_REG_CLOCK_ISP,
+	[GLAMO_ENGINE_JPEG]	= GLAMO_REG_CLOCK_JPEG,
+	[GLAMO_ENGINE_3D]	= GLAMO_REG_CLOCK_3D,
+	[GLAMO_ENGINE_2D]	= GLAMO_REG_CLOCK_2D,
+	[GLAMO_ENGINE_MPEG_ENC] = GLAMO_REG_CLOCK_MPEG,
+	[GLAMO_ENGINE_MPEG_DEC] = GLAMO_REG_CLOCK_MPEG,
+};
+
+void glamo_engine_clkreg_set(struct glamo_core *glamo,
+			     enum glamo_engine engine,
+			     u_int16_t mask, u_int16_t val)
+{
+	reg_set_bit_mask(glamo, engine_clock_regs[engine], mask, val);
+}
+EXPORT_SYMBOL_GPL(glamo_engine_clkreg_set);
+
+u_int16_t glamo_engine_clkreg_get(struct glamo_core *glamo,
+				  enum glamo_engine engine)
+{
+	u_int16_t val;
+
+	spin_lock(&glamo->lock);
+	val = __reg_read(glamo, engine_clock_regs[engine]);
+	spin_unlock(&glamo->lock);
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(glamo_engine_clkreg_get);
+
 struct glamo_script reset_regs[] = {
 	[GLAMO_ENGINE_LCD] = {
 		GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET
diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
index ac5eacf..fb5f0f6 100644
--- a/drivers/mfd/glamo/glamo-core.h
+++ b/drivers/mfd/glamo/glamo-core.h
@@ -98,4 +98,10 @@ void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine);
 int glamo_engine_reclock(struct glamo_core *glamo,
 			 enum glamo_engine engine, int ps);
 
+void glamo_engine_clkreg_set(struct glamo_core *glamo,
+			     enum glamo_engine engine,
+			     u_int16_t mask, u_int16_t val);
+
+u_int16_t glamo_engine_clkreg_get(struct glamo_core *glamo,
+				  enum glamo_engine engine);
 #endif /* __GLAMO_CORE_H */
diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
index 8f5d6b1..5cd6e05 100644
--- a/drivers/mfd/glamo/glamo-fb.c
+++ b/drivers/mfd/glamo/glamo-fb.c
@@ -420,7 +420,34 @@ static int glamofb_set_par(struct fb_info *info)
 
 static int glamofb_blank(int blank_mode, struct fb_info *info)
 {
-	/* FIXME */
+	struct glamofb_handle *gfb = info->par;
+	struct glamo_core *gcore = gfb->mach_info->glamo;
+
+	dev_dbg(gfb->dev, "glamofb_blank(%u)\n", blank_mode);
+
+	switch (blank_mode) {
+	case FB_BLANK_VSYNC_SUSPEND:
+	case FB_BLANK_HSYNC_SUSPEND:
+		/* FIXME: add pdata hook/flag to indicate whether
+		 * we should already switch off pixel clock here */
+		break;
+	case FB_BLANK_POWERDOWN:
+		/* disable the pixel clock */
+		glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD,
+					GLAMO_CLOCK_LCD_EN_DCLK, 0);
+		break;
+	case FB_BLANK_UNBLANK:
+	case FB_BLANK_NORMAL:
+		/* enable the pixel clock */
+		glamo_engine_clkreg_set(gcore, GLAMO_ENGINE_LCD,
+					GLAMO_CLOCK_LCD_EN_DCLK,
+					GLAMO_CLOCK_LCD_EN_DCLK);
+		break;
+	}
+
+	/* FIXME: once we have proper clock management in glamo-core,
+	 * we can determine if other units need MCLK1 or the PLL, and
+	 * disable it if not used. */
 	return 0;
 }
 
-- 
1.5.6.5