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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_11/] [apps/] [sw/] [driver/] [fb/] [spartan_fb.c] - Blame information for rev 154

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 21 mihad
/*
2
 * framebuffer driver for VBE 2.0 compliant graphic boards
3
 *
4
 * switching to graphics mode happens at boot time (while
5
 * running in real mode, see arch/i386/video.S).
6
 *
7
 * (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
8
 *
9
 */
10
 
11
#include <linux/module.h>
12
#include <linux/kernel.h>
13
#include <linux/errno.h>
14
#include <linux/pci.h>
15
#include <linux/string.h>
16
#include <linux/mm.h>
17
#include <linux/tty.h>
18
#include <linux/slab.h>
19
#include <linux/delay.h>
20
#include <linux/fb.h>
21
#include <linux/console.h>
22
#include <linux/selection.h>
23
#include <linux/ioport.h>
24
#include <linux/init.h>
25
#include <linux/wrapper.h>
26
 
27
#include <asm/io.h>
28
#include <asm/mtrr.h>
29
 
30
#include <video/fbcon.h>
31
#include <video/fbcon-cfb8.h>
32
#include <video/fbcon-cfb16.h>
33
#include <video/fbcon-cfb24.h>
34
#include <video/fbcon-cfb32.h>
35
#include <video/fbcon-mac.h>
36
#include <spartan_kint.h> 
37
 
38
#define dac_reg (0x3c8)
39
#define dac_val (0x3c9)
40
 
41
/* SIMON */
42
#define PCI 1
43
 
44 85 mihad
#define OC_PCI_VENDOR 0x1895
45 21 mihad
#define OC_PCI_DEVICE 0x0001
46
 
47
#define VIDEO_WIDTH 640
48
#define VIDEO_HEIGHT 480
49
#define VIDEO_BPP 8
50
 
51
/* --------------------------------------------------------------------- */
52
 
53
/*
54
 * card parameters
55
 */
56
 
57
/* card */
58
unsigned long video_base; /* physical addr */
59
int   Video_size;
60
unsigned long video_vbase;        /* mapped */
61
 
62
MODULE_PARM(video_base, "l");
63
 
64
/* mode */
65
static int  video_bpp;
66
static int  video_width;
67
static int  video_height;
68
static int  video_size;
69
static int  video_height_virtual;
70
static int  video_type = FB_TYPE_PACKED_PIXELS;
71
static int  video_visual;
72
static int  video_linelength;
73
static int  video_cmap_len;
74
 
75
#ifdef PCI
76
/*
77
 * structure for holding board information
78
 * (6 base addresses, mapping, page etc.
79
 */
80
static struct our_dev
81
{
82
        int major ;
83
        u32 bases[6] ;
84
        u8 num_of_bases ;
85
        u32 base_size[6] ;
86
        u32 offset ;
87
        u32 page_addr ;
88
        u32 base_page_offset ;
89
        int current_resource ;
90
        int base_map[6] ;
91
        struct pci_dev *ppci_spartan_dev ;
92
} pspartan_dev ;
93
#endif
94
 
95
/* --------------------------------------------------------------------- */
96
 
97
static struct fb_var_screeninfo vesafb_defined = {
98
        0,0,0,0,    /* W,H, W, H (virtual) load xres,xres_virtual*/
99
        0,0,              /* virtual -> visible no offset */
100
        8,              /* depth -> load bits_per_pixel */
101
        0,               /* greyscale ? */
102
        {0,0,0},   /* R */
103
        {0,0,0},   /* G */
104
        {0,0,0},   /* B */
105
        {0,0,0},   /* transparency */
106
        0,               /* standard pixel format */
107
        FB_ACTIVATE_NOW,
108
        -1,-1,
109
        0,
110
        0L,0L,0L,0L,0L,
111
        0L,0L,0, /* No sync info */
112
        FB_VMODE_NONINTERLACED,
113
        {0,0,0,0,0,0}
114
};
115
 
116
static struct display disp;
117
static struct fb_info fb_info;
118
static struct { u_short blue, green, red, pad; } palette[256];
119
static union {
120
#ifdef FBCON_HAS_CFB16
121
    u16 cfb16[16];
122
#endif
123
#ifdef FBCON_HAS_CFB24
124
    u32 cfb24[16];
125
#endif
126
#ifdef FBCON_HAS_CFB32
127
    u32 cfb32[16];
128
#endif
129
} fbcon_cmap;
130
 
