2 * linux/drivers/video/i810_main.c -- Intel 810 frame buffer device
4 * Copyright (C) 2001 Antonino Daplas<adaplas@pol.net>
8 * Michael Vogt <mvogt@acm.org> - added support for Intel 815 chipsets
9 * and enabling the power-on state of
10 * external VGA connectors for
13 * Fredrik Andersson <krueger@shell.linux.se> - alpha testing of
16 * Brad Corrion <bcorrion@web-co.com> - alpha testing of customized
19 * The code framework is a modification of vfb.c by Geert Uytterhoeven.
20 * DotClock and PLL calculations are partly based on i810_driver.c
21 * in xfree86 v4.0.3 by Precision Insight.
22 * Watermark calculation and tables are based on i810_wmark.c
23 * in xfre86 v4.0.3 by Precision Insight. Slight modifications
24 * only to allow for integer operations instead of floating point.
26 * This file is subject to the terms and conditions of the GNU General Public
27 * License. See the file COPYING in the main directory of this archive for
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
36 #include <linux/slab.h>
38 #include <linux/init.h>
39 #include <linux/pci.h>
40 #include <linux/pci_ids.h>
41 #include <linux/resource.h>
42 #include <linux/unistd.h>
43 #include <linux/console.h>
46 #include <asm/div64.h>
49 #include "i810_regs.h"
51 #include "i810_main.h"
54 * voffset - framebuffer offset in MiB from aperture start address. In order for
55 * the driver to work with X, we must try to use memory holes left untouched by X. The
56 * following table lists where X's different surfaces start at.
58 * ---------------------------------------------
59 * : : 64 MiB : 32 MiB :
60 * ----------------------------------------------
61 * : FrontBuffer : 0 : 0 :
62 * : DepthBuffer : 48 : 16 :
63 * : BackBuffer : 56 : 24 :
64 * ----------------------------------------------
66 * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to
67 * 15 + 1 MiB of Framebuffer memory. For 32 MiB Aperture sizes, a v_offset of 8 MiB should
68 * work, allowing 7 + 1 MiB of Framebuffer memory.
69 * Note, the size of the hole may change depending on how much memory you allocate to X,
70 * and how the memory is split up between these surfaces.
72 * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with
73 * DRI disabled. But if the Frontbuffer is overlapped, X will fail to load.
75 * Experiment with v_offset to find out which works best for you.
77 static u32 v_offset_default __devinitdata
; /* For 32 MiB Aper size, 8 should be the default */
78 static u32 voffset __devinitdata
;
80 static int i810fb_cursor(struct fb_info
*info
, struct fb_cursor
*cursor
);
81 static int __devinit
i810fb_init_pci (struct pci_dev
*dev
,
82 const struct pci_device_id
*entry
);
83 static void __exit
i810fb_remove_pci(struct pci_dev
*dev
);
84 static int i810fb_resume(struct pci_dev
*dev
);
85 static int i810fb_suspend(struct pci_dev
*dev
, pm_message_t state
);
87 /* Chipset Specific Functions */
88 static int i810fb_set_par (struct fb_info
*info
);
89 static int i810fb_getcolreg (u8 regno
, u8
*red
, u8
*green
, u8
*blue
,
90 u8
*transp
, struct fb_info
*info
);
91 static int i810fb_setcolreg (unsigned regno
, unsigned red
, unsigned green
, unsigned blue
,
92 unsigned transp
, struct fb_info
*info
);
93 static int i810fb_pan_display(struct fb_var_screeninfo
*var
, struct fb_info
*info
);
94 static int i810fb_blank (int blank_mode
, struct fb_info
*info
);
97 static void i810fb_release_resource (struct fb_info
*info
, struct i810fb_par
*par
);
100 static const char *i810_pci_list
[] __devinitdata
= {
101 "Intel(R) 810 Framebuffer Device" ,
102 "Intel(R) 810-DC100 Framebuffer Device" ,
103 "Intel(R) 810E Framebuffer Device" ,
104 "Intel(R) 815 (Internal Graphics 100Mhz FSB) Framebuffer Device" ,
105 "Intel(R) 815 (Internal Graphics only) Framebuffer Device" ,
106 "Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"
109 static struct pci_device_id i810fb_pci_tbl
[] = {
110 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82810_IG1
,
111 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0 },
112 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82810_IG3
,
113 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 1 },
114 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82810E_IG
,
115 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 2 },
116 /* mvo: added i815 PCI-ID */
117 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82815_100
,
118 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 3 },
119 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82815_NOAGP
,
120 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 4 },
121 { PCI_VENDOR_ID_INTEL
, PCI_DEVICE_ID_INTEL_82815_CGC
,
122 PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 5 },
126 static struct pci_driver i810fb_driver
= {
128 .id_table
= i810fb_pci_tbl
,
129 .probe
= i810fb_init_pci
,
130 .remove
= __exit_p(i810fb_remove_pci
),
131 .suspend
= i810fb_suspend
,
132 .resume
= i810fb_resume
,
135 static char *mode_option __devinitdata
= NULL
;
136 static int vram __devinitdata
= 4;
137 static int bpp __devinitdata
= 8;
138 static int mtrr __devinitdata
;
139 static int accel __devinitdata
;
140 static int hsync1 __devinitdata
;
141 static int hsync2 __devinitdata
;
142 static int vsync1 __devinitdata
;
143 static int vsync2 __devinitdata
;
144 static int xres __devinitdata
;
146 static int vyres __devinitdata
;
147 static int sync __devinitdata
;
148 static int extvga __devinitdata
;
149 static int dcolor __devinitdata
;
150 static int ddc3 __devinitdata
= 2;
152 /*------------------------------------------------------------*/
154 /**************************************************************
155 * Hardware Low Level Routines *
156 **************************************************************/
159 * i810_screen_off - turns off/on display
160 * @mmio: address of register space
164 * Blanks/unblanks the display
166 static void i810_screen_off(u8 __iomem
*mmio
, u8 mode
)
168 u32 count
= WAIT_COUNT
;
171 i810_writeb(SR_INDEX
, mmio
, SR01
);
172 val
= i810_readb(SR_DATA
, mmio
);
173 val
= (mode
== OFF
) ? val
| SCR_OFF
:
176 while((i810_readw(DISP_SL
, mmio
) & 0xFFF) && count
--);
177 i810_writeb(SR_INDEX
, mmio
, SR01
);
178 i810_writeb(SR_DATA
, mmio
, val
);
182 * i810_dram_off - turns off/on dram refresh
183 * @mmio: address of register space
187 * Turns off DRAM refresh. Must be off for only 2 vsyncs
188 * before data becomes corrupt
190 static void i810_dram_off(u8 __iomem
*mmio
, u8 mode
)
194 val
= i810_readb(DRAMCH
, mmio
);
196 val
= (mode
== OFF
) ? val
: val
| DRAM_ON
;
197 i810_writeb(DRAMCH
, mmio
, val
);
201 * i810_protect_regs - allows rw/ro mode of certain VGA registers
202 * @mmio: address of register space
203 * @mode: protect/unprotect
206 * The IBM VGA standard allows protection of certain VGA registers.
207 * This will protect or unprotect them.
209 static void i810_protect_regs(u8 __iomem
*mmio
, int mode
)
213 i810_writeb(CR_INDEX_CGA
, mmio
, CR11
);
214 reg
= i810_readb(CR_DATA_CGA
, mmio
);
215 reg
= (mode
== OFF
) ? reg
& ~0x80 :
218 i810_writeb(CR_INDEX_CGA
, mmio
, CR11
);
219 i810_writeb(CR_DATA_CGA
, mmio
, reg
);
223 * i810_load_pll - loads values for the hardware PLL clock
224 * @par: pointer to i810fb_par structure
227 * Loads the P, M, and N registers.
229 static void i810_load_pll(struct i810fb_par
*par
)
232 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
234 tmp1
= par
->regs
.M
| par
->regs
.N
<< 16;
235 tmp2
= i810_readl(DCLK_2D
, mmio
);
237 i810_writel(DCLK_2D
, mmio
, tmp1
| tmp2
);
240 tmp2
= i810_readl(DCLK_0DS
, mmio
);
241 tmp2
&= ~(P_OR
<< 16);
242 i810_writel(DCLK_0DS
, mmio
, (tmp1
<< 16) | tmp2
);
244 i810_writeb(MSR_WRITE
, mmio
, par
->regs
.msr
| 0xC8 | 1);
249 * i810_load_vga - load standard VGA registers
250 * @par: pointer to i810fb_par structure
253 * Load values to VGA registers
255 static void i810_load_vga(struct i810fb_par
*par
)
257 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
260 i810_writeb(CR_INDEX_CGA
, mmio
, CR70
);
261 i810_writeb(CR_DATA_CGA
, mmio
, par
->interlace
);
263 i810_writeb(CR_INDEX_CGA
, mmio
, CR00
);
264 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr00
);
265 i810_writeb(CR_INDEX_CGA
, mmio
, CR01
);
266 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr01
);
267 i810_writeb(CR_INDEX_CGA
, mmio
, CR02
);
268 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr02
);
269 i810_writeb(CR_INDEX_CGA
, mmio
, CR03
);
270 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr03
);
271 i810_writeb(CR_INDEX_CGA
, mmio
, CR04
);
272 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr04
);
273 i810_writeb(CR_INDEX_CGA
, mmio
, CR05
);
274 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr05
);
275 i810_writeb(CR_INDEX_CGA
, mmio
, CR06
);
276 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr06
);
277 i810_writeb(CR_INDEX_CGA
, mmio
, CR09
);
278 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr09
);
279 i810_writeb(CR_INDEX_CGA
, mmio
, CR10
);
280 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr10
);
281 i810_writeb(CR_INDEX_CGA
, mmio
, CR11
);
282 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr11
);
283 i810_writeb(CR_INDEX_CGA
, mmio
, CR12
);
284 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr12
);
285 i810_writeb(CR_INDEX_CGA
, mmio
, CR15
);
286 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr15
);
287 i810_writeb(CR_INDEX_CGA
, mmio
, CR16
);
288 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr16
);
292 * i810_load_vgax - load extended VGA registers
293 * @par: pointer to i810fb_par structure
296 * Load values to extended VGA registers
298 static void i810_load_vgax(struct i810fb_par
*par
)
300 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
302 i810_writeb(CR_INDEX_CGA
, mmio
, CR30
);
303 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr30
);
304 i810_writeb(CR_INDEX_CGA
, mmio
, CR31
);
305 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr31
);
306 i810_writeb(CR_INDEX_CGA
, mmio
, CR32
);
307 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr32
);
308 i810_writeb(CR_INDEX_CGA
, mmio
, CR33
);
309 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr33
);
310 i810_writeb(CR_INDEX_CGA
, mmio
, CR35
);
311 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr35
);
312 i810_writeb(CR_INDEX_CGA
, mmio
, CR39
);
313 i810_writeb(CR_DATA_CGA
, mmio
, par
->regs
.cr39
);
317 * i810_load_2d - load grahics registers
318 * @par: pointer to i810fb_par structure
321 * Load values to graphics registers
323 static void i810_load_2d(struct i810fb_par
*par
)
327 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
329 i810_writel(FW_BLC
, mmio
, par
->watermark
);
330 tmp
= i810_readl(PIXCONF
, mmio
);
332 i810_writel(PIXCONF
, mmio
, tmp
);
334 i810_writel(OVRACT
, mmio
, par
->ovract
);
336 i810_writeb(GR_INDEX
, mmio
, GR10
);
337 tmp8
= i810_readb(GR_DATA
, mmio
);
339 i810_writeb(GR_INDEX
, mmio
, GR10
);
340 i810_writeb(GR_DATA
, mmio
, tmp8
);
344 * i810_hires - enables high resolution mode
345 * @mmio: address of register space
347 static void i810_hires(u8 __iomem
*mmio
)
351 i810_writeb(CR_INDEX_CGA
, mmio
, CR80
);
352 val
= i810_readb(CR_DATA_CGA
, mmio
);
353 i810_writeb(CR_INDEX_CGA
, mmio
, CR80
);
354 i810_writeb(CR_DATA_CGA
, mmio
, val
| 1);
355 /* Stop LCD displays from flickering */
356 i810_writel(MEM_MODE
, mmio
, i810_readl(MEM_MODE
, mmio
) | 4);
360 * i810_load_pitch - loads the characters per line of the display
361 * @par: pointer to i810fb_par structure
364 * Loads the characters per line
366 static void i810_load_pitch(struct i810fb_par
*par
)
370 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
372 pitch
= par
->pitch
>> 3;
373 i810_writeb(SR_INDEX
, mmio
, SR01
);
374 val
= i810_readb(SR_DATA
, mmio
);
377 i810_writeb(SR_INDEX
, mmio
, SR01
);
378 i810_writeb(SR_DATA
, mmio
, val
);
381 i810_writeb(CR_INDEX_CGA
, mmio
, CR13
);
382 i810_writeb(CR_DATA_CGA
, mmio
, (u8
) tmp
);
385 i810_writeb(CR_INDEX_CGA
, mmio
, CR41
);
386 val
= i810_readb(CR_DATA_CGA
, mmio
) & ~0x0F;
387 i810_writeb(CR_INDEX_CGA
, mmio
, CR41
);
388 i810_writeb(CR_DATA_CGA
, mmio
, (u8
) tmp
| val
);
392 * i810_load_color - loads the color depth of the display
393 * @par: pointer to i810fb_par structure
396 * Loads the color depth of the display and the graphics engine
398 static void i810_load_color(struct i810fb_par
*par
)
400 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
404 reg1
= i810_readl(PIXCONF
, mmio
) & ~(0xF0000 | 1 << 27);
405 reg2
= i810_readw(BLTCNTL
, mmio
) & ~0x30;
407 reg1
|= 0x8000 | par
->pixconf
;
408 reg2
|= par
->bltcntl
;
409 i810_writel(PIXCONF
, mmio
, reg1
);
410 i810_writew(BLTCNTL
, mmio
, reg2
);
414 * i810_load_regs - loads all registers for the mode
415 * @par: pointer to i810fb_par structure
420 static void i810_load_regs(struct i810fb_par
*par
)
422 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
424 i810_screen_off(mmio
, OFF
);
425 i810_protect_regs(mmio
, OFF
);
426 i810_dram_off(mmio
, OFF
);
430 i810_dram_off(mmio
, ON
);
433 i810_screen_off(mmio
, ON
);
434 i810_protect_regs(mmio
, ON
);
435 i810_load_color(par
);
436 i810_load_pitch(par
);
439 static void i810_write_dac(u8 regno
, u8 red
, u8 green
, u8 blue
,
442 i810_writeb(CLUT_INDEX_WRITE
, mmio
, regno
);
443 i810_writeb(CLUT_DATA
, mmio
, red
);
444 i810_writeb(CLUT_DATA
, mmio
, green
);
445 i810_writeb(CLUT_DATA
, mmio
, blue
);
448 static void i810_read_dac(u8 regno
, u8
*red
, u8
*green
, u8
*blue
,
451 i810_writeb(CLUT_INDEX_READ
, mmio
, regno
);
452 *red
= i810_readb(CLUT_DATA
, mmio
);
453 *green
= i810_readb(CLUT_DATA
, mmio
);
454 *blue
= i810_readb(CLUT_DATA
, mmio
);
457 /************************************************************
458 * VGA State Restore *
459 ************************************************************/
460 static void i810_restore_pll(struct i810fb_par
*par
)
463 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
465 tmp1
= par
->hw_state
.dclk_2d
;
466 tmp2
= i810_readl(DCLK_2D
, mmio
);
469 i810_writel(DCLK_2D
, mmio
, tmp1
| tmp2
);
471 tmp1
= par
->hw_state
.dclk_1d
;
472 tmp2
= i810_readl(DCLK_1D
, mmio
);
475 i810_writel(DCLK_1D
, mmio
, tmp1
| tmp2
);
477 i810_writel(DCLK_0DS
, mmio
, par
->hw_state
.dclk_0ds
);
480 static void i810_restore_dac(struct i810fb_par
*par
)
483 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
485 tmp1
= par
->hw_state
.pixconf
;
486 tmp2
= i810_readl(PIXCONF
, mmio
);
489 i810_writel(PIXCONF
, mmio
, tmp1
| tmp2
);
492 static void i810_restore_vgax(struct i810fb_par
*par
)
495 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
497 for (i
= 0; i
< 4; i
++) {
498 i810_writeb(CR_INDEX_CGA
, mmio
, CR30
+i
);
499 i810_writeb(CR_DATA_CGA
, mmio
, *(&(par
->hw_state
.cr30
) + i
));
501 i810_writeb(CR_INDEX_CGA
, mmio
, CR35
);
502 i810_writeb(CR_DATA_CGA
, mmio
, par
->hw_state
.cr35
);
503 i810_writeb(CR_INDEX_CGA
, mmio
, CR39
);
504 i810_writeb(CR_DATA_CGA
, mmio
, par
->hw_state
.cr39
);
505 i810_writeb(CR_INDEX_CGA
, mmio
, CR41
);
506 i810_writeb(CR_DATA_CGA
, mmio
, par
->hw_state
.cr39
);
508 /*restore interlace*/
509 i810_writeb(CR_INDEX_CGA
, mmio
, CR70
);
510 i
= par
->hw_state
.cr70
;
512 j
= i810_readb(CR_DATA_CGA
, mmio
);
513 i810_writeb(CR_INDEX_CGA
, mmio
, CR70
);
514 i810_writeb(CR_DATA_CGA
, mmio
, j
| i
);
516 i810_writeb(CR_INDEX_CGA
, mmio
, CR80
);
517 i810_writeb(CR_DATA_CGA
, mmio
, par
->hw_state
.cr80
);
518 i810_writeb(MSR_WRITE
, mmio
, par
->hw_state
.msr
);
519 i810_writeb(SR_INDEX
, mmio
, SR01
);
520 i
= (par
->hw_state
.sr01
) & ~0xE0 ;
521 j
= i810_readb(SR_DATA
, mmio
) & 0xE0;
522 i810_writeb(SR_INDEX
, mmio
, SR01
);
523 i810_writeb(SR_DATA
, mmio
, i
| j
);
526 static void i810_restore_vga(struct i810fb_par
*par
)
529 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
531 for (i
= 0; i
< 10; i
++) {
532 i810_writeb(CR_INDEX_CGA
, mmio
, CR00
+ i
);
533 i810_writeb(CR_DATA_CGA
, mmio
, *((&par
->hw_state
.cr00
) + i
));
535 for (i
= 0; i
< 8; i
++) {
536 i810_writeb(CR_INDEX_CGA
, mmio
, CR10
+ i
);
537 i810_writeb(CR_DATA_CGA
, mmio
, *((&par
->hw_state
.cr10
) + i
));
541 static void i810_restore_addr_map(struct i810fb_par
*par
)
544 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
546 i810_writeb(GR_INDEX
, mmio
, GR10
);
547 tmp
= i810_readb(GR_DATA
, mmio
);
548 tmp
&= ADDR_MAP_MASK
;
549 tmp
|= par
->hw_state
.gr10
;
550 i810_writeb(GR_INDEX
, mmio
, GR10
);
551 i810_writeb(GR_DATA
, mmio
, tmp
);
554 static void i810_restore_2d(struct i810fb_par
*par
)
558 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
560 tmp_word
= i810_readw(BLTCNTL
, mmio
);
561 tmp_word
&= ~(3 << 4);
562 tmp_word
|= par
->hw_state
.bltcntl
;
563 i810_writew(BLTCNTL
, mmio
, tmp_word
);
565 i810_dram_off(mmio
, OFF
);
566 i810_writel(PIXCONF
, mmio
, par
->hw_state
.pixconf
);
567 i810_dram_off(mmio
, ON
);
569 tmp_word
= i810_readw(HWSTAM
, mmio
);
571 tmp_word
|= par
->hw_state
.hwstam
;
572 i810_writew(HWSTAM
, mmio
, tmp_word
);
574 tmp_long
= i810_readl(FW_BLC
, mmio
);
575 tmp_long
&= FW_BLC_MASK
;
576 tmp_long
|= par
->hw_state
.fw_blc
;
577 i810_writel(FW_BLC
, mmio
, tmp_long
);
579 i810_writel(HWS_PGA
, mmio
, par
->hw_state
.hws_pga
);
580 i810_writew(IER
, mmio
, par
->hw_state
.ier
);
581 i810_writew(IMR
, mmio
, par
->hw_state
.imr
);
582 i810_writel(DPLYSTAS
, mmio
, par
->hw_state
.dplystas
);
585 static void i810_restore_vga_state(struct i810fb_par
*par
)
587 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
589 i810_screen_off(mmio
, OFF
);
590 i810_protect_regs(mmio
, OFF
);
591 i810_dram_off(mmio
, OFF
);
592 i810_restore_pll(par
);
593 i810_restore_dac(par
);
594 i810_restore_vga(par
);
595 i810_restore_vgax(par
);
596 i810_restore_addr_map(par
);
597 i810_dram_off(mmio
, ON
);
598 i810_restore_2d(par
);
599 i810_screen_off(mmio
, ON
);
600 i810_protect_regs(mmio
, ON
);
603 /***********************************************************************
605 ***********************************************************************/
607 static void i810_save_vgax(struct i810fb_par
*par
)
610 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
612 for (i
= 0; i
< 4; i
++) {
613 i810_writeb(CR_INDEX_CGA
, mmio
, CR30
+ i
);
614 *(&(par
->hw_state
.cr30
) + i
) = i810_readb(CR_DATA_CGA
, mmio
);
616 i810_writeb(CR_INDEX_CGA
, mmio
, CR35
);
617 par
->hw_state
.cr35
= i810_readb(CR_DATA_CGA
, mmio
);
618 i810_writeb(CR_INDEX_CGA
, mmio
, CR39
);
619 par
->hw_state
.cr39
= i810_readb(CR_DATA_CGA
, mmio
);
620 i810_writeb(CR_INDEX_CGA
, mmio
, CR41
);
621 par
->hw_state
.cr41
= i810_readb(CR_DATA_CGA
, mmio
);
622 i810_writeb(CR_INDEX_CGA
, mmio
, CR70
);
623 par
->hw_state
.cr70
= i810_readb(CR_DATA_CGA
, mmio
);
624 par
->hw_state
.msr
= i810_readb(MSR_READ
, mmio
);
625 i810_writeb(CR_INDEX_CGA
, mmio
, CR80
);
626 par
->hw_state
.cr80
= i810_readb(CR_DATA_CGA
, mmio
);
627 i810_writeb(SR_INDEX
, mmio
, SR01
);
628 par
->hw_state
.sr01
= i810_readb(SR_DATA
, mmio
);
631 static void i810_save_vga(struct i810fb_par
*par
)
634 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
636 for (i
= 0; i
< 10; i
++) {
637 i810_writeb(CR_INDEX_CGA
, mmio
, CR00
+ i
);
638 *((&par
->hw_state
.cr00
) + i
) = i810_readb(CR_DATA_CGA
, mmio
);
640 for (i
= 0; i
< 8; i
++) {
641 i810_writeb(CR_INDEX_CGA
, mmio
, CR10
+ i
);
642 *((&par
->hw_state
.cr10
) + i
) = i810_readb(CR_DATA_CGA
, mmio
);
646 static void i810_save_2d(struct i810fb_par
*par
)
648 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
650 par
->hw_state
.dclk_2d
= i810_readl(DCLK_2D
, mmio
);
651 par
->hw_state
.dclk_1d
= i810_readl(DCLK_1D
, mmio
);
652 par
->hw_state
.dclk_0ds
= i810_readl(DCLK_0DS
, mmio
);
653 par
->hw_state
.pixconf
= i810_readl(PIXCONF
, mmio
);
654 par
->hw_state
.fw_blc
= i810_readl(FW_BLC
, mmio
);
655 par
->hw_state
.bltcntl
= i810_readw(BLTCNTL
, mmio
);
656 par
->hw_state
.hwstam
= i810_readw(HWSTAM
, mmio
);
657 par
->hw_state
.hws_pga
= i810_readl(HWS_PGA
, mmio
);
658 par
->hw_state
.ier
= i810_readw(IER
, mmio
);
659 par
->hw_state
.imr
= i810_readw(IMR
, mmio
);
660 par
->hw_state
.dplystas
= i810_readl(DPLYSTAS
, mmio
);
663 static void i810_save_vga_state(struct i810fb_par
*par
)
670 /************************************************************
672 ************************************************************/
674 * get_line_length - calculates buffer pitch in bytes
675 * @par: pointer to i810fb_par structure
676 * @xres_virtual: virtual resolution of the frame
677 * @bpp: bits per pixel
680 * Calculates buffer pitch in bytes.
682 static u32
get_line_length(struct i810fb_par
*par
, int xres_virtual
, int bpp
)
686 length
= xres_virtual
*bpp
;
687 length
= (length
+31)&-32;
693 * i810_calc_dclk - calculates the P, M, and N values of a pixelclock value
694 * @freq: target pixelclock in picoseconds
695 * @m: where to write M register
696 * @n: where to write N register
697 * @p: where to write P register
700 * Based on the formula Freq_actual = (4*M*Freq_ref)/(N^P)
701 * Repeatedly computes the Freq until the actual Freq is equal to
702 * the target Freq or until the loop count is zero. In the latter
703 * case, the actual frequency nearest the target will be used.
705 static void i810_calc_dclk(u32 freq
, u32
*m
, u32
*n
, u32
*p
)
707 u32 m_reg
, n_reg
, p_divisor
, n_target_max
;
708 u32 m_target
, n_target
, p_target
, n_best
, m_best
, mod
;
709 u32 f_out
, target_freq
, diff
= 0, mod_min
, diff_min
;
711 diff_min
= mod_min
= 0xFFFFFFFF;
712 n_best
= m_best
= m_target
= f_out
= 0;
718 * find P such that target freq is 16x reference freq (Hz).
722 while(!((1000000 * p_divisor
)/(16 * 24 * target_freq
)) &&
728 n_reg
= m_reg
= n_target
= 3;
729 while (diff_min
&& mod_min
&& (n_target
< n_target_max
)) {
730 f_out
= (p_divisor
* n_reg
* 1000000)/(4 * 24 * m_reg
);
731 mod
= (p_divisor
* n_reg
* 1000000) % (4 * 24 * m_reg
);
734 if (f_out
<= target_freq
) {
736 diff
= target_freq
- f_out
;
739 diff
= f_out
- target_freq
;
742 if (diff_min
> diff
) {
748 if (!diff
&& mod_min
> mod
) {
754 if (m
) *m
= (m_best
- 2) & 0x3FF;
755 if (n
) *n
= (n_best
- 2) & 0x3FF;
756 if (p
) *p
= (p_target
<< 4);
759 /*************************************************************
760 * Hardware Cursor Routines *
761 *************************************************************/
764 * i810_enable_cursor - show or hide the hardware cursor
765 * @mmio: address of register space
766 * @mode: show (1) or hide (0)
769 * Shows or hides the hardware cursor
771 static void i810_enable_cursor(u8 __iomem
*mmio
, int mode
)
775 temp
= i810_readl(PIXCONF
, mmio
);
776 temp
= (mode
== ON
) ? temp
| CURSOR_ENABLE_MASK
:
777 temp
& ~CURSOR_ENABLE_MASK
;
779 i810_writel(PIXCONF
, mmio
, temp
);
782 static void i810_reset_cursor_image(struct i810fb_par
*par
)
784 u8 __iomem
*addr
= par
->cursor_heap
.virtual;
787 for (i
= 64; i
--; ) {
788 for (j
= 0; j
< 8; j
++) {
789 i810_writeb(j
, addr
, 0xff);
790 i810_writeb(j
+8, addr
, 0x00);
796 static void i810_load_cursor_image(int width
, int height
, u8
*data
,
797 struct i810fb_par
*par
)
799 u8 __iomem
*addr
= par
->cursor_heap
.virtual;
800 int i
, j
, w
= width
/8;
801 int mod
= width
% 8, t_mask
, d_mask
;
803 t_mask
= 0xff >> mod
;
804 d_mask
= ~(0xff >> mod
);
805 for (i
= height
; i
--; ) {
806 for (j
= 0; j
< w
; j
++) {
807 i810_writeb(j
+0, addr
, 0x00);
808 i810_writeb(j
+8, addr
, *data
++);
811 i810_writeb(j
+0, addr
, t_mask
);
812 i810_writeb(j
+8, addr
, *data
++ & d_mask
);
818 static void i810_load_cursor_colors(int fg
, int bg
, struct fb_info
*info
)
820 struct i810fb_par
*par
= info
->par
;
821 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
822 u8 red
, green
, blue
, trans
, temp
;
824 i810fb_getcolreg(bg
, &red
, &green
, &blue
, &trans
, info
);
826 temp
= i810_readb(PIXCONF1
, mmio
);
827 i810_writeb(PIXCONF1
, mmio
, temp
| EXTENDED_PALETTE
);
829 i810_write_dac(4, red
, green
, blue
, mmio
);
831 i810_writeb(PIXCONF1
, mmio
, temp
);
833 i810fb_getcolreg(fg
, &red
, &green
, &blue
, &trans
, info
);
834 temp
= i810_readb(PIXCONF1
, mmio
);
835 i810_writeb(PIXCONF1
, mmio
, temp
| EXTENDED_PALETTE
);
837 i810_write_dac(5, red
, green
, blue
, mmio
);
839 i810_writeb(PIXCONF1
, mmio
, temp
);
843 * i810_init_cursor - initializes the cursor
844 * @par: pointer to i810fb_par structure
847 * Initializes the cursor registers
849 static void i810_init_cursor(struct i810fb_par
*par
)
851 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
853 i810_enable_cursor(mmio
, OFF
);
854 i810_writel(CURBASE
, mmio
, par
->cursor_heap
.physical
);
855 i810_writew(CURCNTR
, mmio
, COORD_ACTIVE
| CURSOR_MODE_64_XOR
);
858 /*********************************************************************
859 * Framebuffer hook helpers *
860 *********************************************************************/
862 * i810_round_off - Round off values to capability of hardware
863 * @var: pointer to fb_var_screeninfo structure
866 * @var contains user-defined information for the mode to be set.
867 * This will try modify those values to ones nearest the
868 * capability of the hardware
870 static void i810_round_off(struct fb_var_screeninfo
*var
)
872 u32 xres
, yres
, vxres
, vyres
;
875 * Presently supports only these configurations
880 vxres
= var
->xres_virtual
;
881 vyres
= var
->yres_virtual
;
883 var
->bits_per_pixel
+= 7;
884 var
->bits_per_pixel
&= ~7;
886 if (var
->bits_per_pixel
< 8)
887 var
->bits_per_pixel
= 8;
888 if (var
->bits_per_pixel
> 32)
889 var
->bits_per_pixel
= 32;
891 round_off_xres(&xres
);
896 xres
= (xres
+ 7) & ~7;
901 round_off_yres(&xres
, &yres
);
910 if (var
->bits_per_pixel
== 32)
911 var
->accel_flags
= 0;
913 /* round of horizontal timings to nearest 8 pixels */
914 var
->left_margin
= (var
->left_margin
+ 4) & ~7;
915 var
->right_margin
= (var
->right_margin
+ 4) & ~7;
916 var
->hsync_len
= (var
->hsync_len
+ 4) & ~7;
918 if (var
->vmode
& FB_VMODE_INTERLACED
) {
919 if (!((yres
+ var
->upper_margin
+ var
->vsync_len
+
920 var
->lower_margin
) & 1))
926 var
->xres_virtual
= vxres
;
927 var
->yres_virtual
= vyres
;
931 * set_color_bitfields - sets rgba fields
932 * @var: pointer to fb_var_screeninfo
935 * The length, offset and ordering for each color field
936 * (red, green, blue) will be set as specified
939 static void set_color_bitfields(struct fb_var_screeninfo
*var
)
941 switch (var
->bits_per_pixel
) {
945 var
->green
.offset
= 0;
946 var
->green
.length
= 8;
947 var
->blue
.offset
= 0;
948 var
->blue
.length
= 8;
949 var
->transp
.offset
= 0;
950 var
->transp
.length
= 0;
953 var
->green
.length
= (var
->green
.length
== 5) ? 5 : 6;
955 var
->blue
.length
= 5;
956 var
->transp
.length
= 6 - var
->green
.length
;
957 var
->blue
.offset
= 0;
958 var
->green
.offset
= 5;
959 var
->red
.offset
= 5 + var
->green
.length
;
960 var
->transp
.offset
= (5 + var
->red
.offset
) & 15;
962 case 24: /* RGB 888 */
963 case 32: /* RGBA 8888 */
964 var
->red
.offset
= 16;
966 var
->green
.offset
= 8;
967 var
->green
.length
= 8;
968 var
->blue
.offset
= 0;
969 var
->blue
.length
= 8;
970 var
->transp
.length
= var
->bits_per_pixel
- 24;
971 var
->transp
.offset
= (var
->transp
.length
) ? 24 : 0;
974 var
->red
.msb_right
= 0;
975 var
->green
.msb_right
= 0;
976 var
->blue
.msb_right
= 0;
977 var
->transp
.msb_right
= 0;
981 * i810_check_params - check if contents in var are valid
982 * @var: pointer to fb_var_screeninfo
983 * @info: pointer to fb_info
986 * This will check if the framebuffer size is sufficient
987 * for the current mode and if the user's monitor has the
988 * required specifications to display the current mode.
990 static int i810_check_params(struct fb_var_screeninfo
*var
,
991 struct fb_info
*info
)
993 struct i810fb_par
*par
= info
->par
;
994 int line_length
, vidmem
, mode_valid
= 0, retval
= 0;
995 u32 vyres
= var
->yres_virtual
, vxres
= var
->xres_virtual
;
1000 line_length
= get_line_length(par
, vxres
, var
->bits_per_pixel
);
1001 vidmem
= line_length
*vyres
;
1003 if (vidmem
> par
->fb
.size
) {
1004 vyres
= par
->fb
.size
/line_length
;
1005 if (vyres
< var
->yres
) {
1006 vyres
= info
->var
.yres
;
1007 vxres
= par
->fb
.size
/vyres
;
1008 vxres
/= var
->bits_per_pixel
>> 3;
1009 line_length
= get_line_length(par
, vxres
,
1010 var
->bits_per_pixel
);
1011 vidmem
= line_length
* info
->var
.yres
;
1012 if (vxres
< var
->xres
) {
1013 printk("i810fb: required video memory, "
1014 "%d bytes, for %dx%d-%d (virtual) "
1015 "is out of range\n",
1016 vidmem
, vxres
, vyres
,
1017 var
->bits_per_pixel
);
1023 var
->xres_virtual
= vxres
;
1024 var
->yres_virtual
= vyres
;
1029 switch (var
->bits_per_pixel
) {
1031 info
->monspecs
.dclkmax
= 234000000;
1034 info
->monspecs
.dclkmax
= 229000000;
1038 info
->monspecs
.dclkmax
= 204000000;
1042 info
->monspecs
.dclkmin
= 15000000;
1044 if (!fb_validate_mode(var
, info
))
1047 #ifdef CONFIG_FB_I810_I2C
1048 if (!mode_valid
&& info
->monspecs
.gtf
&&
1049 !fb_get_mode(FB_MAXTIMINGS
, 0, var
, info
))
1052 if (!mode_valid
&& info
->monspecs
.modedb_len
) {
1053 const struct fb_videomode
*mode
;
1055 mode
= fb_find_best_mode(var
, &info
->modelist
);
1057 fb_videomode_to_var(var
, mode
);
1062 if (!mode_valid
&& info
->monspecs
.modedb_len
== 0) {
1063 if (fb_get_mode(FB_MAXTIMINGS
, 0, var
, info
)) {
1064 int default_sync
= (info
->monspecs
.hfmin
-HFMIN
)
1065 |(info
->monspecs
.hfmax
-HFMAX
)
1066 |(info
->monspecs
.vfmin
-VFMIN
)
1067 |(info
->monspecs
.vfmax
-VFMAX
);
1068 printk("i810fb: invalid video mode%s\n",
1069 default_sync
? "" : ". Specifying "
1070 "vsyncN/hsyncN parameters may help");
1079 * encode_fix - fill up fb_fix_screeninfo structure
1080 * @fix: pointer to fb_fix_screeninfo
1081 * @info: pointer to fb_info
1084 * This will set up parameters that are unmodifiable by the user.
1086 static int encode_fix(struct fb_fix_screeninfo
*fix
, struct fb_info
*info
)
1088 struct i810fb_par
*par
= info
->par
;
1090 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
1092 strcpy(fix
->id
, "I810");
1093 mutex_lock(&info
->mm_lock
);
1094 fix
->smem_start
= par
->fb
.physical
;
1095 fix
->smem_len
= par
->fb
.size
;
1096 mutex_unlock(&info
->mm_lock
);
1097 fix
->type
= FB_TYPE_PACKED_PIXELS
;
1102 switch (info
->var
.bits_per_pixel
) {
1104 fix
->visual
= FB_VISUAL_PSEUDOCOLOR
;
1109 if (info
->var
.nonstd
)
1110 fix
->visual
= FB_VISUAL_DIRECTCOLOR
;
1112 fix
->visual
= FB_VISUAL_TRUECOLOR
;
1118 fix
->line_length
= par
->pitch
;
1119 fix
->mmio_start
= par
->mmio_start_phys
;
1120 fix
->mmio_len
= MMIO_SIZE
;
1121 fix
->accel
= FB_ACCEL_I810
;
1127 * decode_var - modify par according to contents of var
1128 * @var: pointer to fb_var_screeninfo
1129 * @par: pointer to i810fb_par
1132 * Based on the contents of @var, @par will be dynamically filled up.
1133 * @par contains all information necessary to modify the hardware.
1135 static void decode_var(const struct fb_var_screeninfo
*var
,
1136 struct i810fb_par
*par
)
1138 u32 xres
, yres
, vxres
, vyres
;
1142 vxres
= var
->xres_virtual
;
1143 vyres
= var
->yres_virtual
;
1145 switch (var
->bits_per_pixel
) {
1147 par
->pixconf
= PIXCONF8
;
1150 par
->blit_bpp
= BPP8
;
1153 if (var
->green
.length
== 5)
1154 par
->pixconf
= PIXCONF15
;
1156 par
->pixconf
= PIXCONF16
;
1159 par
->blit_bpp
= BPP16
;
1162 par
->pixconf
= PIXCONF24
;
1165 par
->blit_bpp
= BPP24
;
1168 par
->pixconf
= PIXCONF32
;
1171 par
->blit_bpp
= 3 << 24;
1174 if (var
->nonstd
&& var
->bits_per_pixel
!= 8)
1175 par
->pixconf
|= 1 << 27;
1177 i810_calc_dclk(var
->pixclock
, &par
->regs
.M
,
1178 &par
->regs
.N
, &par
->regs
.P
);
1179 i810fb_encode_registers(var
, par
, xres
, yres
);
1181 par
->watermark
= i810_get_watermark(var
, par
);
1182 par
->pitch
= get_line_length(par
, vxres
, var
->bits_per_pixel
);
1186 * i810fb_getcolreg - gets red, green and blue values of the hardware DAC
1191 * @transp: transparency (alpha)
1192 * @info: pointer to fb_info
1195 * Gets the red, green and blue values of the hardware DAC as pointed by @regno
1196 * and writes them to @red, @green and @blue respectively
1198 static int i810fb_getcolreg(u8 regno
, u8
*red
, u8
*green
, u8
*blue
,
1199 u8
*transp
, struct fb_info
*info
)
1201 struct i810fb_par
*par
= info
->par
;
1202 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
1205 if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
1206 if ((info
->var
.green
.length
== 5 && regno
> 31) ||
1207 (info
->var
.green
.length
== 6 && regno
> 63))
1211 temp
= i810_readb(PIXCONF1
, mmio
);
1212 i810_writeb(PIXCONF1
, mmio
, temp
& ~EXTENDED_PALETTE
);
1214 if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
&&
1215 info
->var
.green
.length
== 5)
1216 i810_read_dac(regno
* 8, red
, green
, blue
, mmio
);
1218 else if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
&&
1219 info
->var
.green
.length
== 6) {
1222 i810_read_dac(regno
* 8, red
, &tmp
, blue
, mmio
);
1223 i810_read_dac(regno
* 4, &tmp
, green
, &tmp
, mmio
);
1226 i810_read_dac(regno
, red
, green
, blue
, mmio
);
1229 i810_writeb(PIXCONF1
, mmio
, temp
);
1234 /******************************************************************
1235 * Framebuffer device-specific hooks *
1236 ******************************************************************/
1238 static int i810fb_open(struct fb_info
*info
, int user
)
1240 struct i810fb_par
*par
= info
->par
;
1242 mutex_lock(&par
->open_lock
);
1243 if (par
->use_count
== 0) {
1244 memset(&par
->state
, 0, sizeof(struct vgastate
));
1245 par
->state
.flags
= VGA_SAVE_CMAP
;
1246 par
->state
.vgabase
= par
->mmio_start_virtual
;
1247 save_vga(&par
->state
);
1249 i810_save_vga_state(par
);
1253 mutex_unlock(&par
->open_lock
);
1258 static int i810fb_release(struct fb_info
*info
, int user
)
1260 struct i810fb_par
*par
= info
->par
;
1262 mutex_lock(&par
->open_lock
);
1263 if (par
->use_count
== 0) {
1264 mutex_unlock(&par
->open_lock
);
1268 if (par
->use_count
== 1) {
1269 i810_restore_vga_state(par
);
1270 restore_vga(&par
->state
);
1274 mutex_unlock(&par
->open_lock
);
1280 static int i810fb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
1281 unsigned blue
, unsigned transp
,
1282 struct fb_info
*info
)
1284 struct i810fb_par
*par
= info
->par
;
1285 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
1289 if (regno
> 255) return 1;
1291 if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
1292 if ((info
->var
.green
.length
== 5 && regno
> 31) ||
1293 (info
->var
.green
.length
== 6 && regno
> 63))
1297 if (info
->var
.grayscale
)
1298 red
= green
= blue
= (19595 * red
+ 38470 * green
+
1301 temp
= i810_readb(PIXCONF1
, mmio
);
1302 i810_writeb(PIXCONF1
, mmio
, temp
& ~EXTENDED_PALETTE
);
1304 if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
&&
1305 info
->var
.green
.length
== 5) {
1306 for (i
= 0; i
< 8; i
++)
1307 i810_write_dac((u8
) (regno
* 8) + i
, (u8
) red
,
1308 (u8
) green
, (u8
) blue
, mmio
);
1309 } else if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
&&
1310 info
->var
.green
.length
== 6) {
1314 for (i
= 0; i
< 8; i
++)
1315 i810_write_dac((u8
) (regno
* 8) + i
,
1316 (u8
) red
, (u8
) green
,
1319 i810_read_dac((u8
) (regno
*4), &r
, &g
, &b
, mmio
);
1320 for (i
= 0; i
< 4; i
++)
1321 i810_write_dac((u8
) (regno
*4) + i
, r
, (u8
) green
,
1323 } else if (info
->fix
.visual
== FB_VISUAL_PSEUDOCOLOR
) {
1324 i810_write_dac((u8
) regno
, (u8
) red
, (u8
) green
,
1328 i810_writeb(PIXCONF1
, mmio
, temp
);
1331 switch (info
->var
.bits_per_pixel
) {
1333 if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
) {
1334 if (info
->var
.green
.length
== 5)
1335 ((u32
*)info
->pseudo_palette
)[regno
] =
1336 (regno
<< 10) | (regno
<< 5) |
1339 ((u32
*)info
->pseudo_palette
)[regno
] =
1340 (regno
<< 11) | (regno
<< 5) |
1343 if (info
->var
.green
.length
== 5) {
1345 ((u32
*)info
->pseudo_palette
)[regno
] =
1346 ((red
& 0xf800) >> 1) |
1347 ((green
& 0xf800) >> 6) |
1348 ((blue
& 0xf800) >> 11);
1351 ((u32
*)info
->pseudo_palette
)[regno
] =
1353 ((green
& 0xf800) >> 5) |
1354 ((blue
& 0xf800) >> 11);
1358 case 24: /* RGB 888 */
1359 case 32: /* RGBA 8888 */
1360 if (info
->fix
.visual
== FB_VISUAL_DIRECTCOLOR
)
1361 ((u32
*)info
->pseudo_palette
)[regno
] =
1362 (regno
<< 16) | (regno
<< 8) |
1365 ((u32
*)info
->pseudo_palette
)[regno
] =
1366 ((red
& 0xff00) << 8) |
1368 ((blue
& 0xff00) >> 8);
1375 static int i810fb_pan_display(struct fb_var_screeninfo
*var
,
1376 struct fb_info
*info
)
1378 struct i810fb_par
*par
= info
->par
;
1381 total
= var
->xoffset
* par
->depth
+
1382 var
->yoffset
* info
->fix
.line_length
;
1383 i810fb_load_front(total
, info
);
1388 static int i810fb_blank (int blank_mode
, struct fb_info
*info
)
1390 struct i810fb_par
*par
= info
->par
;
1391 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
1392 int mode
= 0, pwr
, scr_off
= 0;
1394 pwr
= i810_readl(PWR_CLKC
, mmio
);
1396 switch (blank_mode
) {
1397 case FB_BLANK_UNBLANK
:
1402 case FB_BLANK_NORMAL
:
1407 case FB_BLANK_VSYNC_SUSPEND
:
1412 case FB_BLANK_HSYNC_SUSPEND
:
1417 case FB_BLANK_POWERDOWN
:
1426 i810_screen_off(mmio
, scr_off
);
1427 i810_writel(HVSYNC
, mmio
, mode
);
1428 i810_writel(PWR_CLKC
, mmio
, pwr
);
1433 static int i810fb_set_par(struct fb_info
*info
)
1435 struct i810fb_par
*par
= info
->par
;
1437 decode_var(&info
->var
, par
);
1438 i810_load_regs(par
);
1439 i810_init_cursor(par
);
1440 encode_fix(&info
->fix
, info
);
1442 if (info
->var
.accel_flags
&& !(par
->dev_flags
& LOCKUP
)) {
1443 info
->flags
= FBINFO_DEFAULT
| FBINFO_HWACCEL_YPAN
|
1444 FBINFO_HWACCEL_COPYAREA
| FBINFO_HWACCEL_FILLRECT
|
1445 FBINFO_HWACCEL_IMAGEBLIT
;
1446 info
->pixmap
.scan_align
= 2;
1448 info
->pixmap
.scan_align
= 1;
1449 info
->flags
= FBINFO_DEFAULT
| FBINFO_HWACCEL_YPAN
;
1454 static int i810fb_check_var(struct fb_var_screeninfo
*var
,
1455 struct fb_info
*info
)
1460 var
->vmode
&= ~FB_VMODE_MASK
;
1461 var
->vmode
|= FB_VMODE_NONINTERLACED
;
1463 if (var
->vmode
& FB_VMODE_DOUBLE
) {
1464 var
->vmode
&= ~FB_VMODE_MASK
;
1465 var
->vmode
|= FB_VMODE_NONINTERLACED
;
1468 i810_round_off(var
);
1469 if ((err
= i810_check_params(var
, info
)))
1472 i810fb_fill_var_timings(var
);
1473 set_color_bitfields(var
);
1477 static int i810fb_cursor(struct fb_info
*info
, struct fb_cursor
*cursor
)
1479 struct i810fb_par
*par
= info
->par
;
1480 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
1482 if (par
->dev_flags
& LOCKUP
)
1485 if (cursor
->image
.width
> 64 || cursor
->image
.height
> 64)
1488 if ((i810_readl(CURBASE
, mmio
) & 0xf) != par
->cursor_heap
.physical
) {
1489 i810_init_cursor(par
);
1490 cursor
->set
|= FB_CUR_SETALL
;
1493 i810_enable_cursor(mmio
, OFF
);
1495 if (cursor
->set
& FB_CUR_SETPOS
) {
1498 tmp
= (cursor
->image
.dx
- info
->var
.xoffset
) & 0xffff;
1499 tmp
|= (cursor
->image
.dy
- info
->var
.yoffset
) << 16;
1500 i810_writel(CURPOS
, mmio
, tmp
);
1503 if (cursor
->set
& FB_CUR_SETSIZE
)
1504 i810_reset_cursor_image(par
);
1506 if (cursor
->set
& FB_CUR_SETCMAP
)
1507 i810_load_cursor_colors(cursor
->image
.fg_color
,
1508 cursor
->image
.bg_color
,
1511 if (cursor
->set
& (FB_CUR_SETSHAPE
| FB_CUR_SETIMAGE
)) {
1512 int size
= ((cursor
->image
.width
+ 7) >> 3) *
1513 cursor
->image
.height
;
1515 u8
*data
= kmalloc(64 * 8, GFP_ATOMIC
);
1520 switch (cursor
->rop
) {
1522 for (i
= 0; i
< size
; i
++)
1523 data
[i
] = cursor
->image
.data
[i
] ^ cursor
->mask
[i
];
1527 for (i
= 0; i
< size
; i
++)
1528 data
[i
] = cursor
->image
.data
[i
] & cursor
->mask
[i
];
1532 i810_load_cursor_image(cursor
->image
.width
,
1533 cursor
->image
.height
, data
,
1539 i810_enable_cursor(mmio
, ON
);
1544 static struct fb_ops i810fb_ops __devinitdata
= {
1545 .owner
= THIS_MODULE
,
1546 .fb_open
= i810fb_open
,
1547 .fb_release
= i810fb_release
,
1548 .fb_check_var
= i810fb_check_var
,
1549 .fb_set_par
= i810fb_set_par
,
1550 .fb_setcolreg
= i810fb_setcolreg
,
1551 .fb_blank
= i810fb_blank
,
1552 .fb_pan_display
= i810fb_pan_display
,
1553 .fb_fillrect
= i810fb_fillrect
,
1554 .fb_copyarea
= i810fb_copyarea
,
1555 .fb_imageblit
= i810fb_imageblit
,
1556 .fb_cursor
= i810fb_cursor
,
1557 .fb_sync
= i810fb_sync
,
1560 /***********************************************************************
1561 * Power Management *
1562 ***********************************************************************/
1563 static int i810fb_suspend(struct pci_dev
*dev
, pm_message_t mesg
)
1565 struct fb_info
*info
= pci_get_drvdata(dev
);
1566 struct i810fb_par
*par
= info
->par
;
1568 par
->cur_state
= mesg
.event
;
1570 switch (mesg
.event
) {
1571 case PM_EVENT_FREEZE
:
1572 case PM_EVENT_PRETHAW
:
1573 dev
->dev
.power
.power_state
= mesg
;
1577 acquire_console_sem();
1578 fb_set_suspend(info
, 1);
1580 if (info
->fbops
->fb_sync
)
1581 info
->fbops
->fb_sync(info
);
1583 i810fb_blank(FB_BLANK_POWERDOWN
, info
);
1584 agp_unbind_memory(par
->i810_gtt
.i810_fb_memory
);
1585 agp_unbind_memory(par
->i810_gtt
.i810_cursor_memory
);
1587 pci_save_state(dev
);
1588 pci_disable_device(dev
);
1589 pci_set_power_state(dev
, pci_choose_state(dev
, mesg
));
1590 release_console_sem();
1595 static int i810fb_resume(struct pci_dev
*dev
)
1597 struct fb_info
*info
= pci_get_drvdata(dev
);
1598 struct i810fb_par
*par
= info
->par
;
1599 int cur_state
= par
->cur_state
;
1601 par
->cur_state
= PM_EVENT_ON
;
1603 if (cur_state
== PM_EVENT_FREEZE
) {
1604 pci_set_power_state(dev
, PCI_D0
);
1608 acquire_console_sem();
1609 pci_set_power_state(dev
, PCI_D0
);
1610 pci_restore_state(dev
);
1612 if (pci_enable_device(dev
))
1615 pci_set_master(dev
);
1616 agp_bind_memory(par
->i810_gtt
.i810_fb_memory
,
1618 agp_bind_memory(par
->i810_gtt
.i810_cursor_memory
,
1619 par
->cursor_heap
.offset
);
1620 i810fb_set_par(info
);
1621 fb_set_suspend (info
, 0);
1622 info
->fbops
->fb_blank(VESA_NO_BLANKING
, info
);
1624 release_console_sem();
1627 /***********************************************************************
1628 * AGP resource allocation *
1629 ***********************************************************************/
1631 static void __devinit
i810_fix_pointers(struct i810fb_par
*par
)
1633 par
->fb
.physical
= par
->aperture
.physical
+(par
->fb
.offset
<< 12);
1634 par
->fb
.virtual = par
->aperture
.virtual+(par
->fb
.offset
<< 12);
1635 par
->iring
.physical
= par
->aperture
.physical
+
1636 (par
->iring
.offset
<< 12);
1637 par
->iring
.virtual = par
->aperture
.virtual +
1638 (par
->iring
.offset
<< 12);
1639 par
->cursor_heap
.virtual = par
->aperture
.virtual+
1640 (par
->cursor_heap
.offset
<< 12);
1643 static void __devinit
i810_fix_offsets(struct i810fb_par
*par
)
1645 if (vram
+ 1 > par
->aperture
.size
>> 20)
1646 vram
= (par
->aperture
.size
>> 20) - 1;
1647 if (v_offset_default
> (par
->aperture
.size
>> 20))
1648 v_offset_default
= (par
->aperture
.size
>> 20);
1649 if (vram
+ v_offset_default
+ 1 > par
->aperture
.size
>> 20)
1650 v_offset_default
= (par
->aperture
.size
>> 20) - (vram
+ 1);
1652 par
->fb
.size
= vram
<< 20;
1653 par
->fb
.offset
= v_offset_default
<< 20;
1654 par
->fb
.offset
>>= 12;
1656 par
->iring
.offset
= par
->fb
.offset
+ (par
->fb
.size
>> 12);
1657 par
->iring
.size
= RINGBUFFER_SIZE
;
1659 par
->cursor_heap
.offset
= par
->iring
.offset
+ (RINGBUFFER_SIZE
>> 12);
1660 par
->cursor_heap
.size
= 4096;
1663 static int __devinit
i810_alloc_agp_mem(struct fb_info
*info
)
1665 struct i810fb_par
*par
= info
->par
;
1667 struct agp_bridge_data
*bridge
;
1669 i810_fix_offsets(par
);
1670 size
= par
->fb
.size
+ par
->iring
.size
;
1672 if (!(bridge
= agp_backend_acquire(par
->dev
))) {
1673 printk("i810fb_alloc_fbmem: cannot acquire agpgart\n");
1676 if (!(par
->i810_gtt
.i810_fb_memory
=
1677 agp_allocate_memory(bridge
, size
>> 12, AGP_NORMAL_MEMORY
))) {
1678 printk("i810fb_alloc_fbmem: can't allocate framebuffer "
1680 agp_backend_release(bridge
);
1683 if (agp_bind_memory(par
->i810_gtt
.i810_fb_memory
,
1685 printk("i810fb_alloc_fbmem: can't bind framebuffer memory\n");
1686 agp_backend_release(bridge
);
1690 if (!(par
->i810_gtt
.i810_cursor_memory
=
1691 agp_allocate_memory(bridge
, par
->cursor_heap
.size
>> 12,
1692 AGP_PHYSICAL_MEMORY
))) {
1693 printk("i810fb_alloc_cursormem: can't allocate"
1695 agp_backend_release(bridge
);
1698 if (agp_bind_memory(par
->i810_gtt
.i810_cursor_memory
,
1699 par
->cursor_heap
.offset
)) {
1700 printk("i810fb_alloc_cursormem: cannot bind cursor memory\n");
1701 agp_backend_release(bridge
);
1705 par
->cursor_heap
.physical
= par
->i810_gtt
.i810_cursor_memory
->physical
;
1707 i810_fix_pointers(par
);
1709 agp_backend_release(bridge
);
1714 /***************************************************************
1716 ***************************************************************/
1719 * i810_init_monspecs
1720 * @info: pointer to device specific info structure
1723 * Sets the user monitor's horizontal and vertical
1726 static void __devinit
i810_init_monspecs(struct fb_info
*info
)
1732 if (!info
->monspecs
.hfmax
)
1733 info
->monspecs
.hfmax
= hsync2
;
1734 if (!info
->monspecs
.hfmin
)
1735 info
->monspecs
.hfmin
= hsync1
;
1736 if (hsync2
< hsync1
)
1737 info
->monspecs
.hfmin
= hsync2
;
1743 if (IS_DVT
&& vsync1
< 60)
1745 if (!info
->monspecs
.vfmax
)
1746 info
->monspecs
.vfmax
= vsync2
;
1747 if (!info
->monspecs
.vfmin
)
1748 info
->monspecs
.vfmin
= vsync1
;
1749 if (vsync2
< vsync1
)
1750 info
->monspecs
.vfmin
= vsync2
;
1754 * i810_init_defaults - initializes default values to use
1755 * @par: pointer to i810fb_par structure
1756 * @info: pointer to current fb_info structure
1758 static void __devinit
i810_init_defaults(struct i810fb_par
*par
,
1759 struct fb_info
*info
)
1761 mutex_init(&par
->open_lock
);
1764 v_offset_default
= voffset
;
1765 else if (par
->aperture
.size
> 32 * 1024 * 1024)
1766 v_offset_default
= 16;
1768 v_offset_default
= 8;
1774 par
->dev_flags
|= HAS_ACCELERATION
;
1777 par
->dev_flags
|= ALWAYS_SYNC
;
1779 par
->ddc_num
= ddc3
;
1784 par
->i810fb_ops
= i810fb_ops
;
1787 info
->var
.xres
= xres
;
1789 info
->var
.xres
= 640;
1792 info
->var
.yres
= yres
;
1794 info
->var
.yres
= 480;
1797 vyres
= (vram
<< 20)/(info
->var
.xres
*bpp
>> 3);
1799 info
->var
.yres_virtual
= vyres
;
1800 info
->var
.bits_per_pixel
= bpp
;
1803 info
->var
.nonstd
= 1;
1805 if (par
->dev_flags
& HAS_ACCELERATION
)
1806 info
->var
.accel_flags
= 1;
1808 i810_init_monspecs(info
);
1812 * i810_init_device - initialize device
1813 * @par: pointer to i810fb_par structure
1815 static void __devinit
i810_init_device(struct i810fb_par
*par
)
1818 u8 __iomem
*mmio
= par
->mmio_start_virtual
;
1820 if (mtrr
) set_mtrr(par
);
1822 i810_init_cursor(par
);
1824 /* mvo: enable external vga-connector (for laptops) */
1826 i810_writel(HVSYNC
, mmio
, 0);
1827 i810_writel(PWR_CLKC
, mmio
, 3);
1830 pci_read_config_byte(par
->dev
, 0x50, ®
);
1832 par
->mem_freq
= (reg
) ? 133 : 100;
1836 static int __devinit
1837 i810_allocate_pci_resource(struct i810fb_par
*par
,
1838 const struct pci_device_id
*entry
)
1842 if ((err
= pci_enable_device(par
->dev
))) {
1843 printk("i810fb_init: cannot enable device\n");
1846 par
->res_flags
|= PCI_DEVICE_ENABLED
;
1848 if (pci_resource_len(par
->dev
, 0) > 512 * 1024) {
1849 par
->aperture
.physical
= pci_resource_start(par
->dev
, 0);
1850 par
->aperture
.size
= pci_resource_len(par
->dev
, 0);
1851 par
->mmio_start_phys
= pci_resource_start(par
->dev
, 1);
1853 par
->aperture
.physical
= pci_resource_start(par
->dev
, 1);
1854 par
->aperture
.size
= pci_resource_len(par
->dev
, 1);
1855 par
->mmio_start_phys
= pci_resource_start(par
->dev
, 0);
1857 if (!par
->aperture
.size
) {
1858 printk("i810fb_init: device is disabled\n");
1862 if (!request_mem_region(par
->aperture
.physical
,
1864 i810_pci_list
[entry
->driver_data
])) {
1865 printk("i810fb_init: cannot request framebuffer region\n");
1868 par
->res_flags
|= FRAMEBUFFER_REQ
;
1870 par
->aperture
.virtual = ioremap_nocache(par
->aperture
.physical
,
1871 par
->aperture
.size
);
1872 if (!par
->aperture
.virtual) {
1873 printk("i810fb_init: cannot remap framebuffer region\n");
1877 if (!request_mem_region(par
->mmio_start_phys
,
1879 i810_pci_list
[entry
->driver_data
])) {
1880 printk("i810fb_init: cannot request mmio region\n");
1883 par
->res_flags
|= MMIO_REQ
;
1885 par
->mmio_start_virtual
= ioremap_nocache(par
->mmio_start_phys
,
1887 if (!par
->mmio_start_virtual
) {
1888 printk("i810fb_init: cannot remap mmio region\n");
1895 static void __devinit
i810fb_find_init_mode(struct fb_info
*info
)
1897 struct fb_videomode mode
;
1898 struct fb_var_screeninfo var
;
1899 struct fb_monspecs
*specs
= &info
->monspecs
;
1901 #ifdef CONFIG_FB_I810_I2C
1904 struct i810fb_par
*par
= info
->par
;
1907 INIT_LIST_HEAD(&info
->modelist
);
1908 memset(&mode
, 0, sizeof(struct fb_videomode
));
1910 #ifdef CONFIG_FB_I810_I2C
1911 i810_create_i2c_busses(par
);
1913 for (i
= 0; i
< par
->ddc_num
+ 1; i
++) {
1914 err
= i810_probe_i2c_connector(info
, &par
->edid
, i
);
1920 printk("i810fb_init_pci: DDC probe successful\n");
1922 fb_edid_to_monspecs(par
->edid
, specs
);
1924 if (specs
->modedb
== NULL
)
1925 printk("i810fb_init_pci: Unable to get Mode Database\n");
1927 fb_videomode_to_modelist(specs
->modedb
, specs
->modedb_len
,
1929 if (specs
->modedb
!= NULL
) {
1930 const struct fb_videomode
*m
;
1933 if ((m
= fb_find_best_mode(&var
, &info
->modelist
))) {
1940 m
= fb_find_best_display(&info
->monspecs
, &info
->modelist
);
1945 fb_videomode_to_var(&var
, &mode
);
1949 fb_find_mode(&var
, info
, mode_option
, specs
->modedb
,
1950 specs
->modedb_len
, (found
) ? &mode
: NULL
,
1951 info
->var
.bits_per_pixel
);
1954 fb_destroy_modedb(specs
->modedb
);
1955 specs
->modedb
= NULL
;
1959 static int __devinit
i810fb_setup(char *options
)
1961 char *this_opt
, *suffix
= NULL
;
1963 if (!options
|| !*options
)
1966 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1967 if (!strncmp(this_opt
, "mtrr", 4))
1969 else if (!strncmp(this_opt
, "accel", 5))
1971 else if (!strncmp(this_opt
, "extvga", 6))
1973 else if (!strncmp(this_opt
, "sync", 4))
1975 else if (!strncmp(this_opt
, "vram:", 5))
1976 vram
= (simple_strtoul(this_opt
+5, NULL
, 0));
1977 else if (!strncmp(this_opt
, "voffset:", 8))
1978 voffset
= (simple_strtoul(this_opt
+8, NULL
, 0));
1979 else if (!strncmp(this_opt
, "xres:", 5))
1980 xres
= simple_strtoul(this_opt
+5, NULL
, 0);
1981 else if (!strncmp(this_opt
, "yres:", 5))
1982 yres
= simple_strtoul(this_opt
+5, NULL
, 0);
1983 else if (!strncmp(this_opt
, "vyres:", 6))
1984 vyres
= simple_strtoul(this_opt
+6, NULL
, 0);
1985 else if (!strncmp(this_opt
, "bpp:", 4))
1986 bpp
= simple_strtoul(this_opt
+4, NULL
, 0);
1987 else if (!strncmp(this_opt
, "hsync1:", 7)) {
1988 hsync1
= simple_strtoul(this_opt
+7, &suffix
, 0);
1989 if (strncmp(suffix
, "H", 1))
1991 } else if (!strncmp(this_opt
, "hsync2:", 7)) {
1992 hsync2
= simple_strtoul(this_opt
+7, &suffix
, 0);
1993 if (strncmp(suffix
, "H", 1))
1995 } else if (!strncmp(this_opt
, "vsync1:", 7))
1996 vsync1
= simple_strtoul(this_opt
+7, NULL
, 0);
1997 else if (!strncmp(this_opt
, "vsync2:", 7))
1998 vsync2
= simple_strtoul(this_opt
+7, NULL
, 0);
1999 else if (!strncmp(this_opt
, "dcolor", 6))
2001 else if (!strncmp(this_opt
, "ddc3", 4))
2004 mode_option
= this_opt
;
2010 static int __devinit
i810fb_init_pci (struct pci_dev
*dev
,
2011 const struct pci_device_id
*entry
)
2013 struct fb_info
*info
;
2014 struct i810fb_par
*par
= NULL
;
2015 struct fb_videomode mode
;
2016 int i
, err
= -1, vfreq
, hfreq
, pixclock
;
2020 info
= framebuffer_alloc(sizeof(struct i810fb_par
), &dev
->dev
);
2027 if (!(info
->pixmap
.addr
= kzalloc(8*1024, GFP_KERNEL
))) {
2028 i810fb_release_resource(info
, par
);
2031 info
->pixmap
.size
= 8*1024;
2032 info
->pixmap
.buf_align
= 8;
2033 info
->pixmap
.access_align
= 32;
2034 info
->pixmap
.flags
= FB_PIXMAP_SYSTEM
;
2036 if ((err
= i810_allocate_pci_resource(par
, entry
))) {
2037 i810fb_release_resource(info
, par
);
2041 i810_init_defaults(par
, info
);
2043 if ((err
= i810_alloc_agp_mem(info
))) {
2044 i810fb_release_resource(info
, par
);
2048 i810_init_device(par
);
2050 info
->screen_base
= par
->fb
.virtual;
2051 info
->fbops
= &par
->i810fb_ops
;
2052 info
->pseudo_palette
= par
->pseudo_palette
;
2053 fb_alloc_cmap(&info
->cmap
, 256, 0);
2054 i810fb_find_init_mode(info
);
2056 if ((err
= info
->fbops
->fb_check_var(&info
->var
, info
))) {
2057 i810fb_release_resource(info
, par
);
2061 fb_var_to_videomode(&mode
, &info
->var
);
2062 fb_add_videomode(&mode
, &info
->modelist
);
2064 i810fb_init_ringbuffer(info
);
2065 err
= register_framebuffer(info
);
2068 i810fb_release_resource(info
, par
);
2069 printk("i810fb_init: cannot register framebuffer device\n");
2073 pci_set_drvdata(dev
, info
);
2074 pixclock
= 1000000000/(info
->var
.pixclock
);
2076 hfreq
= pixclock
/(info
->var
.xres
+ info
->var
.left_margin
+
2077 info
->var
.hsync_len
+ info
->var
.right_margin
);
2078 vfreq
= hfreq
/(info
->var
.yres
+ info
->var
.upper_margin
+
2079 info
->var
.vsync_len
+ info
->var
.lower_margin
);
2081 printk("I810FB: fb%d : %s v%d.%d.%d%s\n"
2082 "I810FB: Video RAM : %dK\n"
2083 "I810FB: Monitor : H: %d-%d KHz V: %d-%d Hz\n"
2084 "I810FB: Mode : %dx%d-%dbpp@%dHz\n",
2086 i810_pci_list
[entry
->driver_data
],
2087 VERSION_MAJOR
, VERSION_MINOR
, VERSION_TEENIE
, BRANCH_VERSION
,
2088 (int) par
->fb
.size
>>10, info
->monspecs
.hfmin
/1000,
2089 info
->monspecs
.hfmax
/1000, info
->monspecs
.vfmin
,
2090 info
->monspecs
.vfmax
, info
->var
.xres
,
2091 info
->var
.yres
, info
->var
.bits_per_pixel
, vfreq
);
2095 /***************************************************************
2096 * De-initialization *
2097 ***************************************************************/
2099 static void i810fb_release_resource(struct fb_info
*info
,
2100 struct i810fb_par
*par
)
2102 struct gtt_data
*gtt
= &par
->i810_gtt
;
2105 i810_delete_i2c_busses(par
);
2107 if (par
->i810_gtt
.i810_cursor_memory
)
2108 agp_free_memory(gtt
->i810_cursor_memory
);
2109 if (par
->i810_gtt
.i810_fb_memory
)
2110 agp_free_memory(gtt
->i810_fb_memory
);
2112 if (par
->mmio_start_virtual
)
2113 iounmap(par
->mmio_start_virtual
);
2114 if (par
->aperture
.virtual)
2115 iounmap(par
->aperture
.virtual);
2117 if (par
->res_flags
& FRAMEBUFFER_REQ
)
2118 release_mem_region(par
->aperture
.physical
,
2119 par
->aperture
.size
);
2120 if (par
->res_flags
& MMIO_REQ
)
2121 release_mem_region(par
->mmio_start_phys
, MMIO_SIZE
);
2123 framebuffer_release(info
);
2127 static void __exit
i810fb_remove_pci(struct pci_dev
*dev
)
2129 struct fb_info
*info
= pci_get_drvdata(dev
);
2130 struct i810fb_par
*par
= info
->par
;
2132 unregister_framebuffer(info
);
2133 i810fb_release_resource(info
, par
);
2134 pci_set_drvdata(dev
, NULL
);
2135 printk("cleanup_module: unloaded i810 framebuffer device\n");
2139 static int __devinit
i810fb_init(void)
2141 char *option
= NULL
;
2143 if (fb_get_options("i810fb", &option
))
2145 i810fb_setup(option
);
2147 return pci_register_driver(&i810fb_driver
);
2151 /*********************************************************************
2153 *********************************************************************/
2157 static int __devinit
i810fb_init(void)
2162 return pci_register_driver(&i810fb_driver
);
2165 module_param(vram
, int, 0);
2166 MODULE_PARM_DESC(vram
, "System RAM to allocate to framebuffer in MiB"
2168 module_param(voffset
, int, 0);
2169 MODULE_PARM_DESC(voffset
, "at what offset to place start of framebuffer "
2170 "memory (0 to maximum aperture size), in MiB (default = 48)");
2171 module_param(bpp
, int, 0);
2172 MODULE_PARM_DESC(bpp
, "Color depth for display in bits per pixel"
2174 module_param(xres
, int, 0);
2175 MODULE_PARM_DESC(xres
, "Horizontal resolution in pixels (default = 640)");
2176 module_param(yres
, int, 0);
2177 MODULE_PARM_DESC(yres
, "Vertical resolution in scanlines (default = 480)");
2178 module_param(vyres
,int, 0);
2179 MODULE_PARM_DESC(vyres
, "Virtual vertical resolution in scanlines"
2180 " (default = 480)");
2181 module_param(hsync1
, int, 0);
2182 MODULE_PARM_DESC(hsync1
, "Minimum horizontal frequency of monitor in KHz"
2184 module_param(hsync2
, int, 0);
2185 MODULE_PARM_DESC(hsync2
, "Maximum horizontal frequency of monitor in KHz"
2187 module_param(vsync1
, int, 0);
2188 MODULE_PARM_DESC(vsync1
, "Minimum vertical frequency of monitor in Hz"
2190 module_param(vsync2
, int, 0);
2191 MODULE_PARM_DESC(vsync2
, "Maximum vertical frequency of monitor in Hz"
2193 module_param(accel
, bool, 0);
2194 MODULE_PARM_DESC(accel
, "Use Acceleration (BLIT) engine (default = 0)");
2195 module_param(mtrr
, bool, 0);
2196 MODULE_PARM_DESC(mtrr
, "Use MTRR (default = 0)");
2197 module_param(extvga
, bool, 0);
2198 MODULE_PARM_DESC(extvga
, "Enable external VGA connector (default = 0)");
2199 module_param(sync
, bool, 0);
2200 MODULE_PARM_DESC(sync
, "wait for accel engine to finish drawing"
2202 module_param(dcolor
, bool, 0);
2203 MODULE_PARM_DESC(dcolor
, "use DirectColor visuals"
2204 " (default = 0 = TrueColor)");
2205 module_param(ddc3
, bool, 0);
2206 MODULE_PARM_DESC(ddc3
, "Probe DDC bus 3 (default = 0 = no)");
2207 module_param(mode_option
, charp
, 0);
2208 MODULE_PARM_DESC(mode_option
, "Specify initial video mode");
2210 MODULE_AUTHOR("Tony A. Daplas");
2211 MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"
2212 " compatible cards");
2213 MODULE_LICENSE("GPL");
2215 static void __exit
i810fb_exit(void)
2217 pci_unregister_driver(&i810fb_driver
);
2219 module_exit(i810fb_exit
);
2223 module_init(i810fb_init
);