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

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [drivers/] [scr_fb.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999, 2000, 2001 Greg Haerr <greg@censoft.com>
3
 *
4
 * Microwindows Screen Driver for Linux kernel framebuffers
5
 *
6
 * Portions used from Ben Pfaff's BOGL <pfaffben@debian.org>
7
 *
8
 * Note: modify select_fb_driver() to add new framebuffer subdrivers
9
 */
10
#define _GNU_SOURCE 1
11
#include <assert.h>
12
#include <fcntl.h>
13
#include <limits.h>
14
#include <linux/fb.h>
15
#include <linux/kd.h>
16
#include <linux/vt.h>
17
#include <stdarg.h>
18
#include <stdio.h>
19
#include <stdlib.h>
20
#ifndef ARCH_LINUX_POWERPPC
21
#ifdef __GLIBC__
22
#include <sys/io.h>
23
#else
24
#include <asm/io.h>
25
#endif
26
#endif
27
#include <sys/ioctl.h>
28
#include <sys/mman.h>
29
#include <sys/stat.h>
30
#include <sys/time.h>
31
#include <sys/types.h>
32
#include <unistd.h>
33
#include "device.h"
34
#include "genfont.h"
35
#include "genmem.h"
36
#include "fb.h"
37
 
38
/* for Osprey and Embedded Planet boards, set HAVETEXTMODE=0*/
39
#define HAVETEXTMODE    1       /* =0 for graphics only systems*/
40
#define EMBEDDEDPLANET  0        /* =1 for kluge embeddedplanet ppc framebuffer*/
41
 
42
#ifndef FB_TYPE_VGA_PLANES
43
#define FB_TYPE_VGA_PLANES 4
44
#endif
45
 
46
static PSD  fb_open(PSD psd);
47
static void fb_close(PSD psd);
48
static void fb_setportrait(PSD psd, int portraitmode);
49
static void fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette);
50
static void gen_getscreeninfo(PSD psd,PMWSCREENINFO psi);
51
 
52
 
53
SCREENDEVICE    scrdev = {
54
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL,
55
        fb_open,
56
        fb_close,
57
        gen_getscreeninfo,
58
        fb_setpalette,
59
        NULL,                   /* DrawPixel subdriver*/
60
        NULL,                   /* ReadPixel subdriver*/
61
        NULL,                   /* DrawHorzLine subdriver*/
62
        NULL,                   /* DrawVertLine subdriver*/
63
        NULL,                   /* FillRect subdriver*/
64
        gen_fonts,
65
        NULL,                   /* Blit subdriver*/
66
        NULL,                   /* PreSelect*/
67
        NULL,                   /* DrawArea subdriver*/
68
        NULL,                   /* SetIOPermissions*/
69
        gen_allocatememgc,
70
        fb_mapmemgc,
71
        gen_freememgc,
72
        NULL,                   /* StretchBlit subdriver*/
73
        fb_setportrait          /* SetPortrait*/
74
};
75
 
76
/* static variables*/
77
static int fb;                  /* Framebuffer file handle. */
78
static int status;              /* 0=never inited, 1=once inited, 2=inited. */
79
static short saved_red[16];     /* original hw palette*/
80
static short saved_green[16];
81
static short saved_blue[16];
82
 
83
extern SUBDRIVER fbportrait_left, fbportrait_right, fbportrait_down;
84
static PSUBDRIVER pdrivers[4] = { /* portrait mode subdrivers*/
85
        NULL, &fbportrait_left, &fbportrait_right, &fbportrait_down
86
};
87
 
88
/* local functions*/
89
static void     set_directcolor_palette(PSD psd);
90
 
91
/* init framebuffer*/
92
static PSD
93
fb_open(PSD psd)
94
{
95
        char *  env;
96
        int     type, visual;
97
        PSUBDRIVER subdriver;
98
#if EMBEDDEDPLANET
99
        env = "/dev/lcd";
100
        fb = open(env, O_RDWR);
101
        if(fb < 0) {
102
                EPRINTF("Error opening %s: %m", env);
103
                return NULL;
104
        }
105
        /* framebuffer attributes are fixed*/
106
        type = FB_TYPE_PACKED_PIXELS;
107
        visual = FB_VISUAL_PSEUDOCOLOR;
108
        psd->xres = psd->xvirtres = 640;
109
        psd->yres = psd->yvirtres = 480;
110
        psd->planes = 1;
111
        psd->bpp = 8;
112
        /* set linelen to byte length, possibly converted later*/
113
        psd->linelen = psd->xvirtres;
114
        psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp);
115
        psd->size = 0;           /* force subdriver init of size*/
116
 
117
        if (ioctl(fb, 1, 0) < 0) {
118
                EPRINTF("Error: can't enable LCD");
119
                goto fail;
120
        }