131
static int             inverse   = 0;
132
static int             mtrr      = 0;
133
static int             currcon   = 0;
134
 
135
static int             pmi_setpal = 0;   /* pmi for palette changes ??? */
136
static int             ypan       = 0;  /* 0..nothing, 1..ypan, 2..ywrap */
137
 
138
static struct display_switch vesafb_sw;
139
 
140
/* --------------------------------------------------------------------- */
141
 
142
static int vesafb_update_var(int con, struct fb_info *info)
143
{
144
        if (con == currcon && ypan) {
145
                struct fb_var_screeninfo *var = &fb_display[currcon].var;
146
                return 0;
147
        }
148
        return 0;
149
}
150
 
151
static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
152
                         struct fb_info *info)
153
{
154
        memset(fix, 0, sizeof(struct fb_fix_screeninfo));
155
        strcpy(fix->id,"VESA VGA 1");
156
 
157
        fix->smem_start=video_base;
158
        fix->smem_len=video_size;
159
        fix->type = video_type;
160
        fix->visual = video_visual;
161
        fix->xpanstep  = 0;
162
        fix->ypanstep  = ypan     ? 1 : 0;
163
        fix->ywrapstep = (ypan>1) ? 1 : 0;
164
        fix->line_length=video_linelength;
165
        return 0;
166
}
167
 
168
static int vesafb_get_var(struct fb_var_screeninfo *var, int con,
169
                         struct fb_info *info)
170
{
171
        if(con==-1)
172
                memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
173
        else
174
                *var=fb_display[con].var;
175
        return 0;
176
}
177
 
178
static void vesafb_set_disp(int con)
179
{
180
        struct fb_fix_screeninfo fix;
181
        struct display *display;
182
        struct display_switch *sw;
183
 
184
        if (con >= 0)
185
                display = &fb_display[con];
186
        else
187
                display = &disp;        /* used during initialization */
188
 
189
        vesafb_get_fix(&fix, con, 0);
190
 
191
        memset(display, 0, sizeof(struct display));
192
        display->screen_base = (unsigned char *)video_vbase;
193
        display->visual = fix.visual;
194
        display->type = fix.type;
195
        display->type_aux = fix.type_aux;
196
        display->ypanstep = fix.ypanstep;
197
        display->ywrapstep = fix.ywrapstep;
198
        display->line_length = fix.line_length;
199
        display->next_line = fix.line_length;
200
        display->can_soft_blank = 0;
201
        display->inverse = inverse;
202
        vesafb_get_var(&display->var, -1, &fb_info);
203
 
204
        switch (video_bpp) {
205
#ifdef FBCON_HAS_CFB8
206
        case 8:
207
                sw = &fbcon_cfb8;
208
                break;
209
#endif
210
#ifdef FBCON_HAS_CFB16
211
        case 15:
212
        case 16:
213
                sw = &fbcon_cfb16;
214
                display->dispsw_data = fbcon_cmap.cfb16;
215
                break;
216
#endif
217
#ifdef FBCON_HAS_CFB24
218
        case 24:
219
                sw = &fbcon_cfb24;
220
                display->dispsw_data = fbcon_cmap.cfb24;
221
                break;
222
#endif
223
#ifdef FBCON_HAS_CFB32
224
        case 32:
225
                sw = &fbcon_cfb32;
226
                display->dispsw_data = fbcon_cmap.cfb32;
227
                break;
228
#endif
229
        default:
230
#ifdef FBCON_HAS_MAC
231
                sw = &fbcon_mac;
232
                break;
233
#else
234
                sw = &fbcon_dummy;
235
                return;
236
#endif
237
        }
238
        memcpy(&vesafb_sw, sw, sizeof(*sw));
239
        display->dispsw = &vesafb_sw;
240
        if (!ypan) {
241
                display->scrollmode = SCROLL_YREDRAW;
242
                vesafb_sw.bmove = fbcon_redraw_bmove;
243
        }
244
}
245
 
246
static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
247
                          struct fb_info *info)
