xref: /openbmc/linux/drivers/video/fbdev/i810/i810_main.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1   /*-*- linux-c -*-
2   *  linux/drivers/video/i810_main.c -- Intel 810 frame buffer device
3   *
4   *      Copyright (C) 2001 Antonino Daplas<adaplas@pol.net>
5   *      All Rights Reserved
6   *
7   *      Contributors:
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
11   *                                        secondary displays
12   *
13   *         Fredrik Andersson <krueger@shell.linux.se> - alpha testing of
14   *                                        the VESA GTF
15   *
16   *         Brad Corrion <bcorrion@web-co.com> - alpha testing of customized
17   *                                        timings support
18   *
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.
25   *
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
28   *  more details.
29   */
30  
31  #include <linux/aperture.h>
32  #include <linux/module.h>
33  #include <linux/kernel.h>
34  #include <linux/errno.h>
35  #include <linux/string.h>
36  #include <linux/mm.h>
37  #include <linux/slab.h>
38  #include <linux/fb.h>
39  #include <linux/init.h>
40  #include <linux/pci.h>
41  #include <linux/pci_ids.h>
42  #include <linux/resource.h>
43  #include <linux/unistd.h>
44  #include <linux/console.h>
45  #include <linux/io.h>
46  
47  #include <asm/io.h>
48  #include <asm/div64.h>
49  #include <asm/page.h>
50  
51  #include "i810_regs.h"
52  #include "i810.h"
53  #include "i810_main.h"
54  
55  /*
56   * voffset - framebuffer offset in MiB from aperture start address.  In order for
57   * the driver to work with X, we must try to use memory holes left untouched by X. The
58   * following table lists where X's different surfaces start at.
59   *
60   * ---------------------------------------------
61   * :                :  64 MiB     : 32 MiB      :
62   * ----------------------------------------------
63   * : FrontBuffer    :   0         :  0          :
64   * : DepthBuffer    :   48        :  16         :
65   * : BackBuffer     :   56        :  24         :
66   * ----------------------------------------------
67   *
68   * So for chipsets with 64 MiB Aperture sizes, 32 MiB for v_offset is okay, allowing up to
69   * 15 + 1 MiB of Framebuffer memory.  For 32 MiB Aperture sizes, a v_offset of 8 MiB should
70   * work, allowing 7 + 1 MiB of Framebuffer memory.
71   * Note, the size of the hole may change depending on how much memory you allocate to X,
72   * and how the memory is split up between these surfaces.
73   *
74   * Note: Anytime the DepthBuffer or FrontBuffer is overlapped, X would still run but with
75   * DRI disabled.  But if the Frontbuffer is overlapped, X will fail to load.
76   *
77   * Experiment with v_offset to find out which works best for you.
78   */
79  static u32 v_offset_default; /* For 32 MiB Aper size, 8 should be the default */
80  static u32 voffset;
81  
82  static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
83  static int i810fb_init_pci(struct pci_dev *dev,
84  			   const struct pci_device_id *entry);
85  static void i810fb_remove_pci(struct pci_dev *dev);
86  static int i810fb_resume(struct pci_dev *dev);
87  static int i810fb_suspend(struct pci_dev *dev, pm_message_t state);
88  
89  /* Chipset Specific Functions */
90  static int i810fb_set_par    (struct fb_info *info);
91  static int i810fb_getcolreg  (u8 regno, u8 *red, u8 *green, u8 *blue,
92  			      u8 *transp, struct fb_info *info);
93  static int i810fb_setcolreg  (unsigned regno, unsigned red, unsigned green, unsigned blue,
94  			      unsigned transp, struct fb_info *info);
95  static int i810fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
96  static int i810fb_blank      (int blank_mode, struct fb_info *info);
97  
98  /* Initialization */
99  static void i810fb_release_resource       (struct fb_info *info, struct i810fb_par *par);
100  
101  /* PCI */
102  static const char * const i810_pci_list[] = {
103  	"Intel(R) 810 Framebuffer Device"                                 ,
104  	"Intel(R) 810-DC100 Framebuffer Device"                           ,
105  	"Intel(R) 810E Framebuffer Device"                                ,
106  	"Intel(R) 815 (Internal Graphics 100Mhz FSB) Framebuffer Device"  ,
107  	"Intel(R) 815 (Internal Graphics only) Framebuffer Device"        ,
108  	"Intel(R) 815 (Internal Graphics with AGP) Framebuffer Device"
109  };
110  
111  static const struct pci_device_id i810fb_pci_tbl[] = {
112  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG1,
113  	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
114  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3,
115  	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1  },
116  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG,
117  	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
118  	/* mvo: added i815 PCI-ID */
119  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_100,
120  	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
121  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_NOAGP,
122  	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
123  	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
124  	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
125  	{ 0 },
126  };
127  
128  static struct pci_driver i810fb_driver = {
129  	.name     =	"i810fb",
130  	.id_table =	i810fb_pci_tbl,
131  	.probe    =	i810fb_init_pci,
132  	.remove   =	i810fb_remove_pci,
133  	.suspend  =     i810fb_suspend,
134  	.resume   =     i810fb_resume,
135  };
136  
137  static char *mode_option = NULL;
138  static int vram = 4;
139  static int bpp = 8;
140  static bool mtrr;
141  static bool accel;
142  static int hsync1;
143  static int hsync2;
144  static int vsync1;
145  static int vsync2;
146  static int xres;
147  static int yres;
148  static int vyres;
149  static bool sync;
150  static bool extvga;
151  static bool dcolor;
152  static bool ddc3;
153  
154  /*------------------------------------------------------------*/
155  
156  /**************************************************************
157   *                Hardware Low Level Routines                 *
158   **************************************************************/
159  
160  /**
161   * i810_screen_off - turns off/on display
162   * @mmio: address of register space
163   * @mode: on or off
164   *
165   * DESCRIPTION:
166   * Blanks/unblanks the display
167   */
i810_screen_off(u8 __iomem * mmio,u8 mode)168  static void i810_screen_off(u8 __iomem *mmio, u8 mode)
169  {
170  	u32 count = WAIT_COUNT;
171  	u8 val;
172  
173  	i810_writeb(SR_INDEX, mmio, SR01);
174  	val = i810_readb(SR_DATA, mmio);
175  	val = (mode == OFF) ? val | SCR_OFF :
176  		val & ~SCR_OFF;
177  
178  	while((i810_readw(DISP_SL, mmio) & 0xFFF) && count--);
179  	i810_writeb(SR_INDEX, mmio, SR01);
180  	i810_writeb(SR_DATA, mmio, val);
181  }
182  
183  /**
184   * i810_dram_off - turns off/on dram refresh
185   * @mmio: address of register space
186   * @mode: on or off
187   *
188   * DESCRIPTION:
189   * Turns off DRAM refresh.  Must be off for only 2 vsyncs
190   * before data becomes corrupt
191   */
i810_dram_off(u8 __iomem * mmio,u8 mode)192  static void i810_dram_off(u8 __iomem *mmio, u8 mode)
193  {
194  	u8 val;
195  
196  	val = i810_readb(DRAMCH, mmio);
197  	val &= DRAM_OFF;
198  	val = (mode == OFF) ? val : val | DRAM_ON;
199  	i810_writeb(DRAMCH, mmio, val);
200  }
201  
202  /**
203   * i810_protect_regs - allows rw/ro mode of certain VGA registers
204   * @mmio: address of register space
205   * @mode: protect/unprotect
206   *
207   * DESCRIPTION:
208   * The IBM VGA standard allows protection of certain VGA registers.
209   * This will  protect or unprotect them.
210   */
i810_protect_regs(u8 __iomem * mmio,int mode)211  static void i810_protect_regs(u8 __iomem *mmio, int mode)
212  {
213  	u8 reg;
214  
215  	i810_writeb(CR_INDEX_CGA, mmio, CR11);
216  	reg = i810_readb(CR_DATA_CGA, mmio);
217  	reg = (mode == OFF) ? reg & ~0x80 :
218  		reg | 0x80;
219  
220  	i810_writeb(CR_INDEX_CGA, mmio, CR11);
221  	i810_writeb(CR_DATA_CGA, mmio, reg);
222  }
223  
224  /**
225   * i810_load_pll - loads values for the hardware PLL clock
226   * @par: pointer to i810fb_par structure
227   *
228   * DESCRIPTION:
229   * Loads the P, M, and N registers.
230   */
i810_load_pll(struct i810fb_par * par)231  static void i810_load_pll(struct i810fb_par *par)
232  {
233  	u32 tmp1, tmp2;
234  	u8 __iomem *mmio = par->mmio_start_virtual;
235  
236  	tmp1 = par->regs.M | par->regs.N << 16;
237  	tmp2 = i810_readl(DCLK_2D, mmio);
238  	tmp2 &= ~MN_MASK;
239  	i810_writel(DCLK_2D, mmio, tmp1 | tmp2);
240  
241  	tmp1 = par->regs.P;
242  	tmp2 = i810_readl(DCLK_0DS, mmio);
243  	tmp2 &= ~(P_OR << 16);
244  	i810_writel(DCLK_0DS, mmio, (tmp1 << 16) | tmp2);
245  
246  	i810_writeb(MSR_WRITE, mmio, par->regs.msr | 0xC8 | 1);
247  
248  }
249  
250  /**
251   * i810_load_vga - load standard VGA registers
252   * @par: pointer to i810fb_par structure
253   *
254   * DESCRIPTION:
255   * Load values to VGA registers
256   */
i810_load_vga(struct i810fb_par * par)257  static void i810_load_vga(struct i810fb_par *par)
258  {
259  	u8 __iomem *mmio = par->mmio_start_virtual;
260  
261  	/* interlace */
262  	i810_writeb(CR_INDEX_CGA, mmio, CR70);
263  	i810_writeb(CR_DATA_CGA, mmio, par->interlace);
264  
265  	i810_writeb(CR_INDEX_CGA, mmio, CR00);
266  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr00);
267  	i810_writeb(CR_INDEX_CGA, mmio, CR01);
268  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr01);
269  	i810_writeb(CR_INDEX_CGA, mmio, CR02);
270  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr02);
271  	i810_writeb(CR_INDEX_CGA, mmio, CR03);
272  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr03);
273  	i810_writeb(CR_INDEX_CGA, mmio, CR04);
274  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr04);
275  	i810_writeb(CR_INDEX_CGA, mmio, CR05);
276  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr05);
277  	i810_writeb(CR_INDEX_CGA, mmio, CR06);
278  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr06);
279  	i810_writeb(CR_INDEX_CGA, mmio, CR09);
280  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr09);
281  	i810_writeb(CR_INDEX_CGA, mmio, CR10);
282  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr10);
283  	i810_writeb(CR_INDEX_CGA, mmio, CR11);
284  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr11);
285  	i810_writeb(CR_INDEX_CGA, mmio, CR12);
286  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr12);
287  	i810_writeb(CR_INDEX_CGA, mmio, CR15);
288  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr15);
289  	i810_writeb(CR_INDEX_CGA, mmio, CR16);
290  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr16);
291  }
292  
293  /**
294   * i810_load_vgax - load extended VGA registers
295   * @par: pointer to i810fb_par structure
296   *
297   * DESCRIPTION:
298   * Load values to extended VGA registers
299   */
i810_load_vgax(struct i810fb_par * par)300  static void i810_load_vgax(struct i810fb_par *par)
301  {
302  	u8 __iomem *mmio = par->mmio_start_virtual;
303  
304  	i810_writeb(CR_INDEX_CGA, mmio, CR30);
305  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr30);
306  	i810_writeb(CR_INDEX_CGA, mmio, CR31);
307  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr31);
308  	i810_writeb(CR_INDEX_CGA, mmio, CR32);
309  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr32);
310  	i810_writeb(CR_INDEX_CGA, mmio, CR33);
311  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr33);
312  	i810_writeb(CR_INDEX_CGA, mmio, CR35);
313  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr35);
314  	i810_writeb(CR_INDEX_CGA, mmio, CR39);
315  	i810_writeb(CR_DATA_CGA, mmio, par->regs.cr39);
316  }
317  
318  /**
319   * i810_load_2d - load grahics registers
320   * @par: pointer to i810fb_par structure
321   *
322   * DESCRIPTION:
323   * Load values to graphics registers
324   */
i810_load_2d(struct i810fb_par * par)325  static void i810_load_2d(struct i810fb_par *par)
326  {
327  	u32 tmp;
328  	u8 tmp8;
329  	u8 __iomem *mmio = par->mmio_start_virtual;
330  
331    	i810_writel(FW_BLC, mmio, par->watermark);
332  	tmp = i810_readl(PIXCONF, mmio);
333  	tmp |= 1 | 1 << 20;
334  	i810_writel(PIXCONF, mmio, tmp);
335  
336  	i810_writel(OVRACT, mmio, par->ovract);
337  
338  	i810_writeb(GR_INDEX, mmio, GR10);
339  	tmp8 = i810_readb(GR_DATA, mmio);
340  	tmp8 |= 2;
341  	i810_writeb(GR_INDEX, mmio, GR10);
342  	i810_writeb(GR_DATA, mmio, tmp8);
343  }
344  
345  /**
346   * i810_hires - enables high resolution mode
347   * @mmio: address of register space
348   */
i810_hires(u8 __iomem * mmio)349  static void i810_hires(u8 __iomem *mmio)
350  {
351  	u8 val;
352  
353  	i810_writeb(CR_INDEX_CGA, mmio, CR80);
354  	val = i810_readb(CR_DATA_CGA, mmio);
355  	i810_writeb(CR_INDEX_CGA, mmio, CR80);
356  	i810_writeb(CR_DATA_CGA, mmio, val | 1);
357  	/* Stop LCD displays from flickering */
358  	i810_writel(MEM_MODE, mmio, i810_readl(MEM_MODE, mmio) | 4);
359  }
360  
361  /**
362   * i810_load_pitch - loads the characters per line of the display
363   * @par: pointer to i810fb_par structure
364   *
365   * DESCRIPTION:
366   * Loads the characters per line
367   */
i810_load_pitch(struct i810fb_par * par)368  static void i810_load_pitch(struct i810fb_par *par)
369  {
370  	u32 tmp, pitch;
371  	u8 val;
372  	u8 __iomem *mmio = par->mmio_start_virtual;
373  
374  	pitch = par->pitch >> 3;
375  	i810_writeb(SR_INDEX, mmio, SR01);
376  	val = i810_readb(SR_DATA, mmio);
377  	val &= 0xE0;
378  	val |= 1 | 1 << 2;
379  	i810_writeb(SR_INDEX, mmio, SR01);
380  	i810_writeb(SR_DATA, mmio, val);
381  
382  	tmp = pitch & 0xFF;
383  	i810_writeb(CR_INDEX_CGA, mmio, CR13);
384  	i810_writeb(CR_DATA_CGA, mmio, (u8) tmp);
385  
386  	tmp = pitch >> 8;
387  	i810_writeb(CR_INDEX_CGA, mmio, CR41);
388  	val = i810_readb(CR_DATA_CGA, mmio) & ~0x0F;
389  	i810_writeb(CR_INDEX_CGA, mmio, CR41);
390  	i810_writeb(CR_DATA_CGA, mmio, (u8) tmp | val);
391  }
392  
393  /**
394   * i810_load_color - loads the color depth of the display
395   * @par: pointer to i810fb_par structure
396   *
397   * DESCRIPTION:
398   * Loads the color depth of the display and the graphics engine
399   */
i810_load_color(struct i810fb_par * par)400  static void i810_load_color(struct i810fb_par *par)
401  {
402  	u8 __iomem *mmio = par->mmio_start_virtual;
403  	u32 reg1;
404  	u16 reg2;
405  
406  	reg1 = i810_readl(PIXCONF, mmio) & ~(0xF0000 | 1 << 27);
407  	reg2 = i810_readw(BLTCNTL, mmio) & ~0x30;
408  
409  	reg1 |= 0x8000 | par->pixconf;
410  	reg2 |= par->bltcntl;
411  	i810_writel(PIXCONF, mmio, reg1);
412  	i810_writew(BLTCNTL, mmio, reg2);
413  }
414  
415  /**
416   * i810_load_regs - loads all registers for the mode
417   * @par: pointer to i810fb_par structure
418   *
419   * DESCRIPTION:
420   * Loads registers
421   */
i810_load_regs(struct i810fb_par * par)422  static void i810_load_regs(struct i810fb_par *par)
423  {
424  	u8 __iomem *mmio = par->mmio_start_virtual;
425  
426  	i810_screen_off(mmio, OFF);
427  	i810_protect_regs(mmio, OFF);
428  	i810_dram_off(mmio, OFF);
429  	i810_load_pll(par);
430  	i810_load_vga(par);
431  	i810_load_vgax(par);
432  	i810_dram_off(mmio, ON);
433  	i810_load_2d(par);
434  	i810_hires(mmio);
435  	i810_screen_off(mmio, ON);
436  	i810_protect_regs(mmio, ON);
437  	i810_load_color(par);
438  	i810_load_pitch(par);
439  }
440  
i810_write_dac(u8 regno,u8 red,u8 green,u8 blue,u8 __iomem * mmio)441  static void i810_write_dac(u8 regno, u8 red, u8 green, u8 blue,
442  			  u8 __iomem *mmio)
443  {
444  	i810_writeb(CLUT_INDEX_WRITE, mmio, regno);
445  	i810_writeb(CLUT_DATA, mmio, red);
446  	i810_writeb(CLUT_DATA, mmio, green);
447  	i810_writeb(CLUT_DATA, mmio, blue);
448  }
449  
i810_read_dac(u8 regno,u8 * red,u8 * green,u8 * blue,u8 __iomem * mmio)450  static void i810_read_dac(u8 regno, u8 *red, u8 *green, u8 *blue,
451  			  u8 __iomem *mmio)
452  {
453  	i810_writeb(CLUT_INDEX_READ, mmio, regno);
454  	*red = i810_readb(CLUT_DATA, mmio);
455  	*green = i810_readb(CLUT_DATA, mmio);
456  	*blue = i810_readb(CLUT_DATA, mmio);
457  }
458  
459  /************************************************************
460   *                   VGA State Restore                      *
461   ************************************************************/
i810_restore_pll(struct i810fb_par * par)462  static void i810_restore_pll(struct i810fb_par *par)
463  {
464  	u32 tmp1, tmp2;
465  	u8 __iomem *mmio = par->mmio_start_virtual;
466  
467  	tmp1 = par->hw_state.dclk_2d;
468  	tmp2 = i810_readl(DCLK_2D, mmio);
469  	tmp1 &= ~MN_MASK;
470  	tmp2 &= MN_MASK;
471  	i810_writel(DCLK_2D, mmio, tmp1 | tmp2);
472  
473  	tmp1 = par->hw_state.dclk_1d;
474  	tmp2 = i810_readl(DCLK_1D, mmio);
475  	tmp1 &= ~MN_MASK;
476  	tmp2 &= MN_MASK;
477  	i810_writel(DCLK_1D, mmio, tmp1 | tmp2);
478  
479  	i810_writel(DCLK_0DS, mmio, par->hw_state.dclk_0ds);
480  }
481  
i810_restore_dac(struct i810fb_par * par)482  static void i810_restore_dac(struct i810fb_par *par)
483  {
484  	u32 tmp1, tmp2;
485  	u8 __iomem *mmio = par->mmio_start_virtual;
486  
487  	tmp1 = par->hw_state.pixconf;
488  	tmp2 = i810_readl(PIXCONF, mmio);
489  	tmp1 &= DAC_BIT;
490  	tmp2 &= ~DAC_BIT;
491  	i810_writel(PIXCONF, mmio, tmp1 | tmp2);
492  }
493  
i810_restore_vgax(struct i810fb_par * par)494  static void i810_restore_vgax(struct i810fb_par *par)
495  {
496  	u8 i, j;
497  	u8 __iomem *mmio = par->mmio_start_virtual;
498  
499  	for (i = 0; i < 4; i++) {
500  		i810_writeb(CR_INDEX_CGA, mmio, CR30+i);
501  		i810_writeb(CR_DATA_CGA, mmio, *(&(par->hw_state.cr30) + i));
502  	}
503  	i810_writeb(CR_INDEX_CGA, mmio, CR35);
504  	i810_writeb(CR_DATA_CGA, mmio, par->hw_state.cr35);
505  	i810_writeb(CR_INDEX_CGA, mmio, CR39);
506  	i810_writeb(CR_DATA_CGA, mmio, par->hw_state.cr39);
507  	i810_writeb(CR_INDEX_CGA, mmio, CR41);
508  	i810_writeb(CR_DATA_CGA, mmio, par->hw_state.cr39);
509  
510  	/*restore interlace*/
511  	i810_writeb(CR_INDEX_CGA, mmio, CR70);
512  	i = par->hw_state.cr70;
513  	i &= INTERLACE_BIT;
514  	j = i810_readb(CR_DATA_CGA, mmio);
515  	i810_writeb(CR_INDEX_CGA, mmio, CR70);
516  	i810_writeb(CR_DATA_CGA, mmio, j | i);
517  
518  	i810_writeb(CR_INDEX_CGA, mmio, CR80);
519  	i810_writeb(CR_DATA_CGA, mmio, par->hw_state.cr80);
520  	i810_writeb(MSR_WRITE, mmio, par->hw_state.msr);
521  	i810_writeb(SR_INDEX, mmio, SR01);
522  	i = (par->hw_state.sr01) & ~0xE0 ;
523  	j = i810_readb(SR_DATA, mmio) & 0xE0;
524  	i810_writeb(SR_INDEX, mmio, SR01);
525  	i810_writeb(SR_DATA, mmio, i | j);
526  }
527  
i810_restore_vga(struct i810fb_par * par)528  static void i810_restore_vga(struct i810fb_par *par)
529  {
530  	u8 i;
531  	u8 __iomem *mmio = par->mmio_start_virtual;
532  
533  	for (i = 0; i < 10; i++) {
534  		i810_writeb(CR_INDEX_CGA, mmio, CR00 + i);
535  		i810_writeb(CR_DATA_CGA, mmio, *((&par->hw_state.cr00) + i));
536  	}
537  	for (i = 0; i < 8; i++) {
538  		i810_writeb(CR_INDEX_CGA, mmio, CR10 + i);
539  		i810_writeb(CR_DATA_CGA, mmio, *((&par->hw_state.cr10) + i));
540  	}
541  }
542  
i810_restore_addr_map(struct i810fb_par * par)543  static void i810_restore_addr_map(struct i810fb_par *par)
544  {
545  	u8 tmp;
546  	u8 __iomem *mmio = par->mmio_start_virtual;
547  
548  	i810_writeb(GR_INDEX, mmio, GR10);
549  	tmp = i810_readb(GR_DATA, mmio);
550  	tmp &= ADDR_MAP_MASK;
551  	tmp |= par->hw_state.gr10;
552  	i810_writeb(GR_INDEX, mmio, GR10);
553  	i810_writeb(GR_DATA, mmio, tmp);
554  }
555  
i810_restore_2d(struct i810fb_par * par)556  static void i810_restore_2d(struct i810fb_par *par)
557  {
558  	u32 tmp_long;
559  	u16 tmp_word;
560  	u8 __iomem *mmio = par->mmio_start_virtual;
561  
562  	tmp_word = i810_readw(BLTCNTL, mmio);
563  	tmp_word &= ~(3 << 4);
564  	tmp_word |= par->hw_state.bltcntl;
565  	i810_writew(BLTCNTL, mmio, tmp_word);
566  
567  	i810_dram_off(mmio, OFF);
568  	i810_writel(PIXCONF, mmio, par->hw_state.pixconf);
569  	i810_dram_off(mmio, ON);
570  
571  	tmp_word = i810_readw(HWSTAM, mmio);
572  	tmp_word &= 3 << 13;
573  	tmp_word |= par->hw_state.hwstam;
574  	i810_writew(HWSTAM, mmio, tmp_word);
575  
576  	tmp_long = i810_readl(FW_BLC, mmio);
577  	tmp_long &= FW_BLC_MASK;
578  	tmp_long |= par->hw_state.fw_blc;
579  	i810_writel(FW_BLC, mmio, tmp_long);
580  
581  	i810_writel(HWS_PGA, mmio, par->hw_state.hws_pga);
582  	i810_writew(IER, mmio, par->hw_state.ier);
583  	i810_writew(IMR, mmio, par->hw_state.imr);
584  	i810_writel(DPLYSTAS, mmio, par->hw_state.dplystas);
585  }
586  
i810_restore_vga_state(struct i810fb_par * par)587  static void i810_restore_vga_state(struct i810fb_par *par)
588  {
589  	u8 __iomem *mmio = par->mmio_start_virtual;
590  
591  	i810_screen_off(mmio, OFF);
592  	i810_protect_regs(mmio, OFF);
593  	i810_dram_off(mmio, OFF);
594  	i810_restore_pll(par);
595  	i810_restore_dac(par);
596  	i810_restore_vga(par);
597  	i810_restore_vgax(par);
598  	i810_restore_addr_map(par);
599  	i810_dram_off(mmio, ON);
600  	i810_restore_2d(par);
601  	i810_screen_off(mmio, ON);
602  	i810_protect_regs(mmio, ON);
603  }
604  
605  /***********************************************************************
606   *                         VGA State Save                              *
607   ***********************************************************************/
608  
i810_save_vgax(struct i810fb_par * par)609  static void i810_save_vgax(struct i810fb_par *par)
610  {
611  	u8 i;
612  	u8 __iomem *mmio = par->mmio_start_virtual;
613  
614  	for (i = 0; i < 4; i++) {
615  		i810_writeb(CR_INDEX_CGA, mmio, CR30 + i);
616  		*(&(par->hw_state.cr30) + i) = i810_readb(CR_DATA_CGA, mmio);
617  	}
618  	i810_writeb(CR_INDEX_CGA, mmio, CR35);
619  	par->hw_state.cr35 = i810_readb(CR_DATA_CGA, mmio);
620  	i810_writeb(CR_INDEX_CGA, mmio, CR39);
621  	par->hw_state.cr39 = i810_readb(CR_DATA_CGA, mmio);
622  	i810_writeb(CR_INDEX_CGA, mmio, CR41);
623  	par->hw_state.cr41 = i810_readb(CR_DATA_CGA, mmio);
624  	i810_writeb(CR_INDEX_CGA, mmio, CR70);
625  	par->hw_state.cr70 = i810_readb(CR_DATA_CGA, mmio);
626  	par->hw_state.msr = i810_readb(MSR_READ, mmio);
627  	i810_writeb(CR_INDEX_CGA, mmio, CR80);
628  	par->hw_state.cr80 = i810_readb(CR_DATA_CGA, mmio);
629  	i810_writeb(SR_INDEX, mmio, SR01);
630  	par->hw_state.sr01 = i810_readb(SR_DATA, mmio);
631  }
632  
i810_save_vga(struct i810fb_par * par)633  static void i810_save_vga(struct i810fb_par *par)
634  {
635  	u8 i;
636  	u8 __iomem *mmio = par->mmio_start_virtual;
637  
638  	for (i = 0; i < 10; i++) {
639  		i810_writeb(CR_INDEX_CGA, mmio, CR00 + i);
640  		*((&par->hw_state.cr00) + i) = i810_readb(CR_DATA_CGA, mmio);
641  	}
642  	for (i = 0; i < 8; i++) {
643  		i810_writeb(CR_INDEX_CGA, mmio, CR10 + i);
644  		*((&par->hw_state.cr10) + i) = i810_readb(CR_DATA_CGA, mmio);
645  	}
646  }
647  
i810_save_2d(struct i810fb_par * par)648  static void i810_save_2d(struct i810fb_par *par)
649  {
650  	u8 __iomem *mmio = par->mmio_start_virtual;
651  
652  	par->hw_state.dclk_2d = i810_readl(DCLK_2D, mmio);
653  	par->hw_state.dclk_1d = i810_readl(DCLK_1D, mmio);
654  	par->hw_state.dclk_0ds = i810_readl(DCLK_0DS, mmio);
655  	par->hw_state.pixconf = i810_readl(PIXCONF, mmio);
656  	par->hw_state.fw_blc = i810_readl(FW_BLC, mmio);
657  	par->hw_state.bltcntl = i810_readw(BLTCNTL, mmio);
658  	par->hw_state.hwstam = i810_readw(HWSTAM, mmio);
659  	par->hw_state.hws_pga = i810_readl(HWS_PGA, mmio);
660  	par->hw_state.ier = i810_readw(IER, mmio);
661  	par->hw_state.imr = i810_readw(IMR, mmio);
662  	par->hw_state.dplystas = i810_readl(DPLYSTAS, mmio);
663  }
664  
i810_save_vga_state(struct i810fb_par * par)665  static void i810_save_vga_state(struct i810fb_par *par)
666  {
667  	i810_save_vga(par);
668  	i810_save_vgax(par);
669  	i810_save_2d(par);
670  }
671  
672  /************************************************************
673   *                    Helpers                               *
674   ************************************************************/
675  /**
676   * get_line_length - calculates buffer pitch in bytes
677   * @par: pointer to i810fb_par structure
678   * @xres_virtual: virtual resolution of the frame
679   * @bpp: bits per pixel
680   *
681   * DESCRIPTION:
682   * Calculates buffer pitch in bytes.
683   */
get_line_length(struct i810fb_par * par,int xres_virtual,int bpp)684  static u32 get_line_length(struct i810fb_par *par, int xres_virtual, int bpp)
685  {
686     	u32 length;
687  
688  	length = xres_virtual*bpp;
689  	length = (length+31)&-32;
690  	length >>= 3;
691  	return length;
692  }
693  
694  /**
695   * i810_calc_dclk - calculates the P, M, and N values of a pixelclock value
696   * @freq: target pixelclock in picoseconds
697   * @m: where to write M register
698   * @n: where to write N register
699   * @p: where to write P register
700   *
701   * DESCRIPTION:
702   * Based on the formula Freq_actual = (4*M*Freq_ref)/(N^P)
703   * Repeatedly computes the Freq until the actual Freq is equal to
704   * the target Freq or until the loop count is zero.  In the latter
705   * case, the actual frequency nearest the target will be used.
706   */
i810_calc_dclk(u32 freq,u32 * m,u32 * n,u32 * p)707  static void i810_calc_dclk(u32 freq, u32 *m, u32 *n, u32 *p)
708  {
709  	u32 m_reg, n_reg, p_divisor, n_target_max;
710  	u32 m_target, n_target, p_target, n_best, m_best, mod;
711  	u32 f_out, target_freq, diff = 0, mod_min, diff_min;
712  
713  	diff_min = mod_min = 0xFFFFFFFF;
714  	n_best = m_best = m_target = f_out = 0;
715  
716  	target_freq =  freq;
717  	n_target_max = 30;
718  
719  	/*
720  	 * find P such that target freq is 16x reference freq (Hz).
721  	 */
722  	p_divisor = 1;
723  	p_target = 0;
724  	while(!((1000000 * p_divisor)/(16 * 24 * target_freq)) &&
725  	      p_divisor <= 32) {
726  		p_divisor <<= 1;
727  		p_target++;
728  	}
729  
730  	n_reg = m_reg = n_target = 3;
731  	while (diff_min && mod_min && (n_target < n_target_max)) {
732  		f_out = (p_divisor * n_reg * 1000000)/(4 * 24 * m_reg);
733  		mod = (p_divisor * n_reg * 1000000) % (4 * 24 * m_reg);
734  		m_target = m_reg;
735  		n_target = n_reg;
736  		if (f_out <= target_freq) {
737  			n_reg++;
738  			diff = target_freq - f_out;
739  		} else {
740  			m_reg++;
741  			diff = f_out - target_freq;
742  		}
743  
744  		if (diff_min > diff) {
745  			diff_min = diff;
746  			n_best = n_target;
747  			m_best = m_target;
748  		}
749  
750  		if (!diff && mod_min > mod) {
751  			mod_min = mod;
752  			n_best = n_target;
753  			m_best = m_target;
754  		}
755  	}
756  	if (m) *m = (m_best - 2) & 0x3FF;
757  	if (n) *n = (n_best - 2) & 0x3FF;
758  	if (p) *p = (p_target << 4);
759  }
760  
761  /*************************************************************
762   *                Hardware Cursor Routines                   *
763   *************************************************************/
764  
765  /**
766   * i810_enable_cursor - show or hide the hardware cursor
767   * @mmio: address of register space
768   * @mode: show (1) or hide (0)
769   *
770   * Description:
771   * Shows or hides the hardware cursor
772   */
i810_enable_cursor(u8 __iomem * mmio,int mode)773  static void i810_enable_cursor(u8 __iomem *mmio, int mode)
774  {
775  	u32 temp;
776  
777  	temp = i810_readl(PIXCONF, mmio);
778  	temp = (mode == ON) ? temp | CURSOR_ENABLE_MASK :
779  		temp & ~CURSOR_ENABLE_MASK;
780  
781  	i810_writel(PIXCONF, mmio, temp);
782  }
783  
i810_reset_cursor_image(struct i810fb_par * par)784  static void i810_reset_cursor_image(struct i810fb_par *par)
785  {
786  	u8 __iomem *addr = par->cursor_heap.virtual;
787  	int i, j;
788  
789  	for (i = 64; i--; ) {
790  		for (j = 0; j < 8; j++) {
791  			i810_writeb(j, addr, 0xff);
792  			i810_writeb(j+8, addr, 0x00);
793  		}
794  		addr +=16;
795  	}
796  }
797  
i810_load_cursor_image(int width,int height,u8 * data,struct i810fb_par * par)798  static void i810_load_cursor_image(int width, int height, u8 *data,
799  				   struct i810fb_par *par)
800  {
801  	u8 __iomem *addr = par->cursor_heap.virtual;
802  	int i, j, w = width/8;
803  	int mod = width % 8, t_mask, d_mask;
804  
805  	t_mask = 0xff >> mod;
806  	d_mask = ~(0xff >> mod);
807  	for (i = height; i--; ) {
808  		for (j = 0; j < w; j++) {
809  			i810_writeb(j+0, addr, 0x00);
810  			i810_writeb(j+8, addr, *data++);
811  		}
812  		if (mod) {
813  			i810_writeb(j+0, addr, t_mask);
814  			i810_writeb(j+8, addr, *data++ & d_mask);
815  		}
816  		addr += 16;
817  	}
818  }
819  
i810_load_cursor_colors(int fg,int bg,struct fb_info * info)820  static void i810_load_cursor_colors(int fg, int bg, struct fb_info *info)
821  {
822  	struct i810fb_par *par = info->par;
823  	u8 __iomem *mmio = par->mmio_start_virtual;
824  	u8 red, green, blue, trans, temp;
825  
826  	i810fb_getcolreg(bg, &red, &green, &blue, &trans, info);
827  
828  	temp = i810_readb(PIXCONF1, mmio);
829  	i810_writeb(PIXCONF1, mmio, temp | EXTENDED_PALETTE);
830  
831  	i810_write_dac(4, red, green, blue, mmio);
832  
833  	i810_writeb(PIXCONF1, mmio, temp);
834  
835  	i810fb_getcolreg(fg, &red, &green, &blue, &trans, info);
836  	temp = i810_readb(PIXCONF1, mmio);
837  	i810_writeb(PIXCONF1, mmio, temp | EXTENDED_PALETTE);
838  
839  	i810_write_dac(5, red, green, blue, mmio);
840  
841  	i810_writeb(PIXCONF1, mmio, temp);
842  }
843  
844  /**
845   * i810_init_cursor - initializes the cursor
846   * @par: pointer to i810fb_par structure
847   *
848   * DESCRIPTION:
849   * Initializes the cursor registers
850   */
i810_init_cursor(struct i810fb_par * par)851  static void i810_init_cursor(struct i810fb_par *par)
852  {
853  	u8 __iomem *mmio = par->mmio_start_virtual;
854  
855  	i810_enable_cursor(mmio, OFF);
856  	i810_writel(CURBASE, mmio, par->cursor_heap.physical);
857  	i810_writew(CURCNTR, mmio, COORD_ACTIVE | CURSOR_MODE_64_XOR);
858  }
859  
860  /*********************************************************************
861   *                    Framebuffer hook helpers                       *
862   *********************************************************************/
863  /**
864   * i810_round_off -  Round off values to capability of hardware
865   * @var: pointer to fb_var_screeninfo structure
866   *
867   * DESCRIPTION:
868   * @var contains user-defined information for the mode to be set.
869   * This will try modify those values to ones nearest the
870   * capability of the hardware
871   */
i810_round_off(struct fb_var_screeninfo * var)872  static void i810_round_off(struct fb_var_screeninfo *var)
873  {
874  	u32 xres, yres, vxres, vyres;
875  
876  	/*
877  	 *  Presently supports only these configurations
878  	 */
879  
880  	xres = var->xres;
881  	yres = var->yres;
882  	vxres = var->xres_virtual;
883  	vyres = var->yres_virtual;
884  
885  	var->bits_per_pixel += 7;
886  	var->bits_per_pixel &= ~7;
887  
888  	if (var->bits_per_pixel < 8)
889  		var->bits_per_pixel = 8;
890  	if (var->bits_per_pixel > 32)
891  		var->bits_per_pixel = 32;
892  
893  	round_off_xres(&xres);
894  	if (xres < 40)
895  		xres = 40;
896  	if (xres > 2048)
897  		xres = 2048;
898  	xres = (xres + 7) & ~7;
899  
900  	if (vxres < xres)
901  		vxres = xres;
902  
903  	round_off_yres(&xres, &yres);
904  	if (yres < 1)
905  		yres = 1;
906  	if (yres >= 2048)
907  		yres = 2048;
908  
909  	if (vyres < yres)
910  		vyres = yres;
911  
912  	if (var->bits_per_pixel == 32)
913  		var->accel_flags = 0;
914  
915  	/* round of horizontal timings to nearest 8 pixels */
916  	var->left_margin = (var->left_margin + 4) & ~7;
917  	var->right_margin = (var->right_margin + 4) & ~7;
918  	var->hsync_len = (var->hsync_len + 4) & ~7;
919  
920  	if (var->vmode & FB_VMODE_INTERLACED) {
921  		if (!((yres + var->upper_margin + var->vsync_len +
922  		       var->lower_margin) & 1))
923  			var->upper_margin++;
924  	}
925  
926  	var->xres = xres;
927  	var->yres = yres;
928  	var->xres_virtual = vxres;
929  	var->yres_virtual = vyres;
930  }
931  
932  /**
933   * set_color_bitfields - sets rgba fields
934   * @var: pointer to fb_var_screeninfo
935   *
936   * DESCRIPTION:
937   * The length, offset and ordering  for each color field
938   * (red, green, blue)  will be set as specified
939   * by the hardware
940   */
set_color_bitfields(struct fb_var_screeninfo * var)941  static void set_color_bitfields(struct fb_var_screeninfo *var)
942  {
943  	switch (var->bits_per_pixel) {
944  	case 8:
945  		var->red.offset = 0;
946  		var->red.length = 8;
947  		var->green.offset = 0;
948  		var->green.length = 8;
949  		var->blue.offset = 0;
950  		var->blue.length = 8;
951  		var->transp.offset = 0;
952  		var->transp.length = 0;
953  		break;
954  	case 16:
955  		var->green.length = (var->green.length == 5) ? 5 : 6;
956  		var->red.length = 5;
957  		var->blue.length = 5;
958  		var->transp.length = 6 - var->green.length;
959  		var->blue.offset = 0;
960  		var->green.offset = 5;
961  		var->red.offset = 5 + var->green.length;
962  		var->transp.offset =  (5 + var->red.offset) & 15;
963  		break;
964  	case 24:	/* RGB 888   */
965  	case 32:	/* RGBA 8888 */
966  		var->red.offset = 16;
967  		var->red.length = 8;
968  		var->green.offset = 8;
969  		var->green.length = 8;
970  		var->blue.offset = 0;
971  		var->blue.length = 8;
972  		var->transp.length = var->bits_per_pixel - 24;
973  		var->transp.offset = (var->transp.length) ? 24 : 0;
974  		break;
975  	}
976  	var->red.msb_right = 0;
977  	var->green.msb_right = 0;
978  	var->blue.msb_right = 0;
979  	var->transp.msb_right = 0;
980  }
981  
982  /**
983   * i810_check_params - check if contents in var are valid
984   * @var: pointer to fb_var_screeninfo
985   * @info: pointer to fb_info
986   *
987   * DESCRIPTION:
988   * This will check if the framebuffer size is sufficient
989   * for the current mode and if the user's monitor has the
990   * required specifications to display the current mode.
991   */
i810_check_params(struct fb_var_screeninfo * var,struct fb_info * info)992  static int i810_check_params(struct fb_var_screeninfo *var,
993  			     struct fb_info *info)
994  {
995  	struct i810fb_par *par = info->par;
996  	int line_length, vidmem, mode_valid = 0, retval = 0;
997  	u32 vyres = var->yres_virtual, vxres = var->xres_virtual;
998  
999  	/*
1000  	 *  Memory limit
1001  	 */
1002  	line_length = get_line_length(par, vxres, var->bits_per_pixel);
1003  	vidmem = line_length*vyres;
1004  
1005  	if (vidmem > par->fb.size) {
1006  		vyres = par->fb.size/line_length;
1007  		if (vyres < var->yres) {
1008  			vyres = info->var.yres;
1009  			vxres = par->fb.size/vyres;
1010  			vxres /= var->bits_per_pixel >> 3;
1011  			line_length = get_line_length(par, vxres,
1012  						      var->bits_per_pixel);
1013  			vidmem = line_length * info->var.yres;
1014  			if (vxres < var->xres) {
1015  				printk("i810fb: required video memory, "
1016  				       "%d bytes, for %dx%d-%d (virtual) "
1017  				       "is out of range\n",
1018  				       vidmem, vxres, vyres,
1019  				       var->bits_per_pixel);
1020  				return -ENOMEM;
1021  			}
1022  		}
1023  	}
1024  
1025  	var->xres_virtual = vxres;
1026  	var->yres_virtual = vyres;
1027  
1028  	/*
1029  	 * Monitor limit
1030  	 */
1031  	switch (var->bits_per_pixel) {
1032  	case 8:
1033  		info->monspecs.dclkmax = 234000000;
1034  		break;
1035  	case 16:
1036  		info->monspecs.dclkmax = 229000000;
1037  		break;
1038  	case 24:
1039  	case 32:
1040  		info->monspecs.dclkmax = 204000000;
1041  		break;
1042  	}
1043  
1044  	info->monspecs.dclkmin = 15000000;
1045  
1046  	if (!fb_validate_mode(var, info))
1047  		mode_valid = 1;
1048  
1049  #ifdef CONFIG_FB_I810_I2C
1050  	if (!mode_valid && info->monspecs.gtf &&
1051  	    !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1052  		mode_valid = 1;
1053  
1054  	if (!mode_valid && info->monspecs.modedb_len) {
1055  		const struct fb_videomode *mode;
1056  
1057  		mode = fb_find_best_mode(var, &info->modelist);
1058  		if (mode) {
1059  			fb_videomode_to_var(var, mode);
1060  			mode_valid = 1;
1061  		}
1062  	}
1063  #endif
1064  	if (!mode_valid && info->monspecs.modedb_len == 0) {
1065  		if (fb_get_mode(FB_MAXTIMINGS, 0, var, info)) {
1066  			int default_sync = (info->monspecs.hfmin-HFMIN)
1067  				|(info->monspecs.hfmax-HFMAX)
1068  				|(info->monspecs.vfmin-VFMIN)
1069  				|(info->monspecs.vfmax-VFMAX);
1070  			printk("i810fb: invalid video mode%s\n",
1071  			       default_sync ? "" : ". Specifying "
1072  			       "vsyncN/hsyncN parameters may help");
1073  			retval = -EINVAL;
1074  		}
1075  	}
1076  
1077  	return retval;
1078  }
1079  
1080  /**
1081   * encode_fix - fill up fb_fix_screeninfo structure
1082   * @fix: pointer to fb_fix_screeninfo
1083   * @info: pointer to fb_info
1084   *
1085   * DESCRIPTION:
1086   * This will set up parameters that are unmodifiable by the user.
1087   */
encode_fix(struct fb_fix_screeninfo * fix,struct fb_info * info)1088  static int encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
1089  {
1090  	struct i810fb_par *par = info->par;
1091  
1092      	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1093  
1094      	strcpy(fix->id, "I810");
1095  	mutex_lock(&info->mm_lock);
1096      	fix->smem_start = par->fb.physical;
1097      	fix->smem_len = par->fb.size;
1098  	mutex_unlock(&info->mm_lock);
1099      	fix->type = FB_TYPE_PACKED_PIXELS;
1100      	fix->type_aux = 0;
1101  	fix->xpanstep = 8;
1102  	fix->ypanstep = 1;
1103  
1104      	switch (info->var.bits_per_pixel) {
1105  	case 8:
1106  	    	fix->visual = FB_VISUAL_PSEUDOCOLOR;
1107  	    	break;
1108  	case 16:
1109  	case 24:
1110  	case 32:
1111  		if (info->var.nonstd)
1112  			fix->visual = FB_VISUAL_DIRECTCOLOR;
1113  		else
1114  			fix->visual = FB_VISUAL_TRUECOLOR;
1115  	    	break;
1116  	default:
1117  		return -EINVAL;
1118  	}
1119      	fix->ywrapstep = 0;
1120  	fix->line_length = par->pitch;
1121  	fix->mmio_start = par->mmio_start_phys;
1122  	fix->mmio_len = MMIO_SIZE;
1123  	fix->accel = FB_ACCEL_I810;
1124  
1125  	return 0;
1126  }
1127  
1128  /**
1129   * decode_var - modify par according to contents of var
1130   * @var: pointer to fb_var_screeninfo
1131   * @par: pointer to i810fb_par
1132   *
1133   * DESCRIPTION:
1134   * Based on the contents of @var, @par will be dynamically filled up.
1135   * @par contains all information necessary to modify the hardware.
1136  */
decode_var(const struct fb_var_screeninfo * var,struct i810fb_par * par)1137  static void decode_var(const struct fb_var_screeninfo *var,
1138  		       struct i810fb_par *par)
1139  {
1140  	u32 xres, yres, vxres, vyres;
1141  
1142  	xres = var->xres;
1143  	yres = var->yres;
1144  	vxres = var->xres_virtual;
1145  	vyres = var->yres_virtual;
1146  
1147  	switch (var->bits_per_pixel) {
1148  	case 8:
1149  		par->pixconf = PIXCONF8;
1150  		par->bltcntl = 0;
1151  		par->depth = 1;
1152  		par->blit_bpp = BPP8;
1153  		break;
1154  	case 16:
1155  		if (var->green.length == 5)
1156  			par->pixconf = PIXCONF15;
1157  		else
1158  			par->pixconf = PIXCONF16;
1159  		par->bltcntl = 16;
1160  		par->depth = 2;
1161  		par->blit_bpp = BPP16;
1162  		break;
1163  	case 24:
1164  		par->pixconf = PIXCONF24;
1165  		par->bltcntl = 32;
1166  		par->depth = 3;
1167  		par->blit_bpp = BPP24;
1168  		break;
1169  	case 32:
1170  		par->pixconf = PIXCONF32;
1171  		par->bltcntl = 0;
1172  		par->depth = 4;
1173  		par->blit_bpp = 3 << 24;
1174  		break;
1175  	}
1176  	if (var->nonstd && var->bits_per_pixel != 8)
1177  		par->pixconf |= 1 << 27;
1178  
1179  	i810_calc_dclk(var->pixclock, &par->regs.M,
1180  		       &par->regs.N, &par->regs.P);
1181  	i810fb_encode_registers(var, par, xres, yres);
1182  
1183  	par->watermark = i810_get_watermark(var, par);
1184  	par->pitch = get_line_length(par, vxres, var->bits_per_pixel);
1185  }
1186  
1187  /**
1188   * i810fb_getcolreg - gets red, green and blue values of the hardware DAC
1189   * @regno: DAC index
1190   * @red: red
1191   * @green: green
1192   * @blue: blue
1193   * @transp: transparency (alpha)
1194   * @info: pointer to fb_info
1195   *
1196   * DESCRIPTION:
1197   * Gets the red, green and blue values of the hardware DAC as pointed by @regno
1198   * and writes them to @red, @green and @blue respectively
1199   */
i810fb_getcolreg(u8 regno,u8 * red,u8 * green,u8 * blue,u8 * transp,struct fb_info * info)1200  static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue,
1201  			    u8 *transp, struct fb_info *info)
1202  {
1203  	struct i810fb_par *par = info->par;
1204  	u8 __iomem *mmio = par->mmio_start_virtual;
1205  	u8 temp;
1206  
1207  	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1208  		if ((info->var.green.length == 5 && regno > 31) ||
1209  		    (info->var.green.length == 6 && regno > 63))
1210  			return 1;
1211  	}
1212  
1213  	temp = i810_readb(PIXCONF1, mmio);
1214  	i810_writeb(PIXCONF1, mmio, temp & ~EXTENDED_PALETTE);
1215  
1216  	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR &&
1217  	    info->var.green.length == 5)
1218  		i810_read_dac(regno * 8, red, green, blue, mmio);
1219  
1220  	else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR &&
1221  		 info->var.green.length == 6) {
1222  		u8 tmp;
1223  
1224  		i810_read_dac(regno * 8, red, &tmp, blue, mmio);
1225  		i810_read_dac(regno * 4, &tmp, green, &tmp, mmio);
1226  	}
1227  	else
1228  		i810_read_dac(regno, red, green, blue, mmio);
1229  
1230      	*transp = 0;
1231  	i810_writeb(PIXCONF1, mmio, temp);
1232  
1233      	return 0;
1234  }
1235  
1236  /******************************************************************
1237   *           Framebuffer device-specific hooks                    *
1238   ******************************************************************/
1239  
i810fb_open(struct fb_info * info,int user)1240  static int i810fb_open(struct fb_info *info, int user)
1241  {
1242  	struct i810fb_par *par = info->par;
1243  
1244  	mutex_lock(&par->open_lock);
1245  	if (par->use_count == 0) {
1246  		memset(&par->state, 0, sizeof(struct vgastate));
1247  		par->state.flags = VGA_SAVE_CMAP;
1248  		par->state.vgabase = par->mmio_start_virtual;
1249  		save_vga(&par->state);
1250  
1251  		i810_save_vga_state(par);
1252  	}
1253  
1254  	par->use_count++;
1255  	mutex_unlock(&par->open_lock);
1256  
1257  	return 0;
1258  }
1259  
i810fb_release(struct fb_info * info,int user)1260  static int i810fb_release(struct fb_info *info, int user)
1261  {
1262  	struct i810fb_par *par = info->par;
1263  
1264  	mutex_lock(&par->open_lock);
1265  	if (par->use_count == 0) {
1266  		mutex_unlock(&par->open_lock);
1267  		return -EINVAL;
1268  	}
1269  
1270  	if (par->use_count == 1) {
1271  		i810_restore_vga_state(par);
1272  		restore_vga(&par->state);
1273  	}
1274  
1275  	par->use_count--;
1276  	mutex_unlock(&par->open_lock);
1277  
1278  	return 0;
1279  }
1280  
1281  
i810fb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)1282  static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green,
1283  			    unsigned blue, unsigned transp,
1284  			    struct fb_info *info)
1285  {
1286  	struct i810fb_par *par = info->par;
1287  	u8 __iomem *mmio = par->mmio_start_virtual;
1288  	u8 temp;
1289  	int i;
1290  
1291   	if (regno > 255) return 1;
1292  
1293  	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1294  		if ((info->var.green.length == 5 && regno > 31) ||
1295  		    (info->var.green.length == 6 && regno > 63))
1296  			return 1;
1297  	}
1298  
1299  	if (info->var.grayscale)
1300  		red = green = blue = (19595 * red + 38470 * green +
1301  				      7471 * blue) >> 16;
1302  
1303  	temp = i810_readb(PIXCONF1, mmio);
1304  	i810_writeb(PIXCONF1, mmio, temp & ~EXTENDED_PALETTE);
1305  
1306  	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR &&
1307  	    info->var.green.length == 5) {
1308  		for (i = 0; i < 8; i++)
1309  			i810_write_dac((u8) (regno * 8) + i, (u8) red,
1310  				       (u8) green, (u8) blue, mmio);
1311  	} else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR &&
1312  		 info->var.green.length == 6) {
1313  		u8 r, g, b;
1314  
1315  		if (regno < 32) {
1316  			for (i = 0; i < 8; i++)
1317  				i810_write_dac((u8) (regno * 8) + i,
1318  					       (u8) red, (u8) green,
1319  					       (u8) blue, mmio);
1320  		}
1321  		i810_read_dac((u8) (regno*4), &r, &g, &b, mmio);
1322  		for (i = 0; i < 4; i++)
1323  			i810_write_dac((u8) (regno*4) + i, r, (u8) green,
1324  				       b, mmio);
1325  	} else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
1326  		i810_write_dac((u8) regno, (u8) red, (u8) green,
1327  			       (u8) blue, mmio);
1328  	}
1329  
1330  	i810_writeb(PIXCONF1, mmio, temp);
1331  
1332  	if (regno < 16) {
1333  		switch (info->var.bits_per_pixel) {
1334  		case 16:
1335  			if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
1336  				if (info->var.green.length == 5)
1337  					((u32 *)info->pseudo_palette)[regno] =
1338  						(regno << 10) | (regno << 5) |
1339  						regno;
1340  				else
1341  					((u32 *)info->pseudo_palette)[regno] =
1342  						(regno << 11) | (regno << 5) |
1343  						regno;
1344  			} else {
1345  				if (info->var.green.length == 5) {
1346  					/* RGB 555 */
1347  					((u32 *)info->pseudo_palette)[regno] =
1348  						((red & 0xf800) >> 1) |
1349  						((green & 0xf800) >> 6) |
1350  						((blue & 0xf800) >> 11);
1351  				} else {
1352  					/* RGB 565 */
1353  					((u32 *)info->pseudo_palette)[regno] =
1354  						(red & 0xf800) |
1355  						((green & 0xf800) >> 5) |
1356  						((blue & 0xf800) >> 11);
1357  				}
1358  			}
1359  			break;
1360  		case 24:	/* RGB 888 */
1361  		case 32:	/* RGBA 8888 */
1362  			if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
1363  				((u32 *)info->pseudo_palette)[regno] =
1364  					(regno << 16) | (regno << 8) |
1365  					regno;
1366  			else
1367  				((u32 *)info->pseudo_palette)[regno] =
1368  					((red & 0xff00) << 8) |
1369  					(green & 0xff00) |
1370  					((blue & 0xff00) >> 8);
1371  			break;
1372  		}
1373  	}
1374  	return 0;
1375  }
1376  
i810fb_pan_display(struct fb_var_screeninfo * var,struct fb_info * info)1377  static int i810fb_pan_display(struct fb_var_screeninfo *var,
1378  			      struct fb_info *info)
1379  {
1380  	struct i810fb_par *par = info->par;
1381  	u32 total;
1382  
1383  	total = var->xoffset * par->depth +
1384  		var->yoffset * info->fix.line_length;
1385  	i810fb_load_front(total, info);
1386  
1387  	return 0;
1388  }
1389  
i810fb_blank(int blank_mode,struct fb_info * info)1390  static int i810fb_blank (int blank_mode, struct fb_info *info)
1391  {
1392  	struct i810fb_par *par = info->par;
1393  	u8 __iomem *mmio = par->mmio_start_virtual;
1394  	int mode = 0, pwr, scr_off = 0;
1395  
1396  	pwr = i810_readl(PWR_CLKC, mmio);
1397  
1398  	switch (blank_mode) {
1399  	case FB_BLANK_UNBLANK:
1400  		mode = POWERON;
1401  		pwr |= 1;
1402  		scr_off = ON;
1403  		break;
1404  	case FB_BLANK_NORMAL:
1405  		mode = POWERON;
1406  		pwr |= 1;
1407  		scr_off = OFF;
1408  		break;
1409  	case FB_BLANK_VSYNC_SUSPEND:
1410  		mode = STANDBY;
1411  		pwr |= 1;
1412  		scr_off = OFF;
1413  		break;
1414  	case FB_BLANK_HSYNC_SUSPEND:
1415  		mode = SUSPEND;
1416  		pwr |= 1;
1417  		scr_off = OFF;
1418  		break;
1419  	case FB_BLANK_POWERDOWN:
1420  		mode = POWERDOWN;
1421  		pwr &= ~1;
1422  		scr_off = OFF;
1423  		break;
1424  	default:
1425  		return -EINVAL;
1426  	}
1427  
1428  	i810_screen_off(mmio, scr_off);
1429  	i810_writel(HVSYNC, mmio, mode);
1430  	i810_writel(PWR_CLKC, mmio, pwr);
1431  
1432  	return 0;
1433  }
1434  
i810fb_set_par(struct fb_info * info)1435  static int i810fb_set_par(struct fb_info *info)
1436  {
1437  	struct i810fb_par *par = info->par;
1438  
1439  	decode_var(&info->var, par);
1440  	i810_load_regs(par);
1441  	i810_init_cursor(par);
1442  	encode_fix(&info->fix, info);
1443  
1444  	if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) {
1445  		info->flags = FBINFO_HWACCEL_YPAN |
1446  		FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1447  		FBINFO_HWACCEL_IMAGEBLIT;
1448  		info->pixmap.scan_align = 2;
1449  	} else {
1450  		info->pixmap.scan_align = 1;
1451  		info->flags = FBINFO_HWACCEL_YPAN;
1452  	}
1453  	return 0;
1454  }
1455  
i810fb_check_var(struct fb_var_screeninfo * var,struct fb_info * info)1456  static int i810fb_check_var(struct fb_var_screeninfo *var,
1457  			    struct fb_info *info)
1458  {
1459  	int err;
1460  
1461  	if (IS_DVT) {
1462  		var->vmode &= ~FB_VMODE_MASK;
1463  		var->vmode |= FB_VMODE_NONINTERLACED;
1464  	}
1465  	if (var->vmode & FB_VMODE_DOUBLE) {
1466  		var->vmode &= ~FB_VMODE_MASK;
1467  		var->vmode |= FB_VMODE_NONINTERLACED;
1468  	}
1469  
1470  	i810_round_off(var);
1471  	if ((err = i810_check_params(var, info)))
1472  		return err;
1473  
1474  	i810fb_fill_var_timings(var);
1475  	set_color_bitfields(var);
1476  	return 0;
1477  }
1478  
i810fb_cursor(struct fb_info * info,struct fb_cursor * cursor)1479  static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1480  {
1481  	struct i810fb_par *par = info->par;
1482  	u8 __iomem *mmio = par->mmio_start_virtual;
1483  
1484  	if (par->dev_flags & LOCKUP)
1485  		return -ENXIO;
1486  
1487  	if (cursor->image.width > 64 || cursor->image.height > 64)
1488  		return -ENXIO;
1489  
1490  	if ((i810_readl(CURBASE, mmio) & 0xf) != par->cursor_heap.physical) {
1491  		i810_init_cursor(par);
1492  		cursor->set |= FB_CUR_SETALL;
1493  	}
1494  
1495  	i810_enable_cursor(mmio, OFF);
1496  
1497  	if (cursor->set & FB_CUR_SETPOS) {
1498  		u32 tmp;
1499  
1500  		tmp = (cursor->image.dx - info->var.xoffset) & 0xffff;
1501  		tmp |= (cursor->image.dy - info->var.yoffset) << 16;
1502  		i810_writel(CURPOS, mmio, tmp);
1503  	}
1504  
1505  	if (cursor->set & FB_CUR_SETSIZE)
1506  		i810_reset_cursor_image(par);
1507  
1508  	if (cursor->set & FB_CUR_SETCMAP)
1509  		i810_load_cursor_colors(cursor->image.fg_color,
1510  					cursor->image.bg_color,
1511  					info);
1512  
1513  	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1514  		int size = ((cursor->image.width + 7) >> 3) *
1515  			cursor->image.height;
1516  		int i;
1517  		u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
1518  
1519  		if (data == NULL)
1520  			return -ENOMEM;
1521  
1522  		switch (cursor->rop) {
1523  		case ROP_XOR:
1524  			for (i = 0; i < size; i++)
1525  				data[i] = cursor->image.data[i] ^ cursor->mask[i];
1526  			break;
1527  		case ROP_COPY:
1528  		default:
1529  			for (i = 0; i < size; i++)
1530  				data[i] = cursor->image.data[i] & cursor->mask[i];
1531  			break;
1532  		}
1533  
1534  		i810_load_cursor_image(cursor->image.width,
1535  				       cursor->image.height, data,
1536  				       par);
1537  		kfree(data);
1538  	}
1539  
1540  	if (cursor->enable)
1541  		i810_enable_cursor(mmio, ON);
1542  
1543  	return 0;
1544  }
1545  
1546  static const struct fb_ops i810fb_ops = {
1547  	.owner =             THIS_MODULE,
1548  	.fb_open =           i810fb_open,
1549  	.fb_release =        i810fb_release,
1550  	.fb_check_var =      i810fb_check_var,
1551  	.fb_set_par =        i810fb_set_par,
1552  	.fb_setcolreg =      i810fb_setcolreg,
1553  	.fb_blank =          i810fb_blank,
1554  	.fb_pan_display =    i810fb_pan_display,
1555  	.fb_fillrect =       i810fb_fillrect,
1556  	.fb_copyarea =       i810fb_copyarea,
1557  	.fb_imageblit =      i810fb_imageblit,
1558  	.fb_cursor =         i810fb_cursor,
1559  	.fb_sync =           i810fb_sync,
1560  };
1561  
1562  /***********************************************************************
1563   *                         Power Management                            *
1564   ***********************************************************************/
i810fb_suspend(struct pci_dev * dev,pm_message_t mesg)1565  static int i810fb_suspend(struct pci_dev *dev, pm_message_t mesg)
1566  {
1567  	struct fb_info *info = pci_get_drvdata(dev);
1568  	struct i810fb_par *par = info->par;
1569  
1570  	par->cur_state = mesg.event;
1571  
1572  	switch (mesg.event) {
1573  	case PM_EVENT_FREEZE:
1574  	case PM_EVENT_PRETHAW:
1575  		dev->dev.power.power_state = mesg;
1576  		return 0;
1577  	}
1578  
1579  	console_lock();
1580  	fb_set_suspend(info, 1);
1581  
1582  	if (info->fbops->fb_sync)
1583  		info->fbops->fb_sync(info);
1584  
1585  	i810fb_blank(FB_BLANK_POWERDOWN, info);
1586  	agp_unbind_memory(par->i810_gtt.i810_fb_memory);
1587  	agp_unbind_memory(par->i810_gtt.i810_cursor_memory);
1588  
1589  	pci_save_state(dev);
1590  	pci_disable_device(dev);
1591  	pci_set_power_state(dev, pci_choose_state(dev, mesg));
1592  	console_unlock();
1593  
1594  	return 0;
1595  }
1596  
i810fb_resume(struct pci_dev * dev)1597  static int i810fb_resume(struct pci_dev *dev)
1598  {
1599  	struct fb_info *info = pci_get_drvdata(dev);
1600  	struct i810fb_par *par = info->par;
1601  	int cur_state = par->cur_state;
1602  
1603  	par->cur_state = PM_EVENT_ON;
1604  
1605  	if (cur_state == PM_EVENT_FREEZE) {
1606  		pci_set_power_state(dev, PCI_D0);
1607  		return 0;
1608  	}
1609  
1610  	console_lock();
1611  	pci_set_power_state(dev, PCI_D0);
1612  	pci_restore_state(dev);
1613  
1614  	if (pci_enable_device(dev))
1615  		goto fail;
1616  
1617  	pci_set_master(dev);
1618  	agp_bind_memory(par->i810_gtt.i810_fb_memory,
1619  			par->fb.offset);
1620  	agp_bind_memory(par->i810_gtt.i810_cursor_memory,
1621  			par->cursor_heap.offset);
1622  	i810fb_set_par(info);
1623  	fb_set_suspend (info, 0);
1624  	info->fbops->fb_blank(VESA_NO_BLANKING, info);
1625  fail:
1626  	console_unlock();
1627  	return 0;
1628  }
1629  /***********************************************************************
1630   *                  AGP resource allocation                            *
1631   ***********************************************************************/
1632  
i810_fix_pointers(struct i810fb_par * par)1633  static void i810_fix_pointers(struct i810fb_par *par)
1634  {
1635        	par->fb.physical = par->aperture.physical+(par->fb.offset << 12);
1636  	par->fb.virtual = par->aperture.virtual+(par->fb.offset << 12);
1637  	par->iring.physical = par->aperture.physical +
1638  		(par->iring.offset << 12);
1639  	par->iring.virtual = par->aperture.virtual +
1640  		(par->iring.offset << 12);
1641  	par->cursor_heap.virtual = par->aperture.virtual+
1642  		(par->cursor_heap.offset << 12);
1643  }
1644  
i810_fix_offsets(struct i810fb_par * par)1645  static void i810_fix_offsets(struct i810fb_par *par)
1646  {
1647  	if (vram + 1 > par->aperture.size >> 20)
1648  		vram = (par->aperture.size >> 20) - 1;
1649  	if (v_offset_default > (par->aperture.size >> 20))
1650  		v_offset_default = (par->aperture.size >> 20);
1651  	if (vram + v_offset_default + 1 > par->aperture.size >> 20)
1652  		v_offset_default = (par->aperture.size >> 20) - (vram + 1);
1653  
1654  	par->fb.size = vram << 20;
1655  	par->fb.offset = v_offset_default << 20;
1656  	par->fb.offset >>= 12;
1657  
1658  	par->iring.offset = par->fb.offset + (par->fb.size >> 12);
1659  	par->iring.size = RINGBUFFER_SIZE;
1660  
1661  	par->cursor_heap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);
1662  	par->cursor_heap.size = 4096;
1663  }
1664  
i810_alloc_agp_mem(struct fb_info * info)1665  static int i810_alloc_agp_mem(struct fb_info *info)
1666  {
1667  	struct i810fb_par *par = info->par;
1668  	int size;
1669  	struct agp_bridge_data *bridge;
1670  
1671  	i810_fix_offsets(par);
1672  	size = par->fb.size + par->iring.size;
1673  
1674  	if (!(bridge = agp_backend_acquire(par->dev))) {
1675  		printk("i810fb_alloc_fbmem: cannot acquire agpgart\n");
1676  		return -ENODEV;
1677  	}
1678  	if (!(par->i810_gtt.i810_fb_memory =
1679  	      agp_allocate_memory(bridge, size >> 12, AGP_NORMAL_MEMORY))) {
1680  		printk("i810fb_alloc_fbmem: can't allocate framebuffer "
1681  		       "memory\n");
1682  		agp_backend_release(bridge);
1683  		return -ENOMEM;
1684  	}
1685  	if (agp_bind_memory(par->i810_gtt.i810_fb_memory,
1686  			    par->fb.offset)) {
1687  		printk("i810fb_alloc_fbmem: can't bind framebuffer memory\n");
1688  		agp_backend_release(bridge);
1689  		return -EBUSY;
1690  	}
1691  
1692  	if (!(par->i810_gtt.i810_cursor_memory =
1693  	      agp_allocate_memory(bridge, par->cursor_heap.size >> 12,
1694  				  AGP_PHYSICAL_MEMORY))) {
1695  		printk("i810fb_alloc_cursormem:  can't allocate "
1696  		       "cursor memory\n");
1697  		agp_backend_release(bridge);
1698  		return -ENOMEM;
1699  	}
1700  	if (agp_bind_memory(par->i810_gtt.i810_cursor_memory,
1701  			    par->cursor_heap.offset)) {
1702  		printk("i810fb_alloc_cursormem: cannot bind cursor memory\n");
1703  		agp_backend_release(bridge);
1704  		return -EBUSY;
1705  	}
1706  
1707  	par->cursor_heap.physical = par->i810_gtt.i810_cursor_memory->physical;
1708  
1709  	i810_fix_pointers(par);
1710  
1711  	agp_backend_release(bridge);
1712  
1713  	return 0;
1714  }
1715  
1716  /***************************************************************
1717   *                    Initialization                           *
1718   ***************************************************************/
1719  
1720  /**
1721   * i810_init_monspecs
1722   * @info: pointer to device specific info structure
1723   *
1724   * DESCRIPTION:
1725   * Sets the user monitor's horizontal and vertical
1726   * frequency limits
1727   */
i810_init_monspecs(struct fb_info * info)1728  static void i810_init_monspecs(struct fb_info *info)
1729  {
1730  	if (!hsync1)
1731  		hsync1 = HFMIN;
1732  	if (!hsync2)
1733  		hsync2 = HFMAX;
1734  	if (!info->monspecs.hfmax)
1735  		info->monspecs.hfmax = hsync2;
1736  	if (!info->monspecs.hfmin)
1737  		info->monspecs.hfmin = hsync1;
1738  	if (hsync2 < hsync1)
1739  		info->monspecs.hfmin = hsync2;
1740  
1741  	if (!vsync1)
1742  		vsync1 = VFMIN;
1743  	if (!vsync2)
1744  		vsync2 = VFMAX;
1745  	if (IS_DVT && vsync1 < 60)
1746  		vsync1 = 60;
1747  	if (!info->monspecs.vfmax)
1748  		info->monspecs.vfmax = vsync2;
1749  	if (!info->monspecs.vfmin)
1750  		info->monspecs.vfmin = vsync1;
1751  	if (vsync2 < vsync1)
1752  		info->monspecs.vfmin = vsync2;
1753  }
1754  
1755  /**
1756   * i810_init_defaults - initializes default values to use
1757   * @par: pointer to i810fb_par structure
1758   * @info: pointer to current fb_info structure
1759   */
i810_init_defaults(struct i810fb_par * par,struct fb_info * info)1760  static void i810_init_defaults(struct i810fb_par *par, struct fb_info *info)
1761  {
1762  	mutex_init(&par->open_lock);
1763  
1764  	if (voffset)
1765  		v_offset_default = voffset;
1766  	else if (par->aperture.size > 32 * 1024 * 1024)
1767  		v_offset_default = 16;
1768  	else
1769  		v_offset_default = 8;
1770  
1771  	if (!vram)
1772  		vram = 1;
1773  
1774  	if (accel)
1775  		par->dev_flags |= HAS_ACCELERATION;
1776  
1777  	if (sync)
1778  		par->dev_flags |= ALWAYS_SYNC;
1779  
1780  	par->ddc_num = (ddc3 ? 3 : 2);
1781  
1782  	if (bpp < 8)
1783  		bpp = 8;
1784  
1785  	par->i810fb_ops = i810fb_ops;
1786  
1787  	if (xres)
1788  		info->var.xres = xres;
1789  	else
1790  		info->var.xres = 640;
1791  
1792  	if (yres)
1793  		info->var.yres = yres;
1794  	else
1795  		info->var.yres = 480;
1796  
1797  	if (!vyres)
1798  		vyres = (vram << 20)/(info->var.xres*bpp >> 3);
1799  
1800  	info->var.yres_virtual = vyres;
1801  	info->var.bits_per_pixel = bpp;
1802  
1803  	if (dcolor)
1804  		info->var.nonstd = 1;
1805  
1806  	if (par->dev_flags & HAS_ACCELERATION)
1807  		info->var.accel_flags = 1;
1808  
1809  	i810_init_monspecs(info);
1810  }
1811  
1812  /**
1813   * i810_init_device - initialize device
1814   * @par: pointer to i810fb_par structure
1815   */
i810_init_device(struct i810fb_par * par)1816  static void i810_init_device(struct i810fb_par *par)
1817  {
1818  	u8 reg;
1819  	u8 __iomem *mmio = par->mmio_start_virtual;
1820  
1821  	if (mtrr)
1822  		par->wc_cookie= arch_phys_wc_add((u32) par->aperture.physical,
1823  						 par->aperture.size);
1824  
1825  	i810_init_cursor(par);
1826  
1827  	/* mvo: enable external vga-connector (for laptops) */
1828  	if (extvga) {
1829  		i810_writel(HVSYNC, mmio, 0);
1830  		i810_writel(PWR_CLKC, mmio, 3);
1831  	}
1832  
1833  	pci_read_config_byte(par->dev, 0x50, &reg);
1834  	reg &= FREQ_MASK;
1835  	par->mem_freq = (reg) ? 133 : 100;
1836  
1837  }
1838  
i810_allocate_pci_resource(struct i810fb_par * par,const struct pci_device_id * entry)1839  static int i810_allocate_pci_resource(struct i810fb_par *par,
1840  				      const struct pci_device_id *entry)
1841  {
1842  	int err;
1843  
1844  	if ((err = pci_enable_device(par->dev))) {
1845  		printk("i810fb_init: cannot enable device\n");
1846  		return err;
1847  	}
1848  	par->res_flags |= PCI_DEVICE_ENABLED;
1849  
1850  	if (pci_resource_len(par->dev, 0) > 512 * 1024) {
1851  		par->aperture.physical = pci_resource_start(par->dev, 0);
1852  		par->aperture.size = pci_resource_len(par->dev, 0);
1853  		par->mmio_start_phys = pci_resource_start(par->dev, 1);
1854  	} else {
1855  		par->aperture.physical = pci_resource_start(par->dev, 1);
1856  		par->aperture.size = pci_resource_len(par->dev, 1);
1857  		par->mmio_start_phys = pci_resource_start(par->dev, 0);
1858  	}
1859  	if (!par->aperture.size) {
1860  		printk("i810fb_init: device is disabled\n");
1861  		return -ENOMEM;
1862  	}
1863  
1864  	if (!request_mem_region(par->aperture.physical,
1865  				par->aperture.size,
1866  				i810_pci_list[entry->driver_data])) {
1867  		printk("i810fb_init: cannot request framebuffer region\n");
1868  		return -ENODEV;
1869  	}
1870  	par->res_flags |= FRAMEBUFFER_REQ;
1871  
1872  	par->aperture.virtual = ioremap_wc(par->aperture.physical,
1873  					   par->aperture.size);
1874  	if (!par->aperture.virtual) {
1875  		printk("i810fb_init: cannot remap framebuffer region\n");
1876  		return -ENODEV;
1877  	}
1878  
1879  	if (!request_mem_region(par->mmio_start_phys,
1880  				MMIO_SIZE,
1881  				i810_pci_list[entry->driver_data])) {
1882  		printk("i810fb_init: cannot request mmio region\n");
1883  		return -ENODEV;
1884  	}
1885  	par->res_flags |= MMIO_REQ;
1886  
1887  	par->mmio_start_virtual = ioremap(par->mmio_start_phys,
1888  						  MMIO_SIZE);
1889  	if (!par->mmio_start_virtual) {
1890  		printk("i810fb_init: cannot remap mmio region\n");
1891  		return -ENODEV;
1892  	}
1893  
1894  	return 0;
1895  }
1896  
i810fb_find_init_mode(struct fb_info * info)1897  static void i810fb_find_init_mode(struct fb_info *info)
1898  {
1899  	struct fb_videomode mode;
1900  	struct fb_var_screeninfo var;
1901  	struct fb_monspecs *specs = &info->monspecs;
1902  	int found = 0;
1903  #ifdef CONFIG_FB_I810_I2C
1904  	int i;
1905  	int err = 1;
1906  	struct i810fb_par *par = info->par;
1907  #endif
1908  
1909  	INIT_LIST_HEAD(&info->modelist);
1910  	memset(&mode, 0, sizeof(struct fb_videomode));
1911  	var = info->var;
1912  #ifdef CONFIG_FB_I810_I2C
1913  	i810_create_i2c_busses(par);
1914  
1915  	for (i = 0; i < par->ddc_num + 1; i++) {
1916  		err = i810_probe_i2c_connector(info, &par->edid, i);
1917  		if (!err)
1918  			break;
1919  	}
1920  
1921  	if (!err)
1922  		printk("i810fb_init_pci: DDC probe successful\n");
1923  
1924  	fb_edid_to_monspecs(par->edid, specs);
1925  
1926  	if (specs->modedb == NULL)
1927  		printk("i810fb_init_pci: Unable to get Mode Database\n");
1928  
1929  	fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
1930  				 &info->modelist);
1931  	if (specs->modedb != NULL) {
1932  		const struct fb_videomode *m;
1933  
1934  		if (xres && yres) {
1935  			if ((m = fb_find_best_mode(&var, &info->modelist))) {
1936  				mode = *m;
1937  				found  = 1;
1938  			}
1939  		}
1940  
1941  		if (!found) {
1942  			m = fb_find_best_display(&info->monspecs, &info->modelist);
1943  			mode = *m;
1944  			found = 1;
1945  		}
1946  
1947  		fb_videomode_to_var(&var, &mode);
1948  	}
1949  #endif
1950  	if (mode_option)
1951  		fb_find_mode(&var, info, mode_option, specs->modedb,
1952  			     specs->modedb_len, (found) ? &mode : NULL,
1953  			     info->var.bits_per_pixel);
1954  
1955  	info->var = var;
1956  	fb_destroy_modedb(specs->modedb);
1957  	specs->modedb = NULL;
1958  }
1959  
1960  #ifndef MODULE
i810fb_setup(char * options)1961  static int i810fb_setup(char *options)
1962  {
1963  	char *this_opt, *suffix = NULL;
1964  
1965  	if (!options || !*options)
1966  		return 0;
1967  
1968  	while ((this_opt = strsep(&options, ",")) != NULL) {
1969  		if (!strncmp(this_opt, "mtrr", 4))
1970  			mtrr = true;
1971  		else if (!strncmp(this_opt, "accel", 5))
1972  			accel = true;
1973  		else if (!strncmp(this_opt, "extvga", 6))
1974  			extvga = true;
1975  		else if (!strncmp(this_opt, "sync", 4))
1976  			sync = true;
1977  		else if (!strncmp(this_opt, "vram:", 5))
1978  			vram = (simple_strtoul(this_opt+5, NULL, 0));
1979  		else if (!strncmp(this_opt, "voffset:", 8))
1980  			voffset = (simple_strtoul(this_opt+8, NULL, 0));
1981  		else if (!strncmp(this_opt, "xres:", 5))
1982  			xres = simple_strtoul(this_opt+5, NULL, 0);
1983  		else if (!strncmp(this_opt, "yres:", 5))
1984  			yres = simple_strtoul(this_opt+5, NULL, 0);
1985  		else if (!strncmp(this_opt, "vyres:", 6))
1986  			vyres = simple_strtoul(this_opt+6, NULL, 0);
1987  		else if (!strncmp(this_opt, "bpp:", 4))
1988  			bpp = simple_strtoul(this_opt+4, NULL, 0);
1989  		else if (!strncmp(this_opt, "hsync1:", 7)) {
1990  			hsync1 = simple_strtoul(this_opt+7, &suffix, 0);
1991  			if (strncmp(suffix, "H", 1))
1992  				hsync1 *= 1000;
1993  		} else if (!strncmp(this_opt, "hsync2:", 7)) {
1994  			hsync2 = simple_strtoul(this_opt+7, &suffix, 0);
1995  			if (strncmp(suffix, "H", 1))
1996  				hsync2 *= 1000;
1997  		} else if (!strncmp(this_opt, "vsync1:", 7))
1998  			vsync1 = simple_strtoul(this_opt+7, NULL, 0);
1999  		else if (!strncmp(this_opt, "vsync2:", 7))
2000  			vsync2 = simple_strtoul(this_opt+7, NULL, 0);
2001  		else if (!strncmp(this_opt, "dcolor", 6))
2002  			dcolor = true;
2003  		else if (!strncmp(this_opt, "ddc3", 4))
2004  			ddc3 = true;
2005  		else
2006  			mode_option = this_opt;
2007  	}
2008  	return 0;
2009  }
2010  #endif
2011  
i810fb_init_pci(struct pci_dev * dev,const struct pci_device_id * entry)2012  static int i810fb_init_pci(struct pci_dev *dev,
2013  			   const struct pci_device_id *entry)
2014  {
2015  	struct fb_info    *info;
2016  	struct i810fb_par *par = NULL;
2017  	struct fb_videomode mode;
2018  	int err = -1, vfreq, hfreq, pixclock;
2019  
2020  	err = aperture_remove_conflicting_pci_devices(dev, "i810fb");
2021  	if (err)
2022  		return err;
2023  
2024  	info = framebuffer_alloc(sizeof(struct i810fb_par), &dev->dev);
2025  	if (!info)
2026  		return -ENOMEM;
2027  
2028  	par = info->par;
2029  	par->dev = dev;
2030  
2031  	if (!(info->pixmap.addr = kzalloc(8*1024, GFP_KERNEL))) {
2032  		i810fb_release_resource(info, par);
2033  		return -ENOMEM;
2034  	}
2035  	info->pixmap.size = 8*1024;
2036  	info->pixmap.buf_align = 8;
2037  	info->pixmap.access_align = 32;
2038  	info->pixmap.flags = FB_PIXMAP_SYSTEM;
2039  
2040  	if ((err = i810_allocate_pci_resource(par, entry))) {
2041  		i810fb_release_resource(info, par);
2042  		return err;
2043  	}
2044  
2045  	i810_init_defaults(par, info);
2046  
2047  	if ((err = i810_alloc_agp_mem(info))) {
2048  		i810fb_release_resource(info, par);
2049  		return err;
2050  	}
2051  
2052  	i810_init_device(par);
2053  
2054  	info->screen_base = par->fb.virtual;
2055  	info->fbops = &par->i810fb_ops;
2056  	info->pseudo_palette = par->pseudo_palette;
2057  	fb_alloc_cmap(&info->cmap, 256, 0);
2058  	i810fb_find_init_mode(info);
2059  
2060  	if ((err = info->fbops->fb_check_var(&info->var, info))) {
2061  		i810fb_release_resource(info, par);
2062  		return err;
2063  	}
2064  
2065  	fb_var_to_videomode(&mode, &info->var);
2066  	fb_add_videomode(&mode, &info->modelist);
2067  
2068  	i810fb_init_ringbuffer(info);
2069  	err = register_framebuffer(info);
2070  
2071  	if (err < 0) {
2072      		i810fb_release_resource(info, par);
2073  		printk("i810fb_init: cannot register framebuffer device\n");
2074      		return err;
2075      	}
2076  
2077  	pci_set_drvdata(dev, info);
2078  	pixclock = 1000000000/(info->var.pixclock);
2079  	pixclock *= 1000;
2080  	hfreq = pixclock/(info->var.xres + info->var.left_margin +
2081  			  info->var.hsync_len + info->var.right_margin);
2082  	vfreq = hfreq/(info->var.yres + info->var.upper_margin +
2083  		       info->var.vsync_len + info->var.lower_margin);
2084  
2085        	printk("I810FB: fb%d         : %s v%d.%d.%d%s\n"
2086        	       "I810FB: Video RAM   : %dK\n"
2087  	       "I810FB: Monitor     : H: %d-%d KHz V: %d-%d Hz\n"
2088  	       "I810FB: Mode        : %dx%d-%dbpp@%dHz\n",
2089  	       info->node,
2090  	       i810_pci_list[entry->driver_data],
2091  	       VERSION_MAJOR, VERSION_MINOR, VERSION_TEENIE, BRANCH_VERSION,
2092  	       (int) par->fb.size>>10, info->monspecs.hfmin/1000,
2093  	       info->monspecs.hfmax/1000, info->monspecs.vfmin,
2094  	       info->monspecs.vfmax, info->var.xres,
2095  	       info->var.yres, info->var.bits_per_pixel, vfreq);
2096  	return 0;
2097  }
2098  
2099  /***************************************************************
2100   *                     De-initialization                        *
2101   ***************************************************************/
2102  
i810fb_release_resource(struct fb_info * info,struct i810fb_par * par)2103  static void i810fb_release_resource(struct fb_info *info,
2104  				    struct i810fb_par *par)
2105  {
2106  	struct gtt_data *gtt = &par->i810_gtt;
2107  	arch_phys_wc_del(par->wc_cookie);
2108  
2109  	i810_delete_i2c_busses(par);
2110  
2111  	if (par->i810_gtt.i810_cursor_memory)
2112  		agp_free_memory(gtt->i810_cursor_memory);
2113  	if (par->i810_gtt.i810_fb_memory)
2114  		agp_free_memory(gtt->i810_fb_memory);
2115  
2116  	if (par->mmio_start_virtual)
2117  		iounmap(par->mmio_start_virtual);
2118  	if (par->aperture.virtual)
2119  		iounmap(par->aperture.virtual);
2120  	kfree(par->edid);
2121  	if (par->res_flags & FRAMEBUFFER_REQ)
2122  		release_mem_region(par->aperture.physical,
2123  				   par->aperture.size);
2124  	if (par->res_flags & MMIO_REQ)
2125  		release_mem_region(par->mmio_start_phys, MMIO_SIZE);
2126  
2127  	framebuffer_release(info);
2128  
2129  }
2130  
i810fb_remove_pci(struct pci_dev * dev)2131  static void i810fb_remove_pci(struct pci_dev *dev)
2132  {
2133  	struct fb_info *info = pci_get_drvdata(dev);
2134  	struct i810fb_par *par = info->par;
2135  
2136  	unregister_framebuffer(info);
2137  	i810fb_release_resource(info, par);
2138  	printk("cleanup_module:  unloaded i810 framebuffer device\n");
2139  }
2140  
2141  #ifndef MODULE
i810fb_init(void)2142  static int i810fb_init(void)
2143  {
2144  	char *option = NULL;
2145  
2146  	if (fb_modesetting_disabled("i810fb"))
2147  		return -ENODEV;
2148  
2149  	if (fb_get_options("i810fb", &option))
2150  		return -ENODEV;
2151  	i810fb_setup(option);
2152  
2153  	return pci_register_driver(&i810fb_driver);
2154  }
2155  #endif
2156  
2157  /*********************************************************************
2158   *                          Modularization                           *
2159   *********************************************************************/
2160  
2161  #ifdef MODULE
2162  
i810fb_init(void)2163  static int i810fb_init(void)
2164  {
2165  	if (fb_modesetting_disabled("i810fb"))
2166  		return -ENODEV;
2167  
2168  	hsync1 *= 1000;
2169  	hsync2 *= 1000;
2170  
2171  	return pci_register_driver(&i810fb_driver);
2172  }
2173  
2174  module_param(vram, int, 0);
2175  MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB"
2176  		 " (default=4)");
2177  module_param(voffset, int, 0);
2178  MODULE_PARM_DESC(voffset, "at what offset to place start of framebuffer "
2179                   "memory (0 to maximum aperture size), in MiB (default = 48)");
2180  module_param(bpp, int, 0);
2181  MODULE_PARM_DESC(bpp, "Color depth for display in bits per pixel"
2182  		 " (default = 8)");
2183  module_param(xres, int, 0);
2184  MODULE_PARM_DESC(xres, "Horizontal resolution in pixels (default = 640)");
2185  module_param(yres, int, 0);
2186  MODULE_PARM_DESC(yres, "Vertical resolution in scanlines (default = 480)");
2187  module_param(vyres,int, 0);
2188  MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines"
2189  		 " (default = 480)");
2190  module_param(hsync1, int, 0);
2191  MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz"
2192  		 " (default = 29)");
2193  module_param(hsync2, int, 0);
2194  MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz"
2195  		 " (default = 30)");
2196  module_param(vsync1, int, 0);
2197  MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz"
2198  		 " (default = 50)");
2199  module_param(vsync2, int, 0);
2200  MODULE_PARM_DESC(vsync2, "Maximum vertical frequency of monitor in Hz"
2201  		 " (default = 60)");
2202  module_param(accel, bool, 0);
2203  MODULE_PARM_DESC(accel, "Use Acceleration (BLIT) engine (default = 0)");
2204  module_param(mtrr, bool, 0);
2205  MODULE_PARM_DESC(mtrr, "Use MTRR (default = 0)");
2206  module_param(extvga, bool, 0);
2207  MODULE_PARM_DESC(extvga, "Enable external VGA connector (default = 0)");
2208  module_param(sync, bool, 0);
2209  MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"
2210  		 " (default = 0)");
2211  module_param(dcolor, bool, 0);
2212  MODULE_PARM_DESC(dcolor, "use DirectColor visuals"
2213  		 " (default = 0 = TrueColor)");
2214  module_param(ddc3, bool, 0);
2215  MODULE_PARM_DESC(ddc3, "Probe DDC bus 3 (default = 0 = no)");
2216  module_param(mode_option, charp, 0);
2217  MODULE_PARM_DESC(mode_option, "Specify initial video mode");
2218  
2219  MODULE_AUTHOR("Tony A. Daplas");
2220  MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"
2221  		   " compatible cards");
2222  MODULE_LICENSE("GPL");
2223  
i810fb_exit(void)2224  static void __exit i810fb_exit(void)
2225  {
2226  	pci_unregister_driver(&i810fb_driver);
2227  }
2228  module_exit(i810fb_exit);
2229  
2230  #endif /* MODULE */
2231  
2232  module_init(i810fb_init);
2233