summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/dss2/0023-DSS2-pass-the-default-FB-color-format-through-board.patch
blob: 6492905530053bafe09aa7818ca1a83d88b3eb08 (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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
From c02b843c2732bc7b15a3e35b5dd715d68225bbd1 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Wed, 8 Apr 2009 12:51:46 +0200
Subject: [PATCH] DSS2: pass the default FB color format through board info

Add a field to the FB memory region platform data, so that board
init code can pass a default color format to the driver. Set this
format as an initial setting for the given FB.

This is needed for an upcoming patch that adds detection of the
color format set by the bootloader.

Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |  121 +++++++++++++++++++++++++++---
 drivers/video/omap2/omapfb/omapfb.h      |    2 +
 include/linux/omapfb.h                   |    5 +
 3 files changed, 117 insertions(+), 11 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 12ce0c3..67c67c2 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -370,6 +370,21 @@ static enum omap_color_mode fb_mode_to_dss_mode(struct fb_var_screeninfo *var)
 	return -EINVAL;
 }
 
+static int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
+			       struct fb_var_screeninfo *var)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+		struct omapfb_colormode *mode = &omapfb_colormodes[i];
+		if (dssmode == mode->dssmode) {
+			assign_colormode_to_var(var, mode);
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
 void set_fb_fix(struct fb_info *fbi)
 {
 	struct fb_fix_screeninfo *fix = &fbi->fix;
@@ -1267,6 +1282,60 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
 	return omapfb_alloc_fbmem(fbi, size, paddr);
 }
 
+static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format format)
+{
+	enum omap_color_mode mode;
+
+	switch (format) {
+	case OMAPFB_COLOR_RGB565:
+		mode = OMAP_DSS_COLOR_RGB16;
+		break;
+	case OMAPFB_COLOR_YUV422:
+		mode = OMAP_DSS_COLOR_YUV2;
+		break;
+	case OMAPFB_COLOR_CLUT_8BPP:
+		mode = OMAP_DSS_COLOR_CLUT8;
+		break;
+	case OMAPFB_COLOR_CLUT_4BPP:
+		mode = OMAP_DSS_COLOR_CLUT4;
+		break;
+	case OMAPFB_COLOR_CLUT_2BPP:
+		mode = OMAP_DSS_COLOR_CLUT2;
+		break;
+	case OMAPFB_COLOR_CLUT_1BPP:
+		mode = OMAP_DSS_COLOR_CLUT1;
+		break;
+	case OMAPFB_COLOR_RGB444:
+		mode = OMAP_DSS_COLOR_RGB12U;
+		break;
+	case OMAPFB_COLOR_YUY422:
+		mode = OMAP_DSS_COLOR_UYVY;
+		break;
+	case OMAPFB_COLOR_ARGB16:
+		mode = OMAP_DSS_COLOR_ARGB16;
+		break;
+	case OMAPFB_COLOR_RGB24U:
+		mode = OMAP_DSS_COLOR_RGB24U;
+		break;
+	case OMAPFB_COLOR_RGB24P:
+		mode = OMAP_DSS_COLOR_RGB24P;
+		break;
+	case OMAPFB_COLOR_ARGB32:
+		mode = OMAP_DSS_COLOR_ARGB32;
+		break;
+	case OMAPFB_COLOR_RGBA32:
+		mode = OMAP_DSS_COLOR_RGBA32;
+		break;
+	case OMAPFB_COLOR_RGBX32:
+		mode = OMAP_DSS_COLOR_RGBX32;
+		break;
+	default:
+		mode = -EINVAL;
+	}
+
+	return mode;
+}
+
 static int omapfb_parse_vram_param(const char *param, int max_entries,
 		unsigned long *sizes, unsigned long *paddrs)
 {
@@ -1483,9 +1552,36 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
 	}
 
 	var->nonstd = 0;
+	var->bits_per_pixel = 0;
 
 	var->rotate = ofbi->rotation;
 
+	/*
+	 * Check if there is a default color format set in the board file,
+	 * and use this format instead the default deducted from the
+	 * display bpp.
+	 */
+	if (fbdev->dev->platform_data) {
+		struct omapfb_platform_data *opd;
+		int id = ofbi->id;
+
+		opd = fbdev->dev->platform_data;
+		if (opd->mem_desc.region[id].format_used) {
+			enum omap_color_mode mode;
+			enum omapfb_color_format format;
+
+			format = opd->mem_desc.region[id].format;
+			mode = fb_format_to_dss_mode(format);
+			if (mode < 0) {
+				r = mode;
+				goto err;
+			}
+			r = dss_mode_to_fb_mode(mode, var);
+			if (r < 0)
+				goto err;
+		}
+	}
+
 	if (display) {
 		u16 w, h;
 		display->get_resolution(display, &w, &h);
@@ -1502,16 +1598,18 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
 		var->xres_virtual = var->xres;
 		var->yres_virtual = var->yres;
 
-		switch (display->get_recommended_bpp(display)) {
-		case 16:
-			var->bits_per_pixel = 16;
-			break;
-		case 24:
-			var->bits_per_pixel = 32;
-			break;
-		default:
-			dev_err(fbdev->dev, "illegal display bpp\n");
-			return -EINVAL;
+		if (!var->bits_per_pixel) {
+			switch (display->get_recommended_bpp(display)) {
+				case 16:
+					var->bits_per_pixel = 16;
+					break;
+				case 24:
+					var->bits_per_pixel = 32;
+					break;
+				default:
+					dev_err(fbdev->dev, "illegal display bpp\n");
+					return -EINVAL;
+			}
 		}
 	} else {
 		/* if there's no display, let's just guess some basic values */
@@ -1519,7 +1617,8 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
 		var->yres = 240;
 		var->xres_virtual = var->xres;
 		var->yres_virtual = var->yres;
-		var->bits_per_pixel = 16;
+		if (!var->bits_per_pixel)
+			var->bits_per_pixel = 16;
 	}
 
 	r = check_fb_var(fbi, var);
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 65e9e6e..2607def 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -27,6 +27,8 @@
 #define DEBUG
 #endif
 
+#include <mach/display.h>
+
 #ifdef DEBUG
 extern unsigned int omapfb_debug;
 #define DBG(format, ...) \
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 96190b2..7a34f22 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -298,6 +298,11 @@ struct omapfb_mem_region {
 	void __iomem	*vaddr;
 	unsigned long	size;
 	u8		type;		/* OMAPFB_PLANE_MEM_* */
+	enum omapfb_color_format format;/* OMAPFB_COLOR_* */
+	unsigned	format_used:1;	/* Must be set when format is set.
+					 * Needed b/c of the badly chosen 0
+					 * base for OMAPFB_COLOR_* values
+					 */
 	unsigned	alloc:1;	/* allocated by the driver */
 	unsigned	map:1;		/* kernel mapped by the driver */
 };
-- 
1.5.6.5