121
#else
122
        int     tty;
123
        struct fb_fix_screeninfo fb_fix;
124
        struct fb_var_screeninfo fb_var;
125
 
126
        assert(status < 2);
127
 
128
        /* locate and open framebuffer, get info*/
129
        if(!(env = getenv("FRAMEBUFFER")))
130
                env = "/dev/fb0";
131
        fb = open(env, O_RDWR);
132
        if(fb < 0) {
133
                EPRINTF("Error opening %s: %m. Check kernel config\n", env);
134
                return NULL;
135
        }
136
        if(ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1 ||
137
                ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) {
138
                        EPRINTF("Error reading screen info: %m\n");
139
                        goto fail;
140
        }
141
        /* setup screen device from framebuffer info*/
142
        type = fb_fix.type;
143
        visual = fb_fix.visual;
144
 
145
        psd->portrait = MWPORTRAIT_NONE;
146
        psd->xres = psd->xvirtres = fb_var.xres;
147
        psd->yres = psd->yvirtres = fb_var.yres;
148
 
149
        /* set planes from fb type*/
150
        if (type == FB_TYPE_VGA_PLANES)
151
                psd->planes = 4;
152
        else if (type == FB_TYPE_PACKED_PIXELS)
153
                psd->planes = 1;
154
        else psd->planes = 0;    /* force error later*/
155
 
156
        psd->bpp = fb_var.bits_per_pixel;
157
        psd->ncolors = (psd->bpp >= 24)? (1 << 24): (1 << psd->bpp);
158
 
159
        /* set linelen to byte length, possibly converted later*/
160
        psd->linelen = fb_fix.line_length;
161
        psd->size = 0;           /* force subdriver init of size*/
162
#endif /* !EMBEDDEDPLANET*/
163
 
164
        psd->flags = PSF_SCREEN | PSF_HAVEBLIT;
165
        if (psd->bpp == 16)
166
                psd->flags |= PSF_HAVEOP_COPY;
167
 
168
        /* set pixel format*/
169
#ifndef TPHELIO /* temp kluge: VTech Helio kernel needs changing*/
170
        if(visual == FB_VISUAL_TRUECOLOR || visual == FB_VISUAL_DIRECTCOLOR) {
171
                switch(psd->bpp) {
172
                case 8:
173
                        psd->pixtype = MWPF_TRUECOLOR332;
174
                        break;
175
                case 16:
176
                        if (fb_var.green.length == 5)
177
                                psd->pixtype = MWPF_TRUECOLOR555;
178
                        else
179
                                psd->pixtype = MWPF_TRUECOLOR565;
180
                        break;
181
                case 24:
182
                        psd->pixtype = MWPF_TRUECOLOR888;
183
                        break;
184
                case 32:
185
                        psd->pixtype = MWPF_TRUECOLOR0888;
186
                        break;
187
                default:
188
                        EPRINTF(
189
                        "Unsupported %d color (%d bpp) truecolor framebuffer\n",
190
                                psd->ncolors, psd->bpp);
191
                        goto fail;
192
                }
193
        } else
194
#endif
195
                psd->pixtype = MWPF_PALETTE;
196
 
197
        /*DPRINTF("%dx%dx%d linelen %d type %d visual %d bpp %d\n", psd->xres,
198
                psd->yres, psd->ncolors, psd->linelen, type, visual,
199
                psd->bpp);*/
200
 
201
        /* select a framebuffer subdriver based on planes and bpp*/
202
        subdriver = select_fb_subdriver(psd);
203
        if (!subdriver) {
204
                EPRINTF("No driver for screen type %d visual %d bpp %d\n",
205
                        type, visual, psd->bpp);
206
                goto fail;
207
        }
208
 
209
        /*
210
         * set and initialize subdriver into screen driver
211
         * psd->size is calculated by subdriver init
212
         */
213
        if(!set_subdriver(psd, subdriver, TRUE)) {
214
                EPRINTF("Driver initialize failed type %d visual %d bpp %d\n",
215
                        type, visual, psd->bpp);
216
                goto fail;
217
        }
218
 
219
        /* remember original subdriver for portrait mode switching*/
220
        pdrivers[0] = psd->orgsubdriver = subdriver;
221
 
222
#if HAVETEXTMODE
223
        /* open tty, enter graphics mode*/
224
        tty = open ("/dev/tty0", O_RDWR);
225
        if(tty < 0) {
226
                EPRINTF("Error can't open /dev/tty0: %m\n");
227
                goto fail;
228
        }
229
        if(ioctl (tty, KDSETMODE, KD_GRAPHICS) == -1) {
230
                EPRINTF("Error setting graphics mode: %m\n");
231
                close(tty);
232
                goto fail;
233
        }
