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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [video/] [macfb.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we
2
   don't know how to set */
3
 
4
/* (c) 1999 David Huggins-Daines <dhd@debian.org>
5
 
6
   Primarily based on vesafb.c, by Gerd Knorr
7
   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
8
 
9
   Also uses information and code from:
10
 
11
   The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen
12
   Mellinger, Mikael Forselius, Michael Schmitz, and others.
13
 
14
   valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan
15
   Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.
16
 
17
   This code is free software.  You may copy, modify, and distribute
18
   it subject to the terms and conditions of the GNU General Public
19
   License, version 2, or any later version, at your convenience. */
20
 
21
#include <linux/module.h>
22
#include <linux/kernel.h>
23
#include <linux/errno.h>
24
#include <linux/string.h>
25
#include <linux/mm.h>
26
#include <linux/slab.h>
27
#include <linux/delay.h>
28
#include <linux/nubus.h>
29
#include <linux/init.h>
30
#include <linux/fb.h>
31
 
32
#include <asm/setup.h>
33
#include <asm/bootinfo.h>
34
#include <asm/uaccess.h>
35
#include <asm/pgtable.h>
36
#include <asm/irq.h>
37
#include <asm/macintosh.h>
38
#include <asm/io.h>
39
#include <asm/machw.h>
40
 
41
/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */
42
#define DAC_BASE 0x50f24000
43
 
44
/* Some addresses for the DAFB */
45
#define DAFB_BASE 0xf9800200
46
 
47
/* Address for the built-in Civic framebuffer in Quadra AVs */
48
#define CIVIC_BASE 0x50f30800   /* Only tested on 660AV! */
49
 
50
/* GSC (Gray Scale Controller) base address */
51
#define GSC_BASE 0x50F20000
52
 
53
/* CSC (Color Screen Controller) base address */
54
#define CSC_BASE 0x50F20000
55
 
56
static int (*macfb_setpalette) (unsigned int regno, unsigned int red,
57
                                unsigned int green, unsigned int blue,
58
                                struct fb_info *info) = NULL;
59
static int valkyrie_setpalette (unsigned int regno, unsigned int red,
60
                                unsigned int green, unsigned int blue,
61
                                struct fb_info *info);
62
static int dafb_setpalette (unsigned int regno, unsigned int red,
63
                            unsigned int green, unsigned int blue,
64
                            struct fb_info *fb_info);
65
static int rbv_setpalette (unsigned int regno, unsigned int red,
66
                           unsigned int green, unsigned int blue,
67
                           struct fb_info *fb_info);
68
static int mdc_setpalette (unsigned int regno, unsigned int red,
69
                           unsigned int green, unsigned int blue,
70
                           struct fb_info *fb_info);
71
static int toby_setpalette (unsigned int regno, unsigned int red,
72
                            unsigned int green, unsigned int blue,
73
                            struct fb_info *fb_info);
74
static int civic_setpalette (unsigned int regno, unsigned int red,
75
                             unsigned int green, unsigned int blue,
76
                             struct fb_info *fb_info);
77
static int csc_setpalette (unsigned int regno, unsigned int red,
78
                           unsigned int green, unsigned int blue,
79
                           struct fb_info *fb_info);
80
 
81
static volatile struct {
82
        unsigned char addr;
83
        /* Note: word-aligned */
84
        char pad[3];
85
        unsigned char lut;
86
} *valkyrie_cmap_regs;
87
 
88
static volatile struct {
89
        unsigned char addr;
90
        unsigned char lut;
91
} *v8_brazil_cmap_regs;
92
 
93
static volatile struct {
94
        unsigned char addr;
95
        char pad1[3]; /* word aligned */
96
        unsigned char lut;
97
        char pad2[3]; /* word aligned */
98
        unsigned char cntl; /* a guess as to purpose */
99
} *rbv_cmap_regs;
100
 
101
static volatile struct {
102
        unsigned long reset;
103
        unsigned long pad1[3];
104
        unsigned char pad2[3];
105
        unsigned char lut;
106
} *dafb_cmap_regs;
107
 
108
static volatile struct {
109
        unsigned char addr;     /* OFFSET: 0x00 */
110
        unsigned char pad1[15];
111
        unsigned char lut;      /* OFFSET: 0x10 */
112
        unsigned char pad2[15];
113
        unsigned char status;   /* OFFSET: 0x20 */
114
        unsigned char pad3[7];
115
        unsigned long vbl_addr; /* OFFSET: 0x28 */
116
        unsigned int  status2;  /* OFFSET: 0x2C */
117
} *civic_cmap_regs;
118
 
119
static volatile struct {
120
        char    pad1[0x40];
121
        unsigned char   clut_waddr;     /* 0x40 */
122
        char    pad2;
123
        unsigned char   clut_data;      /* 0x42 */
124
        char    pad3[0x3];
125
        unsigned char   clut_raddr;     /* 0x46 */
126
} *csc_cmap_regs;
127
 
128
/* We will leave these the way they are for the time being */
129
struct mdc_cmap_regs {
130
        char pad1[0x200200];
131
        unsigned char addr;
132
        char pad2[6];
133
        unsigned char lut;
134
};
135
 
136
struct toby_cmap_regs {
137
        char pad1[0x90018];
138
        unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */
139
        char pad2[3];
140
        unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */
141
};
142
 
143
struct jet_cmap_regs {
144
        char pad1[0xe0e000];
145
        unsigned char addr;
146
        unsigned char lut;
147
};
148
 
149
#define PIXEL_TO_MM(a)  (((a)*10)/28)   /* width in mm at 72 dpi */     
150
 
151
/* mode */
152
static int  video_slot = 0;
153
 
154
static struct fb_var_screeninfo macfb_defined = {
155
        .bits_per_pixel = 8,
156
        .activate       = FB_ACTIVATE_NOW,
157
        .width          = -1,
158
        .height         = -1,
159
        .right_margin   = 32,
160
        .upper_margin   = 16,
161
        .lower_margin   = 4,
162
        .vsync_len      = 4,
163
        .vmode          = FB_VMODE_NONINTERLACED,
164
};
165
 
166
static struct fb_fix_screeninfo macfb_fix = {
167
        .id     = "Macintosh ",
168
        .type   = FB_TYPE_PACKED_PIXELS,
169
        .accel  = FB_ACCEL_NONE,
170
};
171
 
172
static struct fb_info fb_info;
173
static u32 pseudo_palette[16];
174
static int inverse   = 0;
175
static int vidtest   = 0;
176
 
177
static int valkyrie_setpalette (unsigned int regno, unsigned int red,
178
                                unsigned int green, unsigned int blue,
179
                                struct fb_info *info)
180
{
181
        unsigned long flags;
182
 
183
        red >>= 8;
184
        green >>= 8;
185
        blue >>= 8;
186
 
187
        local_irq_save(flags);
188
 
189
        /* tell clut which address to fill */
190
        nubus_writeb(regno, &valkyrie_cmap_regs->addr);
191
        nop();
192
 
193
        /* send one color channel at a time */
194
        nubus_writeb(red, &valkyrie_cmap_regs->lut);
195
        nop();
196
        nubus_writeb(green, &valkyrie_cmap_regs->lut);
197
        nop();
198
        nubus_writeb(blue, &valkyrie_cmap_regs->lut);
199
 
200
        local_irq_restore(flags);
201
        return 0;
202
}
203
 
204
/* Unlike the Valkyrie, the DAFB cannot set individual colormap
205
   registers.  Therefore, we do what the MacOS driver does (no
206
   kidding!) and simply set them one by one until we hit the one we
207
   want. */
208
static int dafb_setpalette (unsigned int regno, unsigned int red,
209
                            unsigned int green, unsigned int blue,
210
                            struct fb_info *info)
211
{
212
        /* FIXME: really, really need to use ioremap() here,
213
           phys_to_virt() doesn't work anymore */
214
        static int lastreg = -1;
215
        unsigned long flags;
216
 
217
        red >>= 8;
218
        green >>= 8;
219
        blue >>= 8;
220
 
221
        local_irq_save(flags);
222
 
223
        /* fbdev will set an entire colourmap, but X won't.  Hopefully
224
           this should accommodate both of them */
225
        if (regno != lastreg+1) {
226
                int i;
227
 
228
                /* Stab in the dark trying to reset the CLUT pointer */
229
                nubus_writel(0, &dafb_cmap_regs->reset);
230
                nop();
231
 
232
                /* Loop until we get to the register we want */
233
                for (i = 0; i < regno; i++) {
234
                        nubus_writeb(info->cmap.red[i] >> 8, &dafb_cmap_regs->lut);
235
                        nop();
236
                        nubus_writeb(info->cmap.green[i] >> 8, &dafb_cmap_regs->lut);
237
                        nop();
238
                        nubus_writeb(info->cmap.blue[i] >> 8, &dafb_cmap_regs->lut);
239
                        nop();
240
                }
241
        }
242
 
243
        nubus_writeb(red, &dafb_cmap_regs->lut);
244
        nop();
245
        nubus_writeb(green, &dafb_cmap_regs->lut);
246
        nop();
247
        nubus_writeb(blue, &dafb_cmap_regs->lut);
248
 
249
        local_irq_restore(flags);
250
        lastreg = regno;
251
        return 0;
252
}
253
 
254
/* V8 and Brazil seem to use the same DAC.  Sonora does as well. */
255
static int v8_brazil_setpalette (unsigned int regno, unsigned int red,
256
                                 unsigned int green, unsigned int blue,
257
                                 struct fb_info *info)
258
{
259
        unsigned int bpp = info->var.bits_per_pixel;
260
        unsigned char _red  =red>>8;
261
        unsigned char _green=green>>8;
262
        unsigned char _blue =blue>>8;
263
        unsigned char _regno;
264
        unsigned long flags;
265
 
266
        if (bpp > 8) return 1; /* failsafe */
267
 
268
        local_irq_save(flags);
269
 
270
        /* On these chips, the CLUT register numbers are spread out
271
           across the register space.  Thus:
272
 
273
           In 8bpp, all regnos are valid.
274
 
275
           In 4bpp, the regnos are 0x0f, 0x1f, 0x2f, etc, etc
276
 
277
           In 2bpp, the regnos are 0x3f, 0x7f, 0xbf, 0xff */
278
        _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
279
        nubus_writeb(_regno, &v8_brazil_cmap_regs->addr); nop();
280
 
281
        /* send one color channel at a time */
282
        nubus_writeb(_red, &v8_brazil_cmap_regs->lut); nop();
283
        nubus_writeb(_green, &v8_brazil_cmap_regs->lut); nop();
284
        nubus_writeb(_blue, &v8_brazil_cmap_regs->lut);
285
 
286
        local_irq_restore(flags);
287
        return 0;
288
}
289
 
290
static int rbv_setpalette (unsigned int regno, unsigned int red,
291
                           unsigned int green, unsigned int blue,
292
                           struct fb_info *info)
293
{
294
        /* use MSBs */
295
        unsigned char _red  =red>>8;
296
        unsigned char _green=green>>8;
297
        unsigned char _blue =blue>>8;
298
        unsigned char _regno;
299
        unsigned long flags;
300
 
301
        if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
302
 
303
        local_irq_save(flags);
304
 
305
        /* From the VideoToolbox driver.  Seems to be saying that
306
         * regno #254 and #255 are the important ones for 1-bit color,
307
         * regno #252-255 are the important ones for 2-bit color, etc.
308
         */
309
        _regno = regno + (256-(1 << info->var.bits_per_pixel));
310
 
311
        /* reset clut? (VideoToolbox sez "not necessary") */
312
        nubus_writeb(0xFF, &rbv_cmap_regs->cntl); nop();
313
 
314
        /* tell clut which address to use. */
315
        nubus_writeb(_regno, &rbv_cmap_regs->addr); nop();
316
 
317
        /* send one color channel at a time. */
318
        nubus_writeb(_red,   &rbv_cmap_regs->lut); nop();
319
        nubus_writeb(_green, &rbv_cmap_regs->lut); nop();
320
        nubus_writeb(_blue,  &rbv_cmap_regs->lut);
321
 
322
        local_irq_restore(flags); /* done. */
323
        return 0;
324
}
325
 
326
/* Macintosh Display Card (8x24) */
327
static int mdc_setpalette(unsigned int regno, unsigned int red,
328
                          unsigned int green, unsigned int blue,
329
                          struct fb_info *info)
330
{
331
        volatile struct mdc_cmap_regs *cmap_regs =
332
                nubus_slot_addr(video_slot);
333
        /* use MSBs */
334
        unsigned char _red  =red>>8;
335
        unsigned char _green=green>>8;
336
        unsigned char _blue =blue>>8;
337
        unsigned char _regno=regno;
338
        unsigned long flags;
339
 
340
        local_irq_save(flags);
341
 
342
        /* the nop's are there to order writes. */
343
        nubus_writeb(_regno, &cmap_regs->addr); nop();
344
        nubus_writeb(_red, &cmap_regs->lut);    nop();
345
        nubus_writeb(_green, &cmap_regs->lut);  nop();
346
        nubus_writeb(_blue, &cmap_regs->lut);
347
 
348
        local_irq_restore(flags);
349
        return 0;
350
}
351
 
352
/* Toby frame buffer */
353
static int toby_setpalette(unsigned int regno, unsigned int red,
354
                           unsigned int green, unsigned int blue,
355
                           struct fb_info *info)
356
{
357
        volatile struct toby_cmap_regs *cmap_regs =
358
                nubus_slot_addr(video_slot);
359
        unsigned int bpp = info->var.bits_per_pixel;
360
        /* use MSBs */
361
        unsigned char _red  =~(red>>8);
362
        unsigned char _green=~(green>>8);
363
        unsigned char _blue =~(blue>>8);
364
        unsigned char _regno = (regno << (8 - bpp)) | (0xFF >> bpp);
365
        unsigned long flags;
366
 
367
        local_irq_save(flags);
368
 
369
        nubus_writeb(_regno, &cmap_regs->addr); nop();
370
        nubus_writeb(_red, &cmap_regs->lut);    nop();
371
        nubus_writeb(_green, &cmap_regs->lut);  nop();
372
        nubus_writeb(_blue, &cmap_regs->lut);
373
 
374
        local_irq_restore(flags);
375
        return 0;
376
}
377
 
378
/* Jet frame buffer */
379
static int jet_setpalette(unsigned int regno, unsigned int red,
380
                          unsigned int green, unsigned int blue,
381
                          struct fb_info *info)
382
{
383
        volatile struct jet_cmap_regs *cmap_regs =
384
                nubus_slot_addr(video_slot);
385
        /* use MSBs */
386
        unsigned char _red   = (red>>8);
387
        unsigned char _green = (green>>8);
388
        unsigned char _blue  = (blue>>8);
389
        unsigned long flags;
390
 
391
        local_irq_save(flags);
392
 
393
        nubus_writeb(regno, &cmap_regs->addr); nop();
394
        nubus_writeb(_red, &cmap_regs->lut); nop();
395
        nubus_writeb(_green, &cmap_regs->lut); nop();
396
        nubus_writeb(_blue, &cmap_regs->lut);
397
 
398
        local_irq_restore(flags);
399
        return 0;
400
}
401
 
402
/*
403
 * Civic framebuffer -- Quadra AV built-in video.  A chip
404
 * called Sebastian holds the actual color palettes, and
405
 * apparently, there are two different banks of 512K RAM
406
 * which can act as separate framebuffers for doing video
407
 * input and viewing the screen at the same time!  The 840AV
408
 * Can add another 1MB RAM to give the two framebuffers
409
 * 1MB RAM apiece.
410
 *
411
 * FIXME: this doesn't seem to work anymore.
412
 */
413
static int civic_setpalette (unsigned int regno, unsigned int red,
414
                             unsigned int green, unsigned int blue,
415
                             struct fb_info *info)
416
{
417
        static int lastreg = -1;
418
        unsigned long flags;
419
        int clut_status;
420
 
421
        if (info->var.bits_per_pixel > 8) return 1; /* failsafe */
422
 
423
        red   >>= 8;
424
        green >>= 8;
425
        blue  >>= 8;
426
 
427
        local_irq_save(flags);
428
 
429
        /*
430
         * Set the register address
431
         */
432
        nubus_writeb(regno, &civic_cmap_regs->addr); nop();
433
 
434
        /*
435
         * Wait for VBL interrupt here;
436
         * They're usually not enabled from Penguin, so we won't check
437
         */
438
#if 0
439
        {
440
#define CIVIC_VBL_OFFSET        0x120
441
                volatile unsigned long *vbl = nubus_readl(civic_cmap_regs->vbl_addr + CIVIC_VBL_OFFSET);
442
                /* do interrupt setup stuff here? */
443
                *vbl = 0L; nop();       /* clear */
444
                *vbl = 1L; nop();       /* set */
445
                while (*vbl != 0L)      /* wait for next vbl */
446
                {
447
                        usleep(10);     /* needed? */
448
                }
449
                /* do interrupt shutdown stuff here? */
450
        }
451
#endif
452
 
453
        /*
454
         * Grab a status word and do some checking;
455
         * Then finally write the clut!
456
         */
457
        clut_status =  nubus_readb(&civic_cmap_regs->status2);
458
 
459
        if ((clut_status & 0x0008) == 0)
460
        {
461
#if 0
462
                if ((clut_status & 0x000D) != 0)
463
                {
464
                        nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
465
                        nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
466
                }
467
#endif
468
 
469
                nubus_writeb(  red, &civic_cmap_regs->lut); nop();
470
                nubus_writeb(green, &civic_cmap_regs->lut); nop();
471
                nubus_writeb( blue, &civic_cmap_regs->lut); nop();
472
                nubus_writeb( 0x00, &civic_cmap_regs->lut); nop();
473
        }
474
        else
475
        {
476
                unsigned char junk;
477
 
478
                junk = nubus_readb(&civic_cmap_regs->lut); nop();
479
                junk = nubus_readb(&civic_cmap_regs->lut); nop();
480
                junk = nubus_readb(&civic_cmap_regs->lut); nop();
481
                junk = nubus_readb(&civic_cmap_regs->lut); nop();
482
 
483
                if ((clut_status & 0x000D) != 0)
484
                {
485
                        nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
486
                        nubus_writeb(0x00, &civic_cmap_regs->lut); nop();
487
                }
488
 
489
                nubus_writeb(  red, &civic_cmap_regs->lut); nop();
490
                nubus_writeb(green, &civic_cmap_regs->lut); nop();
491
                nubus_writeb( blue, &civic_cmap_regs->lut); nop();
492
                nubus_writeb( junk, &civic_cmap_regs->lut); nop();
493
        }
494
 
495
        local_irq_restore(flags);
496
        lastreg = regno;
497
        return 0;
498
}
499
 
500
/*
501
 * The CSC is the framebuffer on the PowerBook 190 series
502
 * (and the 5300 too, but that's a PowerMac). This function
503
 * brought to you in part by the ECSC driver for MkLinux.
504
 */
505
 
506
static int csc_setpalette (unsigned int regno, unsigned int red,
507
                           unsigned int green, unsigned int blue,
508
                           struct fb_info *info)
509
{
510
        mdelay(1);
511
        csc_cmap_regs->clut_waddr = regno;
512
        csc_cmap_regs->clut_data = red;
513
        csc_cmap_regs->clut_data = green;
514
        csc_cmap_regs->clut_data = blue;
515
        return 0;
516
}
517
 
518
static int macfb_setcolreg(unsigned regno, unsigned red, unsigned green,
519
                           unsigned blue, unsigned transp,
520
                           struct fb_info *fb_info)
521
{
522
        /*
523
         *  Set a single color register. The values supplied are
524
         *  already rounded down to the hardware's capabilities
525
         *  (according to the entries in the `var' structure). Return
526
         *  != 0 for invalid regno.
527
         */
528
 
529
        if (regno >= fb_info->cmap.len)
530
                return 1;
531
 
532
        if (fb_info->var.bits_per_pixel <= 8) {
533
                switch (fb_info->var.bits_per_pixel) {
534
                case 1:
535
                        /* We shouldn't get here */
536
                        break;
537
                case 2:
538
                case 4:
539
                case 8:
540
                        if (macfb_setpalette)
541
                                macfb_setpalette(regno, red, green, blue,
542
                                                 fb_info);
543
                        else
544
                                return 1;
545
                        break;
546
                }
547
        } else if (regno < 16) {
548
                switch (fb_info->var.bits_per_pixel) {
549
                case 16:
550
                        if (fb_info->var.red.offset == 10) {
551
                                /* 1:5:5:5 */
552
                                ((u32*) (fb_info->pseudo_palette))[regno] =
553
                                        ((red   & 0xf800) >>  1) |
554
                                        ((green & 0xf800) >>  6) |
555
                                        ((blue  & 0xf800) >> 11) |
556
                                        ((transp != 0) << 15);
557
                        } else {
558
                                /* 0:5:6:5 */
559
                                ((u32*) (fb_info->pseudo_palette))[regno] =
560
                                        ((red   & 0xf800)      ) |
561
                                        ((green & 0xfc00) >>  5) |
562
                                        ((blue  & 0xf800) >> 11);
563
                        }
564
                        break;
565
                        /* I'm pretty sure that one or the other of these
566
                           doesn't exist on 68k Macs */
567
                case 24:
568
                        red   >>= 8;
569
                        green >>= 8;
570
                        blue  >>= 8;
571
                        ((u32 *)(fb_info->pseudo_palette))[regno] =
572
                                (red   << fb_info->var.red.offset)   |
573
                                (green << fb_info->var.green.offset) |
574
                                (blue  << fb_info->var.blue.offset);
575
                        break;
576
                case 32:
577
                        red   >>= 8;
578
                        green >>= 8;
579
                        blue  >>= 8;
580
                        ((u32 *)(fb_info->pseudo_palette))[regno] =
581
                                (red   << fb_info->var.red.offset)   |
582
                                (green << fb_info->var.green.offset) |
583
                                (blue  << fb_info->var.blue.offset);
584
                        break;
585
                }
586
        }
587
 
588
        return 0;
589
}
590
 
591
static struct fb_ops macfb_ops = {
592
        .owner          = THIS_MODULE,
593
        .fb_setcolreg   = macfb_setcolreg,
594
        .fb_fillrect    = cfb_fillrect,
595
        .fb_copyarea    = cfb_copyarea,
596
        .fb_imageblit   = cfb_imageblit,
597
};
598
 
599
void __init macfb_setup(char *options)
600
{
601
        char *this_opt;
602
 
603
        if (!options || !*options)
604
                return;
605
 
606
        while ((this_opt = strsep(&options, ",")) != NULL) {
607
                if (!*this_opt) continue;
608
 
609
                if (! strcmp(this_opt, "inverse"))
610
                        inverse=1;
611
                /* This means "turn on experimental CLUT code" */
612
                else if (!strcmp(this_opt, "vidtest"))
613
                        vidtest=1;
614
        }
615
}
616
 
617
static void __init iounmap_macfb(void)
618
{
619
        if (valkyrie_cmap_regs)
620
                iounmap(valkyrie_cmap_regs);
621
        if (dafb_cmap_regs)
622
                iounmap(dafb_cmap_regs);
623
        if (v8_brazil_cmap_regs)
624
                iounmap(v8_brazil_cmap_regs);
625
        if (rbv_cmap_regs)
626
                iounmap(rbv_cmap_regs);
627
        if (civic_cmap_regs)
628
                iounmap(civic_cmap_regs);
629
        if (csc_cmap_regs)
630
                iounmap(csc_cmap_regs);
631
}
632
 
633
static int __init macfb_init(void)
634
{
635
        int video_cmap_len, video_is_nubus = 0;
636
        struct nubus_dev* ndev = NULL;
637
        char *option = NULL;
638
        int err;
639
 
640
        if (fb_get_options("macfb", &option))
641
                return -ENODEV;
642
        macfb_setup(option);
643
 
644
        if (!MACH_IS_MAC)
645
                return -ENODEV;
646
 
647
        /* There can only be one internal video controller anyway so
648
           we're not too worried about this */
649
        macfb_defined.xres = mac_bi_data.dimensions & 0xFFFF;
650
        macfb_defined.yres = mac_bi_data.dimensions >> 16;
651
        macfb_defined.bits_per_pixel = mac_bi_data.videodepth;
652
        macfb_fix.line_length = mac_bi_data.videorow;
653
        macfb_fix.smem_len = macfb_fix.line_length * macfb_defined.yres;
654
        /* Note: physical address (since 2.1.127) */
655
        macfb_fix.smem_start = mac_bi_data.videoaddr;
656
        /* This is actually redundant with the initial mappings.
657
           However, there are some non-obvious aspects to the way
658
           those mappings are set up, so this is in fact the safest
659
           way to ensure that this driver will work on every possible
660
           Mac */
661
        fb_info.screen_base = ioremap(mac_bi_data.videoaddr, macfb_fix.smem_len);
662
 
663
        printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
664
               macfb_fix.smem_start, fb_info.screen_base, macfb_fix.smem_len/1024);
665
        printk("macfb: mode is %dx%dx%d, linelength=%d\n",
666
               macfb_defined.xres, macfb_defined.yres, macfb_defined.bits_per_pixel, macfb_fix.line_length);
667
 
668
        /*
669
         *      Fill in the available video resolution
670
         */
671
 
672
        macfb_defined.xres_virtual   = macfb_defined.xres;
673
        macfb_defined.yres_virtual   = macfb_defined.yres;
674
        macfb_defined.height = PIXEL_TO_MM(macfb_defined.yres);
675
        macfb_defined.width  = PIXEL_TO_MM(macfb_defined.xres);
676
 
677
        printk("macfb: scrolling: redraw\n");
678
        macfb_defined.yres_virtual = macfb_defined.yres;
679
 
680
        /* some dummy values for timing to make fbset happy */
681
        macfb_defined.pixclock     = 10000000 / macfb_defined.xres * 1000 / macfb_defined.yres;
682
        macfb_defined.left_margin  = (macfb_defined.xres / 8) & 0xf8;
683
        macfb_defined.hsync_len    = (macfb_defined.xres / 8) & 0xf8;
684
 
685
        switch (macfb_defined.bits_per_pixel) {
686
        case 1:
687
                /* XXX: I think this will catch any program that tries
688
                   to do FBIO_PUTCMAP when the visual is monochrome */
689
                macfb_defined.red.length = macfb_defined.bits_per_pixel;
690
                macfb_defined.green.length = macfb_defined.bits_per_pixel;
691
                macfb_defined.blue.length = macfb_defined.bits_per_pixel;
692
                video_cmap_len = 0;
693
                macfb_fix.visual = FB_VISUAL_MONO01;
694
                break;
695
        case 2:
696
        case 4:
697
        case 8:
698
                macfb_defined.red.length = macfb_defined.bits_per_pixel;
699
                macfb_defined.green.length = macfb_defined.bits_per_pixel;
700
                macfb_defined.blue.length = macfb_defined.bits_per_pixel;
701
                video_cmap_len = 1 << macfb_defined.bits_per_pixel;
702
                macfb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
703
                break;
704
        case 16:
705
                macfb_defined.transp.offset = 15;
706
                macfb_defined.transp.length = 1;
707
                macfb_defined.red.offset = 10;
708
                macfb_defined.red.length = 5;
709
                macfb_defined.green.offset = 5;
710
                macfb_defined.green.length = 5;
711
                macfb_defined.blue.offset = 0;
712
                macfb_defined.blue.length = 5;
713
                printk("macfb: directcolor: "
714
                       "size=1:5:5:5, shift=15:10:5:0\n");
715
                video_cmap_len = 16;
716
                /* Should actually be FB_VISUAL_DIRECTCOLOR, but this
717
                   works too */
718
                macfb_fix.visual = FB_VISUAL_TRUECOLOR;
719
                break;
720
        case 24:
721
        case 32:
722
                /* XXX: have to test these... can any 68k Macs
723
                   actually do this on internal video? */
724
                macfb_defined.red.offset = 16;
725
                macfb_defined.red.length = 8;
726
                macfb_defined.green.offset = 8;
727
                macfb_defined.green.length = 8;
728
                macfb_defined.blue.offset = 0;
729
                macfb_defined.blue.length = 8;
730
                printk("macfb: truecolor: "
731
                       "size=0:8:8:8, shift=0:16:8:0\n");
732
                video_cmap_len = 16;
733
                macfb_fix.visual = FB_VISUAL_TRUECOLOR;
734
        default:
735
                video_cmap_len = 0;
736
                macfb_fix.visual = FB_VISUAL_MONO01;
737
                printk("macfb: unknown or unsupported bit depth: %d\n", macfb_defined.bits_per_pixel);
738
                break;
739
        }
740
 
741
        /* Hardware dependent stuff */
742
        /*  We take a wild guess that if the video physical address is
743
         *  in nubus slot space, that the nubus card is driving video.
744
         *  Penguin really ought to tell us whether we are using internal
745
         *  video or not.
746
         */
747
        /* Hopefully we only find one of them.  Otherwise our NuBus
748
           code is really broken :-) */
749
 
750
        while ((ndev = nubus_find_type(NUBUS_CAT_DISPLAY, NUBUS_TYPE_VIDEO, ndev))
751
                != NULL)
752
        {
753
                if (!(mac_bi_data.videoaddr >= ndev->board->slot_addr
754
                      && (mac_bi_data.videoaddr <
755
                          (unsigned long)nubus_slot_addr(ndev->board->slot+1))))
756
                        continue;
757
                video_is_nubus = 1;
758
                /* We should probably just use the slot address... */
759
                video_slot = ndev->board->slot;
760
 
761
                switch(ndev->dr_hw) {
762
                case NUBUS_DRHW_APPLE_MDC:
763
                        strcat( macfb_fix.id, "Display Card" );
764
                        macfb_setpalette = mdc_setpalette;
765
                        macfb_defined.activate = FB_ACTIVATE_NOW;
766
                        break;
767
                case NUBUS_DRHW_APPLE_TFB:
768
                        strcat( macfb_fix.id, "Toby" );
769
                        macfb_setpalette = toby_setpalette;
770
                        macfb_defined.activate = FB_ACTIVATE_NOW;
771
                        break;
772
                case NUBUS_DRHW_APPLE_JET:
773
                        strcat( macfb_fix.id, "Jet");
774
                        macfb_setpalette = jet_setpalette;
775
                        macfb_defined.activate = FB_ACTIVATE_NOW;
776
                        break;
777
                default:
778
                        strcat( macfb_fix.id, "Generic NuBus" );
779
                        break;
780
                }
781
        }
782
 
783
        /* If it's not a NuBus card, it must be internal video */
784
        /* FIXME: this function is getting way too big.  (this driver
785
           is too...) */
786
        if (!video_is_nubus)
787
                switch( mac_bi_data.id )
788
                {
789
                        /* These don't have onboard video.  Eventually, we may
790
                           be able to write separate framebuffer drivers for
791
                           them (tobyfb.c, hiresfb.c, etc, etc) */
792
                case MAC_MODEL_II:
793
                case MAC_MODEL_IIX:
794
                case MAC_MODEL_IICX:
795
                case MAC_MODEL_IIFX:
796
                        strcat( macfb_fix.id, "Generic NuBus" );
797
                        break;
798
 
799
                        /* Valkyrie Quadras */
800
                case MAC_MODEL_Q630:
801
                        /* I'm not sure about this one */
802
                case MAC_MODEL_P588:
803
                        strcat( macfb_fix.id, "Valkyrie built-in" );
804
                        macfb_setpalette = valkyrie_setpalette;
805
                        macfb_defined.activate = FB_ACTIVATE_NOW;
806
                        valkyrie_cmap_regs = ioremap(DAC_BASE, 0x1000);
807
                        break;
808
 
809
                        /* DAFB Quadras */
810
                        /* Note: these first four have the v7 DAFB, which is
811
                           known to be rather unlike the ones used in the
812
                           other models */
813
                case MAC_MODEL_P475:
814
                case MAC_MODEL_P475F:
815
                case MAC_MODEL_P575:
816
                case MAC_MODEL_Q605:
817
 
818
                case MAC_MODEL_Q800:
819
                case MAC_MODEL_Q650:
820
                case MAC_MODEL_Q610:
821
                case MAC_MODEL_C650:
822
                case MAC_MODEL_C610:
823
                case MAC_MODEL_Q700:
824
                case MAC_MODEL_Q900:
825
                case MAC_MODEL_Q950:
826
                        strcat( macfb_fix.id, "DAFB built-in" );
827
                        macfb_setpalette = dafb_setpalette;
828
                        macfb_defined.activate = FB_ACTIVATE_NOW;
829
                        dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
830
                        break;
831
 
832
                        /* LC II uses the V8 framebuffer */
833
                case MAC_MODEL_LCII:
834
                        strcat( macfb_fix.id, "V8 built-in" );
835
                        macfb_setpalette = v8_brazil_setpalette;
836
                        macfb_defined.activate = FB_ACTIVATE_NOW;
837
                        v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
838
                        break;
839
 
840
                        /* IIvi, IIvx use the "Brazil" framebuffer (which is
841
                           very much like the V8, it seems, and probably uses
842
                           the same DAC) */
843
                case MAC_MODEL_IIVI:
844
                case MAC_MODEL_IIVX:
845
                case MAC_MODEL_P600:
846
                        strcat( macfb_fix.id, "Brazil built-in" );
847
                        macfb_setpalette = v8_brazil_setpalette;
848
                        macfb_defined.activate = FB_ACTIVATE_NOW;
849
                        v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
850
                        break;
851
 
852
                        /* LC III (and friends) use the Sonora framebuffer */
853
                        /* Incidentally this is also used in the non-AV models
854
                           of the x100 PowerMacs */
855
                        /* These do in fact seem to use the same DAC interface
856
                           as the LC II. */
857
                case MAC_MODEL_LCIII:
858
                case MAC_MODEL_P520:
859
                case MAC_MODEL_P550:
860
                case MAC_MODEL_P460:
861
                        macfb_setpalette = v8_brazil_setpalette;
862
                        macfb_defined.activate = FB_ACTIVATE_NOW;
863
                        strcat( macfb_fix.id, "Sonora built-in" );
864
                        v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
865
                        break;
866
 
867
                        /* IIci and IIsi use the infamous RBV chip
868
                           (the IIsi is just a rebadged and crippled
869
                           IIci in a different case, BTW) */
870
                case MAC_MODEL_IICI:
871
                case MAC_MODEL_IISI:
872
                        macfb_setpalette = rbv_setpalette;
873
                        macfb_defined.activate = FB_ACTIVATE_NOW;
874
                        strcat( macfb_fix.id, "RBV built-in" );
875
                        rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
876
                        break;
877
 
878
                        /* AVs use the Civic framebuffer */
879
                case MAC_MODEL_Q840:
880
                case MAC_MODEL_C660:
881
                        macfb_setpalette = civic_setpalette;
882
                        macfb_defined.activate = FB_ACTIVATE_NOW;
883
                        strcat( macfb_fix.id, "Civic built-in" );
884
                        civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
885
                        break;
886
 
887
 
888
                        /* Write a setpalette function for your machine, then
889
                           you can add something similar here.  These are
890
                           grouped by classes of video chipsets.  Some of this
891
                           information is from the VideoToolbox "Bugs" web
892
                           page at
893
                           http://rajsky.psych.nyu.edu/Tips/VideoBugs.html */
894
 
895
                        /* Assorted weirdos */
896
                        /* We think this may be like the LC II */
897
                case MAC_MODEL_LC:
898
                        if (vidtest) {
899
                                macfb_setpalette = v8_brazil_setpalette;
900
                                macfb_defined.activate = FB_ACTIVATE_NOW;
901
                                v8_brazil_cmap_regs =
902
                                        ioremap(DAC_BASE, 0x1000);
903
                        }
904
                        strcat( macfb_fix.id, "LC built-in" );
905
                        break;
906
                        /* We think this may be like the LC II */
907
                case MAC_MODEL_CCL:
908
                        if (vidtest) {
909
                                macfb_setpalette = v8_brazil_setpalette;
910
                                macfb_defined.activate = FB_ACTIVATE_NOW;
911
                                v8_brazil_cmap_regs =
912
                                        ioremap(DAC_BASE, 0x1000);
913
                        }
914
                        strcat( macfb_fix.id, "Color Classic built-in" );
915
                        break;
916
 
917
                        /* And we *do* mean "weirdos" */
918
                case MAC_MODEL_TV:
919
                        strcat( macfb_fix.id, "Mac TV built-in" );
920
                        break;
921
 
922
                        /* These don't have colour, so no need to worry */
923
                case MAC_MODEL_SE30:
924
                case MAC_MODEL_CLII:
925
                        strcat( macfb_fix.id, "Monochrome built-in" );
926
                        break;
927
 
928
                        /* Powerbooks are particularly difficult.  Many of
929
                           them have separate framebuffers for external and
930
                           internal video, which is admittedly pretty cool,
931
                           but will be a bit of a headache to support here.
932
                           Also, many of them are grayscale, and we don't
933
                           really support that. */
934
 
935
                case MAC_MODEL_PB140:
936
                case MAC_MODEL_PB145:
937
                case MAC_MODEL_PB170:
938
                        strcat( macfb_fix.id, "DDC built-in" );
939
                        break;
940
 
941
                        /* Internal is GSC, External (if present) is ViSC */
942
                case MAC_MODEL_PB150:   /* no external video */
943
                case MAC_MODEL_PB160:
944
                case MAC_MODEL_PB165:
945
                case MAC_MODEL_PB180:
946
                case MAC_MODEL_PB210:
947
                case MAC_MODEL_PB230:
948
                        strcat( macfb_fix.id, "GSC built-in" );
949
                        break;
950
 
951
                        /* Internal is TIM, External is ViSC */
952
                case MAC_MODEL_PB165C:
953
                case MAC_MODEL_PB180C:
954
                        strcat( macfb_fix.id, "TIM built-in" );
955
                        break;
956
 
957
                        /* Internal is CSC, External is Keystone+Ariel. */
958
                case MAC_MODEL_PB190:   /* external video is optional */
959
                case MAC_MODEL_PB520:
960
                case MAC_MODEL_PB250:
961
                case MAC_MODEL_PB270C:
962
                case MAC_MODEL_PB280:
963
                case MAC_MODEL_PB280C:
964
                        macfb_setpalette = csc_setpalette;
965
                        macfb_defined.activate = FB_ACTIVATE_NOW;
966
                        strcat( macfb_fix.id, "CSC built-in" );
967
                        csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
968
                        break;
969
 
970
                default:
971
                        strcat( macfb_fix.id, "Unknown/Unsupported built-in" );
972
                        break;
973
                }
974
 
975
        fb_info.fbops           = &macfb_ops;
976
        fb_info.var             = macfb_defined;
977
        fb_info.fix             = macfb_fix;
978
        fb_info.pseudo_palette  = pseudo_palette;
979
        fb_info.flags           = FBINFO_DEFAULT;
980
 
981
        fb_alloc_cmap(&fb_info.cmap, video_cmap_len, 0);
982
 
983
        err = register_framebuffer(&fb_info);
984
        if (!err)
985
                printk("fb%d: %s frame buffer device\n",
986
                       fb_info.node, fb_info.fix.id);
987
        else {
988
                iounmap(fb_info.screen_base);
989
                iounmap_macfb();
990
        }
991
        return err;
992
}
993
 
994
module_init(macfb_init);
995
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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