Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /* -*- linux-c -*- ------------------------------------------------------- *
  2  *
  3  *   Copyright (C) 1991, 1992 Linus Torvalds
  4  *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved
  5  *
  6  *   This file is part of the Linux kernel, and is made available under
  7  *   the terms of the GNU General Public License version 2.
  8  *
  9  * ----------------------------------------------------------------------- */
 10 
 11 /*
 12  * arch/i386/boot/video-mode.c
 13  *
 14  * Set the video mode.  This is separated out into a different
 15  * file in order to be shared with the ACPI wakeup code.
 16  */
 17 
 18 #include "boot.h"
 19 #include "video.h"
 20 #include "vesa.h"
 21 
 22 /*
 23  * Common variables
 24  */
 25 int adapter;                    /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
 26 u16 video_segment;
 27 int force_x, force_y;   /* Don't query the BIOS for cols/rows */
 28 
 29 int do_restore;         /* Screen contents changed during mode flip */
 30 int graphic_mode;       /* Graphic mode with linear frame buffer */
 31 
 32 /* Probe the video drivers and have them generate their mode lists. */
 33 void probe_cards(int unsafe)
 34 {
 35         struct card_info *card;
 36         static u8 probed[2];
 37 
 38         if (probed[unsafe])
 39                 return;
 40 
 41         probed[unsafe] = 1;
 42 
 43         for (card = video_cards; card < video_cards_end; card++) {
 44                 if (card->unsafe == unsafe) {
 45                         if (card->probe)
 46                                 card->nmodes = card->probe();
 47                         else
 48                                 card->nmodes = 0;
 49                 }
 50         }
 51 }
 52 
 53 /* Test if a mode is defined */
 54 int mode_defined(u16 mode)
 55 {
 56         struct card_info *card;
 57         struct mode_info *mi;
 58         int i;
 59 
 60         for (card = video_cards; card < video_cards_end; card++) {
 61                 mi = card->modes;
 62                 for (i = 0; i < card->nmodes; i++, mi++) {
 63                         if (mi->mode == mode)
 64                                 return 1;
 65                 }
 66         }
 67 
 68         return 0;
 69 }
 70 
 71 /* Set mode (without recalc) */
 72 static int raw_set_mode(u16 mode, u16 *real_mode)
 73 {
 74         int nmode, i;
 75         struct card_info *card;
 76         struct mode_info *mi;
 77 
 78         /* Drop the recalc bit if set */
 79         mode &= ~VIDEO_RECALC;
 80 
 81         /* Scan for mode based on fixed ID, position, or resolution */
 82         nmode = 0;
 83         for (card = video_cards; card < video_cards_end; card++) {
 84                 mi = card->modes;
 85                 for (i = 0; i < card->nmodes; i++, mi++) {
 86                         int visible = mi->x || mi->y;
 87 
 88                         if ((mode == nmode && visible) ||
 89                             mode == mi->mode ||
 90                             mode == (mi->y << 8)+mi->x) {
 91                                 *real_mode = mi->mode;
 92                                 return card->set_mode(mi);
 93                         }
 94 
 95                         if (visible)
 96                                 nmode++;
 97                 }
 98         }
 99 
100         /* Nothing found?  Is it an "exceptional" (unprobed) mode? */
101         for (card = video_cards; card < video_cards_end; card++) {
102                 if (mode >= card->xmode_first &&
103                     mode < card->xmode_first+card->xmode_n) {
104                         struct mode_info mix;
105                         *real_mode = mix.mode = mode;
106                         mix.x = mix.y = 0;
107                         return card->set_mode(&mix);
108                 }
109         }
110 
111         /* Otherwise, failure... */
112         return -1;
113 }
114 
115 /*
116  * Recalculate the vertical video cutoff (hack!)
117  */
118 static void vga_recalc_vertical(void)
119 {
120         unsigned int font_size, rows;
121         u16 crtc;
122         u8 pt, ov;
123 
124         set_fs(0);
125         font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
126         rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
127 
128         rows *= font_size;      /* Visible scan lines */
129         rows--;                 /* ... minus one */
130 
131         crtc = vga_crtc();
132 
133         pt = in_idx(crtc, 0x11);
134         pt &= ~0x80;            /* Unlock CR0-7 */
135         out_idx(pt, crtc, 0x11);
136 
137         out_idx((u8)rows, crtc, 0x12); /* Lower height register */
138 
139         ov = in_idx(crtc, 0x07); /* Overflow register */
140         ov &= 0xbd;
141         ov |= (rows >> (8-1)) & 0x02;
142         ov |= (rows >> (9-6)) & 0x40;
143         out_idx(ov, crtc, 0x07);
144 }
145 
146 /* Set mode (with recalc if specified) */
147 int set_mode(u16 mode)
148 {
149         int rv;
150         u16 real_mode;
151 
152         /* Very special mode numbers... */
153         if (mode == VIDEO_CURRENT_MODE)
154                 return 0;       /* Nothing to do... */
155         else if (mode == NORMAL_VGA)
156                 mode = VIDEO_80x25;
157         else if (mode == EXTENDED_VGA)
158                 mode = VIDEO_8POINT;
159 
160         rv = raw_set_mode(mode, &real_mode);
161         if (rv)
162                 return rv;
163 
164         if (mode & VIDEO_RECALC)
165                 vga_recalc_vertical();
166 
167         /* Save the canonical mode number for the kernel, not
168            an alias, size specification or menu position */
169 #ifndef _WAKEUP
170         boot_params.hdr.vid_mode = real_mode;
171 #endif
172         return 0;
173 }
174 
  This page was automatically generated by the LXR engine.