234
        close(tty);
235
#endif
236
        /* mmap framebuffer into this address space*/
237
        psd->size = (psd->size + getpagesize () - 1)
238
                        / getpagesize () * getpagesize ();
239
        psd->addr = mmap(NULL, psd->size, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
240
        if(psd->addr == NULL || psd->addr == (unsigned char *)-1) {
241
                EPRINTF("Error mmaping %s: %m\n", env);
242
                goto fail;
243
        }
244
 
245
        /* save original palette*/
246
        ioctl_getpalette(0, 16, saved_red, saved_green, saved_blue);
247
 
248
        /* setup direct color palette if required (ATI cards)*/
249
        if(visual == FB_VISUAL_DIRECTCOLOR)
250
                set_directcolor_palette(psd);
251
 
252
        status = 2;
253
        return psd;     /* success*/
254
 
255
fail:
256
        close(fb);
257
        return NULL;
258
}
259
 
260
/* close framebuffer*/
261
static void
262
fb_close(PSD psd)
263
{
264
        int     tty;
265
 
266
        /* if not opened, return*/
267
        if(status != 2)
268
                return;
269
        status = 1;
270
 
271
        /* reset hw palette*/
272
        ioctl_setpalette(0, 16, saved_red, saved_green, saved_blue);
273
 
274
        /* unmap framebuffer*/
275
        munmap(psd->addr, psd->size);
276
 
277
#if HAVETEXTMODE
278
        /* enter text mode*/
279
        tty = open ("/dev/tty0", O_RDWR);
280
        ioctl(tty, KDSETMODE, KD_TEXT);
281
        close(tty);
282
#endif
283
        /* close framebuffer*/
284
        close(fb);
285
}
286
 
287
static void
288
fb_setportrait(PSD psd, int portraitmode)
289
{
290
        psd->portrait = portraitmode;
291
 
292
        /* swap x and y in left or right portrait modes*/
293
        if (portraitmode & (MWPORTRAIT_LEFT|MWPORTRAIT_RIGHT)) {
294
                /* swap x, y*/
295
                psd->xvirtres = psd->yres;
296
                psd->yvirtres = psd->xres;
297
        } else {
298
                /* normal x, y*/
299
                psd->xvirtres = psd->xres;
300
                psd->yvirtres = psd->yres;
301
        }
302
        /* assign portrait subdriver which calls original subdriver*/
303
        if (portraitmode == MWPORTRAIT_DOWN)
304
                portraitmode = 3;       /* change bitpos to index*/
305
        set_subdriver(psd, pdrivers[portraitmode], FALSE);
306
}
307
 
308
/* setup directcolor palette - required for ATI cards*/
309
static void
310
set_directcolor_palette(PSD psd)
311
{
312
        int i;
313
        short r[256];
314
 
315
        /* 16bpp uses 32 palette entries*/
316
        if(psd->bpp == 16) {
317
                for(i=0; i<32; ++i)
318
                        r[i] = i<<11;
319
                ioctl_setpalette(0, 32, r, r, r);
320
        } else {
321
                /* 32bpp uses 256 entries*/
322
                for(i=0; i<256; ++i)
323
                        r[i] = i<<8;
324
                ioctl_setpalette(0, 256, r, r, r);
325
        }
326
}
327
 
328
static int fade = 100;
329
 
330
/* convert Microwindows palette to framebuffer format and set it*/
331
static void
332
fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette)
333
{
334
        int     i;
335
        unsigned short  red[count];
336
        unsigned short  green[count];
337
        unsigned short  blue[count];
338
 
339
        /* convert palette to framebuffer format*/
340
        for(i=0; i < count; i++) {
341
                MWPALENTRY *p = &palette[i];
342
 
343
                /* grayscale computation:
344
                 * red[i] = green[i] = blue[i] =
345
                 *      (p->r * 77 + p->g * 151 + p->b * 28);
346
                 */
347
                red[i] = (p->r * fade / 100) << 8;
348
                green[i] = (p->g * fade / 100) << 8;
349
                blue[i] = (p->b * fade / 100) << 8;
350
        }
351
        ioctl_setpalette(first, count, red, green, blue);
352
}
353
 
354
/* get framebuffer palette*/
355
void
356
ioctl_getpalette(int start, int len, short *red, short *green, short *blue)
357
{
358
#if EMBEDDEDPLANET
359
        int             i;
360
        unsigned short  colors[256];
361
 
362
        ioctl(fb, 4, colors);
363
        for (i = start; ((i - start) < len) && (i < 256); i++) {
364
                red[i - start] = (colors[i] & 0xf00) << 4;
365
                green[i - start] = (colors[i] & 0x0f0) << 8;
366
                blue[i - start] = (colors[i] & 0x00f) << 12;
367
        }
368
#else
369
        struct fb_cmap cmap;
370
 
371
        cmap.start = start;
372
        cmap.len = len;
373
        cmap.red = red;
374
        cmap.green = green;
375
        cmap.blue = blue;
376
        cmap.transp = NULL;
377
 
378
        ioctl(fb, FBIOGETCMAP, &cmap);
379
#endif
380
}
381
 