248
{
249
        static int first = 1;
250
 
251
        if (var->xres           != vesafb_defined.xres           ||
252
            var->yres           != vesafb_defined.yres           ||
253
            var->xres_virtual   != vesafb_defined.xres_virtual   ||
254
            var->yres_virtual   >  video_height_virtual          ||
255
            var->yres_virtual   <  video_height                  ||
256
            var->xoffset                                         ||
257
            var->bits_per_pixel != vesafb_defined.bits_per_pixel ||
258
            var->nonstd) {
259
                if (first) {
260
                        printk(KERN_ERR "Vesafb does not support changing the video mode\n");
261
                        first = 0;
262
                }
263
                return -EINVAL;
264
        }
265
 
266
        if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
267
                return 0;
268
 
269
        if (var->yoffset)
270
                return -EINVAL;
271
        return 0;
272
}
273
 
274
static int vesa_getcolreg(unsigned regno, unsigned *red, unsigned *green,
275
                          unsigned *blue, unsigned *transp,
276
                          struct fb_info *fb_info)
277
{
278
        /*
279
         *  Read a single color register and split it into colors/transparent.
280
         *  Return != 0 for invalid regno.
281
         */
282
 
283
        if (regno >= video_cmap_len)
284
                return 1;
285
 
286
        *red   = palette[regno].red;
287
        *green = palette[regno].green;
288
        *blue  = palette[regno].blue;
289
        *transp = 0;
290
        return 0;
291
}
292
 
293
#ifdef FBCON_HAS_CFB8
294
 
295
static void vesa_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
296
{
297
#ifndef PCI
298
        /* without protected mode interface, try VGA registers... */
299
        outb_p(regno,       dac_reg);
300
        outb_p(red   >> 10, dac_val);
301
        outb_p(green >> 10, dac_val);
302
        outb_p(blue  >> 10, dac_val);
303
#else
304
        unsigned long pixel;
305
 
306
        pixel = (blue & 0xf000) | ((green & 0xf000) >> 4) | ((red & 0xf000) >> 8);
307
 
308
        writel(pixel , pspartan_dev.base_map[1] + SPARTAN_CRT_PALETTE_BASE + (regno * 4));
309
#endif 
310
}
311
 
312
#endif
313
 
314
static int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,
315
                          unsigned blue, unsigned transp,
316
                          struct fb_info *fb_info)
317
{
318
        /*
319
         *  Set a single color register. The values supplied are
320
         *  already rounded down to the hardware's capabilities
321
         *  (according to the entries in the `var' structure). Return
322
         *  != 0 for invalid regno.
323
         */
324
        if (regno >= video_cmap_len)
325
                return 1;
326
 
327
        palette[regno].red   = red;
328
        palette[regno].green = green;
329
        palette[regno].blue  = blue;
330
 
331
        switch (video_bpp) {
332
#ifdef FBCON_HAS_CFB8
333
        case 8:
334
                vesa_setpalette(regno,red,green,blue);
335
                break;
336
#endif
337
#ifdef FBCON_HAS_CFB16
338
        case 15:
339
        case 16:
340
                vesa_setpalette(regno,red,green,blue);
341
                break;
342
                if (vesafb_defined.red.offset == 10) {
343
                        /* 1:5:5:5 */
344
                        fbcon_cmap.cfb16[regno] =
345
                                ((red   & 0xf800) >>  1) |
346
                                ((green & 0xf800) >>  6) |
347
                                ((blue  & 0xf800) >> 11);
348
                } else {
349
                        /* 0:5:6:5 */
350
                        fbcon_cmap.cfb16[regno] =
351
                                ((red   & 0xf800)      ) |
352
                                ((green & 0xfc00) >>  5) |
353
                                ((blue  & 0xf800) >> 11);
354
                }
355
                break;
356
#endif
357
#ifdef FBCON_HAS_CFB24
358
        case 24:
359
                red   >>= 8;
360
                green >>= 8;
361
                blue  >>= 8;
362
                fbcon_cmap.cfb24[regno] =
363
                        (red   << vesafb_defined.red.offset)   |
364
                        (green << vesafb_defined.green.offset) |
365
                        (blue  << vesafb_defined.blue.offset);
366
                break;
367
#endif
368
#ifdef FBCON_HAS_CFB32
369
        case 32:
370
                red   >>= 8;
371
                green >>= 8;
372
                blue  >>= 8;
373
                fbcon_cmap.cfb32[regno] =
374
                        (red   << vesafb_defined.red.offset)   |
375
                        (green << vesafb_defined.green.offset) |
376
                        (blue  << vesafb_defined.blue.offset);
377
                break;
378
#endif
379
    }
380
    return 0;
381
}
382
 
