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