Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / bsp / drv / dev / video / vga.c @ 03e9c04a

History | View | Annotate | Download (5.37 KB)

1
/*-
2
 * Copyright (c) 2005-2009, Kohsuke Ohtani
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * vga.c - vga driver
32
 */
33

    
34
#include <driver.h>
35
#include <wscons.h>
36
#include <devctl.h>
37
#include <pm.h>
38

    
39
/* #define DEBUG_VGA 1 */
40

    
41
#ifdef DEBUG_VGA
42
#define DPRINTF(a) printf a
43
#else
44
#define DPRINTF(a)
45
#endif
46

    
47
#define CRTC_INDEX        0x3d4
48
#define CRTC_DATA        0x3d5
49
#define SEQ_INDEX        0x3c4
50
#define SEQ_DATA        0x3c5
51

    
52
#define VID_RAM                0xB8000
53

    
54
struct vga_softc {
55
        device_t        dev;
56
        short                *vram;
57
        int                cols;
58
        int                attr;
59
        int                blank;
60
};
61

    
62
static int        vga_devctl(device_t, u_long, void *);
63
static int        vga_init(struct driver *);
64
static void        vga_cursor(void*, int, int);
65
static void        vga_putc(void *, int, int, int);
66
static void        vga_copyrows(void *,int, int, int);
67
static void        vga_eraserows(void *,int, int);
68
static void        vga_set_attr(void *, int);
69
static void        vga_get_cursor(void *, int *, int *);
70

    
71
static struct devops vga_devops = {
72
        /* open */        no_open,
73
        /* close */        no_close,
74
        /* read */        no_read,
75
        /* write */        no_write,
76
        /* ioctl */        no_ioctl,
77
        /* devctl */        vga_devctl,
78
};
79

    
80
struct driver vga_driver = {
81
        /* name */        "vga",
82
        /* devops */        &vga_devops,
83
        /* devsz */        sizeof(struct vga_softc),
84
        /* flags */        0,
85
        /* probe */        NULL,
86
        /* init */        vga_init,
87
        /* shutdown */        NULL,
88
};
89

    
90
static struct wscons_video_ops wscons_vga_ops = {
91
        vga_cursor,        /* cursor */
92
        vga_putc,        /* putc */
93
        vga_copyrows,        /* copyrows */
94
        vga_eraserows,        /* eraserows */
95
        vga_set_attr,        /* set_attr */
96
        vga_get_cursor,        /* set_cursor */
97
};
98

    
99

    
100
static u_char
101
crtc_read(u_char index)
102
{
103

    
104
        bus_write_8(CRTC_INDEX, index);
105
        return bus_read_8(CRTC_DATA);
106
}
107

    
108
static void
109
crtc_write(u_char index, u_char val)
110
{
111

    
112
        bus_write_8(CRTC_INDEX, index);
113
        bus_write_8(CRTC_DATA, val);
114
}
115

    
116
static void
117
vga_on(void)
118
{
119
        u_char val;
120

    
121
        bus_write_8(SEQ_INDEX, 1);
122
        val = bus_read_8(SEQ_DATA);
123
        bus_write_8(SEQ_DATA, val & ~0x20);
124
}
125

    
126
static void
127
vga_off(void)
128
{
129
        u_char val;
130

    
131
        bus_write_8(SEQ_INDEX, 1);
132
        val = bus_read_8(SEQ_DATA);
133
        bus_write_8(SEQ_DATA, val | 0x20);
134
}
135

    
136
static void
137
vga_cursor(void *aux, int row, int col)
138
{
139
        struct vga_softc *sc = aux;
140
        int pos, s;
141

    
142
        pos = row * sc->cols + col;
143

    
144
        s = splhigh();
145
        crtc_write(0x0e, (u_char)((pos >> 8) & 0xff));
146
        crtc_write(0x0f, (u_char)(pos & 0xff));
147
        splx(s);
148
}
149

    
150
static void
151
vga_putc(void *aux, int row, int col, int ch)
152
{
153
        struct vga_softc *sc = aux;
154

    
155
        sc->vram[row * sc->cols + col] = ch | (sc->attr << 8);
156
}
157

    
158
static void
159
vga_copyrows(void *aux, int srcrow, int dstrow, int nrows)
160
{
161
        struct vga_softc *sc = aux;
162

    
163
        memcpy(sc->vram + dstrow * sc->cols,
164
               sc->vram + srcrow * sc->cols,
165
               (size_t)nrows * sc->cols * 2);
166
}
167

    
168
static void
169
vga_eraserows(void *aux, int row, int nrows)
170
{
171
        struct vga_softc *sc = aux;
172
        int i, start, end;
173

    
174
        start = row * sc->cols;
175
        end = start + nrows * sc->cols;
176

    
177
        for (i = start; i < end; i++)
178
                sc->vram[i] = ' ' | (sc->attr << 8);
179
}
180

    
181
static void
182
vga_set_attr(void *aux, int attr)
183
{
184
        struct vga_softc *sc = aux;
185

    
186
        sc->attr = attr;
187
}
188

    
189

    
190
static void
191
vga_get_cursor(void *aux, int *col, int *row)
192
{
193
        struct vga_softc *sc = aux;
194
        u_int offset;
195
        int s;
196

    
197
        s = splhigh();
198
        offset = crtc_read(0x0e);
199
        offset <<= 8;
200
        offset += crtc_read(0x0f);
201
        *col = (int)offset % sc->cols;
202
        *row = (int)offset / sc->cols;
203
        splx(s);
204
}
205

    
206
static int
207
vga_devctl(device_t dev, u_long cmd, void *arg)
208
{
209
        struct vga_softc *sc = device_private(dev);
210
        int s;
211

    
212
        DPRINTF(("vga: devctl cmd=%x\n", cmd));
213

    
214
        s = splhigh();
215
        switch (cmd) {
216
        case DEVCTL_PM_LCDOFF:
217
                if (!sc->blank) {
218
                        DPRINTF(("vga: LCD off\n"));
219
                        vga_off();
220
                        sc->blank = 1;
221
                }
222
                break;
223
        case DEVCTL_PM_LCDON:
224
                if (sc->blank) {
225
                        vga_on();
226
                        sc->blank = 0;
227
                        DPRINTF(("vga: LCD on\n"));
228
                }
229
                break;
230
        }
231
        splx(s);
232
        return 0;
233
}
234

    
235
static int
236
vga_init(struct driver *self)
237
{
238
        device_t dev;
239
        struct bootinfo *bi;
240
        struct vga_softc *sc;
241

    
242
        machine_bootinfo(&bi);
243

    
244
        dev = device_create(self, "vga", D_CHR);
245

    
246
        sc = device_private(dev);
247
        sc->vram = ptokv(VID_RAM);
248
        sc->cols = bi->video.text_x;
249
        sc->attr = 0x0f;
250
        sc->blank = 0;
251

    
252
        wscons_attach_video(&wscons_vga_ops, sc);
253

    
254
        pm_attach_lcd(dev);
255
        return 0;
256
}