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
|
From a9cc890ffea21fa492678b1755a263120cbddf0e Mon Sep 17 00:00:00 2001
From: Tim Yamin <plasm@roo.me.uk>
Date: Mon, 20 Apr 2009 20:29:11 -0700
Subject: [PATCH] DSS2: OMAPFB: Translate X/Y coordinates for the video planes when rotating.
When rotating the video planes, translate the X/Y coordinates such that
a [0,0] from userspace always maps to the correct upper left corner of
the display. This patch assumes that you rotate plane 0 before rotating
plane 1. Patch also corrects the scaling parameters so that the video is
displayed in the correct orientation (vertically, instead of horizontally)
when rotating by 90 / 270 degrees.
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
---
drivers/video/omap2/dss/dispc.c | 16 ++++++++++++----
drivers/video/omap2/dss/overlay.c | 6 ++++++
drivers/video/omap2/omapfb/omapfb-ioctl.c | 28 ++++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 7e551c2..bece91d 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1580,10 +1580,18 @@ static int _dispc_setup_plane(enum omap_plane plane,
_dispc_set_pic_size(plane, width, height);
if (plane != OMAP_DSS_GFX) {
- _dispc_set_scaling(plane, width, height,
- out_width, out_height,
- ilace, five_taps, fieldmode);
- _dispc_set_vid_size(plane, out_width, out_height);
+ if (rotation == 1 || rotation == 3) {
+ _dispc_set_scaling(plane, width, height,
+ out_height, out_width,
+ ilace, five_taps, fieldmode);
+ _dispc_set_vid_size(plane, out_height, out_width);
+ } else {
+ _dispc_set_scaling(plane, width, height,
+ out_width, out_height,
+ ilace, five_taps, fieldmode);
+ _dispc_set_vid_size(plane, out_width, out_height);
+ }
+
_dispc_set_vid_color_conv(plane, cconv);
}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index c047206..a1a02b5 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -344,6 +344,20 @@
outh = info->out_height;
}
+ if ((ovl->supported_modes & info->color_mode) == 0) {
+ DSSERR("overlay doesn't support mode %d\n", info->color_mode);
+ return -EINVAL;
+ }
+
+ if (ovl->id != OMAP_DSS_GFX && (info->rotation == 1 ||
+ info->rotation == 3)) {
+ if(outw > dh || outh > dw)
+ return -EINVAL;
+
+ /* If coordinates are invalid, they will be clipped later... */
+ return 0;
+ }
+
if (dw < info->pos_x + outw) {
DSSDBG("check_overlay failed 1: %d < %d + %d\n",
dw, info->pos_x, outw);
@@ -356,11 +370,6 @@
return -EINVAL;
}
- if ((ovl->supported_modes & info->color_mode) == 0) {
- DSSERR("overlay doesn't support mode %d\n", info->color_mode);
- return -EINVAL;
- }
-
return 0;
}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 79d8916..b548f62 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -400,7 +400,7 @@
struct omap_overlay *ovl;
bool ilace = 0;
int outw, outh;
- int r;
+ int r, pos_x = 0, pos_y = 0;
int num_planes_enabled = 0;
DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
@@ -451,11 +451,51 @@
else
outh = ovl->info.out_height;
+ if (ovl->id != OMAP_DSS_GFX && ovl->info.rotation != 0) {
+ /* We need to rotate pos_x and pos_y with respect
+ to OMAP_DSS_GFX */
+
+ u16 dw, dh;
+ display->get_resolution(display, &dw, &dh);
+
+ DSSDBG("plane pos was: (%d, %d), %dx%d, scr: %dx%d \n", ovl->info.pos_x,
+ ovl->info.pos_y, outw, outh, dw, dh);
+
+ switch (ovl->info.rotation) {
+ case 1:
+ pos_y = ovl->info.pos_x;
+ pos_x = dw - ovl->info.pos_y - outh;
+ break;
+ case 2:
+ pos_x = dw - ovl->info.pos_x - outw;
+ pos_y = dh - ovl->info.pos_y - outh;
+ break;
+ case 3:
+ pos_x = ovl->info.pos_y;
+ pos_y = dh - ovl->info.pos_x - outw;
+ break;
+ }
+
+ /* Check sanity */
+ if (ovl->info.rotation != 2) {
+ if (dw < pos_x + outh)
+ pos_x = pos_y = 0;
+ else if (dh < pos_y + outw)
+ pos_x = pos_y = 0;
+ } else if ( (dw < ovl->info.pos_x + outw) || (dh < ovl->info.pos_y + outh) )
+ pos_x = pos_y = 0;
+
+ DSSDBG("pos_x is %d, pos_y is %d\n", pos_x, pos_y);
+ } else {
+ pos_x = ovl->info.pos_x;
+ pos_y = ovl->info.pos_y;
+ }
+
r = dispc_setup_plane(ovl->id, ovl->manager->id,
ovl->info.paddr,
ovl->info.screen_width,
- ovl->info.pos_x,
- ovl->info.pos_y,
+ pos_x,
+ pos_y,
ovl->info.width,
ovl->info.height,
outw,
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 79d8916..b548f62 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -484,22 +484,7 @@
if (var->rotate != fbi->var.rotate) {
DBG("rotation changing\n");
-
ofbi->rotation = var->rotate;
-
- if (abs(var->rotate - fbi->var.rotate) != 2) {
- int tmp;
- DBG("rotate changing 90/270 degrees. "
- "swapping x/y res\n");
-
- tmp = var->yres;
- var->yres = var->xres;
- var->xres = tmp;
-
- tmp = var->yres_virtual;
- var->yres_virtual = var->xres_virtual;
- var->xres_virtual = tmp;
- }
}
xres_min = OMAPFB_PLANE_XRES_MIN;
|