383
static void do_install_cmap(int con, struct fb_info *info)
384
{
385
        if (con != currcon)
386
                return;
387
        if (fb_display[con].cmap.len)
388
                fb_set_cmap(&fb_display[con].cmap, 1, vesa_setcolreg, info);
389
        else
390
                fb_set_cmap(fb_default_cmap(video_cmap_len), 1, vesa_setcolreg,
391
                            info);
392
}
393
 
394
static int vesafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
395
                           struct fb_info *info)
396
{
397
        if (con == currcon) /* current console? */
398
                return fb_get_cmap(cmap, kspc, vesa_getcolreg, info);
399
        else if (fb_display[con].cmap.len) /* non default colormap? */
400
                fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
401
        else
402
                fb_copy_cmap(fb_default_cmap(video_cmap_len),
403
                     cmap, kspc ? 0 : 2);
404
        return 0;
405
}
406
 
407
static int vesafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
408
                           struct fb_info *info)
409
{
410
        int err;
411
 
412
        if (!fb_display[con].cmap.len) {        /* no colormap allocated? */
413
                err = fb_alloc_cmap(&fb_display[con].cmap,video_cmap_len,0);
414
                if (err) {
415
                        return err;
416
                }
417
        }
418
        if (1/*con == currcon*/) {                      /* current console? */
419
                return fb_set_cmap(cmap, kspc, vesa_setcolreg, info);
420
        } else {
421
                fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
422
        }
423
        return 0;
424
}
425
 
426
static struct fb_ops vesafb_ops = {
427
        owner:          THIS_MODULE,
428
        fb_get_fix:     vesafb_get_fix,
429
        fb_get_var:     vesafb_get_var,
430
        fb_set_var:     vesafb_set_var,
431
        fb_get_cmap:    vesafb_get_cmap,
432
        fb_set_cmap:    vesafb_set_cmap,
433
};
434
 
435
int __init vesafb_setup(char *options)
436
{
437
        char *this_opt;
438
 
439
        fb_info.fontname[0] = '\0';
440
 
441
        if (!options || !*options)
442
                return 0;
443
 
444
        for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
445
                if (!*this_opt) continue;
446
 
447
                if (! strcmp(this_opt, "inverse"))
448
                        inverse=1;
449
                else if (! strcmp(this_opt, "redraw"))
450
                        ypan=0;
451
                else if (! strcmp(this_opt, "ypan"))
452
                        ypan=1;
453
                else if (! strcmp(this_opt, "ywrap"))
454
                        ypan=2;
455
                else if (! strcmp(this_opt, "vgapal"))
456
                        pmi_setpal=0;
457
                else if (! strcmp(this_opt, "pmipal"))
458
                        pmi_setpal=1;
459
                else if (! strcmp(this_opt, "mtrr"))
460
                        mtrr=1;
461
                else if (!strncmp(this_opt, "font:", 5))
462
                        strcpy(fb_info.fontname, this_opt+5);
463
        }
464
        return 0;
465
}
466
 
467
static int vesafb_switch(int con, struct fb_info *info)
468
{
469
        /* Do we have to save the colormap? */
470
        if (fb_display[currcon].cmap.len)
471
                fb_get_cmap(&fb_display[currcon].cmap, 1, vesa_getcolreg,
472
                            info);
473
 
474
        currcon = con;
475
        /* Install new colormap */
476
        do_install_cmap(con, info);
477
        vesafb_update_var(con,info);
478
        return 1;
479
}
480
 
481
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
482
 
483
static void vesafb_blank(int blank, struct fb_info *info)
484
{
485
        /* Not supported */
486
}
487
 
488
int __init vfb_setup(char *options)
489
{
490
        return 0;
491
}
492
 
