]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/sed13806.c
* Fix startup problems with VFD display on TRAB
[karo-tx-uboot.git] / drivers / sed13806.c
1 /*
2  * (C) Copyright 2002
3  * Stäubli Faverges - <www.staubli.com>
4  * Pierre AUBERT  p.aubert@staubli.com
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24 /* Video support for Epson SED13806 chipset                                  */
25
26 #include <common.h>
27
28 #ifdef CONFIG_VIDEO_SED13806
29
30 #include <video_fb.h>
31 #include <sed13806.h>
32
33 #define readByte(ptrReg)                \
34     *(volatile unsigned char *)(sed13806.isaBase + ptrReg)
35
36 #define writeByte(ptrReg,value) \
37     *(volatile unsigned char *)(sed13806.isaBase + ptrReg) = value
38
39 #define writeWord(ptrReg,value) \
40     (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = ((value >> 8 ) & 0xff) | ((value << 8) & 0xff00))
41
42
43 GraphicDevice sed13806;
44
45 /*-----------------------------------------------------------------------------
46  * EpsonSetRegs -- 
47  *-----------------------------------------------------------------------------
48  */
49 static void EpsonSetRegs (void)
50 {
51     /* the content of the chipset register depends on the board (clocks, ...)*/
52     const S1D_REGS *preg = board_get_regs ();
53     while (preg -> Index) {
54         writeByte (preg -> Index, preg -> Value);
55         preg ++;
56     }
57 }
58     
59 /*-----------------------------------------------------------------------------
60  * video_hw_init -- 
61  *-----------------------------------------------------------------------------
62  */
63 void *video_hw_init (void)
64 {
65     unsigned int *vm, i;
66
67     memset (&sed13806, 0, sizeof (GraphicDevice));
68
69     /* Initialization of the access to the graphic chipset
70        Retreive base address of the chipset
71        (see board/RPXClassic/eccx.c)                                         */
72     if ((sed13806.isaBase = board_video_init ()) == 0) {
73         return (NULL);
74     }
75
76     sed13806.frameAdrs = sed13806.isaBase + FRAME_BUFFER_OFFSET;
77     sed13806.winSizeX = board_get_width ();
78     sed13806.winSizeY = board_get_height ();
79
80 #if defined(CONFIG_VIDEO_SED13806_8BPP)
81     sed13806.gdfIndex = GDF__8BIT_INDEX;
82     sed13806.gdfBytesPP = 1;
83     
84 #elif defined(CONFIG_VIDEO_SED13806_16BPP)
85     sed13806.gdfIndex = GDF_16BIT_565RGB;
86     sed13806.gdfBytesPP = 2;
87
88 #else
89 #error Unsupported SED13806 BPP
90 #endif
91
92     sed13806.memSize = sed13806.winSizeX * sed13806.winSizeY * sed13806.gdfBytesPP;
93
94     /* Load SED registers                                                    */
95     EpsonSetRegs ();
96
97     /* (see board/RPXClassic/RPXClassic.c)                                   */
98     board_validate_screen (sed13806.isaBase);
99
100     /* Clear video memory */
101     i = sed13806.memSize/4;
102     vm = (unsigned int *)sed13806.frameAdrs;
103     while(i--)
104         *vm++ = 0;
105     
106     
107     return (&sed13806);
108 }
109 /*-----------------------------------------------------------------------------
110  * Epson_wait_idle -- Wait for hardware to become idle
111  *-----------------------------------------------------------------------------
112  */
113 static void Epson_wait_idle (void)
114 {
115     while (readByte (BLT_CTRL0) & 0x80);
116
117     /* Read a word in the BitBLT memory area to shutdown the BitBLT engine   */
118     *(volatile unsigned short *)(sed13806.isaBase + BLT_REG);
119 }
120
121 /*-----------------------------------------------------------------------------
122  * video_hw_bitblt -- 
123  *-----------------------------------------------------------------------------
124  */
125 void video_hw_bitblt (
126     unsigned int bpp,             /* bytes per pixel */
127     unsigned int src_x,           /* source pos x */
128     unsigned int src_y,           /* source pos y */
129     unsigned int dst_x,           /* dest pos x */
130     unsigned int dst_y,           /* dest pos y */
131     unsigned int dim_x,           /* frame width */
132     unsigned int dim_y            /* frame height */
133     )
134 {
135     register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
136     unsigned long       srcAddr, dstAddr;
137     unsigned int stride = bpp * pGD -> winSizeX;
138
139     srcAddr = (src_y * stride) + (src_x * bpp);
140     dstAddr = (dst_y * stride) + (dst_x * bpp);
141
142     Epson_wait_idle ();
143     
144     writeByte(BLT_ROP,0x0C);    // source
145     writeByte(BLT_OP,0x02);// move blit in positive direction with ROP
146     writeWord(BLT_MEM_OFF0, stride / 2);
147     if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
148         writeByte(BLT_CTRL1,0x00);
149     }
150     else {
151         writeByte(BLT_CTRL1,0x01);
152     }
153
154     writeWord(BLT_WIDTH0,(dim_x - 1));
155     writeWord(BLT_HEIGHT0,(dim_y - 1));
156     
157     /* set up blit registers                                                 */
158     writeByte(BLT_SRC_ADDR0,srcAddr);
159     writeByte(BLT_SRC_ADDR1,srcAddr>>8); 
160     writeByte(BLT_SRC_ADDR2,srcAddr>>16); 
161     
162     writeByte(BLT_DST_ADDR0,dstAddr);
163     writeByte(BLT_DST_ADDR1,dstAddr>>8); 
164     writeByte(BLT_DST_ADDR2,dstAddr>>16); 
165     
166     /* Engage the blt engine                                                 */
167     /* rectangular region for src and dst                                    */
168     writeByte(BLT_CTRL0,0x80);
169
170     /* wait untill current blits finished                                    */
171     Epson_wait_idle ();
172 }
173 /*-----------------------------------------------------------------------------
174  * video_hw_rectfill -- 
175  *-----------------------------------------------------------------------------
176  */
177 void video_hw_rectfill (
178     unsigned int bpp,             /* bytes per pixel */
179     unsigned int dst_x,           /* dest pos x */
180     unsigned int dst_y,           /* dest pos y */
181     unsigned int dim_x,           /* frame width */
182     unsigned int dim_y,           /* frame height */
183     unsigned int color            /* fill color */
184      )
185 {
186     register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
187     unsigned long       dstAddr;
188     unsigned int stride = bpp * pGD -> winSizeX;
189
190     dstAddr = (dst_y * stride) + (dst_x * bpp);
191
192     Epson_wait_idle ();
193
194     /* set up blit registers                                                 */
195     writeByte(BLT_DST_ADDR0,dstAddr);
196     writeByte(BLT_DST_ADDR1,dstAddr>>8); 
197     writeByte(BLT_DST_ADDR2,dstAddr>>16); 
198
199     writeWord(BLT_WIDTH0,(dim_x - 1));
200     writeWord(BLT_HEIGHT0,(dim_y - 1));
201     writeWord(BLT_FGCOLOR0,color);
202
203     writeByte(BLT_OP,0x0C);  /* solid fill                                   */
204     writeWord(BLT_MEM_OFF0,stride / 2);
205
206     if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
207         writeByte(BLT_CTRL1,0x00);
208     }
209     else {
210         writeByte(BLT_CTRL1,0x01);
211     }
212         
213     /* Engage the blt engine                                                 */
214     /* rectangular region for src and dst                                    */
215     writeByte(BLT_CTRL0,0x80);
216
217     /* wait untill current blits finished                                    */
218     Epson_wait_idle ();
219 }
220
221 /*-----------------------------------------------------------------------------
222  * video_set_lut -- 
223  *-----------------------------------------------------------------------------
224  */
225 void video_set_lut (
226     unsigned int index,           /* color number */
227     unsigned char r,              /* red */
228     unsigned char g,              /* green */
229     unsigned char b               /* blue */
230     )
231 {
232     writeByte(REG_LUT_ADDR, index );
233     writeByte(REG_LUT_DATA, r);
234     writeByte(REG_LUT_DATA, g);
235     writeByte(REG_LUT_DATA, b);
236 }
237 #ifdef CONFIG_VIDEO_HW_CURSOR
238 /*-----------------------------------------------------------------------------
239  * video_set_hw_cursor -- 
240  *-----------------------------------------------------------------------------
241  */
242 void video_set_hw_cursor (int x, int y)
243 {
244     writeByte (LCD_CURSOR_XL, (x & 0xff));
245     writeByte (LCD_CURSOR_XM, (x >> 8));
246     writeByte (LCD_CURSOR_YL, (y & 0xff));
247     writeByte (LCD_CURSOR_YM, (y >> 8));
248 }
249
250 /*-----------------------------------------------------------------------------
251  * video_init_hw_cursor -- 
252  *-----------------------------------------------------------------------------
253  */
254 void video_init_hw_cursor (int font_width, int font_height)
255 {
256     volatile unsigned char *ptr;
257     unsigned char pattern;
258     int i;
259     
260
261     /* Init cursor content
262        Cursor size is 64x64 pixels
263        Start of the cursor memory depends on panel type (dual panel ...)     */
264     if ((i = readByte (LCD_CURSOR_START)) == 0) {
265         ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - HWCURSORSIZE);
266     }
267     else {
268         ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - (i * 8192));
269     }
270
271     /* Fill the first line and the first empty line after cursor             */
272     for (i = 0, pattern = 0; i < 64; i++) {
273         if (i < font_width) {
274             /* Invert background                                             */
275             pattern |= 0x3;
276             
277         }
278         else {
279             /* Background                                                    */
280             pattern |= 0x2;
281         }
282         if ((i & 3) == 3) {
283             *ptr = pattern;
284             *(ptr + font_height * 16) = 0xaa;
285             ptr ++;
286             pattern = 0;
287         }
288         pattern <<= 2;
289     }
290
291     /* Duplicate this line                                                   */
292     for (i = 1; i < font_height; i++) {
293         memcpy ((void *)ptr, (void *)(ptr - 16), 16);
294         ptr += 16;
295     }
296     
297     for (; i < 64; i++) {
298         memcpy ((void *)(ptr + 16), (void *)ptr, 16);
299         ptr += 16;
300     }
301
302     /* Select cursor mode                                                    */
303     writeByte (LCD_CURSOR_CNTL, 1);
304 }
305 #endif
306 #endif