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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [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 716 simons
/* SIMON */
240
/*      psd->addr = mmap(NULL, psd->size, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
241
*/
242
        psd->addr = mmap(NULL, psd->size, PROT_READ|PROT_WRITE,0,fb,0);
243
 
244 673 markom
        if(psd->addr == NULL || psd->addr == (unsigned char *)-1) {
245
                EPRINTF("Error mmaping %s: %m\n", env);
246
                goto fail;
247
        }
248
 
249
        /* save original palette*/
250
        ioctl_getpalette(0, 16, saved_red, saved_green, saved_blue);
251
 
252
        /* setup direct color palette if required (ATI cards)*/
253
        if(visual == FB_VISUAL_DIRECTCOLOR)
254
                set_directcolor_palette(psd);
255
 
256
        status = 2;
257
        return psd;     /* success*/
258
 
259
fail:
260
        close(fb);
261
        return NULL;
262
}
263
 
264
/* close framebuffer*/
265
static void
266
fb_close(PSD psd)
267
{
268
        int     tty;
269
 
270
        /* if not opened, return*/
271
        if(status != 2)
272
                return;
273
        status = 1;
274
 
275
        /* reset hw palette*/
276
        ioctl_setpalette(0, 16, saved_red, saved_green, saved_blue);
277
 
278
        /* unmap framebuffer*/
279
        munmap(psd->addr, psd->size);
280
 
281
#if HAVETEXTMODE
282
        /* enter text mode*/
283
        tty = open ("/dev/tty0", O_RDWR);
284
        ioctl(tty, KDSETMODE, KD_TEXT);
285
        close(tty);
286
#endif
287
        /* close framebuffer*/
288
        close(fb);
289
}
290
 
291
static void
292
fb_setportrait(PSD psd, int portraitmode)
293
{
294
        psd->portrait = portraitmode;
295
 
296
        /* swap x and y in left or right portrait modes*/
297
        if (portraitmode & (MWPORTRAIT_LEFT|MWPORTRAIT_RIGHT)) {
298
                /* swap x, y*/
299
                psd->xvirtres = psd->yres;
300
                psd->yvirtres = psd->xres;
301
        } else {
302
                /* normal x, y*/
303
                psd->xvirtres = psd->xres;
304
                psd->yvirtres = psd->yres;
305
        }
306
        /* assign portrait subdriver which calls original subdriver*/
307
        if (portraitmode == MWPORTRAIT_DOWN)
308
                portraitmode = 3;       /* change bitpos to index*/
309
        set_subdriver(psd, pdrivers[portraitmode], FALSE);
310
}
311
 
312
/* setup directcolor palette - required for ATI cards*/
313
static void
314
set_directcolor_palette(PSD psd)
315
{
316
        int i;
317
        short r[256];
318
 
319
        /* 16bpp uses 32 palette entries*/
320
        if(psd->bpp == 16) {
321
                for(i=0; i<32; ++i)
322
                        r[i] = i<<11;
323
                ioctl_setpalette(0, 32, r, r, r);
324
        } else {
325
                /* 32bpp uses 256 entries*/
326
                for(i=0; i<256; ++i)
327
                        r[i] = i<<8;
328
                ioctl_setpalette(0, 256, r, r, r);
329
        }
330
}
331
 
332
static int fade = 100;
333
 
334
/* convert Microwindows palette to framebuffer format and set it*/
335
static void
336
fb_setpalette(PSD psd,int first, int count, MWPALENTRY *palette)
337
{
338
        int     i;
339
        unsigned short  red[count];
340
        unsigned short  green[count];
341
        unsigned short  blue[count];
342
 
343
        /* convert palette to framebuffer format*/
344
        for(i=0; i < count; i++) {
345
                MWPALENTRY *p = &palette[i];
346
 
347
                /* grayscale computation:
348
                 * red[i] = green[i] = blue[i] =
349
                 *      (p->r * 77 + p->g * 151 + p->b * 28);
350
                 */
351
                red[i] = (p->r * fade / 100) << 8;
352
                green[i] = (p->g * fade / 100) << 8;
353
                blue[i] = (p->b * fade / 100) << 8;
354
        }
355
        ioctl_setpalette(first, count, red, green, blue);
356
}
357
 
358
/* get framebuffer palette*/
359
void
360
ioctl_getpalette(int start, int len, short *red, short *green, short *blue)
361
{
362
#if EMBEDDEDPLANET
363
        int             i;
364
        unsigned short  colors[256];
365
 
366
        ioctl(fb, 4, colors);
367
        for (i = start; ((i - start) < len) && (i < 256); i++) {
368
                red[i - start] = (colors[i] & 0xf00) << 4;
369
                green[i - start] = (colors[i] & 0x0f0) << 8;
370
                blue[i - start] = (colors[i] & 0x00f) << 12;
371
        }
372
#else
373
        struct fb_cmap cmap;
374
 
375
        cmap.start = start;
376
        cmap.len = len;
377
        cmap.red = red;
378
        cmap.green = green;
379
        cmap.blue = blue;
380
        cmap.transp = NULL;
381
 
382
        ioctl(fb, FBIOGETCMAP, &cmap);
383
#endif
384
}
385
 