493
int __init vesafb_init(void)
494
{
495
        struct pci_dev *ppci_spartan_dev = NULL ;
496
        struct page *page;
497
        int size, sz;
498
        int i,j;
499
        unsigned int value;
500
 
501
/*      if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
502
                return -ENXIO;
503
*/
504
#ifndef PCI
505
        video_base          = screen_info.lfb_base;
506
        video_bpp           = screen_info.lfb_depth;
507
        video_width         = screen_info.lfb_width;
508
        video_height        = screen_info.lfb_height;
509
        video_linelength    = screen_info.lfb_linelength;
510
        video_size          = screen_info.lfb_size * 65536;
511
        video_visual        = FB_VISUAL_PSEUDOCOLOR;
512
 
513
        if (!request_mem_region(video_base, video_size, "vesafb")) {
514
                printk(KERN_ERR
515
                       "vesafb: abort, cannot reserve video memory at 0x%lx\n",
516
                        video_base);
517
                return -EBUSY;
518
        }
519
 
520
        video_vbase = ioremap(video_base, video_size);
521
        if (!video_vbase) {
522
                release_mem_region(video_base, video_size);
523
                printk(KERN_ERR
524
                       "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
525
                        video_size, video_base);
526
                return -EIO;
527
        }
528
 
529
        printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
530
               video_base, video_vbase, video_size/1024);
531
        printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
532
               video_width, video_height, video_bpp, video_linelength, screen_info.pages);
533
 
534
        if (screen_info.vesapm_seg) {
535
                printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
536
                       screen_info.vesapm_seg,screen_info.vesapm_off);
537
        }
538
#else
539
 
540
        if((ppci_spartan_dev = pci_find_device(OC_PCI_VENDOR, OC_PCI_DEVICE, ppci_spartan_dev))==NULL ) {
541
                printk(KERN_ERR "vesafb: device not found\n");
542
                return -ENODEV;
543
        }
544
 
545
        /* Check address for PCI registers */
546
        if(ppci_spartan_dev->resource[0].start != 0) {
547
                pspartan_dev.bases[0] = ppci_spartan_dev->resource[0].start;
548
        }
549
        else {
550
                printk(KERN_ERR "vesafb: device not found\n");
551
                return -ENODEV;
552
        }
553
 
554
        /* Check address for CRT registers */
555
        if(ppci_spartan_dev->resource[1].start != 0) {
556
                pspartan_dev.bases[1] = ppci_spartan_dev->resource[1].start;
557
        }
558
        else {
559
                printk(KERN_ERR "vesafb: device not found\n");
560
                return -ENODEV;
561
        }
562
 
563
        /* Disable device response */
564
        pci_read_config_dword(ppci_spartan_dev, PCI_COMMAND, &value);
565
        value &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
566
        pci_write_config_dword(ppci_spartan_dev, PCI_COMMAND, value);
567
 
568
        /* Get PCI registers address space size */
569
        pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0, 0xFFFFFFFF);
570
        pci_read_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0, &value);
571
        pspartan_dev.base_size[0] = 0xFFFFFFFF - value + 1;
572
        value = pspartan_dev.bases[0];
573
        pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_0, value);
574
 
575
        /* Get CRT registers address space size */
576
        pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_1, 0xFFFFFFFF);
577
        pci_read_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_1, &value);
578
        pspartan_dev.base_size[1] = 0xFFFFFFFF - value + 1;
579
        value = pspartan_dev.bases[1];
580
        pci_write_config_dword(ppci_spartan_dev, PCI_BASE_ADDRESS_1, value);
581
 
582
        /* Enable memory access */
583
        pci_read_config_dword(ppci_spartan_dev, PCI_COMMAND, &value);
584
        value |= PCI_COMMAND_MEMORY;
585
        pci_write_config_dword(ppci_spartan_dev, PCI_COMMAND, value);
586
 
587
        /* Set burst length */
588
        pci_write_config_dword(ppci_spartan_dev, PCI_CACHE_LINE_SIZE, 0x4020);
589
 
590
        /* Map PCI registers */
591
        if (!request_mem_region(pspartan_dev.bases[0], pspartan_dev.base_size[0], "vesafb")) {
592
                printk(KERN_ERR
593
                       "vesafb: abort, cannot reserve video memory at 0x%lx\n",
594
                        pspartan_dev.bases[0]);
595
                return -EBUSY;
596
        }
597
 