382
/* set framebuffer palette*/
383
void
384
ioctl_setpalette(int start, int len, short *red, short *green, short *blue)
385
{
386
#if EMBEDDEDPLANET
387
        int             i;
388
        unsigned short  colors[256];
389
 
390
        ioctl(fb, 4, colors);
391
        for (i = start; ((i - start) < len) && (i < 256); i++) {
392
                colors[i] = ((red[i - start] & 0xf000) >> 4)
393
                        | ((green[i - start] & 0xf000) >> 8)
394
                        | ((blue[i - start] & 0xf000) >> 12);
395
        }
396
        ioctl(fb, 3, colors);
397
#else
398
        struct fb_cmap cmap;
399
 
400
        cmap.start = start;
401
        cmap.len = len;
402
        cmap.red = red;
403
        cmap.green = green;
404
        cmap.blue = blue;
405
        cmap.transp = NULL;
406
 
407
        ioctl(fb, FBIOPUTCMAP, &cmap);
408
#endif
409
}
410
 
411
/* experimental palette animation*/
412
void
413
setfadelevel(PSD psd, int f)
414
{
415
        int             i;
416
        unsigned short  r[256], g[256], b[256];
417
        extern MWPALENTRY gr_palette[256];
418
 
419
        if(psd->pixtype != MWPF_PALETTE)
420
                return;
421
 
422
        fade = f;
423
        if(fade > 100)
424
                fade = 100;
425
        for(i=0; i<256; ++i) {
426
                r[i] = (gr_palette[i].r * fade / 100) << 8;
427
                g[i] = (gr_palette[i].g * fade / 100) << 8;
428
                b[i] = (gr_palette[i].b * fade / 100) << 8;
429
        }
430
        ioctl_setpalette(0, 256, r, g, b);
431
}
432
 
433
static void
434
gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
435
{
436
        psi->rows = psd->yvirtres;
437
        psi->cols = psd->xvirtres;
438
        psi->planes = psd->planes;
439
        psi->bpp = psd->bpp;
440
        psi->ncolors = psd->ncolors;
441
        psi->fonts = NUMBER_FONTS;
442
        psi->portrait = psd->portrait;
443
        psi->fbdriver = TRUE;   /* running fb driver, can direct map*/
444
 
445
        psi->pixtype = psd->pixtype;
446
        switch (psd->pixtype) {
447
        case MWPF_TRUECOLOR0888:
448
        case MWPF_TRUECOLOR888:
449
                psi->rmask      = 0xff0000;
450
                psi->gmask      = 0x00ff00;
451
                psi->bmask      = 0x0000ff;
452
                break;
453
        case MWPF_TRUECOLOR565:
454
                psi->rmask      = 0xf800;
455
                psi->gmask      = 0x07e0;
456
                psi->bmask      = 0x001f;
457
                break;
458
        case MWPF_TRUECOLOR555:
459
                psi->rmask      = 0x7c00;
460
                psi->gmask      = 0x03e0;
461
                psi->bmask      = 0x001f;
462
                break;
463
        case MWPF_TRUECOLOR332:
464
                psi->rmask      = 0xe0;
465
                psi->gmask      = 0x1c;
466
                psi->bmask      = 0x03;
467
                break;
468
        case MWPF_PALETTE:
469
        default:
470
                psi->rmask      = 0xff;
471
                psi->gmask      = 0xff;
472
                psi->bmask      = 0xff;
473
                break;
474
        }
475
 
476
        if(psd->yvirtres > 480) {
477
                /* SVGA 800x600*/
478
                psi->xdpcm = 33;        /* assumes screen width of 24 cm*/
479
                psi->ydpcm = 33;        /* assumes screen height of 18 cm*/
480
        } else if(psd->yvirtres > 350) {
481
                /* VGA 640x480*/
482
                psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
483
                psi->ydpcm = 27;        /* assumes screen height of 18 cm*/
484
        } else if(psd->yvirtres <= 240) {
485
                /* half VGA 640x240 */
486
                psi->xdpcm = 14;        /* assumes screen width of 24 cm*/
487
                psi->ydpcm =  5;
488
        } else {
489
                /* EGA 640x350*/
490
                psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
491
                psi->ydpcm = 19;        /* assumes screen height of 18 cm*/
492
        }
493
}

powered by: WebSVN 2.1.0

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