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

Linux Cross Reference
Linux/drivers/video/sticon-bmode.c

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

  1 /*
  2 TPG CVS users: please don't commit changes to this file directly, send
  3 them to prumpf@tux.org and wait for a new version instead.  Otherwise,
  4 your changes will get lost when prumpf releases the next version, as
  5 this file *will* be replaced with it.  You have been warned.
  6 
  7 2000-05-30, <deller@gmx.de>
  8 */
  9 #if 1
 10 #define DPRINTK(x)      printk x
 11 #else
 12 #define DPRINTK(x)
 13 #endif
 14 
 15 /*
 16  *  linux/drivers/video/sticon.c  - console driver using HP's STI firmware
 17  *
 18  *      Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
 19  *
 20  *  Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
 21  *  which were
 22  *
 23  *      Created 28 Sep 1997 by Geert Uytterhoeven
 24  *      Rewritten by Martin Mares <mj@ucw.cz>, July 1998
 25  *      Copyright (C) 1991, 1992  Linus Torvalds
 26  *                          1995  Jay Estabrook
 27  *      Copyright (C) 1995 Geert Uytterhoeven
 28  *      Copyright (C) 1993 Bjoern Brauel
 29  *                         Roman Hodek
 30  *      Copyright (C) 1993 Hamish Macdonald
 31  *                         Greg Harp
 32  *      Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk]
 33  *
 34  *            with work by William Rucklidge (wjr@cs.cornell.edu)
 35  *                         Geert Uytterhoeven
 36  *                         Jes Sorensen (jds@kom.auc.dk)
 37  *                         Martin Apel
 38  *            with work by Guenther Kelleter
 39  *                         Martin Schaller
 40  *                         Andreas Schwab
 41  *                         Emmanuel Marty (core@ggi-project.org)
 42  *                         Jakub Jelinek (jj@ultra.linux.cz)
 43  *                         Martin Mares <mj@ucw.cz>
 44  *
 45  *  This file is subject to the terms and conditions of the GNU General Public
 46  *  License.  See the file COPYING in the main directory of this archive for
 47  *  more details.
 48  */
 49 /*
 50  *  TODO:
 51  *   - call STI in virtual mode rather than in real mode
 52  *   - support for PCI-only STI ROMs (which don't have a traditional region
 53  *     list)
 54  *   - safe detection (i.e. verify there is a graphics device at a given
 55  *     address first, not just read a random device's io space)
 56  *   - support for multiple STI devices in one machine
 57  *   - support for byte-mode STI ROMs
 58  *   - support for just using STI to switch to a colour fb (stifb ?)
 59  *   - try to make it work on m68k hp workstations ;)
 60  */
 61 
 62 #include <linux/types.h>
 63 #include <linux/sched.h>
 64 #include <linux/fs.h>
 65 #include <linux/kernel.h>
 66 #include <linux/tty.h>
 67 #include <linux/console.h>
 68 #include <linux/string.h>
 69 #include <linux/kd.h>
 70 #include <linux/malloc.h>
 71 #include <linux/vt_kern.h>
 72 #include <linux/selection.h>
 73 #include <linux/ioport.h>
 74 #include <linux/init.h>
 75 #include <linux/delay.h>
 76 
 77 #include <asm/io.h>
 78 #include <asm/real.h>
 79 
 80 #include <linux/module.h>
 81 #include <linux/fb.h>
 82 #include <linux/smp.h>
 83 
 84 #include <asm/irq.h>
 85 #include <asm/system.h>
 86 #include <asm/uaccess.h>
 87 
 88 #include <video/fbcon.h>
 89 #include <video/font.h>
 90 
 91 #include "sti-bmode.h"
 92 
 93 /* The latency of the STI functions cannot really be reduced by setting
 94  * this to 0;  STI doesn't seem to be designed to allow calling a different
 95  * function (or the same function with different arguments) after a
 96  * function exited with 1 as return value.
 97  *
 98  * As all of the functions below could be called from interrupt context,
 99  * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1)
100  * block.  Really bad latency there.
101  *
102  * Probably the best solution to all this is have the generic code manage
103  * the screen buffer and a kernel thread to call STI occasionally.
104  * 
105  * Luckily, the frame buffer guys have the same problem so we can just wait
106  * for them to fix it and steal their solution.   prumpf
107  *
108  * Actually, another long-term viable solution is to completely do STI
109  * support in userspace - that way we avoid the potential license issues
110  * of using proprietary fonts, too. */
111  
112 #define STI_WAIT 1
113 #define STI_PTR(p) ( (typeof(p)) virt_to_phys(p))
114 #define PTR_STI(p) ( (typeof(p)) phys_to_virt((unsigned long)p) )
115 
116 static struct sti_struct default_sti = {
117         SPIN_LOCK_UNLOCKED,
118 };
119 
120 static struct sti_font_flags default_font_flags = {
121         STI_WAIT, 0, 0, NULL
122 };
123 
124 /* The colour indices used by STI are
125  *   0 - Black
126  *   1 - White
127  *   2 - Red
128  *   3 - Yellow/Brown
129  *   4 - Green
130  *   5 - Cyan
131  *   6 - Blue
132  *   7 - Magenta
133  *
134  * So we have the same colours as VGA (basically one bit each for R, G, B),
135  * but have to translate them, anyway. */
136 
137 static u8 col_trans[8] = {
138         0, 6, 4, 5,
139         2, 7, 3, 1
140 };
141 
142 #define c_fg(sti, c) col_trans[((c>> 8) & 7)]
143 #define c_bg(sti, c) col_trans[((c>>11) & 7)]
144 #define c_index(sti, c) (c&0xff)
145 
146 #define sti_onscreen_x(sti) (PTR_STI(sti->glob_cfg)->onscreen_x)
147 #define sti_onscreen_y(sti) (PTR_STI(sti->glob_cfg)->onscreen_y)
148 #define sti_font_x(sti) (STI_U8(PTR_STI(sti->font)->width))
149 #define sti_font_y(sti) (STI_U8(PTR_STI(sti->font)->height))
150 
151 static struct sti_init_flags default_init_flags = {
152         STI_WAIT, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, NULL
153 };
154 
155 static void sti_init_graph(struct sti_struct *sti) 
156 {
157         struct sti_init_inptr_ext inptr_ext = {
158                 0, { 0 }, 0, NULL
159         };
160         struct sti_init_inptr inptr = {
161                 3, STI_PTR(&inptr_ext)
162         };
163         struct sti_init_outptr outptr = { 0 };
164         unsigned long flags;
165         s32 ret;
166 
167         spin_lock_irqsave(&sti->lock, flags);
168 
169         ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr,
170                 &outptr, sti->glob_cfg);
171 
172         spin_unlock_irqrestore(&sti->lock, flags);
173 
174         sti->text_planes = outptr.text_planes;
175 }
176 
177 #if 0
178 static struct sti_conf_flags default_conf_flags = {
179         STI_WAIT, 0, NULL
180 };
181 
182 static void sti_inq_conf(struct sti_struct *sti)
183 {
184         struct sti_conf_inptr inptr = { NULL };
185         struct sti_conf_outptr_ext outptr_ext = { future_ptr: NULL };
186         struct sti_conf_outptr outptr = {
187                 ext_ptr: STI_PTR(&outptr_ext)
188         };
189         unsigned long flags;
190         s32 ret;
191         
192         do {
193                 spin_lock_irqsave(&sti->lock, flags);
194                 ret = STI_CALL(sti->inq_conf, &default_conf_flags,
195                         &inptr, &outptr, sti->glob_cfg);
196                 spin_unlock_irqrestore(&sti->lock, flags);
197         } while(ret == 1);
198 }
199 #endif
200 
201 static void sti_putc(struct sti_struct *sti, int c, int y, int x)
202 {
203         struct sti_font_inptr inptr = {
204                 (u32) sti->font, c_index(sti, c), c_fg(sti, c), c_bg(sti, c),
205                 x * sti_font_x(sti), y * sti_font_y(sti), NULL
206         };
207         struct sti_font_outptr outptr = {
208                 0, NULL
209         };
210         s32 ret;
211         unsigned long flags;
212 
213         do {
214                 spin_lock_irqsave(&sti->lock, flags);
215                 ret = STI_CALL(sti->font_unpmv, &default_font_flags,
216                         &inptr, &outptr, sti->glob_cfg);
217                 spin_unlock_irqrestore(&sti->lock, flags);
218         } while(ret == 1);
219 }
220 
221 static struct sti_blkmv_flags clear_blkmv_flags = {
222         STI_WAIT, 1, 1, 0, 0, NULL
223 };
224 
225 static void sti_set(struct sti_struct *sti, int src_y, int src_x,
226         int height, int width, u8 color)
227 {
228         struct sti_blkmv_inptr inptr = {
229                 color, color,
230                 src_x, src_y ,
231                 src_x, src_y ,
232                 width, height,
233                 NULL
234         };
235         struct sti_blkmv_outptr outptr = { 0, NULL };
236         s32 ret = 0;
237         unsigned long flags;
238         
239         do {
240                 spin_lock_irqsave(&sti->lock, flags);
241                 ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
242                         &inptr, &outptr, sti->glob_cfg);
243                 spin_unlock_irqrestore(&sti->lock, flags);
244         } while(ret == 1);
245 }
246 
247 static void sti_clear(struct sti_struct *sti, int src_y, int src_x,
248         int height, int width)
249 {
250         struct sti_blkmv_inptr inptr = {
251                 0, 0,
252                 src_x * sti_font_x(sti), src_y * sti_font_y(sti),
253                 src_x * sti_font_x(sti), src_y * sti_font_y(sti),
254                 width * sti_font_x(sti), height* sti_font_y(sti),
255                 NULL
256         };
257         struct sti_blkmv_outptr outptr = { 0, NULL };
258         s32 ret = 0;
259         unsigned long flags;
260 
261         do {
262                 spin_lock_irqsave(&sti->lock, flags);
263                 ret = STI_CALL(sti->block_move, &clear_blkmv_flags,
264                         &inptr, &outptr, sti->glob_cfg);
265                 spin_unlock_irqrestore(&sti->lock, flags);
266         } while(ret == 1);
267 }
268 
269 static struct sti_blkmv_flags default_blkmv_flags = {
270         STI_WAIT, 0, 0, 0, 0, NULL
271 };
272 
273 static void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
274         int dst_y, int dst_x, int height, int width)
275 {
276         struct sti_blkmv_inptr inptr = {
277                 0, 0,
278                 src_x * sti_font_x(sti), src_y * sti_font_y(sti),
279                 dst_x * sti_font_x(sti), dst_y * sti_font_y(sti),
280                 width * sti_font_x(sti), height* sti_font_y(sti),
281                 NULL
282         };
283         struct sti_blkmv_outptr outptr = { 0, NULL };
284         s32 ret = 0;
285         unsigned long flags;
286 
287         do {
288                 spin_lock_irqsave(&sti->lock, flags);
289                 ret = STI_CALL(sti->block_move, &default_blkmv_flags,
290                         &inptr, &outptr, sti->glob_cfg);
291                 spin_unlock_irqrestore(&sti->lock, flags);
292         } while(ret == 1);
293 }
294 
295 
296 /* STICON */
297 
298 static const char __init *sticon_startup(void)
299 {
300         return "STI console";
301 }
302 
303 static int sticon_set_palette(struct vc_data *c, unsigned char *table)
304 {
305         return -EINVAL;
306 }
307 static int sticon_font_op(struct vc_data *c, struct console_font_op *op)
308 {
309         return -ENOSYS;
310 }
311 
312 static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
313 {
314         sti_putc(&default_sti, c, ypos, xpos);
315 }
316 
317 static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
318         int count, int ypos, int xpos)
319 {
320         while(count--) {
321                 sti_putc(&default_sti, *s++, ypos, xpos++);
322         }
323 }
324 
325 static void sticon_cursor(struct vc_data *conp, int mode)
326 {
327 }
328 
329 static int sticon_scroll(struct vc_data *conp, int t, int b, int dir,
330                         int count)
331 {
332         struct sti_struct *sti = &default_sti;
333 
334         if(console_blanked)
335                 return 0;
336 
337         sticon_cursor(conp, CM_ERASE);
338 
339         switch(dir) {
340         case SM_UP:
341                 sti_bmove(sti, t+count, 0, t, 0, b-t-count, conp->vc_cols);
342                 sti_clear(sti, b-count, 0, count, conp->vc_cols);
343 
344                 break;
345 
346         case SM_DOWN:
347                 sti_bmove(sti, t, 0, t+count, 0, b-t-count, conp->vc_cols);
348                 sti_clear(sti, t, 0, count, conp->vc_cols);
349 
350                 break;
351         }
352 
353         return 0;
354 }
355         
356 static void sticon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
357         int height, int width)
358 {
359         sti_bmove(&default_sti, sy, sx, dy, dx, height, width);
360 }
361 
362 static void sticon_init(struct vc_data *c, int init)
363 {
364         struct sti_struct *sti = &default_sti;
365         int vc_cols, vc_rows;
366 
367         sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
368         c->vc_can_do_color = 1;
369         vc_cols = PTR_STI(sti->glob_cfg)->onscreen_x / sti_font_x(sti);
370         vc_rows = PTR_STI(sti->glob_cfg)->onscreen_y / sti_font_y(sti);
371 
372         vc_resize_con(vc_rows, vc_cols, c->vc_num);
373 }
374 
375 static void sticon_deinit(struct vc_data *c)
376 {
377 }
378 
379 static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
380                         int width)
381 {
382         sti_clear(&default_sti, sy, sx, height, width);
383 }
384 
385 static int sticon_switch(struct vc_data *conp)
386 {
387         return 0;
388 }
389 
390 static int sticon_blank(struct vc_data *conp, int blank)
391 {
392         return 0;
393 }
394 
395 static int sticon_scrolldelta(struct vc_data *conp, int lines)
396 {
397         return 0;
398 }
399 
400 static int sticon_set_origin(struct vc_data *conp)
401 {
402         return 0;
403 }
404 
405 static u16 *sticon_screen_pos(struct vc_data *conp, int offset)
406 {
407         return NULL;
408 }
409 
410 static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, int *px, int *py)
411 {
412         return 0;
413 }
414 
415 static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, u8 blink, u8 underline, u8 reverse)
416 {
417         u8 attr = ((color & 0x70) >> 1) | ((color & 7));
418 
419         if(reverse) {
420                 color = ((color>>3)&0x7) | ((color &0x7)<<3);
421         }
422 
423 
424         return attr;
425 }
426 
427 static struct consw sti_con = {
428         con_startup:            sticon_startup, 
429         con_init:               sticon_init,
430         con_deinit:             sticon_deinit,
431         con_clear:              sticon_clear,
432         con_putc:               sticon_putc,
433         con_putcs:              sticon_putcs,
434         con_cursor:             sticon_cursor,
435         con_scroll:             sticon_scroll,
436         con_bmove:              sticon_bmove,
437         con_switch:             sticon_switch,
438         con_blank:              sticon_blank,
439         con_font_op:            sticon_font_op,
440         con_set_palette:        sticon_set_palette,
441         con_scrolldelta:        sticon_scrolldelta,
442         con_set_origin:         sticon_set_origin,
443         con_save_screen:        NULL,
444         con_build_attr:         sticon_build_attr,
445         con_invert_region:      NULL,
446         con_screen_pos:         sticon_screen_pos,
447         con_getxy:              sticon_getxy,
448 };
449 
450 #include <asm/pgalloc.h>        /* need cache flush routines */
451 static void __init sti_rom_copy(unsigned long base, unsigned long offset,
452                                 unsigned long count, void *dest)
453 {
454         void *savedest = dest;
455         int savecount = count;
456 
457         while(count >= 4) {
458                 count -= 4;
459                 *(u32 *)dest = gsc_readl(base + offset);
460 #if 0
461                 DPRINTK(("%08x\n", *(u32 *)dest));
462                 if(*(u32 *)dest == 0x64646464) {
463                   DPRINTK(("!!!!\n"));
464                   { u32 foo = 0; while(foo += 0x100); }
465                 }
466 #endif
467                 offset += 4;
468                 dest += 4;
469         }
470         while(count) {
471                 count--;
472                 *(u8 *)dest = gsc_readb(base + offset);
473                 offset++;
474                 dest++;
475         }
476         __flush_dcache_range(dest, count);
477         __flush_icache_range(dest, count);
478 }
479 
480 static void dump_sti_rom(struct sti_rom *rom)
481 {
482         printk("STI byte mode ROM type %d\n", STI_U8(rom->type));
483         printk(" supports %d monitors\n", STI_U8(rom->num_mons));
484         printk(" conforms to STI ROM spec revision %d.%02x\n",
485                 STI_U8(rom->revno[0]) >> 4, STI_U8(rom->revno[0]) & 0x0f);
486         printk(__FUNCTION__ ": %d\n", __LINE__);
487         printk(" graphics id %02x%02x%02x%02x%02x%02x%02x%02x\n",
488                 (unsigned int) STI_U8(rom->graphics_id[0]), 
489                 (unsigned int) STI_U8(rom->graphics_id[1]), 
490                 (unsigned int) STI_U8(rom->graphics_id[2]), 
491                 (unsigned int) STI_U8(rom->graphics_id[3]), 
492                 (unsigned int) STI_U8(rom->graphics_id[4]), 
493                 (unsigned int) STI_U8(rom->graphics_id[5]), 
494                 (unsigned int) STI_U8(rom->graphics_id[6]), 
495                 (unsigned int) STI_U8(rom->graphics_id[7]));
496         printk(__FUNCTION__ ": %d\n", __LINE__);
497         printk(" font start %08x\n",  STI_U32(rom->font_start));
498         printk(__FUNCTION__ ": %d\n", __LINE__);
499         printk(" region list %08x\n", STI_U32(rom->region_list));
500         printk(__FUNCTION__ ": %d\n", __LINE__);
501         printk(" init_graph %08x\n",  STI_U32(rom->init_graph));
502         printk(__FUNCTION__ ": %d\n", __LINE__);
503         printk(" alternate code type %d\n", STI_U8(rom->alt_code_type));
504         printk(__FUNCTION__ ": %d\n", __LINE__);
505 }
506 
507 static void __init sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
508                                   struct sti_rom *raw_rom)
509 {
510         struct sti_rom_font *raw_font;
511         struct sti_cooked_font *cooked_font;
512         struct sti_rom_font *font_start;
513 
514         cooked_font =
515                 kmalloc(sizeof *cooked_font, GFP_KERNEL);
516         if(!cooked_font)
517                 return;
518 
519         cooked_rom->font_start = cooked_font;
520 
521 #if 0
522         DPRINTK(("%p = %p + %08x\n",
523                ((void *)raw_rom) + (STI_U32(raw_rom->font_start)),
524                ((void *)raw_rom), (STI_U32(raw_rom->font_start))));
525 #endif
526         raw_font = ((void *)raw_rom) + STI_U32(raw_rom->font_start) - 3;
527 
528         font_start = raw_font;
529         cooked_font->raw = raw_font;
530 
531         DPRINTK(("next font %08x\n", STI_U32(raw_font->next_font)));
532 
533         while(0 && STI_U32(raw_font->next_font)) {
534                 raw_font = ((void *)font_start) + STI_U32(raw_font->next_font);
535                 
536                 cooked_font->next_font =
537                         kmalloc(sizeof *cooked_font, GFP_KERNEL);
538                 if(!cooked_font->next_font)
539                         return;
540 
541                 cooked_font = cooked_font->next_font;
542 
543 //              cooked_font->raw = raw_font;
544 
545                 DPRINTK(("raw_font %p\n",
546                        raw_font));
547                 DPRINTK(("next_font %08x %p\n",
548                        STI_U32(raw_font->next_font),
549                        ((void *)font_start) + STI_U32(raw_font->next_font)));
550         }
551 
552         cooked_font->next_font = NULL;
553 }
554 
555 static unsigned long __init sti_cook_function(void *function,
556                                               u32 size)
557 {
558         sti_u32 *func = (sti_u32 *)function;
559         u32 *ret;
560         int i;
561 
562         ret = kmalloc(size, GFP_KERNEL);
563         if(!ret) {
564                 printk(KERN_ERR __FILE__ ": could not get memory.\n");
565                 return 0;
566         }
567 
568         for(i=0; i<(size/4); i++)
569             ret[i] = STI_U32(func[i]);
570 
571         flush_all_caches();
572         
573         return virt_to_phys(ret);
574 }
575 
576 static int font_index, font_height, font_width;
577 
578 static int __init sti_search_font(struct sti_cooked_rom *rom,
579                                   int height, int width)
580 {
581         struct sti_cooked_font *font;
582         int i = 0;
583         
584         for(font = rom->font_start; font; font = font->next_font, i++) {
585                 if((STI_U8(font->raw->width) == width) &&
586                    (STI_U8(font->raw->height) == height))
587                         return i;
588         }
589 
590         return 0;
591 }
592 
593 static struct sti_cooked_font * __init
594 sti_select_font(struct sti_cooked_rom *rom)
595 {
596         struct sti_cooked_font *font;
597         int i;
598 
599         if(font_width && font_height)
600                 font_index = sti_search_font(rom, font_height, font_width);
601 
602         for(font = rom->font_start, i = font_index;
603             font && (i > 0);
604             font = font->next_font, i--);
605 
606         if(font)
607                 return font;
608         else
609                 return rom->font_start;
610 }
611         
612 /* address is a pointer to a word mode or pci rom */
613 static struct sti_struct * __init sti_read_rom(unsigned long address)
614 {
615         struct sti_struct *ret = NULL;
616         struct sti_cooked_rom *cooked = NULL;
617         struct sti_rom *raw = NULL;
618         unsigned long size;
619 
620         ret = &default_sti;
621 
622         if(!ret)
623                 goto out_err;
624 
625         cooked = kmalloc(sizeof *cooked, GFP_KERNEL);
626         raw = kmalloc(sizeof *raw, GFP_KERNEL);
627         
628         if(!(raw && cooked))
629                 goto out_err;
630 
631         /* reallocate raw */
632         sti_rom_copy(address, 0, sizeof *raw, raw);
633 
634         dump_sti_rom(raw);
635 
636         size = STI_U32(raw->last_addr) + 1;
637         size = 128*1024;
638 //      DPRINTK(("size %08lx\n", size));
639 //      DPRINTK(("font_start %08x\n", STI_U32(raw->font_start)));
640 //      kfree(raw);
641         raw = kmalloc(size, GFP_KERNEL);
642         if(!raw)
643                 goto out_err;
644         sti_rom_copy(address, 0, size-1, raw);
645 
646         sti_cook_fonts(cooked, raw);
647 //      sti_cook_regions(cooked, raw);
648 //      sti_cook_functions(cooked, raw);
649 
650         if(STI_U32(raw->region_list)) {
651                 struct sti_rom_region *region =
652                         ((void *)raw) + STI_U32(raw->region_list) - 3;
653 
654 //              DPRINTK(("region_list %08x\n", STI_U32(raw->region_list)));
655 
656                 ret->regions = kmalloc(32, GFP_KERNEL); /* FIXME!! */
657 
658                 ret->regions[0] = STI_U32(region[0].region);
659                 ret->regions[1] = STI_U32(region[1].region);
660                 ret->regions[2] = STI_U32(region[2].region);
661                 ret->regions[3] = STI_U32(region[3].region);
662                 ret->regions[4] = STI_U32(region[4].region);
663                 ret->regions[5] = STI_U32(region[5].region);
664                 ret->regions[6] = STI_U32(region[6].region);
665                 ret->regions[7] = STI_U32(region[7].region);
666         }
667 
668         address = virt_to_phys(raw);
669 
670 #if 0
671         DPRINTK(("init_graph %08x %08x\n"
672                "state_mgmt %08x %08x\n"
673                "font_unpmv %08x %08x\n"
674                "block_move %08x %08x\n"
675                "self_test  %08x %08x\n"
676                "excep_hdlr %08x %08x\n"
677                "irq_conf   %08x %08x\n"
678                "set_cm_e   %08x %08x\n"
679                "dma_ctrl   %08x %08x\n"
680                "flow_ctrl  %08x %08x\n"
681                "user_timin %08x %08x\n"
682                "process_m  %08x %08x\n"
683                "sti_util   %08x %08x\n"
684                "end_addr   %08x %08x\n",
685                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
686                STI_U32(raw->state_mgmt), STI_U32(raw->state_mgmt_m68k),
687                STI_U32(raw->font_unpmv), STI_U32(raw->font_unpmv_m68k),
688                STI_U32(raw->block_move), STI_U32(raw->block_move_m68k),
689                STI_U32(raw->self_test), STI_U32(raw->self_test_m68k),
690                STI_U32(raw->excep_hdlr), STI_U32(raw->excep_hdlr_m68k),
691                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
692                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
693                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
694                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
695                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
696                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
697                STI_U32(raw->init_graph), STI_U32(raw->init_graph_m68k),
698                STI_U32(raw->end_addr), STI_U32(raw->end_addr_m68k) ) );
699 #endif
700 
701         ret->init_graph = sti_cook_function(((void *)raw)+STI_U32(raw->init_graph)-3,
702                                             (STI_U32(raw->state_mgmt) -
703                                              STI_U32(raw->init_graph))/4);
704 
705 
706         ret->font_unpmv = sti_cook_function(((void *)raw)+STI_U32(raw->font_unpmv)-3,
707                                             (STI_U32(raw->block_move) -
708                                              STI_U32(raw->font_unpmv))/4);
709 
710         ret->block_move = sti_cook_function(((void *)raw)+STI_U32(raw->block_move)-3,
711                                             (STI_U32(raw->self_test) -
712                                              STI_U32(raw->block_move))/4);
713 
714         ret->inq_conf = sti_cook_function(((void *)raw)+STI_U32(raw->inq_conf),
715                                           STI_U32(raw->set_cm_entry) -
716                                           STI_U32(raw->inq_conf));
717 
718         ret->rom = cooked;
719         ret->rom->raw = raw;
720 
721         ret->font = (struct sti_rom_font *) virt_to_phys(sti_select_font(ret->rom)->raw);
722 
723         return ret;
724 
725 out_err:
726         if(raw)
727                 kfree(raw);
728         if(cooked)
729                 kfree(cooked);
730 
731         return NULL;
732 }
733 
734 #if 0
735 static void dump_globcfg_ext(struct sti_glob_cfg_ext *cfg)
736 {
737         DPRINTK(("monitor %d\n"
738                 "in friendly mode: %d\n"
739                 "power consumption %d watts\n"
740                 "freq ref %d\n"
741                 "sti_mem_addr %p\n",
742                 cfg->curr_mon,
743                 cfg->friendly_boot,
744                 cfg->power,
745                 cfg->freq_ref,
746                 cfg->sti_mem_addr));
747 }
748 
749 static void dump_globcfg(struct sti_glob_cfg *glob_cfg)
750 {
751         DPRINTK(("%d text planes\n"
752                 "%4d x %4d screen resolution\n"
753                 "%4d x %4d offscreen\n"
754                 "%4d x %4d layout\n"
755                 "regions at %08x %08x %08x %08x\n"
756                 "regions at %08x %08x %08x %08x\n"
757                 "reent_lvl %d\n"
758                 "save_addr %p\n",
759                 glob_cfg->text_planes,
760                 glob_cfg->onscreen_x, glob_cfg->onscreen_y,
761                 glob_cfg->offscreen_x, glob_cfg->offscreen_y,
762                 glob_cfg->total_x, glob_cfg->total_y,
763                 glob_cfg->region_ptrs[0], glob_cfg->region_ptrs[1],
764                 glob_cfg->region_ptrs[2], glob_cfg->region_ptrs[3],
765                 glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
766                 glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
767                 glob_cfg->reent_lvl,
768                 glob_cfg->save_addr));
769         dump_globcfg_ext(PTR_STI(glob_cfg->ext_ptr));
770 }
771 #endif
772                 
773 static void __init sti_init_glob_cfg(struct sti_struct *sti, unsigned long hpa,
774                                      unsigned long rom_address)
775 {
776         struct sti_glob_cfg *glob_cfg;
777         struct sti_glob_cfg_ext *glob_cfg_ext;
778         void *save_addr;
779         void *sti_mem_addr;
780 
781         glob_cfg = kmalloc(sizeof *sti->glob_cfg, GFP_KERNEL);
782         glob_cfg_ext = kmalloc(sizeof *glob_cfg_ext, GFP_KERNEL);
783         save_addr = kmalloc(1024 /*XXX*/, GFP_KERNEL);
784         sti_mem_addr = kmalloc(1024, GFP_KERNEL);
785 
786         if((!glob_cfg) || (!glob_cfg_ext) || (!save_addr) || (!sti_mem_addr))
787                 return;
788 
789         memset(glob_cfg, 0, sizeof *glob_cfg);
790         memset(glob_cfg_ext, 0, sizeof *glob_cfg_ext);
791         memset(save_addr, 0, 1024);
792         memset(sti_mem_addr, 0, 1024);
793 
794         glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);
795         glob_cfg->save_addr = STI_PTR(save_addr);
796         glob_cfg->region_ptrs[0] = ((sti->regions[0]>>18)<<12) + rom_address;
797         glob_cfg->region_ptrs[1] = ((sti->regions[1]>>18)<<12) + hpa;
798         glob_cfg->region_ptrs[2] = ((sti->regions[2]>>18)<<12) + hpa;
799         glob_cfg->region_ptrs[3] = ((sti->regions[3]>>18)<<12) + hpa;
800         glob_cfg->region_ptrs[4] = ((sti->regions[4]>>18)<<12) + hpa;
801         glob_cfg->region_ptrs[5] = ((sti->regions[5]>>18)<<12) + hpa;
802         glob_cfg->region_ptrs[6] = ((sti->regions[6]>>18)<<12) + hpa;
803         glob_cfg->region_ptrs[7] = ((sti->regions[7]>>18)<<12) + hpa;
804 
805         glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
806 
807         sti->glob_cfg = STI_PTR(glob_cfg);
808 }
809 
810 static void __init sti_try_rom(unsigned long address, unsigned long hpa)
811 {
812         struct sti_struct *sti = NULL;
813         u16 sig;
814         
815         /* if we can't read the ROM, bail out early.  Not being able
816          * to read the hpa is okay, for romless sti */
817         if(pdc_add_valid((void*)address))
818                 return;
819 
820         printk("found potential STI ROM at %08lx\n", address);
821 
822         sig = le16_to_cpu(gsc_readw(address));
823 
824         if((sig&0xff) == 0x01) {
825                 sti = sti_read_rom(address);
826         }
827 
828         if(sig == 0x0303) {
829                 printk("STI word mode ROM at %08lx, ignored\n",
830                        address);
831 
832                 sti = NULL;
833         }
834 
835         if(!sti)
836                 return;
837 
838         /* this is hacked.  We need a better way to find out the HPA for
839          * romless STI (eg search for the graphics devices we know about
840          * by sversion) */
841         if (!pdc_add_valid((void *)0xf5000000)) DPRINTK(("f4000000 b\n"));
842         if (!pdc_add_valid((void *)0xf7000000)) DPRINTK(("f6000000 b\n"));
843         if (!pdc_add_valid((void *)0xf9000000)) DPRINTK(("f8000000 b\n"));
844         if (!pdc_add_valid((void *)0xfb000000)) DPRINTK(("fa000000 b\n"));
845         sti_init_glob_cfg(sti, hpa, address);
846 
847         sti_init_graph(sti);
848 
849         //sti_inq_conf(sti);
850 #if !defined(SERIAL_CONSOLE)    
851         { 
852             extern void pdc_console_die(void);  
853             pdc_console_die(); 
854         }
855 #endif
856                 
857         take_over_console(&sti_con, 0, MAX_NR_CONSOLES-1, 1);
858 
859         /* sti_inq_conf(sti); */
860 }
861 
862 static unsigned long sti_address;
863 static unsigned long sti_hpa;
864 
865 static void __init sti_init_roms(void)
866 {
867         /* handle the command line */
868         if(sti_address && sti_hpa) {
869                 sti_try_rom(sti_address, sti_hpa);
870 
871                 return;
872         }
873 
874         /* 712, 715, some other boxes don't have a separate STI ROM,
875          * but use part of the regular flash */
876         if(PAGE0->proc_sti) {
877                 printk("STI ROM from PDC at %08x\n", PAGE0->proc_sti);
878                 if(!pdc_add_valid((void *)0xf9000000))
879                         sti_try_rom(PAGE0->proc_sti, 0xf8000000);
880                 else if(!pdc_add_valid((void *)0xf5000000))
881                         sti_try_rom(PAGE0->proc_sti, 0xf4000000);
882                 else if(!pdc_add_valid((void *)0xf7000000))
883                         sti_try_rom(PAGE0->proc_sti, 0xf6000000);
884                 else if(!pdc_add_valid((void *)0xfb000000))
885                         sti_try_rom(PAGE0->proc_sti, 0xfa000000);
886         }
887 
888         /* standard locations for GSC graphic devices */
889         if(!pdc_add_valid((void *)0xf4000000))
890                 sti_try_rom(0xf4000000, 0xf4000000);
891         if(!pdc_add_valid((void *)0xf6000000))
892                 sti_try_rom(0xf6000000, 0xf6000000);
893         if(!pdc_add_valid((void *)0xf8000000))
894                 sti_try_rom(0xf8000000, 0xf8000000);
895         if(!pdc_add_valid((void *)0xfa000000))
896                 sti_try_rom(0xfa000000, 0xfa000000);
897 }
898 
899 static int __init sti_init(void)
900 {
901         printk("searching for byte mode STI ROMs\n");
902         sti_init_roms();
903         return 0;
904 }
905 
906 module_init(sti_init)
907 

~ [ 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.