OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [char/] [vesa_blank.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * vesa_blank.c
3
 *
4
 * Exported functions:
5
 *      void vesa_blank(void);
6
 *      void vesa_unblank(void);
7
 *      void vesa_powerdown(void);
8
 *      void set_vesa_blanking(const unsigned long arg);
9
 *
10
 * Not all hardware reacts well to this code - activate at your own risk.
11
 * Activation is done using a sufficiently recent version of setterm
12
 * or using a tiny C program like the following.
13
 *
14
-----------------------------------------------------------------------
15
|#include <stdio.h>
16
|#include <linux/termios.h>
17
|main(int argc, char *argv[]) {
18
|    int fd;
19
|    struct { char ten, onoff; } arg;
20
|
21
|    if (argc != 2) {
22
|       fprintf(stderr, "usage: setvesablank on|vsync|hsync|powerdown|off\n");
23
|       exit(1);
24
|    }
25
|    if ((fd = open("/dev/console", 0)) < 0)
26
|      fd = 0;
27
|    arg.ten = 10;
28
|    arg.onoff = 0;
29
|    if (!strcmp(argv[1], "on") || !strcmp(argv[1], "vsync"))
30
|      arg.onoff = 1;
31
|    else if (!strcmp(argv[1], "hsync"))
32
|      arg.onoff = 2;
33
|    else if (!strcmp(argv[1], "powerdown"))
34
|      arg.onoff = 3;
35
|    if (ioctl(fd, TIOCLINUX, &arg)) {
36
|       perror("setvesablank: TIOCLINUX");
37
|       exit(1);
38
|    }
39
|    exit(0);
40
|}
41
-----------------------------------------------------------------------
42
*/
43
 
44
#include <asm/io.h>
45
#include <asm/system.h>
46
#include <asm/segment.h>
47
#include <linux/mm.h>
48
 
49
extern unsigned short video_port_reg, video_port_val;
50
 
51
/*
52
 * This file handles the VESA Power Saving Protocol that lets a
53
 * monitor be powered down whenever not needed for a longer time.
54
 * The VESA protocol defines:
55
 *
56
 *  Mode/Status         HSync   VSync   Video
57
 *  -------------------------------------------
58
 *  "On"                on      on      active  (mode 0)
59
 *  "Suspend" {either}  on      off     blank   (mode 1)
60
 *            {  or  }  off     on      blank   (mode 2)
61
 *  "Off"               off     off     blank   (mode 3)
62
 *
63
 * Original code taken from the Power Management Utility (PMU) of
64
 * Huang shi chao, delivered together with many new monitor models
65
 * capable of the VESA Power Saving Protocol.
66
 *
67
 * Adapted to Linux by Christoph Rimek (chrimek@toppoint.de)  15-may-94.
68
 * A slightly adapted fragment of his README follows.
69
 *
70
 * Two-stage blanking by todd j. derr (tjd@barefoot.org)      10-oct-95.
71
 
72
Patch (based on Linux Kernel revision 1.0) for handling the Power Saving
73
feature of the new monitor generation. The code works on all these monitors
74
(mine is a Smile 1506) and should run on *all* video adapter cards (change
75
some i/o-addresses), although tested only on two different VGA-cards: a
76
cheap Cirrus Logic (5428) and a miro Crystal 8S (S3-805).
77
 
78
You can choose from two options:
79
 
80
(1) Setting vesa_blanking_mode to 1 or 2.
81
    The code will save the current setting of your video adapters'
82
    register settings and then program the controller to turn off
83
    the vertical synchronization pulse (mode 1) or horizontal
84
    synchronization pulse (mode 2).  Mode 1 should work with most
85
    monitors, but the VESA spec allows mode 2, so it's included for
86
    completeness. You may set this blanking interval in minutes by
87
    echoing the escape sequence 'ESC[9;interval]' to the terminal.
88
    By default this interval is set to 10 minutes.
89
 
90
    If you use one of these modes, you can also set a second interval
91
    by echoing the escape sequence 'ESC[14;interval]' to the terminal.
92
    The monitor will be turned off completely (mode 3) after being in
93
    suspend mode for the specified interval. An interval of 0 disables
94
    this feature which is the default.
95
 
96
    Both intervals may be set within the range of 0..60 minutes.
97
 
98
(2) Setting vesa_blanking_mode to 3.
99
    If your monitor locally has an Off_Mode timer then you should not
100
    force your video card to send the OFF-signal - your monitor will
101
    power down by itself.
102
    If your monitor cannot handle this and needs the Off-signal directly,
103
    or if you like your monitor to power down immediately when the
104
    blank_timer times out, then you choose this option.
105
 
106
On the other hand I'd recommend to not choose this second option unless
107
it is absolutely necessary. Powering down a monitor to the Off_State with
108
an approx. power consumption of 3-5 Watts is a rather strong action for
109
the CRT and it should not be done every now and then. If the software only
110
sends the signal to enter Standby mode, you have the chance to interfere
111
before the monitor powers down. Do not set a too short period, if you love
112
your hardware :-)) .
113
 
114
By default vesa_blanking_mode is set to 0, thus not using any power saving
115
features.
116
*/
117
 
118
#define seq_port_reg    (0x3c4)         /* Sequencer register select port */
119
#define seq_port_val    (0x3c5)         /* Sequencer register value port  */
120
#define video_misc_rd   (0x3cc)         /* Video misc. read port          */
121
#define video_misc_wr   (0x3c2)         /* Video misc. write port         */
122
 
123
/* structure holding original VGA register settings */
124
static struct {
125
        unsigned char   SeqCtrlIndex;           /* Sequencer Index reg.   */
126
        unsigned char   CrtCtrlIndex;           /* CRT-Contr. Index reg.  */
127
        unsigned char   CrtMiscIO;              /* Miscellaneous register */
128
        unsigned char   HorizontalTotal;        /* CRT-Controller:00h */
129
        unsigned char   HorizDisplayEnd;        /* CRT-Controller:01h */
130
        unsigned char   StartHorizRetrace;      /* CRT-Controller:04h */
131
        unsigned char   EndHorizRetrace;        /* CRT-Controller:05h */
132
        unsigned char   Overflow;               /* CRT-Controller:07h */
133
        unsigned char   StartVertRetrace;       /* CRT-Controller:10h */
134
        unsigned char   EndVertRetrace;         /* CRT-Controller:11h */
135
        unsigned char   ModeControl;            /* CRT-Controller:17h */
136
        unsigned char   ClockingMode;           /* Seq-Controller:01h */
137
} vga;
138
 
139
#define VESA_NO_BLANKING        0
140
#define VESA_VSYNC_SUSPEND      1
141
#define VESA_HSYNC_SUSPEND      2
142
#define VESA_POWERDOWN          (VESA_HSYNC_SUSPEND | VESA_VSYNC_SUSPEND)
143
 
144
#define DEFAULT_VESA_BLANKING_MODE      VESA_NO_BLANKING
145
 
146
static int vesa_blanking_mode = DEFAULT_VESA_BLANKING_MODE;
147
static int suspend_vesa_blanking_mode = DEFAULT_VESA_BLANKING_MODE;
148
static int vesa_blanked = 0;
149
 
150
/* routine to blank a vesa screen */
151
void vesa_blank(void)
152
{
153
        int mode;
154
 
155
        if((mode = vesa_blanking_mode) == 0)
156
          return;
157
 
158
        /* save original values of VGA controller registers */
159
        if(!vesa_blanked) {
160
            cli();
161
            vga.SeqCtrlIndex = inb_p(seq_port_reg);
162
            vga.CrtCtrlIndex = inb_p(video_port_reg);
163
            vga.CrtMiscIO = inb_p(video_misc_rd);
164
            sti();
165
 
166
            outb_p(0x00,video_port_reg);                /* HorizontalTotal */
167
            vga.HorizontalTotal = inb_p(video_port_val);
168
            outb_p(0x01,video_port_reg);                /* HorizDisplayEnd */
169
            vga.HorizDisplayEnd = inb_p(video_port_val);
170
            outb_p(0x04,video_port_reg);                /* StartHorizRetrace */
171
            vga.StartHorizRetrace = inb_p(video_port_val);
172
            outb_p(0x05,video_port_reg);                /* EndHorizRetrace */
173
            vga.EndHorizRetrace = inb_p(video_port_val);
174
            outb_p(0x07,video_port_reg);                /* Overflow */
175
            vga.Overflow = inb_p(video_port_val);
176
            outb_p(0x10,video_port_reg);                /* StartVertRetrace */
177
            vga.StartVertRetrace = inb_p(video_port_val);
178
            outb_p(0x11,video_port_reg);                /* EndVertRetrace */
179
            vga.EndVertRetrace = inb_p(video_port_val);
180
            outb_p(0x17,video_port_reg);                /* ModeControl */
181
            vga.ModeControl = inb_p(video_port_val);
182
            outb_p(0x01,seq_port_reg);                  /* ClockingMode */
183
            vga.ClockingMode = inb_p(seq_port_val);
184
        }
185
 
186
        /* assure that video is enabled */
187
        /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
188
        cli();
189
        outb_p(0x01,seq_port_reg);
190
        outb_p(vga.ClockingMode | 0x20,seq_port_val);
191
 
192
        /* test for vertical retrace in process.... */
193
        if ((vga.CrtMiscIO & 0x80) == 0x80)
194
                outb_p(vga.CrtMiscIO & 0xef,video_misc_wr);
195
 
196
        /*
197
         * Set <End of vertical retrace> to minimum (0) and
198
         * <Start of vertical Retrace> to maximum (incl. overflow)
199
         * Result: turn off vertical sync (VSync) pulse.
200
         */
201
        if (mode & VESA_VSYNC_SUSPEND) {
202
            outb_p(0x10,video_port_reg);        /* StartVertRetrace */
203
            outb_p(0xff,video_port_val);        /* maximum value */
204
            outb_p(0x11,video_port_reg);        /* EndVertRetrace */
205
            outb_p(0x40,video_port_val);        /* minimum (bits 0..3)  */
206
            outb_p(0x07,video_port_reg);                /* Overflow */
207
            outb_p(vga.Overflow | 0x84,video_port_val); /* bits 9,10 of  */
208
                                                        /* vert. retrace */
209
        }
210
 
211
        if (mode & VESA_HSYNC_SUSPEND) {
212
            /*
213
             * Set <End of horizontal retrace> to minimum (0) and
214
             *  <Start of horizontal Retrace> to maximum
215
             * Result: turn off horizontal sync (HSync) pulse.
216
             */
217
            outb_p(0x04,video_port_reg);        /* StartHorizRetrace */
218
            outb_p(0xff,video_port_val);        /* maximum */
219
            outb_p(0x05,video_port_reg);        /* EndHorizRetrace */
220
            outb_p(0x00,video_port_val);        /* minimum (0) */
221
        }
222
 
223
        /* restore both index registers */
224
        outb_p(vga.SeqCtrlIndex,seq_port_reg);
225
        outb_p(vga.CrtCtrlIndex,video_port_reg);
226
        sti();
227
 
228
        vesa_blanked = mode;
229
}
230
 
231
/* routine to unblank a vesa screen */
232
void vesa_unblank(void)
233
{
234
        if (!vesa_blanked)
235
          return;
236
 
237
        /* restore original values of VGA controller registers */
238
        cli();
239
        outb_p(vga.CrtMiscIO,video_misc_wr);
240
 
241
        outb_p(0x00,video_port_reg);            /* HorizontalTotal */
242
        outb_p(vga.HorizontalTotal,video_port_val);
243
        outb_p(0x01,video_port_reg);            /* HorizDisplayEnd */
244
        outb_p(vga.HorizDisplayEnd,video_port_val);
245
        outb_p(0x04,video_port_reg);            /* StartHorizRetrace */
246
        outb_p(vga.StartHorizRetrace,video_port_val);
247
        outb_p(0x05,video_port_reg);            /* EndHorizRetrace */
248
        outb_p(vga.EndHorizRetrace,video_port_val);
249
        outb_p(0x07,video_port_reg);            /* Overflow */
250
        outb_p(vga.Overflow,video_port_val);
251
        outb_p(0x10,video_port_reg);            /* StartVertRetrace */
252
        outb_p(vga.StartVertRetrace,video_port_val);
253
        outb_p(0x11,video_port_reg);            /* EndVertRetrace */
254
        outb_p(vga.EndVertRetrace,video_port_val);
255
        outb_p(0x17,video_port_reg);            /* ModeControl */
256
        outb_p(vga.ModeControl,video_port_val);
257
        outb_p(0x01,seq_port_reg);              /* ClockingMode */
258
        outb_p(vga.ClockingMode,seq_port_val);
259
 
260
        /* restore index/control registers */
261
        outb_p(vga.SeqCtrlIndex,seq_port_reg);
262
        outb_p(vga.CrtCtrlIndex,video_port_reg);
263
        sti();
264
 
265
        vesa_blanked = 0;
266
}
267
 
268
void set_vesa_blanking(const unsigned long arg)
269
{
270
        unsigned char *argp = (unsigned char *)(arg + 1);
271
        unsigned int mode;
272
 
273
        if (verify_area(VERIFY_READ, argp, 1))
274
                return;
275
 
276
        mode = get_user(argp);
277
        vesa_blanking_mode = suspend_vesa_blanking_mode =
278
                ((mode <= VESA_POWERDOWN) ? mode : DEFAULT_VESA_BLANKING_MODE);
279
}
280
 
281
void vesa_powerdown(void)
282
{
283
        if(vesa_blanking_mode == VESA_VSYNC_SUSPEND
284
                || vesa_blanking_mode == VESA_HSYNC_SUSPEND)
285
        {
286
                vesa_blanking_mode = VESA_POWERDOWN;
287
                vesa_blank();
288
                vesa_blanking_mode = suspend_vesa_blanking_mode;
289
        }
290
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.