2 * drivers/video/imsttfb.c -- frame buffer device for IMS TwinTurbo
4 * This file is derived from the powermac console "imstt" driver:
5 * Copyright (C) 1997 Sigurdur Asgeirsson
6 * With additional hacking by Jeffrey Kuskin (jsk@mojave.stanford.edu)
7 * Modified by Danilo Beuche 1998
8 * Some register values added by Damien Doligez, INRIA Rocquencourt
10 * This file was written by Ryan Nielsen (ran@krazynet.com)
11 * Most of the frame buffer device stuff was copied from atyfb.c
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file COPYING in the main directory of this archive for
18 #include <linux/config.h>
19 #include <linux/module.h>
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/string.h>
24 #include <linux/tty.h>
25 #include <linux/malloc.h>
26 #include <linux/vmalloc.h>
27 #include <linux/delay.h>
28 #include <linux/interrupt.h>
30 #include <linux/console.h>
31 #include <linux/selection.h>
32 #include <linux/init.h>
33 #include <linux/pci.h>
35 #include <asm/uaccess.h>
37 #if defined(CONFIG_PPC)
38 #include <linux/nvram.h>
40 #include <asm/pci-bridge.h>
41 #include <video/macmodes.h>
44 #include <video/fbcon.h>
45 #include <video/fbcon-cfb8.h>
46 #include <video/fbcon-cfb16.h>
47 #include <video/fbcon-cfb24.h>
48 #include <video/fbcon-cfb32.h>
51 #define eieio() /* Enforce In-order Execution of I/O */
54 /* TwinTurbo (Cosmo) registers */
61 DP_OCTL
= 5, /* 0x14 */
65 BLTCTL
= 10, /* 0x28 */
67 /* Scan Timing Generator Registers */
80 STGCTL
= 24, /* 0x60 */
82 /* Screen Refresh Generator Registers */
87 SRGCTL
= 29, /* 0x74 */
89 /* RAM Refresh Generator Registers */
90 RRCIV
= 30, /* 0x78 */
94 /* System Registers */
98 SSTATUS
= 36, /* 0x90 */
112 /* IBM 624 RAMDAC Direct Registers */
124 /* IBM 624 RAMDAC Indirect Registers */
126 CLKCTL
= 0x02, /* (0x01) Miscellaneous Clock Control */
127 SYNCCTL
= 0x03, /* (0x00) Sync Control */
128 HSYNCPOS
= 0x04, /* (0x00) Horizontal Sync Position */
129 PWRMNGMT
= 0x05, /* (0x00) Power Management */
130 DACOP
= 0x06, /* (0x02) DAC Operation */
131 PALETCTL
= 0x07, /* (0x00) Palette Control */
132 SYSCLKCTL
= 0x08, /* (0x01) System Clock Control */
133 PIXFMT
= 0x0a, /* () Pixel Format [bpp >> 3 + 2] */
134 BPP8
= 0x0b, /* () 8 Bits/Pixel Control */
135 BPP16
= 0x0c, /* () 16 Bits/Pixel Control [bit 1=1 for 565] */
136 BPP24
= 0x0d, /* () 24 Bits/Pixel Control */
137 BPP32
= 0x0e, /* () 32 Bits/Pixel Control */
138 PIXCTL1
= 0x10, /* (0x05) Pixel PLL Control 1 */
139 PIXCTL2
= 0x11, /* (0x00) Pixel PLL Control 2 */
140 SYSCLKN
= 0x15, /* () System Clock N (System PLL Reference Divider) */
141 SYSCLKM
= 0x16, /* () System Clock M (System PLL VCO Divider) */
142 SYSCLKP
= 0x17, /* () System Clock P */
143 SYSCLKC
= 0x18, /* () System Clock C */
145 * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)
146 * c is charge pump bias which depends on the VCO frequency
148 PIXM0
= 0x20, /* () Pixel M 0 */
149 PIXN0
= 0x21, /* () Pixel N 0 */
150 PIXP0
= 0x22, /* () Pixel P 0 */
151 PIXC0
= 0x23, /* () Pixel C 0 */
152 CURSCTL
= 0x30, /* (0x00) Cursor Control */
153 CURSXLO
= 0x31, /* () Cursor X position, low 8 bits */
154 CURSXHI
= 0x32, /* () Cursor X position, high 8 bits */
155 CURSYLO
= 0x33, /* () Cursor Y position, low 8 bits */
156 CURSYHI
= 0x34, /* () Cursor Y position, high 8 bits */
157 CURSHOTX
= 0x35, /* () Cursor Hot Spot X */
158 CURSHOTY
= 0x36, /* () Cursor Hot Spot Y */
159 CURSACCTL
= 0x37, /* () Advanced Cursor Control Enable */
160 CURSACATTR
= 0x38, /* () Advanced Cursor Attribute */
161 CURS1R
= 0x40, /* () Cursor 1 Red */
162 CURS1G
= 0x41, /* () Cursor 1 Green */
163 CURS1B
= 0x42, /* () Cursor 1 Blue */
164 CURS2R
= 0x43, /* () Cursor 2 Red */
165 CURS2G
= 0x44, /* () Cursor 2 Green */
166 CURS2B
= 0x45, /* () Cursor 2 Blue */
167 CURS3R
= 0x46, /* () Cursor 3 Red */
168 CURS3G
= 0x47, /* () Cursor 3 Green */
169 CURS3B
= 0x48, /* () Cursor 3 Blue */
170 BORDR
= 0x60, /* () Border Color Red */
171 BORDG
= 0x61, /* () Border Color Green */
172 BORDB
= 0x62, /* () Border Color Blue */
173 MISCTL1
= 0x70, /* (0x00) Miscellaneous Control 1 */
174 MISCTL2
= 0x71, /* (0x00) Miscellaneous Control 2 */
175 MISCTL3
= 0x72, /* (0x00) Miscellaneous Control 3 */
176 KEYCTL
= 0x78 /* (0x00) Key Control/DB Operation */
179 /* TI TVP 3030 RAMDAC Direct Registers */
181 TVPADDRW
= 0x00, /* 0 Palette/Cursor RAM Write Adress/Index */
182 TVPPDATA
= 0x04, /* 1 Palette Data RAM Data */
183 TVPPMASK
= 0x08, /* 2 Pixel Read-Mask */
184 TVPPADRR
= 0x0c, /* 3 Palette/Cursor RAM Read Adress */
185 TVPCADRW
= 0x10, /* 4 Cursor/Overscan Color Write Address */
186 TVPCDATA
= 0x14, /* 5 Cursor/Overscan Color Data */
188 TVPCADRR
= 0x1c, /* 7 Cursor/Overscan Color Read Address */
190 TVPDCCTL
= 0x24, /* 9 Direct Cursor Control */
191 TVPIDATA
= 0x28, /* 10 Index Data */
192 TVPCRDAT
= 0x2c, /* 11 Cursor RAM Data */
193 TVPCXPOL
= 0x30, /* 12 Cursor-Position X LSB */
194 TVPCXPOH
= 0x34, /* 13 Cursor-Position X MSB */
195 TVPCYPOL
= 0x38, /* 14 Cursor-Position Y LSB */
196 TVPCYPOH
= 0x3c, /* 15 Cursor-Position Y MSB */
199 /* TI TVP 3030 RAMDAC Indirect Registers */
201 TVPIRREV
= 0x01, /* Silicon Revision [RO] */
202 TVPIRICC
= 0x06, /* Indirect Cursor Control (0x00) */
203 TVPIRBRC
= 0x07, /* Byte Router Control (0xe4) */
204 TVPIRLAC
= 0x0f, /* Latch Control (0x06) */
205 TVPIRTCC
= 0x18, /* True Color Control (0x80) */
206 TVPIRMXC
= 0x19, /* Multiplex Control (0x98) */
207 TVPIRCLS
= 0x1a, /* Clock Selection (0x07) */
208 TVPIRPPG
= 0x1c, /* Palette Page (0x00) */
209 TVPIRGEC
= 0x1d, /* General Control (0x00) */
210 TVPIRMIC
= 0x1e, /* Miscellaneous Control (0x00) */
211 TVPIRPLA
= 0x2c, /* PLL Address */
212 TVPIRPPD
= 0x2d, /* Pixel Clock PLL Data */
213 TVPIRMPD
= 0x2e, /* Memory Clock PLL Data */
214 TVPIRLPD
= 0x2f, /* Loop Clock PLL Data */
215 TVPIRCKL
= 0x30, /* Color-Key Overlay Low */
216 TVPIRCKH
= 0x31, /* Color-Key Overlay High */
217 TVPIRCRL
= 0x32, /* Color-Key Red Low */
218 TVPIRCRH
= 0x33, /* Color-Key Red High */
219 TVPIRCGL
= 0x34, /* Color-Key Green Low */
220 TVPIRCGH
= 0x35, /* Color-Key Green High */
221 TVPIRCBL
= 0x36, /* Color-Key Blue Low */
222 TVPIRCBH
= 0x37, /* Color-Key Blue High */
223 TVPIRCKC
= 0x38, /* Color-Key Control (0x00) */
224 TVPIRMLC
= 0x39, /* MCLK/Loop Clock Control (0x18) */
225 TVPIRSEN
= 0x3a, /* Sense Test (0x00) */
226 TVPIRTMD
= 0x3b, /* Test Mode Data */
227 TVPIRRML
= 0x3c, /* CRC Remainder LSB [RO] */
228 TVPIRRMM
= 0x3d, /* CRC Remainder MSB [RO] */
229 TVPIRRMS
= 0x3e, /* CRC Bit Select [WO] */
230 TVPIRDID
= 0x3f, /* Device ID [RO] (0x30) */
231 TVPIRRES
= 0xff /* Software Reset [WO] */
238 static struct initvalues ibm_initregs
[] __initdata
= {
248 * Note that colors in X are correct only if all video data is
249 * passed through the palette in the DAC. That is, "indirect
250 * color" must be configured. This is the case for the IBM DAC
251 * used in the 2MB and 4MB cards, at least.
266 { CURSACATTR
, 0xa8 },
285 static struct initvalues tvp_initregs
[] __initdata
= {
318 struct imstt_regvals
{
320 __u16 hes
, heb
, hsb
, ht
, ves
, veb
, vsb
, vt
, vil
;
321 __u8 pclk_m
, pclk_n
, pclk_p
;
322 /* Values of the tvp which change depending on colormode x resolution */
323 __u8 mlc
[3]; /* Memory Loop Config 0x39 */
324 __u8 lckl_p
[3]; /* P value of LCKL PLL */
327 struct imstt_cursor
{
328 struct timer_list timer
;
333 __u16 x
, y
, width
, height
;
336 struct fb_info_imstt
{
338 struct fb_fix_screeninfo fix
;
340 struct display_switch dispsw
;
342 #ifdef FBCON_HAS_CFB16
345 #ifdef FBCON_HAS_CFB24
348 #ifdef FBCON_HAS_CFB32
353 __u8 red
, green
, blue
;
355 struct imstt_regvals init
;
356 struct imstt_cursor cursor
;
357 __u8
*frame_buffer_phys
, *frame_buffer
;
358 __u32
*dc_regs_phys
, *dc_regs
;
359 __u8
*cmap_regs_phys
, *cmap_regs
;
369 #define USE_NV_MODES 1
371 #define INIT_XRES 640
372 #define INIT_YRES 480
373 #define CURSOR_BLINK_RATE 20
374 #define CURSOR_DRAW_DELAY 2
376 static int currcon
= 0;
377 static char fontname
[40] __initdata
= { 0 };
378 static char curblink __initdata
= 1;
379 static char noaccel __initdata
= 0;
380 #if defined(CONFIG_PPC)
381 static signed char init_vmode __initdata
= -1, init_cmode __initdata
= -1;
383 static struct fb_info_imstt
*fb_info_imstt_p
[FB_MAX
] = { 0, 0, 0, 0, 0, 0, 0, 0 };
385 static struct imstt_regvals tvp_reg_init_2
= {
387 0x0002, 0x0006, 0x0026, 0x0028, 0x0003, 0x0016, 0x0196, 0x0197, 0x0196,
389 { 0x3c, 0x3b, 0x39 }, { 0xf3, 0xf3, 0xf3 }
392 static struct imstt_regvals tvp_reg_init_6
= {
394 0x0004, 0x0009, 0x0031, 0x0036, 0x0003, 0x002a, 0x020a, 0x020d, 0x020a,
396 { 0x39, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }
399 static struct imstt_regvals tvp_reg_init_12
= {
401 0x0005, 0x000e, 0x0040, 0x0042, 0x0003, 0x018, 0x270, 0x271, 0x270,
403 { 0x3a, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }
406 static struct imstt_regvals tvp_reg_init_13
= {
408 0x0004, 0x0011, 0x0045, 0x0048, 0x0003, 0x002a, 0x029a, 0x029b, 0x0000,
410 { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
413 static struct imstt_regvals tvp_reg_init_17
= {
415 0x0006, 0x0210, 0x0250, 0x0053, 0x1003, 0x0021, 0x0321, 0x0324, 0x0000,
417 { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
420 static struct imstt_regvals tvp_reg_init_18
= {
422 0x0009, 0x0011, 0x059, 0x5b, 0x0003, 0x0031, 0x0397, 0x039a, 0x0000,
424 { 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }
427 static struct imstt_regvals tvp_reg_init_19
= {
429 0x0009, 0x0016, 0x0066, 0x0069, 0x0003, 0x0027, 0x03e7, 0x03e8, 0x03e7,
431 { 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
434 static struct imstt_regvals tvp_reg_init_20
= {
436 0x0009, 0x0018, 0x0068, 0x006a, 0x0003, 0x0029, 0x0429, 0x042a, 0x0000,
438 { 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }
442 getclkMHz (struct fb_info_imstt
*p
)
444 __u32 clk_m
, clk_n
, clk_p
;
446 clk_m
= p
->init
.pclk_m
;
447 clk_n
= p
->init
.pclk_n
;
448 clk_p
= p
->init
.pclk_p
;
450 return 20 * (clk_m
+ 1) / ((clk_n
+ 1) * (clk_p
? 2 * clk_p
: 1));
454 setclkMHz (struct fb_info_imstt
*p
, __u32 MHz
)
456 __u32 clk_m
, clk_n
, clk_p
, x
, stage
, spilled
;
458 clk_m
= clk_n
= clk_p
= 0;
469 x
= 20 * (clk_m
+ 1) / ((clk_n
+ 1) * (clk_p
? 2 * clk_p
: 1));
475 } else if (spilled
&& x
< MHz
) {
480 p
->init
.pclk_m
= clk_m
;
481 p
->init
.pclk_n
= clk_n
;
482 p
->init
.pclk_p
= clk_p
;
485 static struct imstt_regvals
*
486 compute_imstt_regvals_ibm (struct fb_info_imstt
*p
, int xres
, int yres
)
488 struct imstt_regvals
*init
= &p
->init
;
489 __u32 MHz
, hes
, heb
, veb
, htp
, vtp
;
493 hes
= 0x0008; heb
= 0x0012; veb
= 0x002a; htp
= 10; vtp
= 2;
497 hes
= 0x0005; heb
= 0x0020; veb
= 0x0028; htp
= 8; vtp
= 3;
498 MHz
= 57 /* .27_ */ ;
501 hes
= 0x000a; heb
= 0x001c; veb
= 0x0020; htp
= 8; vtp
= 3;
505 hes
= 0x0012; heb
= 0x0022; veb
= 0x0031; htp
= 4; vtp
= 3;
506 MHz
= 101 /* .6_ */ ;
509 hes
= 0x0012; heb
= 0x002f; veb
= 0x0029; htp
= 4; vtp
= 1;
510 MHz
= yres
== 960 ? 126 : 135;
513 hes
= 0x0018; heb
= 0x0040; veb
= 0x002a; htp
= 4; vtp
= 3;
524 init
->hsb
= init
->heb
+ (xres
>> 3);
525 init
->ht
= init
->hsb
+ htp
;
528 init
->vsb
= init
->veb
+ yres
;
529 init
->vt
= init
->vsb
+ vtp
;
530 init
->vil
= init
->vsb
;
537 static struct imstt_regvals
*
538 compute_imstt_regvals_tvp (struct fb_info_imstt
*p
, int xres
, int yres
)
540 struct imstt_regvals
*init
;
544 init
= &tvp_reg_init_2
;
547 init
= &tvp_reg_init_6
;
550 init
= &tvp_reg_init_12
;
553 init
= &tvp_reg_init_13
;
556 init
= &tvp_reg_init_17
;
559 init
= &tvp_reg_init_18
;
562 init
= yres
== 960 ? &tvp_reg_init_19
: &tvp_reg_init_20
;
572 static struct imstt_regvals
*
573 compute_imstt_regvals (struct fb_info_imstt
*p
, u_int xres
, u_int yres
)
575 if (p
->ramdac
== IBM
)
576 return compute_imstt_regvals_ibm(p
, xres
, yres
);
578 return compute_imstt_regvals_tvp(p
, xres
, yres
);
582 set_imstt_regvals_ibm (struct fb_info_imstt
*p
, u_int bpp
)
584 struct imstt_regvals
*init
= &p
->init
;
585 __u8 pformat
= (bpp
>> 3) + 2;
587 p
->cmap_regs
[PIDXHI
] = 0; eieio();
588 p
->cmap_regs
[PIDXLO
] = PIXM0
; eieio();
589 p
->cmap_regs
[PIDXDATA
] = init
->pclk_m
; eieio();
590 p
->cmap_regs
[PIDXLO
] = PIXN0
; eieio();
591 p
->cmap_regs
[PIDXDATA
] = init
->pclk_n
; eieio();
592 p
->cmap_regs
[PIDXLO
] = PIXP0
; eieio();
593 p
->cmap_regs
[PIDXDATA
] = init
->pclk_p
; eieio();
594 p
->cmap_regs
[PIDXLO
] = PIXC0
; eieio();
595 p
->cmap_regs
[PIDXDATA
] = 0x02; eieio();
597 p
->cmap_regs
[PIDXLO
] = PIXFMT
; eieio();
598 p
->cmap_regs
[PIDXDATA
] = pformat
; eieio();
602 set_imstt_regvals_tvp (struct fb_info_imstt
*p
, u_int bpp
)
604 struct imstt_regvals
*init
= &p
->init
;
605 __u8 tcc
, mxc
, lckl_n
, mic
;
614 lckl_p
= init
->lckl_p
[0];
621 lckl_p
= init
->lckl_p
[1];
628 lckl_p
= init
->lckl_p
[2];
635 lckl_p
= init
->lckl_p
[2];
640 p
->cmap_regs
[TVPADDRW
] = TVPIRPLA
; eieio();
641 p
->cmap_regs
[TVPIDATA
] = 0x00; eieio();
642 p
->cmap_regs
[TVPADDRW
] = TVPIRPPD
; eieio();
643 p
->cmap_regs
[TVPIDATA
] = init
->pclk_m
; eieio();
644 p
->cmap_regs
[TVPADDRW
] = TVPIRPPD
; eieio();
645 p
->cmap_regs
[TVPIDATA
] = init
->pclk_n
; eieio();
646 p
->cmap_regs
[TVPADDRW
] = TVPIRPPD
; eieio();
647 p
->cmap_regs
[TVPIDATA
] = init
->pclk_p
; eieio();
649 p
->cmap_regs
[TVPADDRW
] = TVPIRTCC
; eieio();
650 p
->cmap_regs
[TVPIDATA
] = tcc
; eieio();
651 p
->cmap_regs
[TVPADDRW
] = TVPIRMXC
; eieio();
652 p
->cmap_regs
[TVPIDATA
] = mxc
; eieio();
653 p
->cmap_regs
[TVPADDRW
] = TVPIRMIC
; eieio();
654 p
->cmap_regs
[TVPIDATA
] = mic
; eieio();
656 p
->cmap_regs
[TVPADDRW
] = TVPIRPLA
; eieio();
657 p
->cmap_regs
[TVPIDATA
] = 0x00; eieio();
658 p
->cmap_regs
[TVPADDRW
] = TVPIRLPD
; eieio();
659 p
->cmap_regs
[TVPIDATA
] = lckl_n
; eieio();
661 p
->cmap_regs
[TVPADDRW
] = TVPIRPLA
; eieio();
662 p
->cmap_regs
[TVPIDATA
] = 0x15; eieio();
663 p
->cmap_regs
[TVPADDRW
] = TVPIRMLC
; eieio();
664 p
->cmap_regs
[TVPIDATA
] = mlc
; eieio();
666 p
->cmap_regs
[TVPADDRW
] = TVPIRPLA
; eieio();
667 p
->cmap_regs
[TVPIDATA
] = 0x2a; eieio();
668 p
->cmap_regs
[TVPADDRW
] = TVPIRLPD
; eieio();
669 p
->cmap_regs
[TVPIDATA
] = lckl_p
; eieio();
673 set_imstt_regvals (struct fb_info_imstt
*p
, u_int bpp
)
675 struct imstt_regvals
*init
= &p
->init
;
676 __u32 ctl
, pitch
, byteswap
, scr
;
678 if (p
->ramdac
== IBM
)
679 set_imstt_regvals_ibm(p
, bpp
);
681 set_imstt_regvals_tvp(p
, bpp
);
684 * From what I (jsk) can gather poking around with MacsBug,
685 * bits 8 and 9 in the SCR register control endianness
686 * correction (byte swapping). These bits must be set according
687 * to the color depth as follows:
688 * Color depth Bit 9 Bit 8
689 * ========== ===== =====
697 pitch
= init
->pitch
>> 2;
702 pitch
= init
->pitch
>> 1;
707 pitch
= init
->pitch
- (p
->init
.pitch
>> 2);
716 if (p
->ramdac
== TVP
)
719 out_le32(&p
->dc_regs
[HES
], init
->hes
);
720 out_le32(&p
->dc_regs
[HEB
], init
->heb
);
721 out_le32(&p
->dc_regs
[HSB
], init
->hsb
);
722 out_le32(&p
->dc_regs
[HT
], init
->ht
);
723 out_le32(&p
->dc_regs
[VES
], init
->ves
);
724 out_le32(&p
->dc_regs
[VEB
], init
->veb
);
725 out_le32(&p
->dc_regs
[VSB
], init
->vsb
);
726 out_le32(&p
->dc_regs
[VT
], init
->vt
);
727 out_le32(&p
->dc_regs
[VIL
], init
->vil
);
728 out_le32(&p
->dc_regs
[HCIV
], 1);
729 out_le32(&p
->dc_regs
[VCIV
], 1);
730 out_le32(&p
->dc_regs
[TCDR
], 4);
731 out_le32(&p
->dc_regs
[RRCIV
], 1);
732 out_le32(&p
->dc_regs
[RRSC
], 0x980);
733 out_le32(&p
->dc_regs
[RRCR
], 0x11);
735 if (p
->ramdac
== IBM
) {
736 out_le32(&p
->dc_regs
[HRIR
], 0x0100);
737 out_le32(&p
->dc_regs
[CMR
], 0x00ff);
738 out_le32(&p
->dc_regs
[SRGCTL
], 0x0073);
740 out_le32(&p
->dc_regs
[HRIR
], 0x0200);
741 out_le32(&p
->dc_regs
[CMR
], 0x01ff);
742 out_le32(&p
->dc_regs
[SRGCTL
], 0x0003);
745 switch (p
->total_vram
) {
747 scr
= 0x059d | byteswap
;
753 scr
= 0x150dd | byteswap
;
757 out_le32(&p
->dc_regs
[SCR
], scr
);
758 out_le32(&p
->dc_regs
[SPR
], pitch
);
759 out_le32(&p
->dc_regs
[STGCTL
], ctl
);
763 set_offset (struct display
*disp
, struct fb_info_imstt
*p
)
765 __u32 off
= disp
->var
.yoffset
* (disp
->line_length
>> 3)
766 + ((disp
->var
.xoffset
* (disp
->var
.bits_per_pixel
>> 3)) >> 3);
767 out_le32(&p
->dc_regs
[SSR
], off
);
771 set_555 (struct fb_info_imstt
*p
)
773 if (p
->ramdac
== IBM
) {
774 p
->cmap_regs
[PIDXHI
] = 0; eieio();
775 p
->cmap_regs
[PIDXLO
] = BPP16
; eieio();
776 p
->cmap_regs
[PIDXDATA
] = 0x01; eieio();
778 p
->cmap_regs
[TVPADDRW
] = TVPIRTCC
; eieio();
779 p
->cmap_regs
[TVPIDATA
] = 0x44; eieio();
784 set_565 (struct fb_info_imstt
*p
)
786 if (p
->ramdac
== IBM
) {
787 p
->cmap_regs
[PIDXHI
] = 0; eieio();
788 p
->cmap_regs
[PIDXLO
] = BPP16
; eieio();
789 p
->cmap_regs
[PIDXDATA
] = 0x03; eieio();
791 p
->cmap_regs
[TVPADDRW
] = TVPIRTCC
; eieio();
792 p
->cmap_regs
[TVPIDATA
] = 0x45; eieio();
797 imstt_set_cursor (struct fb_info_imstt
*p
, int on
)
799 struct imstt_cursor
*c
= &p
->cursor
;
801 if (p
->ramdac
== IBM
) {
802 p
->cmap_regs
[PIDXHI
] = 0; eieio();
804 p
->cmap_regs
[PIDXLO
] = CURSCTL
; eieio();
805 p
->cmap_regs
[PIDXDATA
] = 0x00; eieio();
807 p
->cmap_regs
[PIDXLO
] = CURSXHI
; eieio();
808 p
->cmap_regs
[PIDXDATA
] = c
->x
>> 8; eieio();
809 p
->cmap_regs
[PIDXLO
] = CURSXLO
; eieio();
810 p
->cmap_regs
[PIDXDATA
] = c
->x
& 0xff; eieio();
811 p
->cmap_regs
[PIDXLO
] = CURSYHI
; eieio();
812 p
->cmap_regs
[PIDXDATA
] = c
->y
>> 8; eieio();
813 p
->cmap_regs
[PIDXLO
] = CURSYLO
; eieio();
814 p
->cmap_regs
[PIDXDATA
] = c
->y
& 0xff; eieio();
815 p
->cmap_regs
[PIDXLO
] = CURSCTL
; eieio();
816 p
->cmap_regs
[PIDXDATA
] = 0x02; eieio();
820 p
->cmap_regs
[TVPADDRW
] = TVPIRICC
; eieio();
821 p
->cmap_regs
[TVPIDATA
] = 0x00; eieio();
823 __u16 x
= c
->x
+ 0x40, y
= c
->y
+ 0x40;
825 p
->cmap_regs
[TVPCXPOH
] = x
>> 8; eieio();
826 p
->cmap_regs
[TVPCXPOL
] = x
& 0xff; eieio();
827 p
->cmap_regs
[TVPCYPOH
] = y
>> 8; eieio();
828 p
->cmap_regs
[TVPCYPOL
] = y
& 0xff; eieio();
829 p
->cmap_regs
[TVPADDRW
] = TVPIRICC
; eieio();
830 p
->cmap_regs
[TVPIDATA
] = 0x02; eieio();
836 imsttfbcon_cursor (struct display
*disp
, int mode
, int x
, int y
)
838 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)disp
->fb_info
;
839 struct imstt_cursor
*c
= &p
->cursor
;
841 x
*= fontwidth(disp
);
842 y
*= fontheight(disp
);
844 if (c
->x
== x
&& c
->y
== y
&& (mode
== CM_ERASE
) == !c
->enable
)
849 imstt_set_cursor(p
, 0);
850 c
->x
= x
- disp
->var
.xoffset
;
851 c
->y
= y
- disp
->var
.yoffset
;
860 imstt_set_cursor(p
, c
->on
);
862 c
->vbl_cnt
= CURSOR_DRAW_DELAY
;
869 imsttfbcon_set_font (struct display
*disp
, int width
, int height
)
871 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)disp
->fb_info
;
872 struct imstt_cursor
*c
= &p
->cursor
;
876 if (width
> 32 || height
> 32)
882 fgc
= ~attr_bgcol_ec(disp
, disp
->conp
);
884 if (p
->ramdac
== IBM
) {
885 p
->cmap_regs
[PIDXHI
] = 1; eieio();
886 for (x
= 0; x
< 0x100; x
++) {
887 p
->cmap_regs
[PIDXLO
] = x
; eieio();
888 p
->cmap_regs
[PIDXDATA
] = 0x00; eieio();
890 p
->cmap_regs
[PIDXHI
] = 1; eieio();
891 for (y
= 0; y
< height
; y
++)
892 for (x
= 0; x
< width
>> 2; x
++) {
893 p
->cmap_regs
[PIDXLO
] = x
+ y
* 8; eieio();
894 p
->cmap_regs
[PIDXDATA
] = 0xff; eieio();
896 p
->cmap_regs
[PIDXHI
] = 0; eieio();
897 p
->cmap_regs
[PIDXLO
] = CURS1R
; eieio();
898 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
899 p
->cmap_regs
[PIDXLO
] = CURS1G
; eieio();
900 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
901 p
->cmap_regs
[PIDXLO
] = CURS1B
; eieio();
902 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
903 p
->cmap_regs
[PIDXLO
] = CURS2R
; eieio();
904 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
905 p
->cmap_regs
[PIDXLO
] = CURS2G
; eieio();
906 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
907 p
->cmap_regs
[PIDXLO
] = CURS2B
; eieio();
908 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
909 p
->cmap_regs
[PIDXLO
] = CURS3R
; eieio();
910 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
911 p
->cmap_regs
[PIDXLO
] = CURS3G
; eieio();
912 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
913 p
->cmap_regs
[PIDXLO
] = CURS3B
; eieio();
914 p
->cmap_regs
[PIDXDATA
] = fgc
; eieio();
916 p
->cmap_regs
[TVPADDRW
] = TVPIRICC
; eieio();
917 p
->cmap_regs
[TVPIDATA
] &= 0x03; eieio();
918 p
->cmap_regs
[TVPADDRW
] = 0; eieio();
919 for (x
= 0; x
< 0x200; x
++) {
920 p
->cmap_regs
[TVPCRDAT
] = 0x00; eieio();
922 for (x
= 0; x
< 0x200; x
++) {
923 p
->cmap_regs
[TVPCRDAT
] = 0xff; eieio();
925 p
->cmap_regs
[TVPADDRW
] = TVPIRICC
; eieio();
926 p
->cmap_regs
[TVPIDATA
] &= 0x03; eieio();
927 for (y
= 0; y
< height
; y
++)
928 for (x
= 0; x
< width
>> 3; x
++) {
929 p
->cmap_regs
[TVPADDRW
] = x
+ y
* 8; eieio();
930 p
->cmap_regs
[TVPCRDAT
] = 0xff; eieio();
932 p
->cmap_regs
[TVPADDRW
] = TVPIRICC
; eieio();
933 p
->cmap_regs
[TVPIDATA
] |= 0x08; eieio();
934 for (y
= 0; y
< height
; y
++)
935 for (x
= 0; x
< width
>> 3; x
++) {
936 p
->cmap_regs
[TVPADDRW
] = x
+ y
* 8; eieio();
937 p
->cmap_regs
[TVPCRDAT
] = 0xff; eieio();
939 p
->cmap_regs
[TVPCADRW
] = 0x00; eieio();
940 for (x
= 0; x
< 12; x
++) {
941 p
->cmap_regs
[TVPCDATA
] = fgc
; eieio();
949 imstt_cursor_timer_handler (unsigned long dev_addr
)
951 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)dev_addr
;
952 struct imstt_cursor
*c
= &p
->cursor
;
957 if (c
->vbl_cnt
&& --c
->vbl_cnt
== 0) {
959 imstt_set_cursor(p
, c
->on
);
960 c
->vbl_cnt
= c
->blink_rate
;
964 c
->timer
.expires
= jiffies
+ (HZ
/ 50);
965 add_timer(&c
->timer
);
969 imstt_cursor_init (struct fb_info_imstt
*p
)
971 struct imstt_cursor
*c
= &p
->cursor
;
973 imsttfbcon_set_font(&p
->disp
, fontwidth(&p
->disp
), fontheight(&p
->disp
));
979 c
->vbl_cnt
= CURSOR_DRAW_DELAY
;
982 c
->blink_rate
= CURSOR_BLINK_RATE
;
983 init_timer(&c
->timer
);
984 c
->timer
.expires
= jiffies
+ (HZ
/ 50);
985 c
->timer
.data
= (unsigned long)p
;
986 c
->timer
.function
= imstt_cursor_timer_handler
;
987 add_timer(&c
->timer
);
992 imsttfbcon_bmove (struct display
*disp
, int sy
, int sx
, int dy
, int dx
, int height
, int width
)
994 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)disp
->fb_info
;
995 __u32 Bpp
, line_pitch
,
996 fb_offset_old
, fb_offset_new
,
997 sp
, dp_octl
, cnt
, bltctl
;
999 Bpp
= disp
->var
.bits_per_pixel
>> 3,
1001 sy
*= fontheight(disp
);
1002 sx
*= fontwidth(disp
);
1004 dy
*= fontheight(disp
);
1005 dx
*= fontwidth(disp
);
1007 height
*= fontheight(disp
);
1009 width
*= fontwidth(disp
);
1013 line_pitch
= disp
->line_length
;
1015 sp
= line_pitch
<< 16;
1021 sp
|= -(line_pitch
) & 0xffff;
1022 dp_octl
= -(line_pitch
) & 0xffff;
1025 dp_octl
= line_pitch
;
1031 cnt
|= -(width
) & 0xffff;
1035 fb_offset_old
= sy
* line_pitch
+ sx
;
1036 fb_offset_new
= dy
* line_pitch
+ dx
;
1038 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x80);
1039 out_le32(&p
->dc_regs
[S1SA
], fb_offset_old
);
1040 out_le32(&p
->dc_regs
[SP
], sp
);
1041 out_le32(&p
->dc_regs
[DSA
], fb_offset_new
);
1042 out_le32(&p
->dc_regs
[CNT
], cnt
);
1043 out_le32(&p
->dc_regs
[DP_OCTL
], dp_octl
);
1044 out_le32(&p
->dc_regs
[BLTCTL
], bltctl
);
1045 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x80);
1046 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x40);
1050 imsttfbcon_clear (struct vc_data
*conp
, struct display
*disp
,
1051 int sy
, int sx
, int height
, int width
)
1053 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)disp
->fb_info
;
1054 __u32 Bpp
, line_pitch
, bgc
;
1056 bgc
= attr_bgcol_ec(disp
, conp
);
1060 Bpp
= disp
->var
.bits_per_pixel
>> 3,
1061 line_pitch
= disp
->line_length
;
1063 sy
*= fontheight(disp
);
1065 sx
*= fontwidth(disp
);
1067 height
*= fontheight(disp
);
1069 width
*= fontwidth(disp
);
1073 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x80);
1074 out_le32(&p
->dc_regs
[DSA
], sy
+ sx
);
1075 out_le32(&p
->dc_regs
[CNT
], (height
<< 16) | width
);
1076 out_le32(&p
->dc_regs
[DP_OCTL
], line_pitch
);
1077 out_le32(&p
->dc_regs
[BI
], 0xffffffff);
1078 out_le32(&p
->dc_regs
[MBC
], 0xffffffff);
1079 out_le32(&p
->dc_regs
[CLR
], bgc
);
1080 out_le32(&p
->dc_regs
[BLTCTL
], 0x200000);
1081 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x80);
1082 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x40);
1086 imsttfbcon_revc (struct display
*disp
, int sx
, int sy
)
1088 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)disp
->fb_info
;
1089 __u32 Bpp
, line_pitch
, height
, width
;
1091 Bpp
= disp
->var
.bits_per_pixel
>> 3,
1092 line_pitch
= disp
->line_length
;
1094 height
= fontheight(disp
);
1095 width
= fontwidth(disp
) * Bpp
;
1102 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x80);
1103 out_le32(&p
->dc_regs
[DSA
], sy
+ sx
);
1104 out_le32(&p
->dc_regs
[S1SA
], sy
+ sx
);
1105 out_le32(&p
->dc_regs
[CNT
], (height
<< 16) | width
);
1106 out_le32(&p
->dc_regs
[DP_OCTL
], line_pitch
);
1107 out_le32(&p
->dc_regs
[SP
], line_pitch
);
1108 out_le32(&p
->dc_regs
[BLTCTL
], 0x40005);
1109 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x80);
1110 while(in_le32(&p
->dc_regs
[SSTATUS
]) & 0x40);
1113 #ifdef FBCON_HAS_CFB8
1114 static struct display_switch fbcon_imstt8
= {
1115 fbcon_cfb8_setup
, imsttfbcon_bmove
, imsttfbcon_clear
, fbcon_cfb8_putc
,
1116 fbcon_cfb8_putcs
, imsttfbcon_revc
, imsttfbcon_cursor
, imsttfbcon_set_font
, fbcon_cfb8_clear_margins
,
1117 FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
1120 #ifdef FBCON_HAS_CFB16
1121 static struct display_switch fbcon_imstt16
= {
1122 fbcon_cfb16_setup
, imsttfbcon_bmove
, imsttfbcon_clear
, fbcon_cfb16_putc
,
1123 fbcon_cfb16_putcs
, imsttfbcon_revc
, imsttfbcon_cursor
, imsttfbcon_set_font
, fbcon_cfb16_clear_margins
,
1124 FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
1127 #ifdef FBCON_HAS_CFB24
1128 static struct display_switch fbcon_imstt24
= {
1129 fbcon_cfb24_setup
, imsttfbcon_bmove
, imsttfbcon_clear
, fbcon_cfb24_putc
,
1130 fbcon_cfb24_putcs
, imsttfbcon_revc
, imsttfbcon_cursor
, imsttfbcon_set_font
, fbcon_cfb24_clear_margins
,
1131 FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
1134 #ifdef FBCON_HAS_CFB32
1135 static struct display_switch fbcon_imstt32
= {
1136 fbcon_cfb32_setup
, imsttfbcon_bmove
, imsttfbcon_clear
, fbcon_cfb32_putc
,
1137 fbcon_cfb32_putcs
, imsttfbcon_revc
, imsttfbcon_cursor
, imsttfbcon_set_font
, fbcon_cfb32_clear_margins
,
1138 FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
1142 #ifdef CONFIG_FB_COMPAT_XPMAC
1143 #include <asm/vc_ioctl.h>
1145 extern struct vc_mode display_info
;
1146 extern struct fb_info
*console_fb_info
;
1149 set_display_info (struct display
*disp
)
1151 display_info
.width
= disp
->var
.xres
;
1152 display_info
.height
= disp
->var
.yres
;
1153 display_info
.depth
= disp
->var
.bits_per_pixel
;
1154 display_info
.pitch
= disp
->line_length
;
1156 switch (disp
->var
.xres
) {
1158 display_info
.mode
= 2;
1161 display_info
.mode
= 6;
1164 display_info
.mode
= 12;
1167 display_info
.mode
= 13;
1170 display_info
.mode
= 17;
1173 display_info
.mode
= 18;
1176 display_info
.mode
= disp
->var
.yres
== 960 ? 19 : 20;
1179 display_info
.mode
= 0;
1185 imsttfb_getcolreg (u_int regno
, u_int
*red
, u_int
*green
,
1186 u_int
*blue
, u_int
*transp
, struct fb_info
*info
)
1188 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1192 *red
= (p
->palette
[regno
].red
<< 8) | p
->palette
[regno
].red
;
1193 *green
= (p
->palette
[regno
].green
<< 8) | p
->palette
[regno
].green
;
1194 *blue
= (p
->palette
[regno
].blue
<< 8) | p
->palette
[regno
].blue
;
1201 imsttfb_setcolreg (u_int regno
, u_int red
, u_int green
, u_int blue
,
1202 u_int transp
, struct fb_info
*info
)
1204 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1205 u_int bpp
= fb_display
[currcon
].var
.bits_per_pixel
;
1215 p
->palette
[regno
].red
= red
;
1216 p
->palette
[regno
].green
= green
;
1217 p
->palette
[regno
].blue
= blue
;
1219 /* PADDRW/PDATA are the same as TVPPADDRW/TVPPDATA */
1220 if (0 && bpp
== 16) /* screws up X */
1221 p
->cmap_regs
[PADDRW
] = regno
<< 3;
1223 p
->cmap_regs
[PADDRW
] = regno
;
1226 p
->cmap_regs
[PDATA
] = red
; eieio();
1227 p
->cmap_regs
[PDATA
] = green
; eieio();
1228 p
->cmap_regs
[PDATA
] = blue
; eieio();
1232 #ifdef FBCON_HAS_CFB16
1234 p
->fbcon_cmap
.cfb16
[regno
] = (regno
<< (fb_display
[currcon
].var
.green
.length
== 5 ? 10 : 11)) | (regno
<< 5) | regno
;
1237 #ifdef FBCON_HAS_CFB24
1239 p
->fbcon_cmap
.cfb24
[regno
] = (regno
<< 16) | (regno
<< 8) | regno
;
1242 #ifdef FBCON_HAS_CFB32
1244 i
= (regno
<< 8) | regno
;
1245 p
->fbcon_cmap
.cfb32
[regno
] = (i
<< 16) | i
;
1254 do_install_cmap (int con
, struct fb_info
*info
)
1256 if (fb_display
[con
].cmap
.len
)
1257 fb_set_cmap(&fb_display
[con
].cmap
, 1, imsttfb_setcolreg
, info
);
1259 u_int size
= fb_display
[con
].var
.bits_per_pixel
== 16 ? 32 : 256;
1260 fb_set_cmap(fb_default_cmap(size
), 1, imsttfb_setcolreg
, info
);
1265 imsttfb_open (struct fb_info
*info
, int user
)
1272 imsttfb_release (struct fb_info
*info
, int user
)
1279 imsttfb_get_fix (struct fb_fix_screeninfo
*fix
, int con
, struct fb_info
*info
)
1281 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1282 struct fb_var_screeninfo
*var
= &fb_display
[con
].var
;
1285 fix
->visual
= var
->bits_per_pixel
== 8 ? FB_VISUAL_PSEUDOCOLOR
1286 : FB_VISUAL_DIRECTCOLOR
;
1287 fix
->line_length
= var
->xres
* (var
->bits_per_pixel
>> 3);
1293 imsttfb_get_var (struct fb_var_screeninfo
*var
, int con
, struct fb_info
*info
)
1295 *var
= fb_display
[con
].var
;
1301 set_dispsw (struct display
*disp
, struct fb_info_imstt
*p
)
1303 u_int accel
= disp
->var
.accel_flags
& FB_ACCELF_TEXT
;
1305 if (disp
->conp
&& disp
->conp
->vc_sw
&& disp
->conp
->vc_sw
->con_cursor
)
1306 disp
->conp
->vc_sw
->con_cursor(disp
->conp
, CM_ERASE
);
1308 p
->dispsw
= fbcon_dummy
;
1309 disp
->dispsw
= &p
->dispsw
;
1310 disp
->dispsw_data
= 0;
1311 switch (disp
->var
.bits_per_pixel
) {
1313 disp
->var
.red
.offset
= 0;
1314 disp
->var
.red
.length
= 8;
1315 disp
->var
.green
.offset
= 0;
1316 disp
->var
.green
.length
= 8;
1317 disp
->var
.blue
.offset
= 0;
1318 disp
->var
.blue
.length
= 8;
1319 disp
->var
.transp
.offset
= 0;
1320 disp
->var
.transp
.length
= 0;
1321 #ifdef FBCON_HAS_CFB8
1322 p
->dispsw
= accel
? fbcon_imstt8
: fbcon_cfb8
;
1325 case 16: /* RGB 555 or 565 */
1326 if (disp
->var
.green
.length
!= 6)
1327 disp
->var
.red
.offset
= 10;
1328 disp
->var
.red
.length
= 5;
1329 disp
->var
.green
.offset
= 5;
1330 if (disp
->var
.green
.length
!= 6)
1331 disp
->var
.green
.length
= 5;
1332 disp
->var
.blue
.offset
= 0;
1333 disp
->var
.blue
.length
= 5;
1334 disp
->var
.transp
.offset
= 0;
1335 disp
->var
.transp
.length
= 0;
1336 #ifdef FBCON_HAS_CFB16
1337 p
->dispsw
= accel
? fbcon_imstt16
: fbcon_cfb16
;
1338 disp
->dispsw_data
= p
->fbcon_cmap
.cfb16
;
1341 case 24: /* RGB 888 */
1342 disp
->var
.red
.offset
= 16;
1343 disp
->var
.red
.length
= 8;
1344 disp
->var
.green
.offset
= 8;
1345 disp
->var
.green
.length
= 8;
1346 disp
->var
.blue
.offset
= 0;
1347 disp
->var
.blue
.length
= 8;
1348 disp
->var
.transp
.offset
= 0;
1349 disp
->var
.transp
.length
= 0;
1350 #ifdef FBCON_HAS_CFB24
1351 p
->dispsw
= accel
? fbcon_imstt24
: fbcon_cfb24
;
1352 disp
->dispsw_data
= p
->fbcon_cmap
.cfb24
;
1355 case 32: /* RGBA 8888 */
1356 disp
->var
.red
.offset
= 16;
1357 disp
->var
.red
.length
= 8;
1358 disp
->var
.green
.offset
= 8;
1359 disp
->var
.green
.length
= 8;
1360 disp
->var
.blue
.offset
= 0;
1361 disp
->var
.blue
.length
= 8;
1362 disp
->var
.transp
.offset
= 24;
1363 disp
->var
.transp
.length
= 8;
1364 #ifdef FBCON_HAS_CFB32
1365 p
->dispsw
= accel
? fbcon_imstt32
: fbcon_cfb32
;
1366 disp
->dispsw_data
= p
->fbcon_cmap
.cfb32
;
1371 if (accel
&& p
->ramdac
!= IBM
) {
1372 p
->dispsw
.cursor
= 0;
1373 p
->dispsw
.set_font
= 0;
1376 #ifdef CONFIG_FB_COMPAT_XPMAC
1377 set_display_info(disp
);
1382 set_disp (struct display
*disp
, struct fb_info_imstt
*p
)
1384 u_int accel
= disp
->var
.accel_flags
& FB_ACCELF_TEXT
;
1386 disp
->fb_info
= &p
->info
;
1388 set_dispsw(disp
, p
);
1390 disp
->visual
= disp
->var
.bits_per_pixel
== 8 ? FB_VISUAL_PSEUDOCOLOR
1391 : FB_VISUAL_DIRECTCOLOR
;
1392 disp
->screen_base
= (__u8
*)p
->frame_buffer
;
1393 disp
->visual
= p
->fix
.visual
;
1394 disp
->type
= p
->fix
.type
;
1395 disp
->type_aux
= p
->fix
.type_aux
;
1396 disp
->line_length
= disp
->var
.xres
* (disp
->var
.bits_per_pixel
>> 3);
1397 disp
->can_soft_blank
= 1;
1400 disp
->ywrapstep
= 0;
1402 disp
->scrollmode
= SCROLL_YNOMOVE
;
1403 if (disp
->var
.yres
== disp
->var
.yres_virtual
) {
1404 __u32 vram
= (p
->total_vram
- (PAGE_SIZE
<< 2));
1405 disp
->var
.yres_virtual
= ((vram
<< 3) / disp
->var
.bits_per_pixel
) / disp
->var
.xres_virtual
;
1406 if (disp
->var
.yres_virtual
< disp
->var
.yres
)
1407 disp
->var
.yres_virtual
= disp
->var
.yres
;
1410 disp
->scrollmode
= SCROLL_YREDRAW
;
1413 disp
->var
.activate
= 0;
1414 disp
->var
.red
.msb_right
= 0;
1415 disp
->var
.green
.msb_right
= 0;
1416 disp
->var
.blue
.msb_right
= 0;
1417 disp
->var
.transp
.msb_right
= 0;
1418 disp
->var
.height
= -1;
1419 disp
->var
.width
= -1;
1420 disp
->var
.vmode
= FB_VMODE_NONINTERLACED
;
1421 disp
->var
.left_margin
= disp
->var
.right_margin
= 16;
1422 disp
->var
.upper_margin
= disp
->var
.lower_margin
= 16;
1423 disp
->var
.hsync_len
= disp
->var
.vsync_len
= 8;
1427 imsttfb_set_var (struct fb_var_screeninfo
*var
, int con
, struct fb_info
*info
)
1429 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1430 struct display
*disp
;
1431 u_int oldbpp
, oldxres
, oldyres
, oldgreenlen
, oldaccel
;
1433 disp
= &fb_display
[con
];
1435 if ((var
->bits_per_pixel
!= 8 && var
->bits_per_pixel
!= 16
1436 && var
->bits_per_pixel
!= 24 && var
->bits_per_pixel
!= 32)
1437 || var
->xres_virtual
< var
->xres
|| var
->yres_virtual
< var
->yres
1439 || (var
->vmode
& FB_VMODE_MASK
) != FB_VMODE_NONINTERLACED
)
1442 if ((var
->xres
* var
->yres
) * (var
->bits_per_pixel
>> 3) > p
->total_vram
1443 || (var
->xres_virtual
* var
->yres_virtual
) * (var
->bits_per_pixel
>> 3) > p
->total_vram
)
1446 if (!((var
->activate
& FB_ACTIVATE_MASK
) == FB_ACTIVATE_NOW
))
1449 if (!compute_imstt_regvals(p
, var
->xres
, var
->yres
))
1452 oldbpp
= disp
->var
.bits_per_pixel
;
1453 oldxres
= disp
->var
.xres
;
1454 oldyres
= disp
->var
.yres
;
1455 oldgreenlen
= disp
->var
.green
.length
;
1456 oldaccel
= disp
->var
.accel_flags
;
1458 disp
->var
.bits_per_pixel
= var
->bits_per_pixel
;
1459 disp
->var
.xres
= var
->xres
;
1460 disp
->var
.yres
= var
->yres
;
1461 disp
->var
.xres_virtual
= var
->xres_virtual
;
1462 disp
->var
.yres_virtual
= var
->yres_virtual
;
1463 disp
->var
.green
.length
= var
->green
.length
;
1464 disp
->var
.accel_flags
= var
->accel_flags
;
1468 if (info
->changevar
)
1469 (*info
->changevar
)(con
);
1471 if (con
== currcon
) {
1472 if (oldgreenlen
!= disp
->var
.green
.length
) {
1473 if (disp
->var
.green
.length
== 6)
1478 if (oldxres
!= disp
->var
.xres
|| oldyres
!= disp
->var
.yres
|| oldbpp
!= disp
->var
.bits_per_pixel
)
1479 set_imstt_regvals(p
, disp
->var
.bits_per_pixel
);
1482 disp
->var
.pixclock
= 1000000 / getclkMHz(p
);
1484 if (oldbpp
!= disp
->var
.bits_per_pixel
) {
1485 int err
= fb_alloc_cmap(&disp
->cmap
, 0, 0);
1488 do_install_cmap(con
, info
);
1496 imsttfb_pan_display (struct fb_var_screeninfo
*var
, int con
, struct fb_info
*info
)
1498 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1499 struct display
*disp
= &fb_display
[con
];
1501 if (var
->xoffset
+ disp
->var
.xres
> disp
->var
.xres_virtual
1502 || var
->yoffset
+ disp
->var
.yres
> disp
->var
.yres_virtual
)
1505 disp
->var
.xoffset
= var
->xoffset
;
1506 disp
->var
.yoffset
= var
->yoffset
;
1508 set_offset(disp
, p
);
1514 imsttfb_get_cmap (struct fb_cmap
*cmap
, int kspc
, int con
, struct fb_info
*info
)
1516 if (con
== currcon
) /* current console? */
1517 return fb_get_cmap(cmap
, kspc
, imsttfb_getcolreg
, info
);
1518 else if (fb_display
[con
].cmap
.len
) /* non default colormap? */
1519 fb_copy_cmap(&fb_display
[con
].cmap
, cmap
, kspc
? 0 : 2);
1521 u_int size
= fb_display
[con
].var
.bits_per_pixel
== 16 ? 32 : 256;
1522 fb_copy_cmap(fb_default_cmap(size
), cmap
, kspc
? 0 : 2);
1529 imsttfb_set_cmap (struct fb_cmap
*cmap
, int kspc
, int con
, struct fb_info
*info
)
1533 if (!fb_display
[con
].cmap
.len
) { /* no colormap allocated? */
1534 int size
= fb_display
[con
].var
.bits_per_pixel
== 16 ? 32 : 256;
1535 if ((err
= fb_alloc_cmap(&fb_display
[con
].cmap
, size
, 0)))
1538 if (con
== currcon
) /* current console? */
1539 return fb_set_cmap(cmap
, kspc
, imsttfb_setcolreg
, info
);
1541 fb_copy_cmap(cmap
, &fb_display
[con
].cmap
, kspc
? 0 : 1);
1546 #define FBIMSTT_SETREG 0x545401
1547 #define FBIMSTT_GETREG 0x545402
1548 #define FBIMSTT_SETCMAPREG 0x545403
1549 #define FBIMSTT_GETCMAPREG 0x545404
1550 #define FBIMSTT_SETIDXREG 0x545405
1551 #define FBIMSTT_GETIDXREG 0x545406
1554 imsttfb_ioctl (struct inode
*inode
, struct file
*file
, u_int cmd
,
1555 u_long arg
, int con
, struct fb_info
*info
)
1557 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1562 case FBIMSTT_SETREG
:
1563 if (copy_from_user(reg
, (void *)arg
, 8) || reg
[0] > (0x1000 - sizeof(reg
[0])) / sizeof(reg
[0]))
1565 out_le32(&p
->dc_regs
[reg
[0]], reg
[1]);
1567 case FBIMSTT_GETREG
:
1568 if (copy_from_user(reg
, (void *)arg
, 4) || reg
[0] > (0x1000 - sizeof(reg
[0])) / sizeof(reg
[0]))
1570 reg
[1] = in_le32(&p
->dc_regs
[reg
[0]]);
1571 if (copy_to_user((void *)(arg
+ 4), ®
[1], 4))
1574 case FBIMSTT_SETCMAPREG
:
1575 if (copy_from_user(reg
, (void *)arg
, 8) || reg
[0] > (0x1000 - sizeof(reg
[0])) / sizeof(reg
[0]))
1577 out_le32(&((u_int
*)p
->cmap_regs
)[reg
[0]], reg
[1]);
1579 case FBIMSTT_GETCMAPREG
:
1580 if (copy_from_user(reg
, (void *)arg
, 4) || reg
[0] > (0x1000 - sizeof(reg
[0])) / sizeof(reg
[0]))
1582 reg
[1] = in_le32(&((u_int
*)p
->cmap_regs
)[reg
[0]]);
1583 if (copy_to_user((void *)(arg
+ 4), ®
[1], 4))
1586 case FBIMSTT_SETIDXREG
:
1587 if (copy_from_user(idx
, (void *)arg
, 2))
1589 p
->cmap_regs
[PIDXHI
] = 0; eieio();
1590 p
->cmap_regs
[PIDXLO
] = idx
[0]; eieio();
1591 p
->cmap_regs
[PIDXDATA
] = idx
[1]; eieio();
1593 case FBIMSTT_GETIDXREG
:
1594 if (copy_from_user(idx
, (void *)arg
, 1))
1596 p
->cmap_regs
[PIDXHI
] = 0; eieio();
1597 p
->cmap_regs
[PIDXLO
] = idx
[0]; eieio();
1598 idx
[1] = p
->cmap_regs
[PIDXDATA
];
1599 if (copy_to_user((void *)(arg
+ 1), &idx
[1], 1))
1603 return -ENOIOCTLCMD
;
1607 static struct fb_ops imsttfb_ops
= {
1615 imsttfb_pan_display
,
1620 imsttfbcon_switch (int con
, struct fb_info
*info
)
1622 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1623 struct display
*old
= &fb_display
[currcon
], *new = &fb_display
[con
];
1626 fb_get_cmap(&old
->cmap
, 1, imsttfb_getcolreg
, info
);
1628 if (old
->conp
&& old
->conp
->vc_sw
&& old
->conp
->vc_sw
->con_cursor
)
1629 old
->conp
->vc_sw
->con_cursor(old
->conp
, CM_ERASE
);
1633 if (old
->var
.xres
!= new->var
.xres
1634 || old
->var
.yres
!= new->var
.yres
1635 || old
->var
.bits_per_pixel
!= new->var
.bits_per_pixel
1636 || old
->var
.green
.length
!= new->var
.green
.length
1637 || old
->var
.accel_flags
!= new->var
.accel_flags
) {
1639 if (!compute_imstt_regvals(p
, new->var
.xres
, new->var
.yres
))
1641 if (new->var
.bits_per_pixel
== 16) {
1642 if (new->var
.green
.length
== 6)
1647 set_imstt_regvals(p
, new->var
.bits_per_pixel
);
1651 imsttfbcon_set_font(new, fontwidth(new), fontheight(new));
1653 do_install_cmap(con
, info
);
1659 imsttfbcon_updatevar (int con
, struct fb_info
*info
)
1661 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1662 struct display
*disp
= &fb_display
[con
];
1667 if (p
->ramdac
== IBM
)
1668 imsttfbcon_cursor(disp
, CM_ERASE
, p
->cursor
.x
, p
->cursor
.y
);
1670 set_offset(disp
, p
);
1677 imsttfbcon_blank (int blank
, struct fb_info
*info
)
1679 struct fb_info_imstt
*p
= (struct fb_info_imstt
*)info
;
1682 ctrl
= in_le32(&p
->dc_regs
[STGCTL
]);
1684 switch (blank
- 1) {
1685 case VESA_NO_BLANKING
:
1686 case VESA_POWERDOWN
:
1687 ctrl
&= ~0x00000380;
1688 if (p
->ramdac
== IBM
) {
1689 p
->cmap_regs
[PIDXHI
] = 0; eieio();
1690 p
->cmap_regs
[PIDXLO
] = MISCTL2
; eieio();
1691 p
->cmap_regs
[PIDXDATA
] = 0x55; eieio();
1692 p
->cmap_regs
[PIDXLO
] = MISCTL1
; eieio();
1693 p
->cmap_regs
[PIDXDATA
] = 0x11; eieio();
1694 p
->cmap_regs
[PIDXLO
] = SYNCCTL
; eieio();
1695 p
->cmap_regs
[PIDXDATA
] = 0x0f; eieio();
1696 p
->cmap_regs
[PIDXLO
] = PWRMNGMT
;eieio();
1697 p
->cmap_regs
[PIDXDATA
] = 0x1f; eieio();
1698 p
->cmap_regs
[PIDXLO
] = CLKCTL
; eieio();
1699 p
->cmap_regs
[PIDXDATA
] = 0xc0;
1702 case VESA_VSYNC_SUSPEND
:
1703 ctrl
&= ~0x00000020;
1705 case VESA_HSYNC_SUSPEND
:
1706 ctrl
&= ~0x00000010;
1710 if (p
->ramdac
== IBM
) {
1712 p
->cmap_regs
[PIDXHI
] = 0; eieio();
1713 p
->cmap_regs
[PIDXLO
] = CLKCTL
; eieio();
1714 p
->cmap_regs
[PIDXDATA
] = 0x01; eieio();
1715 p
->cmap_regs
[PIDXLO
] = PWRMNGMT
;eieio();
1716 p
->cmap_regs
[PIDXDATA
] = 0x00; eieio();
1717 p
->cmap_regs
[PIDXLO
] = SYNCCTL
; eieio();
1718 p
->cmap_regs
[PIDXDATA
] = 0x00; eieio();
1719 p
->cmap_regs
[PIDXLO
] = MISCTL1
; eieio();
1720 p
->cmap_regs
[PIDXDATA
] = 0x01; eieio();
1721 p
->cmap_regs
[PIDXLO
] = MISCTL2
; eieio();
1722 p
->cmap_regs
[PIDXDATA
] = 0x45; eieio();
1726 out_le32(&p
->dc_regs
[STGCTL
], ctrl
);
1730 init_imstt(struct fb_info_imstt
*p
)
1735 tmp
= in_le32(&p
->dc_regs
[PRC
]);
1736 if (p
->ramdac
== IBM
)
1737 p
->total_vram
= (tmp
& 0x0004) ? 0x400000 : 0x200000;
1739 p
->total_vram
= 0x800000;
1741 ip
= (__u32
*)p
->frame_buffer
;
1742 end
= (__u32
*)(p
->frame_buffer
+ p
->total_vram
);
1746 /* initialize the card */
1747 tmp
= in_le32(&p
->dc_regs
[STGCTL
]);
1748 out_le32(&p
->dc_regs
[STGCTL
], tmp
& ~0x1);
1749 out_le32(&p
->dc_regs
[SSR
], 0);
1751 /* set default values for DAC registers */
1752 if (p
->ramdac
== IBM
) {
1753 p
->cmap_regs
[PPMASK
] = 0xff; eieio();
1754 p
->cmap_regs
[PIDXHI
] = 0; eieio();
1755 for (i
= 0; i
< sizeof(ibm_initregs
) / sizeof(*ibm_initregs
); i
++) {
1756 p
->cmap_regs
[PIDXLO
] = ibm_initregs
[i
].addr
; eieio();
1757 p
->cmap_regs
[PIDXDATA
] = ibm_initregs
[i
].value
; eieio();
1760 for (i
= 0; i
< sizeof(tvp_initregs
) / sizeof(*tvp_initregs
); i
++) {
1761 p
->cmap_regs
[TVPADDRW
] = tvp_initregs
[i
].addr
; eieio();
1762 p
->cmap_regs
[TVPIDATA
] = tvp_initregs
[i
].value
; eieio();
1766 #if USE_NV_MODES && defined(CONFIG_PPC)
1768 int vmode
= init_vmode
, cmode
= init_cmode
;
1771 vmode
= nvram_read_byte(NV_VMODE
);
1772 if (vmode
<= 0 || vmode
> VMODE_MAX
)
1773 vmode
= VMODE_640_480_67
;
1776 cmode
= nvram_read_byte(NV_CMODE
);
1777 if (cmode
< CMODE_8
|| cmode
> CMODE_32
)
1780 if (mac_vmode_to_var(vmode
, cmode
, &p
->disp
.var
)) {
1781 p
->disp
.var
.xres
= p
->disp
.var
.xres_virtual
= INIT_XRES
;
1782 p
->disp
.var
.yres
= p
->disp
.var
.yres_virtual
= INIT_YRES
;
1783 p
->disp
.var
.bits_per_pixel
= INIT_BPP
;
1787 p
->disp
.var
.xres
= p
->disp
.var
.xres_virtual
= INIT_XRES
;
1788 p
->disp
.var
.yres
= p
->disp
.var
.yres_virtual
= INIT_YRES
;
1789 p
->disp
.var
.bits_per_pixel
= INIT_BPP
;
1792 if ((p
->disp
.var
.xres
* p
->disp
.var
.yres
) * (p
->disp
.var
.bits_per_pixel
>> 3) > p
->total_vram
1793 || !(compute_imstt_regvals(p
, p
->disp
.var
.xres
, p
->disp
.var
.yres
))) {
1794 printk("imsttfb: %ux%ux%u not supported\n", p
->disp
.var
.xres
, p
->disp
.var
.yres
, p
->disp
.var
.bits_per_pixel
);
1799 sprintf(p
->fix
.id
, "IMS TT (%s)", p
->ramdac
== IBM
? "IBM" : "TVP");
1800 p
->fix
.smem_start
= p
->frame_buffer_phys
;
1801 p
->fix
.smem_len
= p
->total_vram
;
1802 p
->fix
.mmio_start
= p
->dc_regs_phys
;
1803 p
->fix
.mmio_len
= 0x1000;
1804 p
->fix
.accel
= FB_ACCEL_IMS_TWINTURBO
;
1805 p
->fix
.type
= FB_TYPE_PACKED_PIXELS
;
1806 p
->fix
.visual
= p
->disp
.var
.bits_per_pixel
== 8 ? FB_VISUAL_PSEUDOCOLOR
1807 : FB_VISUAL_DIRECTCOLOR
;
1808 p
->fix
.line_length
= p
->disp
.var
.xres
* (p
->disp
.var
.bits_per_pixel
>> 3);
1809 p
->fix
.xpanstep
= 8;
1810 p
->fix
.ypanstep
= 1;
1811 p
->fix
.ywrapstep
= 0;
1813 p
->disp
.var
.accel_flags
= noaccel
? 0 : FB_ACCELF_TEXT
;
1814 set_disp(&p
->disp
, p
);
1816 if (!noaccel
&& p
->ramdac
== IBM
)
1817 imstt_cursor_init(p
);
1818 if (p
->disp
.var
.green
.length
== 6)
1822 set_imstt_regvals(p
, p
->disp
.var
.bits_per_pixel
);
1824 p
->disp
.var
.pixclock
= 1000000 / getclkMHz(p
);
1826 strcpy(p
->info
.modename
, p
->fix
.id
);
1827 strcpy(p
->info
.fontname
, fontname
);
1829 p
->info
.fbops
= &imsttfb_ops
;
1830 p
->info
.disp
= &p
->disp
;
1831 p
->info
.changevar
= 0;
1832 p
->info
.switch_con
= &imsttfbcon_switch
;
1833 p
->info
.updatevar
= &imsttfbcon_updatevar
;
1834 p
->info
.blank
= &imsttfbcon_blank
;
1835 p
->info
.flags
= FBINFO_FLAG_DEFAULT
;
1837 for (i
= 0; i
< 16; i
++) {
1838 u_int j
= color_table
[i
];
1839 p
->palette
[i
].red
= default_red
[j
];
1840 p
->palette
[i
].green
= default_grn
[j
];
1841 p
->palette
[i
].blue
= default_blu
[j
];
1844 if (register_framebuffer(&p
->info
) < 0) {
1849 i
= GET_FB_IDX(p
->info
.node
);
1850 tmp
= (in_le32(&p
->dc_regs
[SSTATUS
]) & 0x0f00) >> 8;
1851 printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",
1852 i
, p
->fix
.id
, p
->total_vram
>> 20, tmp
);
1854 fb_info_imstt_p
[i
] = p
;
1855 #ifdef CONFIG_FB_COMPAT_XPMAC
1856 strncpy(display_info
.name
, "IMS,tt128mb", sizeof(display_info
.name
));
1857 display_info
.fb_address
= (__u32
)p
->frame_buffer_phys
;
1858 display_info
.cmap_adr_address
= (__u32
)&p
->cmap_regs_phys
[PADDRW
];
1859 display_info
.cmap_data_address
= (__u32
)&p
->cmap_regs_phys
[PDATA
];
1860 display_info
.disp_reg_address
= (__u32
)p
->dc_regs_phys
;
1861 if (!console_fb_info
)
1862 console_fb_info
= &p
->info
;
1863 #endif /* CONFIG_FB_COMPAT_XPMAC */
1866 #if defined(CONFIG_FB_OF) && !defined(MODULE)
1868 imsttfb_of_init(struct device_node
*dp
)
1870 struct fb_info_imstt
*p
;
1876 for (i
= 0; i
< dp
->n_addrs
; i
++) {
1877 if (dp
->addrs
[i
].size
>= 0x02000000)
1878 addr
= dp
->addrs
[i
].address
;
1883 if (!pci_device_loc(dp
, &bus
, &devfn
)) {
1884 if (!pcibios_read_config_word(bus
, devfn
, PCI_COMMAND
, &cmd
) && !(cmd
& PCI_COMMAND_MEMORY
)) {
1885 cmd
|= PCI_COMMAND_MEMORY
;
1886 pcibios_write_config_word(bus
, devfn
, PCI_COMMAND
, cmd
);
1890 p
= kmalloc(sizeof(struct fb_info_imstt
), GFP_ATOMIC
);
1893 memset(p
, 0, sizeof(struct fb_info_imstt
));
1895 if (dp
->name
[11] == '8' || (dp
->name
[6] == '3' && dp
->name
[7] == 'd'))
1900 p
->frame_buffer_phys
= (__u8
*)addr
;
1901 p
->frame_buffer
= (__u8
*)ioremap(addr
, p
->ramdac
== IBM
? 0x400000 : 0x800000);
1902 p
->dc_regs_phys
= (__u32
*)(addr
+ 0x800000);
1903 p
->dc_regs
= (__u32
*)ioremap(addr
+ 0x800000, 0x1000);
1904 p
->cmap_regs_phys
= (__u8
*)(addr
+ 0x840000);
1905 p
->cmap_regs
= (__u8
*)ioremap(addr
+ 0x840000, 0x1000);
1915 #if defined(CONFIG_FB_OF) && !defined(MODULE)
1916 /* We don't want to be called like this. */
1917 /* We rely on Open Firmware (offb) instead. */
1918 #elif defined(CONFIG_PCI)
1919 struct pci_dev
*pdev
;
1920 struct fb_info_imstt
*p
;
1924 for (pdev
= pci_devices
; pdev
; pdev
= pdev
->next
) {
1925 if (!(((pdev
->class >> 16) == PCI_BASE_CLASS_DISPLAY
)
1926 && (pdev
->vendor
== PCI_VENDOR_ID_IMS
)))
1929 pci_read_config_word(pdev
, PCI_COMMAND
, &cmd
);
1930 if (!(cmd
& PCI_COMMAND_MEMORY
)) {
1931 cmd
|= PCI_COMMAND_MEMORY
;
1932 pci_write_config_word(pdev
, PCI_COMMAND
, cmd
);
1935 addr
= pdev
->resource
[0].start
;
1939 p
= kmalloc(sizeof(struct fb_info_imstt
), GFP_ATOMIC
);
1942 memset(p
, 0, sizeof(struct fb_info_imstt
));
1944 printk("imsttfb: device=%04x\n", pdev
->device
);
1946 switch (pdev
->device
) {
1947 case 0x9128: /* IMS,tt128mbA */
1950 case 0x9135: /* IMS,tt3d */
1956 p
->frame_buffer_phys
= (__u8
*)addr
;
1957 p
->frame_buffer
= (__u8
*)ioremap(addr
, p
->ramdac
== IBM
? 0x400000 : 0x800000);
1958 p
->dc_regs_phys
= (__u32
*)(addr
+ 0x800000);
1959 p
->dc_regs
= (__u32
*)ioremap(addr
+ 0x800000, 0x1000);
1960 p
->cmap_regs_phys
= (__u8
*)(addr
+ 0x840000);
1961 p
->cmap_regs
= (__u8
*)ioremap(addr
+ 0x840000, 0x1000);
1965 #endif /* CONFIG_PCI */
1966 for (i
= 0; i
< FB_MAX
; i
++) {
1967 if (fb_info_imstt_p
[i
])
1975 imsttfb_setup(char *options
)
1979 if (!options
|| !*options
)
1982 for (this_opt
= strtok(options
, ","); this_opt
;
1983 this_opt
= strtok(NULL
, ",")) {
1984 if (!strncmp(this_opt
, "font:", 5)) {
1989 for (i
= 0; i
< sizeof(fontname
) - 1; i
++)
1990 if (!*p
|| *p
== ' ' || *p
== ',')
1992 memcpy(fontname
, this_opt
+ 5, i
);
1994 } else if (!strncmp(this_opt
, "noblink", 7)) {
1996 } else if (!strncmp(this_opt
, "noaccel", 7)) {
1999 #if defined(CONFIG_PPC)
2000 else if (!strncmp(this_opt
, "vmode:", 6)) {
2001 int vmode
= simple_strtoul(this_opt
+6, NULL
, 0);
2002 if (vmode
> 0 && vmode
<= VMODE_MAX
)
2004 } else if (!strncmp(this_opt
, "cmode:", 6)) {
2005 int cmode
= simple_strtoul(this_opt
+6, NULL
, 0);
2009 init_cmode
= CMODE_8
;
2014 init_cmode
= CMODE_16
;
2019 init_cmode
= CMODE_32
;
2034 return imsttfb_init();
2038 cleanup_module (void)
2040 struct fb_info_imstt
*p
;
2043 for (i
= 0; i
< FB_MAX
; i
++) {
2044 p
= fb_info_imstt_p
[i
];
2047 iounmap(p
->cmap_regs
);
2048 iounmap(p
->dc_regs
);
2049 iounmap(p
->frame_buffer
);
2054 #include "macmodes.c"