1 /*
2 (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
3 (c) Copyright 2000-2004 Convergence (integrated media) GmbH
4
5 All rights reserved.
6
7 Written by Denis Oliver Kropp <dok@directfb.org>,
8 Andreas Hundt <andi@fischlustig.de>,
9 Sven Neumann <neo@directfb.org>,
10 Ville Syrjälä <syrjala@sci.fi> and
11 Claudio Ciccani <klan@users.sf.net>.
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the
25 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA.
27 */
28
29 #include <directfb.h>
30
31 #include <core/coredefs.h>
32
33 #include "cyber5k.h"
34 #include "cyber5k_overlay.h"
35 #include "regs.h"
36 #include "mmio.h"
37
38 static int overlay_byte_per_pixel = 2;
39 static int overlay_init = 0;
40
41 static unsigned char savedReg74, savedReg75; /*FIFO control registers for 2D Graphics*/
42 static unsigned char savedRegD9[2], savedRegDA[2], savedRegDD[2]; /*FIFO control registers for Overlay*/
43 /*Following is our FIFO policy number, should be programmed to
44 0x3CE/0x74, 0x3CE/0x75, 0x3CE(0x3C4)/0xD9, 0x3CE(0x3C4)/0xDA,
45 0x3CE(0x3c4)/0xDD respectively in order to get a best memory bandwidth.
46 Current value is a group of experence value based on 70MHZ EDO/SG RAM.*/
47 static unsigned char bFIFOPolicyNum[5] = {0x10, 0x10, 0x1C, 0x1C, 0x06};
48
49
50 static void
cyber_videoreg_mask(unsigned char index,unsigned char value,unsigned char mask)51 cyber_videoreg_mask( unsigned char index, unsigned char value, unsigned char mask )
52 {
53 unsigned char tmp;
54
55 cyber_out8( cyber_mmio, GRAINDEX, index );
56 tmp = cyber_in8( cyber_mmio, GRADATA );
57 tmp &= mask;
58 tmp |= value;
59 cyber_out8( cyber_mmio, GRADATA, tmp );
60 }
61
62 static void
cyber_seqreg_mask(unsigned char index,unsigned char value,unsigned char mask)63 cyber_seqreg_mask( unsigned char index, unsigned char value, unsigned char mask )
64 {
65 unsigned char tmp;
66
67 cyber_out8( cyber_mmio, SEQINDEX, index );
68 tmp = cyber_in8( cyber_mmio, SEQDATA );
69
70 tmp &= mask;
71 tmp |= value;
72 cyber_out8( cyber_mmio, SEQDATA, tmp );
73 }
74
75 static void
cyber_overlayreg_mask(unsigned char index,unsigned char value,unsigned char mask)76 cyber_overlayreg_mask( unsigned char index, unsigned char value, unsigned char mask ) {
77 unsigned char tmp;
78
79 cyber_out8( cyber_mmio, GRAINDEX, index );
80 tmp = cyber_in8( cyber_mmio, GRADATA );
81
82 tmp &= mask;
83 tmp |= value;
84 cyber_out8(cyber_mmio, GRADATA, tmp);
85 }
86
cyber_cleanup_overlay(void)87 void cyber_cleanup_overlay(void)
88 {
89 /*restore FIFO control regs*/
90 cyber_seqreg_mask(0xA7, 0x0, ~0x5);
91
92
93 if (!overlay_init)
94 return;
95 overlay_init = 0;
96
97
98 cyber_grphw(0x74, savedReg74);
99 cyber_grphw(0x75, savedReg75);
100
101 cyber_grphw(0xD9, savedRegD9[0]);
102 cyber_grphw(0xDA, savedRegDA[0]);
103 cyber_grphw(0xDD, savedRegDD[0]);
104
105 cyber_seqw(0xD9, savedRegD9[1]);
106 cyber_seqw(0xDA, savedRegDA[1]);
107 cyber_seqw(0xDD, savedRegDD[1]);
108 }
109
cyber_init_overlay(void)110 void cyber_init_overlay(void)
111 {
112 /*Clear Overlay path first*/
113 cyber_grphw(DISP_CTL_I, 0x00);
114
115 /* Video Display Vertical Starting Line (may not need initiate here)*/
116 cyber_grphw(DEST_RECT_TOP_L, 0x00);
117 cyber_grphw(DEST_RECT_TOP_H, 0x00);
118
119 /* Overlay Vertical DDA Increment Value*/
120 cyber_grphw(DDA_Y_INC_L, 0x00);
121 cyber_grphw(DDA_Y_INC_H, 0x10);
122
123 /* Video Memory Starting Address*/
124 cyber_grphw(MEMORY_START_L, 0x00);
125 cyber_grphw(MEMORY_START_M, 0x0f);
126 cyber_grphw(MEMORY_START_H, 0x03); /* Temporary fixed to 0x30f00 = 0xc3c00 >> 2*/
127 /* 0x3c00 = 0x300*0x14 = 768*20*/
128
129 /* Video Display Horizontal Starting Pixel -- may not need init here*/
130 cyber_grphw(DEST_RECT_LEFT_L, 0x20);
131 cyber_grphw(DEST_RECT_LEFT_H, 0x00);
132
133 /* Video Display Horizontal Ending Pixel -- may not need init here*/
134 cyber_grphw(DEST_RECT_RIGHT_L, 0x60);
135 cyber_grphw(DEST_RECT_RIGHT_H, 0x01);
136
137 /* Video Display Vertical Ending Line -- may not need init here*/
138 cyber_grphw(DEST_RECT_BOTTOM_L, 0xe0);
139 cyber_grphw(DEST_RECT_BOTTOM_H, 0x00);
140
141 /* Video Color Compare Register*/
142 cyber_grphw(COLOR_CMP_RED, 0x00);
143 cyber_grphw(COLOR_CMP_GREEN,0x00);
144 cyber_grphw(COLOR_CMP_BLUE, 0x00);
145
146 /* Video Horizontal DDA Increment Value*/
147 cyber_grphw(DDA_X_INC_L, 0x00);
148 cyber_grphw(DDA_X_INC_H, 0x10);
149
150 /* Video Format Control*/
151 cyber_grphw(VIDEO_FORMAT, 0x00);
152
153 /* Video Misc Control*/
154 cyber_grphw(MISC_CTL_I, 0x00);
155
156 cyber_grphw(MISC_CTL_I, 0x01); /* Video Misc Control*/
157
158 /*default to colorkey*/
159 cyber_grphw(DISP_CTL_I, 0x04 );
160
161 #ifdef NTSCTVOUT /*if your TV output mode is NTSC*/
162 cyber_seqreg_mask(0xA6, 0x20, ~0x30);
163 #else /*if your TV output mode is PAL*/
164 cyber_seqreg_mask(0xA6, 0x30, ~0x30);
165 #endif
166
167
168 if (overlay_init)
169 return;
170 overlay_init = 1;
171
172
173
174 /* the following code is commented out, since saved values are not clean if */
175 /* DirectFB crashed while underlay was enabled, hardcoded bootup */
176 /* values instead (see below) */
177
178 /*
179 cyber_out8(cyber_mmio, GRAINDEX, 0x74);
180 savedReg74 = cyber_in8(cyber_mmio, GRADATA);
181 cyber_out8(cyber_mmio, GRAINDEX, 0x75);
182 savedReg75 = cyber_in8(cyber_mmio, GRADATA);
183
184 cyber_out8(cyber_mmio, GRAINDEX, 0xD9);
185 savedRegD9[0] = cyber_in8(cyber_mmio, GRADATA);
186 cyber_out8(cyber_mmio, GRAINDEX, 0xDA);
187 savedRegDA[0] = cyber_in8(cyber_mmio, GRADATA);
188 cyber_out8(cyber_mmio, GRAINDEX, 0xDD);
189 savedRegDD[0] = cyber_in8(cyber_mmio, GRADATA);
190
191 cyber_out8(cyber_mmio, SEQINDEX, 0xD9);
192 savedRegD9[1] = cyber_in8(cyber_mmio, SEQDATA);
193 cyber_out8(cyber_mmio, SEQINDEX, 0xDA);
194 savedRegDA[1] = cyber_in8(cyber_mmio, SEQDATA);
195 cyber_out8(cyber_mmio, SEQINDEX, 0xDD);
196 savedRegDD[1] = cyber_in8(cyber_mmio, SEQDATA);
197 */
198
199
200 savedReg74 = 0x1b;
201 savedReg74 = 0x1e;
202
203 savedRegD9[0] = 0x0f;
204 savedRegDA[0] = 0x1b;
205 savedRegDD[0] = 0x00;
206
207 savedRegD9[1] = 0x0f;
208 savedRegDA[1] = 0x1b;
209 savedRegDD[1] = 0x00;
210 }
211
cyber_change_overlay_fifo(void)212 void cyber_change_overlay_fifo(void)
213 {
214 cyber_grphw(0x74, bFIFOPolicyNum[0]);
215 cyber_grphw(0x75, bFIFOPolicyNum[1]);
216 cyber_grphw(0xD9, bFIFOPolicyNum[2]);
217 cyber_grphw(0xDA, bFIFOPolicyNum[3]);
218
219 cyber_videoreg_mask(0xA6, 0x08, ~0x08);
220 cyber_videoreg_mask(0xF1, 0x40, (unsigned char)(~0xC0));
221 cyber_overlayreg_mask(FIFO_CTL_I, bFIFOPolicyNum[4] & 0x05, ~0x05);
222 cyber_overlayreg_mask(FIFO_CTL_I, 0x2, ~0x02);
223 }
224
cyber_set_overlay_format(int format)225 void cyber_set_overlay_format(int format) {
226 switch (format) {
227 case OVERLAY_YUV422:
228 cyber_overlayreg_mask( VIDEO_FORMAT, 0x00, 0xF8 );
229 overlay_byte_per_pixel = 2;
230 break;
231 case OVERLAY_RGB555:
232 cyber_overlayreg_mask( VIDEO_FORMAT, 0x01, 0xF8 );
233 overlay_byte_per_pixel = 2;
234 break;
235 case OVERLAY_RGB565:
236 cyber_overlayreg_mask( VIDEO_FORMAT, 0x02, 0xF8 );
237 overlay_byte_per_pixel = 2;
238 break;
239 case OVERLAY_RGB888:
240 cyber_overlayreg_mask( VIDEO_FORMAT, 0x03, 0xF8 );
241 overlay_byte_per_pixel = 3;
242 break;
243 case OVERLAY_RGB8888:
244 cyber_overlayreg_mask( VIDEO_FORMAT, 0x04, 0xF8 );
245 overlay_byte_per_pixel = 4;
246 break;
247 case OVERLAY_RGB8:
248 cyber_overlayreg_mask( VIDEO_FORMAT, 0x05, 0xF8 );
249 overlay_byte_per_pixel = 1;
250 break;
251 case OVERLAY_RGB4444:
252 cyber_overlayreg_mask( VIDEO_FORMAT, 0x06, 0xF8 );
253 overlay_byte_per_pixel = 2;
254 break;
255 case OVERLAY_RGB8T:
256 cyber_overlayreg_mask( VIDEO_FORMAT, 0x07, 0xF8 );
257 overlay_byte_per_pixel = 1;
258 break;
259 }
260 }
261
cyber_set_overlay_mode(int mode)262 void cyber_set_overlay_mode(int mode)
263 {
264 switch (mode) {
265 case OVERLAY_COLORKEY:
266 cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0xFD );
267 break;
268 case OVERLAY_WINDOWKEY:
269 default:
270 cyber_overlayreg_mask( DISP_CTL_I, 0x02, 0xFD );
271 break;
272 }
273 }
274
cyber_set_overlay_srcaddr(int addr,int x,int y,int width,int pitch)275 void cyber_set_overlay_srcaddr(int addr, int x, int y, int width, int pitch)
276 {
277 unsigned char bHigh;
278 int wByteFetch;
279
280 addr += y * pitch + x * overlay_byte_per_pixel;
281 addr >>= 2;
282
283 /*playback start addr*/
284 cyber_grphw( MEMORY_START_L, (unsigned char)( addr & 0x0000FF) );
285 cyber_grphw( MEMORY_START_M, (unsigned char)((addr & 0x00FF00) >> 8) );
286 cyber_grphw( MEMORY_START_H, (unsigned char)((addr & 0xFF0000) >> 16) );
287
288 /* pitch is a multiple of 64 bits*/
289 pitch >>= 3; /* 64 bit address field*/
290 wByteFetch = (width * overlay_byte_per_pixel + 7) >> 3;
291
292 bHigh = (unsigned char)(pitch >> 8) & 0x0F;
293 bHigh = bHigh | (((unsigned char)(wByteFetch >> 8)) << 4 );
294
295 cyber_grphw( MEMORY_PITCH_L, (unsigned char)(pitch) );
296 cyber_grphw( MEMORY_PITCH_H, bHigh );
297
298 cyber_grphw( MEMORY_OFFSET_PHASE, (unsigned char)(wByteFetch) );
299
300 if (width > 720) /*Turn off interpolation*/
301 cyber_overlayreg_mask( DISP_CTL_I, 0x20, 0xDF );
302 else { /*Turn off interpolation*/
303 if (width > 360) { /* Y Only*/
304 cyber_seqreg_mask(0xA6, 0x40, ~0x40);
305 }
306 else {
307 cyber_seqreg_mask(0xA6, 0x00, ~0x40);
308 }
309
310 cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0xDF );
311 }
312 }
313
cyber_set_overlay_window(int left,int top,int right,int bottom)314 void cyber_set_overlay_window(int left, int top, int right, int bottom)
315 {
316 cyber_grphw( DEST_RECT_LEFT_L, (unsigned char)(left ) );
317 cyber_grphw( DEST_RECT_LEFT_H, (unsigned char)(left >> 8) );
318 cyber_grphw( DEST_RECT_RIGHT_L, (unsigned char)(right ) );
319 cyber_grphw( DEST_RECT_RIGHT_H, (unsigned char)(right >> 8) );
320
321 cyber_grphw( DEST_RECT_TOP_L, (unsigned char)(top ) );
322 cyber_grphw( DEST_RECT_TOP_H, (unsigned char)(top >> 8) );
323 cyber_grphw( DEST_RECT_BOTTOM_L, (unsigned char)(bottom ) );
324 cyber_grphw( DEST_RECT_BOTTOM_H, (unsigned char)(bottom >> 8) );
325 }
326
cyber_set_overlay_scale(unsigned char bEnableBob,int wSrcXExt,int wDstXExt,int wSrcYExt,int wDstYExt)327 void cyber_set_overlay_scale( unsigned char bEnableBob, int wSrcXExt, int wDstXExt, int wSrcYExt, int wDstYExt )
328 {
329 int dwScale;
330
331 cyber_grphw( DDA_X_INIT_L, 0x0 ); /* set to 0x800;*/
332 cyber_grphw( DDA_X_INIT_H, 0x8 );
333 if ( wSrcXExt == wDstXExt )
334 dwScale = 0x1000;
335 else
336 dwScale = ( wSrcXExt * 0x1000 ) / wDstXExt;
337 cyber_grphw( DDA_X_INC_L, (unsigned char)( dwScale & 0x00FF) );
338 cyber_grphw( DDA_X_INC_H, (unsigned char)((dwScale & 0xFF00) >> 8) );
339
340 cyber_grphw( DDA_Y_INIT_L, 0x0 ); /* set to 0x800;*/
341 cyber_grphw( DDA_Y_INIT_H, 0x8 );
342
343 if ( wSrcYExt == wDstYExt )
344 dwScale = 0x1000;
345 else
346 dwScale = ( wSrcYExt * 0x1000 ) / wDstYExt;
347
348
349 if (bEnableBob == 0) {/*Disable Bob mode*/
350 cyber_seqreg_mask(0xA7, 0x0, ~0x5); /*Bob/Weave disable*/
351 }
352 else {/*Enable Bob mode*/
353 wSrcYExt = wSrcYExt / 2;
354 if (wSrcYExt == wDstYExt)
355 dwScale = 0x1000;
356 else
357 dwScale = ( wSrcYExt * 0x1000 ) / wDstYExt;
358 if (dwScale <= 0x815 && dwScale >= 0x7eb) {
359 cyber_seqreg_mask(0xA7, 0x5, ~0x5); /*Bob/Weave enable*/
360 }
361 else {
362 cyber_seqreg_mask(0xA7, 0x4, ~0x5); /*Bob/Weave enable*/
363 }
364 }
365
366 cyber_grphw( DDA_Y_INC_L, (unsigned char)( dwScale & 0x00FF) );
367 cyber_grphw( DDA_Y_INC_H, (unsigned char)((dwScale & 0xFF00) >> 8) );
368 }
369
cyber_enable_overlay(int enable)370 void cyber_enable_overlay(int enable)
371 {
372 if (enable)
373 cyber_overlayreg_mask( DISP_CTL_I, 0x84, (unsigned char)(~0x84) );
374 else
375 cyber_overlayreg_mask( DISP_CTL_I, 0x00, 0x7F ); /* Disable Vafc !!!*/
376 }
377