5265ae6b0a96e4c7737ce9d37d9adf18fb173a3f
[openembedded.git] /
1 From 77e848eeba461e9b55b09d39fd0d640caea13e19 Mon Sep 17 00:00:00 2001
2 From: Hardik Shah <hardik.shah@ti.com>
3 Date: Thu, 9 Apr 2009 12:09:44 +0530
4 Subject: [PATCH 27/69] DSS2: VRFB rotation and mirroring implemented.
5
6 DSS2 modified to accept the rotation_type input
7 to get the dma or VRFB rotation.
8
9 DSS2: VRFB: Changed to pass DSS mode to vrfb_setup instead of Bpp.
10
11 VRFB size registers requires the width to be halved when the
12 mode is YUV or UYVY.  So modifed to pass the mode to omap_vrfb_setup
13 function.
14
15 Code added by Tim Yamin for few bug fixes
16
17 Signed-off-by: Tim Yamin <plasm@roo.me.uk>
18 Signed-off-by: Hardik Shah <hardik.shah@ti.com>
19 ---
20  arch/arm/plat-omap/include/mach/display.h |    6 ++
21  arch/arm/plat-omap/include/mach/vrfb.h    |    3 +-
22  arch/arm/plat-omap/vrfb.c                 |   36 +++++++++-
23  drivers/video/omap2/dss/dispc.c           |  109 +++++++++++++++++++++++++++--
24  drivers/video/omap2/dss/dss.h             |    1 +
25  drivers/video/omap2/dss/manager.c         |    1 +
26  6 files changed, 144 insertions(+), 12 deletions(-)
27
28 diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
29 index 6b702c7..b0a6272 100644
30 --- a/arch/arm/plat-omap/include/mach/display.h
31 +++ b/arch/arm/plat-omap/include/mach/display.h
32 @@ -341,6 +341,11 @@ enum omap_dss_overlay_managers {
33  
34  struct omap_overlay_manager;
35  
36 +enum omap_dss_rotation_type {
37 +       OMAP_DSS_ROT_DMA = 0,
38 +       OMAP_DSS_ROT_VRFB = 1,
39 +};
40 +
41  struct omap_overlay_info {
42         bool enabled;
43  
44 @@ -351,6 +356,7 @@ struct omap_overlay_info {
45         u16 height;
46         enum omap_color_mode color_mode;
47         u8 rotation;
48 +       enum omap_dss_rotation_type rotation_type;
49         bool mirror;
50  
51         u16 pos_x;
52 diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h
53 index 2047862..12c7fab 100644
54 --- a/arch/arm/plat-omap/include/mach/vrfb.h
55 +++ b/arch/arm/plat-omap/include/mach/vrfb.h
56 @@ -24,6 +24,7 @@
57  #ifndef __VRFB_H
58  #define __VRFB_H
59  
60 +#include <mach/display.h>
61  #define OMAP_VRFB_LINE_LEN 2048
62  
63  struct vrfb
64 @@ -42,6 +43,6 @@ extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
65                 u8 bytespp);
66  extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
67                 u16 width, u16 height,
68 -               u8 bytespp);
69 +               enum omap_color_mode color_mode);
70  
71  #endif /* __VRFB_H */
72 diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
73 index d68065f..2f08f6d 100644
74 --- a/arch/arm/plat-omap/vrfb.c
75 +++ b/arch/arm/plat-omap/vrfb.c
76 @@ -5,7 +5,6 @@
77  
78  #include <mach/io.h>
79  #include <mach/vrfb.h>
80 -
81  /*#define DEBUG*/
82  
83  #ifdef DEBUG
84 @@ -50,19 +49,48 @@ EXPORT_SYMBOL(omap_vrfb_adjust_size);
85  
86  void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
87                 u16 width, u16 height,
88 -               u8 bytespp)
89 +               enum omap_color_mode color_mode)
90  {
91         unsigned pixel_size_exp;
92         u16 vrfb_width;
93         u16 vrfb_height;
94         u8 ctx = vrfb->context;
95 +       u8 bytespp;
96  
97         DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr,
98                         width, height, bytespp);
99  
100 -       if (bytespp == 4)
101 +       switch (color_mode) {
102 +       case OMAP_DSS_COLOR_RGB16:
103 +       case OMAP_DSS_COLOR_ARGB16:
104 +               bytespp = 2;
105 +               break;
106 +
107 +       case OMAP_DSS_COLOR_RGB24P:
108 +               bytespp = 3;
109 +               break;
110 +
111 +       case OMAP_DSS_COLOR_RGB24U:
112 +       case OMAP_DSS_COLOR_ARGB32:
113 +       case OMAP_DSS_COLOR_RGBA32:
114 +       case OMAP_DSS_COLOR_RGBX32:
115 +       case OMAP_DSS_COLOR_YUV2:
116 +       case OMAP_DSS_COLOR_UYVY:
117 +               bytespp = 4;
118 +               break;
119 +
120 +       default:
121 +               BUG();
122 +               return;
123 +       }
124 +
125 +       if (color_mode == OMAP_DSS_COLOR_YUV2 ||
126 +                       color_mode == OMAP_DSS_COLOR_UYVY)
127 +               width >>= 1;
128 +
129 +       if (bytespp == 4) {
130                 pixel_size_exp = 2;
131 -       else if (bytespp == 2)
132 +       } else if (bytespp == 2)
133                 pixel_size_exp = 1;
134         else
135                 BUG();
136 diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
137 index 16c68b8..23a8155 100644
138 --- a/drivers/video/omap2/dss/dispc.c
139 +++ b/drivers/video/omap2/dss/dispc.c
140 @@ -1106,7 +1106,7 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
141                         case 0: vidrot = 0; break;
142                         case 1: vidrot = 1; break;
143                         case 2: vidrot = 2; break;
144 -                       case 3: vidrot = 1; break;
145 +                       case 3: vidrot = 3; break;
146                         }
147                 }
148  
149 @@ -1134,7 +1134,92 @@ static s32 pixinc(int pixels, u8 ps)
150                 BUG();
151  }
152  
153 -static void calc_rotation_offset(u8 rotation, bool mirror,
154 +static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
155 +               u16 screen_width,
156 +               u16 width, u16 height,
157 +               enum omap_color_mode color_mode, bool fieldmode,
158 +               unsigned *offset0, unsigned *offset1,
159 +               s32 *row_inc, s32 *pix_inc)
160 +{
161 +       u8 ps;
162 +
163 +       switch (color_mode) {
164 +       case OMAP_DSS_COLOR_RGB16:
165 +       case OMAP_DSS_COLOR_ARGB16:
166 +               ps = 2;
167 +               break;
168 +
169 +       case OMAP_DSS_COLOR_RGB24P:
170 +               ps = 3;
171 +               break;
172 +
173 +       case OMAP_DSS_COLOR_RGB24U:
174 +       case OMAP_DSS_COLOR_ARGB32:
175 +       case OMAP_DSS_COLOR_RGBA32:
176 +       case OMAP_DSS_COLOR_RGBX32:
177 +       case OMAP_DSS_COLOR_YUV2:
178 +       case OMAP_DSS_COLOR_UYVY:
179 +               ps = 4;
180 +               break;
181 +
182 +       default:
183 +               BUG();
184 +               return;
185 +       }
186 +
187 +       DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width,
188 +                       width, height);
189 +       switch (rotation + mirror * 4) {
190 +       case 0:
191 +       case 2:
192 +               /*
193 +                * If the pixel format is YUV or UYVY divide the width
194 +                * of the image by 2 for 0 and 180 degree rotation.
195 +                */
196 +               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
197 +                       color_mode == OMAP_DSS_COLOR_UYVY)
198 +                       width = width >> 1;
199 +       case 1:
200 +       case 3:
201 +               *offset0 = 0;
202 +               if (fieldmode)
203 +                       *offset1 = screen_width * ps;
204 +               else
205 +                       *offset1 = 0;
206 +
207 +               *row_inc = pixinc(1 + (screen_width - width) +
208 +                               (fieldmode ? screen_width : 0),
209 +                               ps);
210 +               *pix_inc = pixinc(1, ps);
211 +               break;
212 +
213 +       case 4:
214 +       case 6:
215 +               /* If the pixel format is YUV or UYVY divide the width
216 +                * of the image by 2  for 0 degree and 180 degree
217 +                */
218 +               if (color_mode == OMAP_DSS_COLOR_YUV2 ||
219 +                       color_mode == OMAP_DSS_COLOR_UYVY)
220 +                       width = width >> 1;
221 +       case 5:
222 +       case 7:
223 +               *offset0 = 0;
224 +               if (fieldmode)
225 +                       *offset1 = screen_width * ps;
226 +               else
227 +                       *offset1 = 0;
228 +               *row_inc = pixinc(1 - (screen_width + width) -
229 +                               (fieldmode ? screen_width : 0),
230 +                               ps);
231 +               *pix_inc = pixinc(1, ps);
232 +               break;
233 +
234 +       default:
235 +               BUG();
236 +       }
237 +}
238 +
239 +static void calc_dma_rotation_offset(u8 rotation, bool mirror,
240                 u16 screen_width,
241                 u16 width, u16 height,
242                 enum omap_color_mode color_mode, bool fieldmode,
243 @@ -1357,6 +1442,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
244                 u16 out_width, u16 out_height,
245                 enum omap_color_mode color_mode,
246                 bool ilace,
247 +               enum omap_dss_rotation_type rotation_type,
248                 u8 rotation, int mirror)
249  {
250         const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
251 @@ -1463,10 +1549,16 @@ static int _dispc_setup_plane(enum omap_plane plane,
252                         return -EINVAL;
253         }
254  
255 -       calc_rotation_offset(rotation, mirror,
256 -                       screen_width, width, frame_height, color_mode,
257 -                       fieldmode,
258 -                       &offset0, &offset1, &row_inc, &pix_inc);
259 +       if (rotation_type == OMAP_DSS_ROT_DMA)
260 +               calc_dma_rotation_offset(rotation, mirror,
261 +                               screen_width, width, frame_height, color_mode,
262 +                               fieldmode,
263 +                               &offset0, &offset1, &row_inc, &pix_inc);
264 +       else
265 +               calc_vrfb_rotation_offset(rotation, mirror,
266 +                               screen_width, width, frame_height, color_mode,
267 +                               fieldmode,
268 +                               &offset0, &offset1, &row_inc, &pix_inc);
269  
270         DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
271                         offset0, offset1, row_inc, pix_inc);
272 @@ -2889,6 +2981,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
273                        u16 out_width, u16 out_height,
274                        enum omap_color_mode color_mode,
275                        bool ilace,
276 +                      enum omap_dss_rotation_type rotation_type,
277                        u8 rotation, bool mirror)
278  {
279         int r = 0;
280 @@ -2909,6 +3002,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
281                            width, height,
282                            out_width, out_height,
283                            color_mode, ilace,
284 +                          rotation_type,
285                            rotation, mirror);
286  
287         enable_clocks(0);
288 @@ -3122,7 +3216,8 @@ void dispc_setup_partial_planes(struct omap_display *display,
289                                 pw, ph,
290                                 pow, poh,
291                                 pi->color_mode, 0,
292 -                               pi->rotation, // XXX rotation probably wrong
293 +                               pi->rotation_type,
294 +                               pi->rotation,
295                                 pi->mirror);
296  
297                 dispc_enable_plane(ovl->id, 1);
298 diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
299 index d0917a8..584dce6 100644
300 --- a/drivers/video/omap2/dss/dss.h
301 +++ b/drivers/video/omap2/dss/dss.h
302 @@ -272,6 +272,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
303                       u16 out_width, u16 out_height,
304                       enum omap_color_mode color_mode,
305                       bool ilace,
306 +                     enum omap_dss_rotation_type rotation_type,
307                       u8 rotation, bool mirror);
308  
309  void dispc_go(enum omap_channel channel);
310 diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
311 index b0fee80..8ca0bbb 100644
312 --- a/drivers/video/omap2/dss/manager.c
313 +++ b/drivers/video/omap2/dss/manager.c
314 @@ -395,6 +395,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
315                                 outh,
316                                 ovl->info.color_mode,
317                                 ilace,
318 +                               ovl->info.rotation_type,
319                                 ovl->info.rotation,
320                                 ovl->info.mirror);
321  
322 -- 
323 1.6.2.4
324