598
        pspartan_dev.base_map[0] = (unsigned long)ioremap(pspartan_dev.bases[0], pspartan_dev.base_size[0]);
599
        if (!pspartan_dev.base_map[0]) {
600
                release_mem_region(pspartan_dev.bases[0], pspartan_dev.base_size[0]);
601
                printk(KERN_ERR
602
                       "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
603
                        pspartan_dev.base_size[0], pspartan_dev.bases[0]);
604
                return -EIO;
605
        }
606
 
607
        /* Map CRT registers */
608
        if (!request_mem_region(pspartan_dev.bases[1], pspartan_dev.base_size[1], "vesafb")) {
609
                printk(KERN_ERR
610
                       "vesafb: abort, cannot reserve video memory at 0x%lx\n",
611
                        pspartan_dev.bases[1]);
612
                return -EBUSY;
613
        }
614
 
615
        pspartan_dev.base_map[1] = (unsigned long)ioremap(pspartan_dev.bases[1], pspartan_dev.base_size[1]);
616
        if (!pspartan_dev.base_map[1]) {
617
                release_mem_region(pspartan_dev.bases[0], pspartan_dev.base_size[0]);
618
                release_mem_region(pspartan_dev.bases[1], pspartan_dev.base_size[1]);
619
                printk(KERN_ERR
620
                       "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
621
                        pspartan_dev.base_size[1], pspartan_dev.bases[1]);
622
                return -EIO;
623
        }
624
 
625
        /* Set address mask for CRT registers */
626
        writel(0xffffffff & ~(pspartan_dev.base_size[1] - 1), pspartan_dev.base_map[0] + SPARTAN_P_AM1_ADDR);
627
 
628
        /* Set address traslation for CRT registers */
629
        writel(0, pspartan_dev.base_map[0] + SPARTAN_P_TA1_ADDR);
630
 
631
        /* Enable address traslation for CRT registers */
632
        writel(0x04, pspartan_dev.base_map[0] + SPARTAN_P_IMG_CTRL1_ADDR);
633
 
634
        video_width         = VIDEO_WIDTH;
635
        video_height        = VIDEO_HEIGHT;
636
        video_linelength    = VIDEO_WIDTH;
637
        video_size          = VIDEO_WIDTH*VIDEO_HEIGHT;
638
        video_bpp           = VIDEO_BPP;
639
        video_visual        = FB_VISUAL_PSEUDOCOLOR;
640
 
641
        for (sz = 0, size = PAGE_SIZE; size < video_size; sz++, size <<= 1);
642
        video_vbase = __get_free_pages(GFP_KERNEL, sz);
643
 
644
        if (video_vbase == 0) {
645
                printk(KERN_ERR "vesafb: abort, cannot allocate video memory\n");
646
                return -EIO;
647
        }
648
 
649
 
650
        video_base = virt_to_bus((unsigned char *)video_vbase);
651
 
652
        for (page = virt_to_page((unsigned char *)video_vbase); page <= virt_to_page((unsigned char *)(video_vbase + video_size - 1)); page++)
653
                mem_map_reserve(page);
654
 
655
        printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
656
               video_base, video_vbase, video_size/1024);
657
        printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d\n",
658
               video_width, video_height, video_bpp, video_linelength);
659
 
660
        /* Set wishbone base address for frame buffer */
661
        writel(video_base & 0x80000000, pspartan_dev.base_map[0] + SPARTAN_W_BA1_ADDR);
662
 
663
        /* Set address mask for frame buffer */
664
        writel(0x80000000, pspartan_dev.base_map[0] + SPARTAN_W_AM1_ADDR);
665
 
666
        /* Enable address traslation for CRT registers */
667 36 tadej
        writel(0x01, pspartan_dev.base_map[0] + SPARTAN_W_IMG_CTRL1_ADDR);
668 21 mihad
 
669
        /* Set base address of frame buffer in CRT */
670
        writel(video_base, pspartan_dev.base_map[1] + SPARTAN_CRT_ADDR);
671
#endif
672
        ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
673
 
674
        vesafb_defined.xres=video_width;
675
        vesafb_defined.yres=video_height;
676
        vesafb_defined.xres_virtual=video_width;
677
        vesafb_defined.yres_virtual=video_width;
678
        vesafb_defined.bits_per_pixel=video_bpp;
679
 
