~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/video/fbcon-sti.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * linux/drivers/video/fbcon-sti.c -- Low level frame buffer
  3  *      operations for generic HP video boards using STI (standard
  4  *      text interface) firmware
  5  *
  6  *  Based on linux/drivers/video/fbcon-artist.c
  7  *      Created 5 Apr 1997 by Geert Uytterhoeven
  8  *      Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
  9  *
 10  * This file is subject to the terms and conditions of the GNU General Public
 11  * License.  See the file COPYING in the main directory of this archive for
 12  * more details.  */
 13 
 14 #include <linux/module.h>
 15 #include <linux/tty.h>
 16 #include <linux/console.h>
 17 #include <linux/string.h>
 18 #include <linux/fb.h>
 19 #include <asm/delay.h>
 20 #include <asm/types.h>
 21 
 22 #include <video/fbcon.h>
 23 #include <video/fbcon-mfb.h>
 24 
 25 #include "sti.h"
 26 
 27 /* Translate an address as it would be found in a 2048x2048x1 bit frame
 28  * buffer into a logical address Artist actually expects.  Addresses fed
 29  * into Artist look like this:
 30  *  fixed          Y               X
 31  * FFFF FFFF LLLL LLLL LLLC CCCC CCCC CC00
 32  *
 33  * our "RAM" addresses look like this:
 34  * 
 35  * FFFF FFFF 0000 0LLL LLLL LLLL CCCC CCCC [CCC]
 36  *
 37  * */
 38 
 39 static inline u32
 40 ram2log(void * addr)
 41 {
 42         u32 a = (unsigned long) addr;
 43         u32 r;
 44 
 45 #if 0
 46         r  =   a & 0xff000000;          /* fixed part */
 47         r += ((a & 0x000000ff) << 5);
 48         r += ((a & 0x00ffff00) << 3);
 49 #else
 50         r  =   a & 0xff000000;          /* fixed part */
 51         r += ((a & 0x000000ff) << 5);
 52         r += ((a & 0x0007ff00) << 5);
 53 #endif
 54 
 55         return r;
 56 }
 57 
 58 /* All those functions need better names. */
 59 
 60 static void
 61 memcpy_fromhp_tohp(void *dest, void *src, int count)
 62 {
 63         unsigned long d = ram2log(dest);
 64         unsigned long s = ram2log(src);
 65 
 66         count += 3;
 67         count &= ~3; /* XXX */
 68 
 69         while(count) {
 70                 count --;
 71                 gsc_writel(~gsc_readl(s), d);
 72                 d += 32*4;
 73                 s += 32*4;
 74         }
 75 }
 76 
 77 static void
 78 memcpy_tohp(void *dest, void *src, int count)
 79 {
 80         unsigned long d = (unsigned long) dest;
 81         u32 *s = (u32 *)src;
 82 
 83         count += 3;
 84         count &= ~3; /* XXX */
 85 
 86         d = ram2log(dest);
 87 
 88         while(count) {
 89                 count--;
 90                 gsc_writel(*s++, d);
 91                 d += 32*4;
 92         }
 93 }
 94 
 95 static void
 96 memcopy_fromhp(void *dest, void *src, int count)
 97 {
 98         /* FIXME */
 99         printk("uhm ...\n");
100 }
101 
102 static void
103 memset_tohp(void *dest, u32 word, int count)
104 {
105         unsigned long d = ram2log(dest);
106 
107         count += 3;
108         count &= ~3;
109 
110         while(count) {
111                 count--;
112                 gsc_writel(word, d);
113                 d += 32;
114         }
115 }
116 
117 static u8
118 readb_hp(void *src)
119 {
120         unsigned long s = ram2log(src);
121 
122         return ~gsc_readb(s);
123 }
124 
125 static void
126 writeb_hp(u8 b, void *dst)
127 {
128         unsigned long d = ram2log(dst);
129 
130         if((d&0xf0000000) != 0xf0000000) {
131                 printk("writeb_hp %02x %p (%08lx) (%p)\n",
132                         b, dst, d, __builtin_return_address(0));
133                 return;
134         }
135 
136         gsc_writeb(b, d);
137 }
138 
139 static void
140 fbcon_sti_setup(struct display *p)
141 {
142         if (p->line_length)
143                 p->next_line = p->line_length;
144         else
145                 p->next_line = p->var.xres_virtual>>3;
146         p->next_plane = 0;
147 }
148 
149 static void
150 fbcon_sti_bmove(struct display *p, int sy, int sx,
151                 int dy, int dx,
152                 int height, int width)
153 {
154 #if 0 /* Unfortunately, still broken */
155         sti_bmove(&default_sti /* FIXME */, sy, sx, dy, dx, height, width);
156 #else
157         u8 *src, *dest;
158         u_int rows;
159 
160         if (sx == 0 && dx == 0 && width == p->next_line) {
161                 src = p->screen_base+sy*fontheight(p)*width;
162                 dest = p->screen_base+dy*fontheight(p)*width;
163                 memcpy_fromhp_tohp(dest, src, height*fontheight(p)*width);
164         } else if (dy <= sy) {
165                 src = p->screen_base+sy*fontheight(p)*p->next_line+sx;
166                 dest = p->screen_base+dy*fontheight(p)*p->next_line+dx;
167                 for (rows = height*fontheight(p); rows--;) {
168                         memcpy_fromhp_tohp(dest, src, width);
169                         src += p->next_line;
170                         dest += p->next_line;
171                 }
172         } else {
173                 src = p->screen_base+((sy+height)*fontheight(p)-1)*p->next_line+sx;
174                 dest = p->screen_base+((dy+height)*fontheight(p)-1)*p->next_line+dx;
175                 for (rows = height*fontheight(p); rows--;) {
176                         memcpy_fromhp_tohp(dest, src, width);
177                         src -= p->next_line;
178                         dest -= p->next_line;
179                 }
180         }
181 #endif
182 }
183 
184 static void
185 fbcon_sti_clear(struct vc_data *conp,
186                 struct display *p, int sy, int sx,
187                 int height, int width)
188 {
189         u8 *dest;
190         u_int rows;
191         int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
192 
193         dest = p->screen_base+sy*fontheight(p)*p->next_line+sx;
194 
195         if (sx == 0 && width == p->next_line) {
196                 if (inverse)
197                         memset_tohp(dest, ~0, height*fontheight(p)*width);
198                 else
199                         memset_tohp(dest,  0, height*fontheight(p)*width);
200         } else
201                 for (rows = height*fontheight(p); rows--; dest += p->next_line)
202                         if (inverse)
203                                 memset_tohp(dest, 0xffffffff, width);
204                         else
205                                 memset_tohp(dest, 0x00000000, width);
206 }
207 
208 static void fbcon_sti_putc(struct vc_data *conp,
209                            struct display *p, int c,
210                            int yy, int xx)
211 {
212         u8 *dest, *cdat;
213         u_int rows, bold, revs, underl;
214         u8 d;
215 
216         dest = p->screen_base+yy*fontheight(p)*p->next_line+xx;
217         cdat = p->fontdata+(c&p->charmask)*fontheight(p);
218         bold = attr_bold(p,c);
219         revs = attr_reverse(p,c);
220         underl = attr_underline(p,c);
221 
222         for (rows = fontheight(p); rows--; dest += p->next_line) {
223                 d = *cdat++;
224                 if (underl && !rows)
225                         d = 0xff;
226                 else if (bold)
227                         d |= d>>1;
228                 if (revs)
229                         d = ~d;
230                 writeb_hp (d, dest);
231         }
232 }
233 
234 static void fbcon_sti_putcs(struct vc_data *conp,
235                             struct display *p, 
236                             const unsigned short *s,
237                             int count, int yy, int xx)
238 {
239         u8 *dest, *dest0, *cdat;
240         u_int rows, bold, revs, underl;
241         u8 d;
242         u16 c;
243 
244         if(((unsigned)xx > 200) || ((unsigned) yy > 200)) {
245                 printk("refusing to putcs %p %p %p %d %d %d (%p)\n",
246                         conp, p, s, count, yy, xx, __builtin_return_address(0));
247                 return;
248         }       
249 
250 
251         dest0 = p->screen_base+yy*fontheight(p)*p->next_line+xx;
252         if(((u32)dest0&0xf0000000)!=0xf0000000) {
253                 printk("refusing to putcs %p %p %p %d %d %d (%p) %p = %p + %d * %d * %ld + %d\n",
254                         conp, p, s, count, yy, xx, __builtin_return_address(0),
255                         dest0, p->screen_base, yy, fontheight(p), p->next_line,
256                         xx);
257                 return;
258         }       
259 
260         bold = attr_bold(p,scr_readw(s));
261         revs = attr_reverse(p,scr_readw(s));
262         underl = attr_underline(p,scr_readw(s));
263 
264         while (count--) {
265                 c = scr_readw(s++) & p->charmask;
266                 dest = dest0++;
267                 cdat = p->fontdata+c*fontheight(p);
268                 for (rows = fontheight(p); rows--; dest += p->next_line) {
269                         d = *cdat++;
270                         if (0 && underl && !rows)
271                                 d = 0xff;
272                         else if (0 && bold)
273                                 d |= d>>1;
274                         if (revs)
275                                 d = ~d;
276                         writeb_hp (d, dest);
277                 }
278         }
279 }
280 
281 static void fbcon_sti_revc(struct display *p,
282                            int xx, int yy)
283 {
284         u8 *dest, d;
285         u_int rows;
286 
287 
288         dest = p->screen_base+yy*fontheight(p)*p->next_line+xx;
289         for (rows = fontheight(p); rows--; dest += p->next_line) {
290                 d = readb_hp(dest);
291                 writeb_hp (~d, dest);
292         }
293 }
294 
295 static void
296 fbcon_sti_clear_margins(struct vc_data *conp,
297                         struct display *p,
298                         int bottom_only)
299 {
300         u8 *dest;
301         int height, bottom;
302         int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
303 
304 
305         /* XXX Need to handle right margin? */
306 
307         height = p->var.yres - conp->vc_rows * fontheight(p);
308         if (!height)
309                 return;
310         bottom = conp->vc_rows + p->yscroll;
311         if (bottom >= p->vrows)
312                 bottom -= p->vrows;
313         dest = p->screen_base + bottom * fontheight(p) * p->next_line;
314         if (inverse)
315                 memset_tohp(dest, 0xffffffff, height * p->next_line);
316         else
317                 memset_tohp(dest, 0x00000000, height * p->next_line);
318 }
319 
320 
321     /*
322      *  `switch' for the low level operations
323      */
324 
325 struct display_switch fbcon_sti = {
326         fbcon_sti_setup, fbcon_sti_bmove, fbcon_sti_clear,
327         fbcon_sti_putc, fbcon_sti_putcs, fbcon_sti_revc,
328         NULL, NULL, fbcon_sti_clear_margins,
329         FONTWIDTH(8)
330 };
331 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.