386
/* set framebuffer palette*/
387
void
388
ioctl_setpalette(int start, int len, short *red, short *green, short *blue)
389
{
390
#if EMBEDDEDPLANET
391
        int             i;
392
        unsigned short  colors[256];
393
 
394
        ioctl(fb, 4, colors);
395
        for (i = start; ((i - start) < len) && (i < 256); i++) {
396
                colors[i] = ((red[i - start] & 0xf000) >> 4)
397
                        | ((green[i - start] & 0xf000) >> 8)
398
                        | ((blue[i - start] & 0xf000) >> 12);
399
        }
400
        ioctl(fb, 3, colors);
401
#else
402
        struct fb_cmap cmap;
403
 
404
        cmap.start = start;
405
        cmap.len = len;
406
        cmap.red = red;
407
        cmap.green = green;
408
        cmap.blue = blue;
409
        cmap.transp = NULL;
410
 
411
        ioctl(fb, FBIOPUTCMAP, &cmap);
412
#endif
413
}
414
 
415
/* experimental palette animation*/
416
void
417
setfadelevel(PSD psd, int f)
418
{
419
        int             i;
420
        unsigned short  r[256], g[256], b[256];
421
        extern MWPALENTRY gr_palette[256];
422
 
423
        if(psd->pixtype != MWPF_PALETTE)
424
                return;
425
 
426
        fade = f;
427
        if(fade > 100)
428
                fade = 100;
429
        for(i=0; i<256; ++i) {
430
                r[i] = (gr_palette[i].r * fade / 100) << 8;
431
                g[i] = (gr_palette[i].g * fade / 100) << 8;
432
                b[i] = (gr_palette[i].b * fade / 100) << 8;
433
        }
434
        ioctl_setpalette(0, 256, r, g, b);
435
}
436
 
437
static void
438
gen_getscreeninfo(PSD psd,PMWSCREENINFO psi)
439
{
440
        psi->rows = psd->yvirtres;
441
        psi->cols = psd->xvirtres;
442
        psi->planes = psd->planes;
443
        psi->bpp = psd->bpp;
444
        psi->ncolors = psd->ncolors;
445
        psi->fonts = NUMBER_FONTS;
446
        psi->portrait = psd->portrait;
447
        psi->fbdriver = TRUE;   /* running fb driver, can direct map*/
448
 
449
        psi->pixtype = psd->pixtype;
450
        switch (psd->pixtype) {
451
        case MWPF_TRUECOLOR0888:
452
        case MWPF_TRUECOLOR888:
453
                psi->rmask      = 0xff0000;
454
                psi->gmask      = 0x00ff00;
455
                psi->bmask      = 0x0000ff;
456
                break;
457
        case MWPF_TRUECOLOR565:
458
                psi->rmask      = 0xf800;
459
                psi->gmask      = 0x07e0;
460
                psi->bmask      = 0x001f;
461
                break;
462
        case MWPF_TRUECOLOR555:
463
                psi->rmask      = 0x7c00;
464
                psi->gmask      = 0x03e0;
465
                psi->bmask      = 0x001f;
466
                break;
467
        case MWPF_TRUECOLOR332:
468
                psi->rmask      = 0xe0;
469
                psi->gmask      = 0x1c;
470
                psi->bmask      = 0x03;
471
                break;
472
        case MWPF_PALETTE:
473
        default:
474
                psi->rmask      = 0xff;
475
                psi->gmask      = 0xff;
476
                psi->bmask      = 0xff;
477
                break;
478
        }
479
 
480
        if(psd->yvirtres > 480) {
481
                /* SVGA 800x600*/
482
                psi->xdpcm = 33;        /* assumes screen width of 24 cm*/
483
                psi->ydpcm = 33;        /* assumes screen height of 18 cm*/
484
        } else if(psd->yvirtres > 350) {
485
                /* VGA 640x480*/
486
                psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
487
                psi->ydpcm = 27;        /* assumes screen height of 18 cm*/
488
        } else if(psd->yvirtres <= 240) {
489
                /* half VGA 640x240 */
490
                psi->xdpcm = 14;        /* assumes screen width of 24 cm*/
491
                psi->ydpcm =  5;
492
        } else {
493
                /* EGA 640x350*/
494
                psi->xdpcm = 27;        /* assumes screen width of 24 cm*/
495
                psi->ydpcm = 19;        /* assumes screen height of 18 cm*/
496
        }
497
}

powered by: WebSVN 2.1.0

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