680
        if (ypan && vesafb_defined.yres_virtual > video_height) {
681
                printk(KERN_INFO "vesafb: scrolling: %s using protected mode interface, yres_virtual=%d\n",
682
                       (ypan > 1) ? "ywrap" : "ypan",vesafb_defined.yres_virtual);
683
        } else {
684
                printk(KERN_INFO "vesafb: scrolling: redraw\n");
685
                vesafb_defined.yres_virtual = video_height;
686
                ypan = 0;
687
        }
688
        video_height_virtual = vesafb_defined.yres_virtual;
689
 
690
        /* some dummy values for timing to make fbset happy */
691
        vesafb_defined.pixclock     = 10000000 / video_width * 1000 / video_height;
692
        vesafb_defined.left_margin  = (video_width / 8) & 0xf8;
693
        vesafb_defined.right_margin = 32;
694
        vesafb_defined.upper_margin = 16;
695
        vesafb_defined.lower_margin = 4;
696
        vesafb_defined.hsync_len    = (video_width / 8) & 0xf8;
697
        vesafb_defined.vsync_len    = 4;
698
 
699
        vesafb_defined.red.length   = 6;
700
        vesafb_defined.green.length = 6;
701
        vesafb_defined.blue.length  = 6;
702
        for(i = 0; i < 16; i++) {
703
                j = color_table[i];
704
                palette[i].red   = default_red[j];
705
                palette[i].green = default_grn[j];
706
                palette[i].blue  = default_blu[j];
707
        }
708
        video_cmap_len = 256;
709
 
710
        strcpy(fb_info.modename, "VESA VGA 1");
711
        fb_info.changevar = NULL;
712
        fb_info.node = -1;
713
        fb_info.fbops = &vesafb_ops;
714
        fb_info.disp=&disp;
715
        fb_info.switch_con=&vesafb_switch;
716
        fb_info.updatevar=&vesafb_update_var;
717
        fb_info.blank=&vesafb_blank;
718
        fb_info.flags=FBINFO_FLAG_DEFAULT;
719
        vesafb_set_disp(-1);
720
 
721
#ifdef PCI
722
        /* Enable CRT */
723
        writel(0x01, pspartan_dev.base_map[1] + SPARTAN_CRT_CTRL);
724
#endif
725
 
726
        if (register_framebuffer(&fb_info)<0) {
727
                for (page = virt_to_page(video_vbase); page <= virt_to_page(video_vbase + video_size - 1); page++)
728
                        mem_map_unreserve(page);
729
                for (sz = 0, size = PAGE_SIZE; size < video_size; sz++, size <<= 1);
730
                free_pages(video_vbase, sz);
731
 
732
                return -EINVAL;
733
        }
734
 
735
        printk(KERN_INFO "fb%d: %s frame buffer device\n",
736
               GET_FB_IDX(fb_info.node), fb_info.modename);
737
 
738
        printk("fb%d: %s frame buffer device\n",
739
               GET_FB_IDX(fb_info.node), fb_info.modename);
740
        return 0;
741
}
742
 
743
int init_module(void)
744
{
745
        return vesafb_init();
746
}
747
 
748
void cleanup_module(void)
749
{
750
        int size, sz;
751
        struct page *page;
752
 
753
        unregister_framebuffer(&fb_info);
754
 
755
        for (page = virt_to_page(video_vbase); page <= virt_to_page(video_vbase + video_size - 1); page++)
756
                mem_map_unreserve(page);
757
 
758
        for (sz = 0, size = PAGE_SIZE; size < video_size; sz++, size <<= 1);
759
        free_pages(video_vbase, sz);
760
 
761
        iounmap((unsigned char *)pspartan_dev.bases[0]);
762
        release_mem_region(pspartan_dev.bases[0], pspartan_dev.base_size[0]);
763
 
764
        iounmap((unsigned char *)pspartan_dev.bases[1]);
765
        release_mem_region(pspartan_dev.bases[1], pspartan_dev.base_size[1]);
766
}
767
 
768
/*
769
 * Overrides for Emacs so that we follow Linus's tabbing style.
770
 * ---------------------------------------------------------------------------
771
 * Local variables:
772
 * c-basic-offset: 8
773
 * End:
774
 */

powered by: WebSVN 2.1.0

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