1/*
2 * intelfb
3 *
4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
5 * 945G/945GM integrated graphics chips.
6 *
7 * Copyright � 2002, 2003 David Dawes <dawes@xfree86.org>
8 *                   2004 Sylvain Meyer
9 *                   2006 David Airlie
10 *
11 * This driver consists of two parts.  The first part (intelfbdrv.c) provides
12 * the basic fbdev interfaces, is derived in part from the radeonfb and
13 * vesafb drivers, and is covered by the GPL.  The second part (intelfbhw.c)
14 * provides the code to program the hardware.  Most of it is derived from
15 * the i810/i830 XFree86 driver.  The HW-specific code is covered here
16 * under a dual license (GPL and MIT/XFree86 license).
17 *
18 * Author: David Dawes
19 *
20 */
21
22/* $DHD: intelfb/intelfbdrv.c,v 1.20 2003/06/27 15:17:40 dawes Exp $ */
23
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/errno.h>
28#include <linux/string.h>
29#include <linux/mm.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include <linux/fb.h>
33#include <linux/ioport.h>
34#include <linux/init.h>
35#include <linux/pci.h>
36#include <linux/vmalloc.h>
37#include <linux/pagemap.h>
38#include <linux/screen_info.h>
39
40#include <asm/io.h>
41
42#ifdef CONFIG_MTRR
43#include <asm/mtrr.h>
44#endif
45
46#include "intelfb.h"
47#include "intelfbhw.h"
48#include "../edid.h"
49
50static void __devinit get_initial_mode(struct intelfb_info *dinfo);
51static void update_dinfo(struct intelfb_info *dinfo,
52			 struct fb_var_screeninfo *var);
53static int intelfb_open(struct fb_info *info, int user);
54static int intelfb_release(struct fb_info *info, int user);
55static int intelfb_check_var(struct fb_var_screeninfo *var,
56			     struct fb_info *info);
57static int intelfb_set_par(struct fb_info *info);
58static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
59			     unsigned blue, unsigned transp,
60			     struct fb_info *info);
61
62static int intelfb_blank(int blank, struct fb_info *info);
63static int intelfb_pan_display(struct fb_var_screeninfo *var,
64			       struct fb_info *info);
65
66static void intelfb_fillrect(struct fb_info *info,
67			     const struct fb_fillrect *rect);
68static void intelfb_copyarea(struct fb_info *info,
69			     const struct fb_copyarea *region);
70static void intelfb_imageblit(struct fb_info *info,
71			      const struct fb_image *image);
72static int intelfb_cursor(struct fb_info *info,
73			   struct fb_cursor *cursor);
74
75static int intelfb_sync(struct fb_info *info);
76
77static int intelfb_ioctl(struct fb_info *info,
78			 unsigned int cmd, unsigned long arg);
79
80static int __devinit intelfb_pci_register(struct pci_dev *pdev,
81					  const struct pci_device_id *ent);
82static void __devexit intelfb_pci_unregister(struct pci_dev *pdev);
83static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo);
84
85/*
86 * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the
87 * mobile chipsets from being registered.
88 */
89#if DETECT_VGA_CLASS_ONLY
90#define INTELFB_CLASS_MASK ~0 << 8
91#else
92#define INTELFB_CLASS_MASK 0
93#endif
94
95static struct pci_device_id intelfb_pci_table[] __devinitdata = {
96	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_830M, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_830M },
97	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_845G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_845G },
98	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
99	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
100	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
101	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
102	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
103	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
104	{ 0, }
105};
106
107/* Global data */
108static int num_registered = 0;
109
110/* fb ops */
111static struct fb_ops intel_fb_ops = {
112	.owner =		THIS_MODULE,
113	.fb_open =              intelfb_open,
114	.fb_release =           intelfb_release,
115	.fb_check_var =         intelfb_check_var,
116	.fb_set_par =           intelfb_set_par,
117	.fb_setcolreg =		intelfb_setcolreg,
118	.fb_blank =		intelfb_blank,
119	.fb_pan_display =       intelfb_pan_display,
120	.fb_fillrect  =         intelfb_fillrect,
121	.fb_copyarea  =         intelfb_copyarea,
122	.fb_imageblit =         intelfb_imageblit,
123	.fb_cursor =            intelfb_cursor,
124	.fb_sync =              intelfb_sync,
125	.fb_ioctl =		intelfb_ioctl
126};
127
128/* PCI driver module table */
129static struct pci_driver intelfb_driver = {
130	.name =		"intelfb",
131	.id_table =	intelfb_pci_table,
132	.probe =	intelfb_pci_register,
133	.remove =	__devexit_p(intelfb_pci_unregister)
134};
135
136/* Module description/parameters */
137MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, "
138	      "Sylvain Meyer <sylvain.meyer@worldonline.fr>");
139MODULE_DESCRIPTION(
140	"Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS " chipsets");
141MODULE_LICENSE("Dual BSD/GPL");
142MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
143
144static int accel        = 1;
145static int vram         = 4;
146static int hwcursor     = 0;
147static int mtrr         = 1;
148static int fixed        = 0;
149static int noinit       = 0;
150static int noregister   = 0;
151static int probeonly    = 0;
152static int idonly       = 0;
153static int bailearly    = 0;
154static int voffset	= 48;
155static char *mode       = NULL;
156
157module_param(accel, bool, S_IRUGO);
158MODULE_PARM_DESC(accel, "Enable hardware acceleration");
159module_param(vram, int, S_IRUGO);
160MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB");
161module_param(voffset, int, S_IRUGO);
162MODULE_PARM_DESC(voffset, "Offset of framebuffer in MiB");
163module_param(hwcursor, bool, S_IRUGO);
164MODULE_PARM_DESC(hwcursor, "Enable HW cursor");
165module_param(mtrr, bool, S_IRUGO);
166MODULE_PARM_DESC(mtrr, "Enable MTRR support");
167module_param(fixed, bool, S_IRUGO);
168MODULE_PARM_DESC(fixed, "Disable mode switching");
169module_param(noinit, bool, 0);
170MODULE_PARM_DESC(noinit, "Don't initialise graphics mode when loading");
171module_param(noregister, bool, 0);
172MODULE_PARM_DESC(noregister, "Don't register, just probe and exit (debug)");
173module_param(probeonly, bool, 0);
174MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)");
175module_param(idonly, bool, 0);
176MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)");
177module_param(bailearly, bool, 0);
178MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)");
179module_param(mode, charp, S_IRUGO);
180MODULE_PARM_DESC(mode,
181		 "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\"");
182
183#ifndef MODULE
184#define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name)))
185#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0)
186#define OPT_STRVAL(opt, name) (opt + strlen(name))
187
188static __inline__ char *
189get_opt_string(const char *this_opt, const char *name)
190{
191	const char *p;
192	int i;
193	char *ret;
194
195	p = OPT_STRVAL(this_opt, name);
196	i = 0;
197	while (p[i] && p[i] != ' ' && p[i] != ',')
198		i++;
199	ret = kmalloc(i + 1, GFP_KERNEL);
200	if (ret) {
201		strncpy(ret, p, i);
202		ret[i] = '\0';
203	}
204	return ret;
205}
206
207static __inline__ int
208get_opt_int(const char *this_opt, const char *name, int *ret)
209{
210	if (!ret)
211		return 0;
212
213	if (!OPT_EQUAL(this_opt, name))
214		return 0;
215
216	*ret = OPT_INTVAL(this_opt, name);
217	return 1;
218}
219
220static __inline__ int
221get_opt_bool(const char *this_opt, const char *name, int *ret)
222{
223	if (!ret)
224		return 0;
225
226	if (OPT_EQUAL(this_opt, name)) {
227		if (this_opt[strlen(name)] == '=')
228			*ret = simple_strtoul(this_opt + strlen(name) + 1,
229					      NULL, 0);
230		else
231			*ret = 1;
232	} else {
233		if (OPT_EQUAL(this_opt, "no") && OPT_EQUAL(this_opt + 2, name))
234			*ret = 0;
235		else
236			return 0;
237	}
238	return 1;
239}
240
241static int __init
242intelfb_setup(char *options)
243{
244	char *this_opt;
245
246	DBG_MSG("intelfb_setup\n");
247
248	if (!options || !*options) {
249		DBG_MSG("no options\n");
250		return 0;
251	} else
252		DBG_MSG("options: %s\n", options);
253
254	/*
255	 * These are the built-in options analogous to the module parameters
256	 * defined above.
257	 *
258	 * The syntax is:
259	 *
260	 *    video=intelfb:[mode][,<param>=<val>] ...
261	 *
262	 * e.g.,
263	 *
264	 *    video=intelfb:1024x768-16@75,accel=0
265	 */
266
267	while ((this_opt = strsep(&options, ","))) {
268		if (!*this_opt)
269			continue;
270		if (get_opt_bool(this_opt, "accel", &accel))
271			;
272 		else if (get_opt_int(this_opt, "vram", &vram))
273			;
274		else if (get_opt_bool(this_opt, "hwcursor", &hwcursor))
275			;
276		else if (get_opt_bool(this_opt, "mtrr", &mtrr))
277			;
278		else if (get_opt_bool(this_opt, "fixed", &fixed))
279			;
280		else if (get_opt_bool(this_opt, "init", &noinit))
281			noinit = !noinit;
282		else if (OPT_EQUAL(this_opt, "mode="))
283			mode = get_opt_string(this_opt, "mode=");
284		else
285			mode = this_opt;
286	}
287
288	return 0;
289}
290
291#endif
292
293static int __init
294intelfb_init(void)
295{
296#ifndef MODULE
297	char *option = NULL;
298#endif
299
300	DBG_MSG("intelfb_init\n");
301
302	INF_MSG("Framebuffer driver for "
303		"Intel(R) " SUPPORTED_CHIPSETS " chipsets\n");
304	INF_MSG("Version " INTELFB_VERSION "\n");
305
306	if (idonly)
307		return -ENODEV;
308
309#ifndef MODULE
310	if (fb_get_options("intelfb", &option))
311		return -ENODEV;
312	intelfb_setup(option);
313#endif
314
315	return pci_register_driver(&intelfb_driver);
316}
317
318static void __exit
319intelfb_exit(void)
320{
321	DBG_MSG("intelfb_exit\n");
322	pci_unregister_driver(&intelfb_driver);
323}
324
325module_init(intelfb_init);
326module_exit(intelfb_exit);
327
328/***************************************************************
329 *                     mtrr support functions                  *
330 ***************************************************************/
331
332#ifdef CONFIG_MTRR
333static inline void __devinit set_mtrr(struct intelfb_info *dinfo)
334{
335	dinfo->mtrr_reg = mtrr_add(dinfo->aperture.physical,
336				   dinfo->aperture.size, MTRR_TYPE_WRCOMB, 1);
337	if (dinfo->mtrr_reg < 0) {
338		ERR_MSG("unable to set MTRR\n");
339		return;
340	}
341	dinfo->has_mtrr = 1;
342}
343static inline void unset_mtrr(struct intelfb_info *dinfo)
344{
345  	if (dinfo->has_mtrr)
346  		mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
347			 dinfo->aperture.size);
348}
349#else
350#define set_mtrr(x) WRN_MSG("MTRR is disabled in the kernel\n")
351
352#define unset_mtrr(x) do { } while (0)
353#endif /* CONFIG_MTRR */
354
355/***************************************************************
356 *                        driver init / cleanup                *
357 ***************************************************************/
358
359static void
360cleanup(struct intelfb_info *dinfo)
361{
362	DBG_MSG("cleanup\n");
363
364	if (!dinfo)
365		return;
366
367	intelfbhw_disable_irq(dinfo);
368
369	fb_dealloc_cmap(&dinfo->info->cmap);
370	kfree(dinfo->info->pixmap.addr);
371
372	if (dinfo->registered)
373		unregister_framebuffer(dinfo->info);
374
375	unset_mtrr(dinfo);
376
377	if (dinfo->fbmem_gart && dinfo->gtt_fb_mem) {
378		agp_unbind_memory(dinfo->gtt_fb_mem);
379		agp_free_memory(dinfo->gtt_fb_mem);
380	}
381	if (dinfo->gtt_cursor_mem) {
382		agp_unbind_memory(dinfo->gtt_cursor_mem);
383		agp_free_memory(dinfo->gtt_cursor_mem);
384	}
385	if (dinfo->gtt_ring_mem) {
386		agp_unbind_memory(dinfo->gtt_ring_mem);
387		agp_free_memory(dinfo->gtt_ring_mem);
388	}
389
390#ifdef CONFIG_FB_INTEL_I2C
391	/* un-register I2C bus */
392	intelfb_delete_i2c_busses(dinfo);
393#endif
394
395	if (dinfo->mmio_base)
396		iounmap((void __iomem *)dinfo->mmio_base);
397	if (dinfo->aperture.virtual)
398		iounmap((void __iomem *)dinfo->aperture.virtual);
399
400	if (dinfo->flag & INTELFB_MMIO_ACQUIRED)
401		release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE);
402	if (dinfo->flag & INTELFB_FB_ACQUIRED)
403		release_mem_region(dinfo->aperture.physical,
404				   dinfo->aperture.size);
405	framebuffer_release(dinfo->info);
406}
407
408#define bailout(dinfo) do {						\
409	DBG_MSG("bailout\n");						\
410	cleanup(dinfo);							\
411	INF_MSG("Not going to register framebuffer, exiting...\n");	\
412	return -ENODEV;							\
413} while (0)
414
415
416static int __devinit
417intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
418{
419	struct fb_info *info;
420	struct intelfb_info *dinfo;
421	int i, err, dvo;
422	int aperture_size, stolen_size;
423	struct agp_kern_info gtt_info;
424	int agp_memtype;
425	const char *s;
426	struct agp_bridge_data *bridge;
427 	int aperture_bar = 0;
428 	int mmio_bar = 1;
429	int offset;
430
431	DBG_MSG("intelfb_pci_register\n");
432
433	num_registered++;
434	if (num_registered != 1) {
435		ERR_MSG("Attempted to register %d devices "
436			"(should be only 1).\n", num_registered);
437		return -ENODEV;
438	}
439
440	info = framebuffer_alloc(sizeof(struct intelfb_info), &pdev->dev);
441	if (!info) {
442		ERR_MSG("Could not allocate memory for intelfb_info.\n");
443		return -ENODEV;
444	}
445	if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
446		ERR_MSG("Could not allocate cmap for intelfb_info.\n");
447		goto err_out_cmap;
448		return -ENODEV;
449	}
450
451	dinfo = info->par;
452	dinfo->info  = info;
453	dinfo->fbops = &intel_fb_ops;
454	dinfo->pdev  = pdev;
455
456	/* Reserve pixmap space. */
457	info->pixmap.addr = kzalloc(64 * 1024, GFP_KERNEL);
458	if (info->pixmap.addr == NULL) {
459		ERR_MSG("Cannot reserve pixmap memory.\n");
460		goto err_out_pixmap;
461	}
462
463	/* set early this option because it could be changed by tv encoder
464	   driver */
465	dinfo->fixed_mode = fixed;
466
467	/* Enable device. */
468	if ((err = pci_enable_device(pdev))) {
469		ERR_MSG("Cannot enable device.\n");
470		cleanup(dinfo);
471		return -ENODEV;
472	}
473
474	/* Set base addresses. */
475	if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
476	    (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
477	    (ent->device == PCI_DEVICE_ID_INTEL_945G)  ||
478	    (ent->device == PCI_DEVICE_ID_INTEL_945GM)) {
479		aperture_bar = 2;
480		mmio_bar = 0;
481	}
482	dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
483	dinfo->aperture.size     = pci_resource_len(pdev, aperture_bar);
484	dinfo->mmio_base_phys    = pci_resource_start(pdev, mmio_bar);
485	DBG_MSG("fb aperture: 0x%llx/0x%llx, MMIO region: 0x%llx/0x%llx\n",
486		(unsigned long long)pci_resource_start(pdev, aperture_bar),
487		(unsigned long long)pci_resource_len(pdev, aperture_bar),
488		(unsigned long long)pci_resource_start(pdev, mmio_bar),
489		(unsigned long long)pci_resource_len(pdev, mmio_bar));
490
491	/* Reserve the fb and MMIO regions */
492	if (!request_mem_region(dinfo->aperture.physical, dinfo->aperture.size,
493				INTELFB_MODULE_NAME)) {
494		ERR_MSG("Cannot reserve FB region.\n");
495		cleanup(dinfo);
496		return -ENODEV;
497	}
498
499	dinfo->flag |= INTELFB_FB_ACQUIRED;
500
501	if (!request_mem_region(dinfo->mmio_base_phys,
502				INTEL_REG_SIZE,
503				INTELFB_MODULE_NAME)) {
504		ERR_MSG("Cannot reserve MMIO region.\n");
505		cleanup(dinfo);
506		return -ENODEV;
507	}
508
509	dinfo->flag |= INTELFB_MMIO_ACQUIRED;
510
511	/* Get the chipset info. */
512	dinfo->pci_chipset = pdev->device;
513
514	if (intelfbhw_get_chipset(pdev, dinfo)) {
515		cleanup(dinfo);
516		return -ENODEV;
517	}
518
519	if (intelfbhw_get_memory(pdev, &aperture_size,&stolen_size)) {
520		cleanup(dinfo);
521		return -ENODEV;
522	}
523
524	INF_MSG("%02x:%02x.%d: %s, aperture size %dMB, "
525		"stolen memory %dkB\n",
526		pdev->bus->number, PCI_SLOT(pdev->devfn),
527		PCI_FUNC(pdev->devfn), dinfo->name,
528		BtoMB(aperture_size), BtoKB(stolen_size));
529
530	/* Set these from the options. */
531	dinfo->accel    = accel;
532	dinfo->hwcursor = hwcursor;
533
534	if (NOACCEL_CHIPSET(dinfo) && dinfo->accel == 1) {
535		INF_MSG("Acceleration is not supported for the %s chipset.\n",
536			dinfo->name);
537		dinfo->accel = 0;
538	}
539
540	/* Framebuffer parameters - Use all the stolen memory if >= vram */
541	if (ROUND_UP_TO_PAGE(stolen_size) >= MB(vram)) {
542		dinfo->fb.size = ROUND_UP_TO_PAGE(stolen_size);
543		dinfo->fbmem_gart = 0;
544	} else {
545		dinfo->fb.size =  MB(vram);
546		dinfo->fbmem_gart = 1;
547	}
548
549	/* Allocate space for the ring buffer and HW cursor if enabled. */
550	if (dinfo->accel) {
551		dinfo->ring.size = RINGBUFFER_SIZE;
552		dinfo->ring_tail_mask = dinfo->ring.size - 1;
553	}
554	if (dinfo->hwcursor) {
555		dinfo->cursor.size = HW_CURSOR_SIZE;
556	}
557
558	/* Use agpgart to manage the GATT */
559	if (!(bridge = agp_backend_acquire(pdev))) {
560		ERR_MSG("cannot acquire agp\n");
561		cleanup(dinfo);
562		return -ENODEV;
563	}
564
565	/* get the current gatt info */
566	if (agp_copy_info(bridge, &gtt_info)) {
567		ERR_MSG("cannot get agp info\n");
568		agp_backend_release(bridge);
569		cleanup(dinfo);
570		return -ENODEV;
571	}
572
573	if (MB(voffset) < stolen_size)
574		offset = (stolen_size >> 12);
575	else
576		offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
577
578	/* set the mem offsets - set them after the already used pages */
579	if (dinfo->accel) {
580		dinfo->ring.offset = offset + gtt_info.current_memory;
581	}
582	if (dinfo->hwcursor) {
583		dinfo->cursor.offset = offset +
584			+ gtt_info.current_memory + (dinfo->ring.size >> 12);
585	}
586	if (dinfo->fbmem_gart) {
587		dinfo->fb.offset = offset +
588			+ gtt_info.current_memory + (dinfo->ring.size >> 12)
589			+ (dinfo->cursor.size >> 12);
590	}
591
592	/* Allocate memories (which aren't stolen) */
593	/* Map the fb and MMIO regions */
594	/* ioremap only up to the end of used aperture */
595	dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache
596		(dinfo->aperture.physical, ((offset + dinfo->fb.offset) << 12)
597		 + dinfo->fb.size);
598	if (!dinfo->aperture.virtual) {
599		ERR_MSG("Cannot remap FB region.\n");
600		cleanup(dinfo);
601		return -ENODEV;
602	}
603
604	dinfo->mmio_base =
605		(u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
606					       INTEL_REG_SIZE);
607	if (!dinfo->mmio_base) {
608		ERR_MSG("Cannot remap MMIO region.\n");
609		cleanup(dinfo);
610		return -ENODEV;
611	}
612
613	if (dinfo->accel) {
614		if (!(dinfo->gtt_ring_mem =
615		      agp_allocate_memory(bridge, dinfo->ring.size >> 12,
616					  AGP_NORMAL_MEMORY))) {
617			ERR_MSG("cannot allocate ring buffer memory\n");
618			agp_backend_release(bridge);
619			cleanup(dinfo);
620			return -ENOMEM;
621		}
622		if (agp_bind_memory(dinfo->gtt_ring_mem,
623				    dinfo->ring.offset)) {
624			ERR_MSG("cannot bind ring buffer memory\n");
625			agp_backend_release(bridge);
626			cleanup(dinfo);
627			return -EBUSY;
628		}
629		dinfo->ring.physical = dinfo->aperture.physical
630			+ (dinfo->ring.offset << 12);
631		dinfo->ring.virtual  = dinfo->aperture.virtual
632			+ (dinfo->ring.offset << 12);
633		dinfo->ring_head = 0;
634	}
635	if (dinfo->hwcursor) {
636		agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY
637			: AGP_NORMAL_MEMORY;
638		if (!(dinfo->gtt_cursor_mem =
639		      agp_allocate_memory(bridge, dinfo->cursor.size >> 12,
640					  agp_memtype))) {
641			ERR_MSG("cannot allocate cursor memory\n");
642			agp_backend_release(bridge);
643			cleanup(dinfo);
644			return -ENOMEM;
645		}
646		if (agp_bind_memory(dinfo->gtt_cursor_mem,
647				    dinfo->cursor.offset)) {
648			ERR_MSG("cannot bind cursor memory\n");
649			agp_backend_release(bridge);
650			cleanup(dinfo);
651			return -EBUSY;
652		}
653		if (dinfo->mobile)
654			dinfo->cursor.physical
655				= dinfo->gtt_cursor_mem->physical;
656		else
657			dinfo->cursor.physical = dinfo->aperture.physical
658				+ (dinfo->cursor.offset << 12);
659		dinfo->cursor.virtual = dinfo->aperture.virtual
660			+ (dinfo->cursor.offset << 12);
661	}
662	if (dinfo->fbmem_gart) {
663		if (!(dinfo->gtt_fb_mem =
664		      agp_allocate_memory(bridge, dinfo->fb.size >> 12,
665					  AGP_NORMAL_MEMORY))) {
666			WRN_MSG("cannot allocate framebuffer memory - use "
667				"the stolen one\n");
668			dinfo->fbmem_gart = 0;
669		}
670		if (agp_bind_memory(dinfo->gtt_fb_mem,
671				    dinfo->fb.offset)) {
672			WRN_MSG("cannot bind framebuffer memory - use "
673				"the stolen one\n");
674			dinfo->fbmem_gart = 0;
675		}
676	}
677
678	/* update framebuffer memory parameters */
679	if (!dinfo->fbmem_gart)
680		dinfo->fb.offset = 0;   /* starts at offset 0 */
681	dinfo->fb.physical = dinfo->aperture.physical
682		+ (dinfo->fb.offset << 12);
683	dinfo->fb.virtual = dinfo->aperture.virtual + (dinfo->fb.offset << 12);
684	dinfo->fb_start = dinfo->fb.offset << 12;
685
686	/* release agpgart */
687	agp_backend_release(bridge);
688
689	if (mtrr)
690		set_mtrr(dinfo);
691
692	DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n",
693		dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size,
694		dinfo->fb.virtual);
695	DBG_MSG("MMIO: 0x%x/0x%x (0x%p)\n",
696		dinfo->mmio_base_phys, INTEL_REG_SIZE,
697		dinfo->mmio_base);
698	DBG_MSG("ring buffer: 0x%x/0x%x (0x%p)\n",
699		dinfo->ring.physical, dinfo->ring.size,
700		dinfo->ring.virtual);
701	DBG_MSG("HW cursor: 0x%x/0x%x (0x%p) (offset 0x%x) (phys 0x%x)\n",
702		dinfo->cursor.physical, dinfo->cursor.size,
703		dinfo->cursor.virtual, dinfo->cursor.offset,
704		dinfo->cursor.physical);
705
706	DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, "
707		"noinit = %d\n", vram, accel, hwcursor, fixed, noinit);
708	DBG_MSG("options: mode = \"%s\"\n", mode ? mode : "");
709
710	if (probeonly)
711		bailout(dinfo);
712
713	/*
714	 * Check if the LVDS port or any DVO ports are enabled.  If so,
715	 * don't allow mode switching
716	 */
717	dvo = intelfbhw_check_non_crt(dinfo);
718	if (dvo) {
719		dinfo->fixed_mode = 1;
720		WRN_MSG("Non-CRT device is enabled ( ");
721		i = 0;
722		while (dvo) {
723			if (dvo & 1) {
724				s = intelfbhw_dvo_to_string(1 << i);
725				if (s)
726					printk("%s ", s);
727			}
728			dvo >>= 1;
729			++i;
730		}
731		printk(").  Disabling mode switching.\n");
732	}
733
734	if (bailearly == 1)
735		bailout(dinfo);
736
737	if (FIXED_MODE(dinfo) && ORIG_VIDEO_ISVGA != VIDEO_TYPE_VLFB) {
738		ERR_MSG("Video mode must be programmed at boot time.\n");
739		cleanup(dinfo);
740		return -ENODEV;
741	}
742
743	if (bailearly == 2)
744		bailout(dinfo);
745
746	/* Initialise dinfo and related data. */
747	/* If an initial mode was programmed at boot time, get its details. */
748	if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB)
749		get_initial_mode(dinfo);
750
751	if (bailearly == 3)
752		bailout(dinfo);
753
754	if (FIXED_MODE(dinfo)) {
755		/* remap fb address */
756		update_dinfo(dinfo, &dinfo->initial_var);
757	}
758
759	if (bailearly == 4)
760		bailout(dinfo);
761
762
763	if (intelfb_set_fbinfo(dinfo)) {
764		cleanup(dinfo);
765		return -ENODEV;
766	}
767
768	if (bailearly == 5)
769		bailout(dinfo);
770
771#ifdef CONFIG_FB_INTEL_I2C
772	/* register I2C bus */
773	intelfb_create_i2c_busses(dinfo);
774#endif
775
776	if (bailearly == 6)
777		bailout(dinfo);
778
779	pci_set_drvdata(pdev, dinfo);
780
781	/* Save the initial register state. */
782	i = intelfbhw_read_hw_state(dinfo, &dinfo->save_state,
783				    bailearly > 6 ? bailearly - 6 : 0);
784	if (i != 0) {
785		DBG_MSG("intelfbhw_read_hw_state returned %d\n", i);
786		bailout(dinfo);
787	}
788
789	intelfbhw_print_hw_state(dinfo, &dinfo->save_state);
790
791	if (bailearly == 18)
792		bailout(dinfo);
793
794	/* Cursor initialisation */
795	if (dinfo->hwcursor) {
796		intelfbhw_cursor_init(dinfo);
797		intelfbhw_cursor_reset(dinfo);
798	}
799
800	if (bailearly == 19)
801		bailout(dinfo);
802
803	/* 2d acceleration init */
804	if (dinfo->accel)
805		intelfbhw_2d_start(dinfo);
806
807	if (bailearly == 20)
808		bailout(dinfo);
809
810	if (noregister)
811		bailout(dinfo);
812
813	if (register_framebuffer(dinfo->info) < 0) {
814		ERR_MSG("Cannot register framebuffer.\n");
815		cleanup(dinfo);
816		return -ENODEV;
817	}
818
819	dinfo->registered = 1;
820	dinfo->open = 0;
821
822	init_waitqueue_head(&dinfo->vsync.wait);
823	spin_lock_init(&dinfo->int_lock);
824	dinfo->irq_flags = 0;
825	dinfo->vsync.pan_display = 0;
826	dinfo->vsync.pan_offset = 0;
827
828	return 0;
829
830err_out_pixmap:
831	fb_dealloc_cmap(&info->cmap);
832err_out_cmap:
833	framebuffer_release(info);
834	return -ENODEV;
835}
836
837static void __devexit
838intelfb_pci_unregister(struct pci_dev *pdev)
839{
840	struct intelfb_info *dinfo = pci_get_drvdata(pdev);
841
842	DBG_MSG("intelfb_pci_unregister\n");
843
844	if (!dinfo)
845		return;
846
847	cleanup(dinfo);
848
849	pci_set_drvdata(pdev, NULL);
850}
851
852/***************************************************************
853 *                       helper functions                      *
854 ***************************************************************/
855
856int __inline__
857intelfb_var_to_depth(const struct fb_var_screeninfo *var)
858{
859	DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n",
860		var->bits_per_pixel, var->green.length);
861
862	switch (var->bits_per_pixel) {
863	case 16:
864		return (var->green.length == 6) ? 16 : 15;
865	case 32:
866		return 24;
867	default:
868		return var->bits_per_pixel;
869	}
870}
871
872
873static __inline__ int
874var_to_refresh(const struct fb_var_screeninfo *var)
875{
876	int xtot = var->xres + var->left_margin + var->right_margin +
877		   var->hsync_len;
878	int ytot = var->yres + var->upper_margin + var->lower_margin +
879		   var->vsync_len;
880
881	return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot;
882}
883
884/***************************************************************
885 *                Various intialisation functions              *
886 ***************************************************************/
887
888static void __devinit
889get_initial_mode(struct intelfb_info *dinfo)
890{
891	struct fb_var_screeninfo *var;
892	int xtot, ytot;
893
894	DBG_MSG("get_initial_mode\n");
895
896	dinfo->initial_vga = 1;
897	dinfo->initial_fb_base = screen_info.lfb_base;
898	dinfo->initial_video_ram = screen_info.lfb_size * KB(64);
899	dinfo->initial_pitch = screen_info.lfb_linelength;
900
901	var = &dinfo->initial_var;
902	memset(var, 0, sizeof(*var));
903	var->xres = screen_info.lfb_width;
904	var->yres = screen_info.lfb_height;
905	var->bits_per_pixel = screen_info.lfb_depth;
906	switch (screen_info.lfb_depth) {
907	case 15:
908		var->bits_per_pixel = 16;
909		break;
910	case 24:
911		var->bits_per_pixel = 32;
912		break;
913	}
914
915	DBG_MSG("Initial info: FB is 0x%x/0x%x (%d kByte)\n",
916		dinfo->initial_fb_base, dinfo->initial_video_ram,
917		BtoKB(dinfo->initial_video_ram));
918
919	DBG_MSG("Initial info: mode is %dx%d-%d (%d)\n",
920		var->xres, var->yres, var->bits_per_pixel,
921		dinfo->initial_pitch);
922
923	/* Dummy timing values (assume 60Hz) */
924	var->left_margin = (var->xres / 8) & 0xf8;
925	var->right_margin = 32;
926	var->upper_margin = 16;
927	var->lower_margin = 4;
928	var->hsync_len = (var->xres / 8) & 0xf8;
929	var->vsync_len = 4;
930
931	xtot = var->xres + var->left_margin +
932		var->right_margin + var->hsync_len;
933	ytot = var->yres + var->upper_margin +
934		var->lower_margin + var->vsync_len;
935	var->pixclock = 10000000 / xtot * 1000 / ytot * 100 / 60;
936
937	var->height = -1;
938	var->width = -1;
939
940	if (var->bits_per_pixel > 8) {
941		var->red.offset = screen_info.red_pos;
942		var->red.length = screen_info.red_size;
943		var->green.offset = screen_info.green_pos;
944		var->green.length = screen_info.green_size;
945		var->blue.offset = screen_info.blue_pos;
946		var->blue.length = screen_info.blue_size;
947		var->transp.offset = screen_info.rsvd_pos;
948		var->transp.length = screen_info.rsvd_size;
949	} else {
950		var->red.length = 8;
951		var->green.length = 8;
952		var->blue.length = 8;
953	}
954}
955
956static int __devinit
957intelfb_init_var(struct intelfb_info *dinfo)
958{
959	struct fb_var_screeninfo *var;
960	int msrc = 0;
961
962	DBG_MSG("intelfb_init_var\n");
963
964	var = &dinfo->info->var;
965	if (FIXED_MODE(dinfo)) {
966	        memcpy(var, &dinfo->initial_var,
967		       sizeof(struct fb_var_screeninfo));
968		msrc = 5;
969	} else {
970		const u8 *edid_s = fb_firmware_edid(&dinfo->pdev->dev);
971		u8 *edid_d = NULL;
972
973		if (edid_s) {
974			edid_d = kmemdup(edid_s, EDID_LENGTH, GFP_KERNEL);
975
976			if (edid_d) {
977				fb_edid_to_monspecs(edid_d,
978						    &dinfo->info->monspecs);
979				kfree(edid_d);
980			}
981		}
982
983		if (mode) {
984			printk("intelfb: Looking for mode in private "
985			       "database\n");
986			msrc = fb_find_mode(var, dinfo->info, mode,
987					    dinfo->info->monspecs.modedb,
988					    dinfo->info->monspecs.modedb_len,
989					    NULL, 0);
990
991			if (msrc && msrc > 1) {
992				printk("intelfb: No mode in private database, "
993				       "intelfb: looking for mode in global "
994				       "database ");
995				msrc = fb_find_mode(var, dinfo->info, mode,
996						    NULL, 0, NULL, 0);
997
998				if (msrc)
999					msrc |= 8;
1000			}
1001
1002		}
1003
1004		if (!msrc) {
1005			msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE,
1006					    NULL, 0, NULL, 0);
1007		}
1008	}
1009
1010	if (!msrc) {
1011		ERR_MSG("Cannot find a suitable video mode.\n");
1012		return 1;
1013	}
1014
1015	INF_MSG("Initial video mode is %dx%d-%d@%d.\n", var->xres, var->yres,
1016		var->bits_per_pixel, var_to_refresh(var));
1017
1018	DBG_MSG("Initial video mode is from %d.\n", msrc);
1019
1020#if ALLOCATE_FOR_PANNING
1021	/* Allow use of half of the video ram for panning */
1022	var->xres_virtual = var->xres;
1023	var->yres_virtual =
1024		dinfo->fb.size / 2 / (var->bits_per_pixel * var->xres);
1025	if (var->yres_virtual < var->yres)
1026		var->yres_virtual = var->yres;
1027#else
1028	var->yres_virtual = var->yres;
1029#endif
1030
1031	if (dinfo->accel)
1032		var->accel_flags |= FB_ACCELF_TEXT;
1033	else
1034		var->accel_flags &= ~FB_ACCELF_TEXT;
1035
1036	return 0;
1037}
1038
1039static int __devinit
1040intelfb_set_fbinfo(struct intelfb_info *dinfo)
1041{
1042	struct fb_info *info = dinfo->info;
1043
1044	DBG_MSG("intelfb_set_fbinfo\n");
1045
1046	info->flags = FBINFO_FLAG_DEFAULT;
1047	info->fbops = &intel_fb_ops;
1048	info->pseudo_palette = dinfo->pseudo_palette;
1049
1050	info->pixmap.size = 64*1024;
1051	info->pixmap.buf_align = 8;
1052	info->pixmap.access_align = 32;
1053	info->pixmap.flags = FB_PIXMAP_SYSTEM;
1054
1055	if (intelfb_init_var(dinfo))
1056		return 1;
1057
1058	info->pixmap.scan_align = 1;
1059	strcpy(info->fix.id, dinfo->name);
1060	info->fix.smem_start = dinfo->fb.physical;
1061	info->fix.smem_len = dinfo->fb.size;
1062	info->fix.type = FB_TYPE_PACKED_PIXELS;
1063	info->fix.type_aux = 0;
1064	info->fix.xpanstep = 8;
1065	info->fix.ypanstep = 1;
1066	info->fix.ywrapstep = 0;
1067	info->fix.mmio_start = dinfo->mmio_base_phys;
1068	info->fix.mmio_len = INTEL_REG_SIZE;
1069	info->fix.accel = FB_ACCEL_I830;
1070	update_dinfo(dinfo, &info->var);
1071
1072	return 0;
1073}
1074
1075/* Update dinfo to match the active video mode. */
1076static void
1077update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
1078{
1079	DBG_MSG("update_dinfo\n");
1080
1081	dinfo->bpp = var->bits_per_pixel;
1082	dinfo->depth = intelfb_var_to_depth(var);
1083	dinfo->xres = var->xres;
1084	dinfo->yres = var->xres;
1085	dinfo->pixclock = var->pixclock;
1086
1087	dinfo->info->fix.visual = dinfo->visual;
1088	dinfo->info->fix.line_length = dinfo->pitch;
1089
1090	switch (dinfo->bpp) {
1091	case 8:
1092		dinfo->visual = FB_VISUAL_PSEUDOCOLOR;
1093		dinfo->pitch = var->xres_virtual;
1094		break;
1095	case 16:
1096		dinfo->visual = FB_VISUAL_TRUECOLOR;
1097		dinfo->pitch = var->xres_virtual * 2;
1098		break;
1099	case 32:
1100		dinfo->visual = FB_VISUAL_TRUECOLOR;
1101		dinfo->pitch = var->xres_virtual * 4;
1102		break;
1103	}
1104
1105	/* Make sure the line length is a aligned correctly. */
1106	if (IS_I9XX(dinfo))
1107		dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX);
1108	else
1109		dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT);
1110
1111	if (FIXED_MODE(dinfo))
1112		dinfo->pitch = dinfo->initial_pitch;
1113
1114	dinfo->info->screen_base = (char __iomem *)dinfo->fb.virtual;
1115	dinfo->info->fix.line_length = dinfo->pitch;
1116	dinfo->info->fix.visual = dinfo->visual;
1117}
1118
1119/* fbops functions */
1120
1121/***************************************************************
1122 *                       fbdev interface                       *
1123 ***************************************************************/
1124
1125static int
1126intelfb_open(struct fb_info *info, int user)
1127{
1128	struct intelfb_info *dinfo = GET_DINFO(info);
1129
1130	if (user) {
1131		dinfo->open++;
1132	}
1133
1134	return 0;
1135}
1136
1137static int
1138intelfb_release(struct fb_info *info, int user)
1139{
1140	struct intelfb_info *dinfo = GET_DINFO(info);
1141
1142	if (user) {
1143		dinfo->open--;
1144		msleep(1);
1145		if (!dinfo->open) {
1146			intelfbhw_disable_irq(dinfo);
1147		}
1148	}
1149
1150	return 0;
1151}
1152
1153static int
1154intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1155{
1156	int change_var = 0;
1157	struct fb_var_screeninfo v;
1158	struct intelfb_info *dinfo;
1159	static int first = 1;
1160	int i;
1161	/* Good pitches to allow tiling.  Don't care about pitches < 1024. */
1162	static const int pitches[] = {
1163		128 * 8,
1164		128 * 16,
1165		128 * 32,
1166		128 * 64,
1167		0
1168	};
1169
1170	DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags);
1171
1172	dinfo = GET_DINFO(info);
1173
1174	/* update the pitch */
1175	if (intelfbhw_validate_mode(dinfo, var) != 0)
1176		return -EINVAL;
1177
1178	v = *var;
1179
1180	for (i = 0; pitches[i] != 0; i++) {
1181		if (pitches[i] >= v.xres_virtual) {
1182			v.xres_virtual = pitches[i];
1183			break;
1184		}
1185	}
1186
1187	/* Check for a supported bpp. */
1188	if (v.bits_per_pixel <= 8) {
1189		v.bits_per_pixel = 8;
1190	} else if (v.bits_per_pixel <= 16) {
1191		if (v.bits_per_pixel == 16)
1192			v.green.length = 6;
1193		v.bits_per_pixel = 16;
1194	} else if (v.bits_per_pixel <= 32) {
1195		v.bits_per_pixel = 32;
1196	} else
1197		return -EINVAL;
1198
1199	change_var = ((info->var.xres != var->xres) ||
1200		      (info->var.yres != var->yres) ||
1201		      (info->var.xres_virtual != var->xres_virtual) ||
1202		      (info->var.yres_virtual != var->yres_virtual) ||
1203		      (info->var.bits_per_pixel != var->bits_per_pixel) ||
1204		      memcmp(&info->var.red, &var->red, sizeof(var->red)) ||
1205		      memcmp(&info->var.green, &var->green,
1206			     sizeof(var->green)) ||
1207		      memcmp(&info->var.blue, &var->blue, sizeof(var->blue)));
1208
1209	if (FIXED_MODE(dinfo) &&
1210	    (change_var ||
1211	     var->yres_virtual > dinfo->initial_var.yres_virtual ||
1212	     var->yres_virtual < dinfo->initial_var.yres ||
1213	     var->xoffset || var->nonstd)) {
1214		if (first) {
1215			ERR_MSG("Changing the video mode is not supported.\n");
1216			first = 0;
1217		}
1218		return -EINVAL;
1219	}
1220
1221	switch (intelfb_var_to_depth(&v)) {
1222	case 8:
1223		v.red.offset = v.green.offset = v.blue.offset = 0;
1224		v.red.length = v.green.length = v.blue.length = 8;
1225		v.transp.offset = v.transp.length = 0;
1226		break;
1227	case 15:
1228		v.red.offset = 10;
1229		v.green.offset = 5;
1230		v.blue.offset = 0;
1231		v.red.length = v.green.length = v.blue.length = 5;
1232		v.transp.offset = v.transp.length = 0;
1233		break;
1234	case 16:
1235		v.red.offset = 11;
1236		v.green.offset = 5;
1237		v.blue.offset = 0;
1238		v.red.length = 5;
1239		v.green.length = 6;
1240		v.blue.length = 5;
1241		v.transp.offset = v.transp.length = 0;
1242		break;
1243	case 24:
1244		v.red.offset = 16;
1245		v.green.offset = 8;
1246		v.blue.offset = 0;
1247		v.red.length = v.green.length = v.blue.length = 8;
1248		v.transp.offset = v.transp.length = 0;
1249		break;
1250	case 32:
1251		v.red.offset = 16;
1252		v.green.offset = 8;
1253		v.blue.offset = 0;
1254		v.red.length = v.green.length = v.blue.length = 8;
1255		v.transp.offset = 24;
1256		v.transp.length = 8;
1257		break;
1258	}
1259
1260	if (v.xoffset < 0)
1261		v.xoffset = 0;
1262	if (v.yoffset < 0)
1263		v.yoffset = 0;
1264
1265	if (v.xoffset > v.xres_virtual - v.xres)
1266		v.xoffset = v.xres_virtual - v.xres;
1267	if (v.yoffset > v.yres_virtual - v.yres)
1268		v.yoffset = v.yres_virtual - v.yres;
1269
1270	v.red.msb_right = v.green.msb_right = v.blue.msb_right =
1271			  v.transp.msb_right = 0;
1272
1273        *var = v;
1274
1275	return 0;
1276}
1277
1278static int
1279intelfb_set_par(struct fb_info *info)
1280{
1281 	struct intelfb_hwstate *hw;
1282        struct intelfb_info *dinfo = GET_DINFO(info);
1283
1284	if (FIXED_MODE(dinfo)) {
1285		ERR_MSG("Changing the video mode is not supported.\n");
1286		return -EINVAL;
1287	}
1288
1289 	hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
1290 	if (!hw)
1291 		return -ENOMEM;
1292
1293	DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
1294		info->var.yres, info->var.bits_per_pixel);
1295
1296	intelfb_blank(FB_BLANK_POWERDOWN, info);
1297
1298	if (ACCEL(dinfo, info))
1299		intelfbhw_2d_stop(dinfo);
1300
1301 	memcpy(hw, &dinfo->save_state, sizeof(*hw));
1302 	if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
1303 		goto invalid_mode;
1304 	if (intelfbhw_program_mode(dinfo, hw, 0))
1305 		goto invalid_mode;
1306
1307#if REGDUMP > 0
1308 	intelfbhw_read_hw_state(dinfo, hw, 0);
1309 	intelfbhw_print_hw_state(dinfo, hw);
1310#endif
1311
1312	update_dinfo(dinfo, &info->var);
1313
1314	if (ACCEL(dinfo, info))
1315		intelfbhw_2d_start(dinfo);
1316
1317	intelfb_pan_display(&info->var, info);
1318
1319	intelfb_blank(FB_BLANK_UNBLANK, info);
1320
1321	if (ACCEL(dinfo, info)) {
1322		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
1323		FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1324		FBINFO_HWACCEL_IMAGEBLIT;
1325	} else {
1326		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1327	}
1328	kfree(hw);
1329	return 0;
1330invalid_mode:
1331	kfree(hw);
1332	return -EINVAL;
1333}
1334
1335static int
1336intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1337		  unsigned blue, unsigned transp, struct fb_info *info)
1338{
1339	struct intelfb_info *dinfo = GET_DINFO(info);
1340
1341#if VERBOSE > 0
1342	DBG_MSG("intelfb_setcolreg: regno %d, depth %d\n", regno, dinfo->depth);
1343#endif
1344
1345	if (regno > 255)
1346		return 1;
1347
1348	if (dinfo->depth == 8) {
1349		red >>= 8;
1350		green >>= 8;
1351		blue >>= 8;
1352
1353		intelfbhw_setcolreg(dinfo, regno, red, green, blue,
1354				    transp);
1355	}
1356
1357	if (regno < 16) {
1358		switch (dinfo->depth) {
1359		case 15:
1360			dinfo->pseudo_palette[regno] = ((red & 0xf800) >>  1) |
1361				((green & 0xf800) >>  6) |
1362				((blue & 0xf800) >> 11);
1363			break;
1364		case 16:
1365			dinfo->pseudo_palette[regno] = (red & 0xf800) |
1366				((green & 0xfc00) >>  5) |
1367				((blue  & 0xf800) >> 11);
1368			break;
1369		case 24:
1370			dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) |
1371				(green & 0xff00) |
1372				((blue  & 0xff00) >> 8);
1373			break;
1374		}
1375	}
1376
1377	return 0;
1378}
1379
1380static int
1381intelfb_blank(int blank, struct fb_info *info)
1382{
1383	intelfbhw_do_blank(blank, info);
1384	return 0;
1385}
1386
1387static int
1388intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1389{
1390	intelfbhw_pan_display(var, info);
1391	return 0;
1392}
1393
1394/* When/if we have our own ioctls. */
1395static int
1396intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
1397{
1398	int retval = 0;
1399	struct intelfb_info *dinfo = GET_DINFO(info);
1400	u32 pipe = 0;
1401
1402	switch (cmd) {
1403		case FBIO_WAITFORVSYNC:
1404			if (get_user(pipe, (__u32 __user *)arg))
1405				return -EFAULT;
1406
1407			retval = intelfbhw_wait_for_vsync(dinfo, pipe);
1408			break;
1409		default:
1410			break;
1411	}
1412
1413	return retval;
1414}
1415
1416static void
1417intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
1418{
1419        struct intelfb_info *dinfo = GET_DINFO(info);
1420	u32 rop, color;
1421
1422#if VERBOSE > 0
1423	DBG_MSG("intelfb_fillrect\n");
1424#endif
1425
1426	if (!ACCEL(dinfo, info) || dinfo->depth == 4)
1427		return cfb_fillrect(info, rect);
1428
1429	if (rect->rop == ROP_COPY)
1430		rop = PAT_ROP_GXCOPY;
1431	else // ROP_XOR
1432		rop = PAT_ROP_GXXOR;
1433
1434	if (dinfo->depth != 8)
1435		color = dinfo->pseudo_palette[rect->color];
1436	else
1437		color = rect->color;
1438
1439	intelfbhw_do_fillrect(dinfo, rect->dx, rect->dy,
1440			      rect->width, rect->height, color,
1441			      dinfo->pitch, info->var.bits_per_pixel,
1442			      rop);
1443}
1444
1445static void
1446intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1447{
1448        struct intelfb_info *dinfo = GET_DINFO(info);
1449
1450#if VERBOSE > 0
1451	DBG_MSG("intelfb_copyarea\n");
1452#endif
1453
1454	if (!ACCEL(dinfo, info) || dinfo->depth == 4)
1455		return cfb_copyarea(info, region);
1456
1457	intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx,
1458			    region->dy, region->width, region->height,
1459			    dinfo->pitch, info->var.bits_per_pixel);
1460}
1461
1462static void
1463intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
1464{
1465        struct intelfb_info *dinfo = GET_DINFO(info);
1466	u32 fgcolor, bgcolor;
1467
1468#if VERBOSE > 0
1469	DBG_MSG("intelfb_imageblit\n");
1470#endif
1471
1472	if (!ACCEL(dinfo, info) || dinfo->depth == 4
1473	    || image->depth != 1)
1474		return cfb_imageblit(info, image);
1475
1476	if (dinfo->depth != 8) {
1477		fgcolor = dinfo->pseudo_palette[image->fg_color];
1478		bgcolor = dinfo->pseudo_palette[image->bg_color];
1479	} else {
1480		fgcolor = image->fg_color;
1481		bgcolor = image->bg_color;
1482	}
1483
1484	if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width,
1485				    image->height, image->data,
1486				    image->dx, image->dy,
1487				    dinfo->pitch, info->var.bits_per_pixel))
1488		return cfb_imageblit(info, image);
1489}
1490
1491static int
1492intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1493{
1494        struct intelfb_info *dinfo = GET_DINFO(info);
1495	u32 physical;
1496#if VERBOSE > 0
1497	DBG_MSG("intelfb_cursor\n");
1498#endif
1499
1500	if (!dinfo->hwcursor)
1501		return -ENODEV;
1502
1503	intelfbhw_cursor_hide(dinfo);
1504
1505	/* If XFree killed the cursor - restore it */
1506	physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical :
1507		   (dinfo->cursor.offset << 12);
1508
1509	if (INREG(CURSOR_A_BASEADDR) != physical) {
1510		u32 fg, bg;
1511
1512		DBG_MSG("the cursor was killed - restore it !!\n");
1513		DBG_MSG("size %d, %d   pos %d, %d\n",
1514			cursor->image.width, cursor->image.height,
1515			cursor->image.dx, cursor->image.dy);
1516
1517		intelfbhw_cursor_init(dinfo);
1518		intelfbhw_cursor_reset(dinfo);
1519		intelfbhw_cursor_setpos(dinfo, cursor->image.dx,
1520					cursor->image.dy);
1521
1522		if (dinfo->depth != 8) {
1523			fg =dinfo->pseudo_palette[cursor->image.fg_color];
1524			bg =dinfo->pseudo_palette[cursor->image.bg_color];
1525		} else {
1526			fg = cursor->image.fg_color;
1527			bg = cursor->image.bg_color;
1528		}
1529		intelfbhw_cursor_setcolor(dinfo, bg, fg);
1530		intelfbhw_cursor_load(dinfo, cursor->image.width,
1531				      cursor->image.height,
1532				      dinfo->cursor_src);
1533
1534		if (cursor->enable)
1535			intelfbhw_cursor_show(dinfo);
1536		return 0;
1537	}
1538
1539	if (cursor->set & FB_CUR_SETPOS) {
1540		u32 dx, dy;
1541
1542		dx = cursor->image.dx - info->var.xoffset;
1543		dy = cursor->image.dy - info->var.yoffset;
1544
1545		intelfbhw_cursor_setpos(dinfo, dx, dy);
1546	}
1547
1548	if (cursor->set & FB_CUR_SETSIZE) {
1549		if (cursor->image.width > 64 || cursor->image.height > 64)
1550			return -ENXIO;
1551
1552		intelfbhw_cursor_reset(dinfo);
1553	}
1554
1555	if (cursor->set & FB_CUR_SETCMAP) {
1556		u32 fg, bg;
1557
1558		if (dinfo->depth != 8) {
1559			fg = dinfo->pseudo_palette[cursor->image.fg_color];
1560			bg = dinfo->pseudo_palette[cursor->image.bg_color];
1561		} else {
1562			fg = cursor->image.fg_color;
1563			bg = cursor->image.bg_color;
1564		}
1565
1566		intelfbhw_cursor_setcolor(dinfo, bg, fg);
1567	}
1568
1569	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1570		u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8);
1571		u32 size = s_pitch * cursor->image.height;
1572		u8 *dat = (u8 *) cursor->image.data;
1573		u8 *msk = (u8 *) cursor->mask;
1574		u8 src[64];
1575		u32 i;
1576
1577		if (cursor->image.depth != 1)
1578			return -ENXIO;
1579
1580		switch (cursor->rop) {
1581		case ROP_XOR:
1582			for (i = 0; i < size; i++)
1583				src[i] = dat[i] ^ msk[i];
1584			break;
1585		case ROP_COPY:
1586		default:
1587			for (i = 0; i < size; i++)
1588				src[i] = dat[i] & msk[i];
1589			break;
1590		}
1591
1592		/* save the bitmap to restore it when XFree will
1593		   make the cursor dirty */
1594		memcpy(dinfo->cursor_src, src, size);
1595
1596		intelfbhw_cursor_load(dinfo, cursor->image.width,
1597				      cursor->image.height, src);
1598	}
1599
1600	if (cursor->enable)
1601		intelfbhw_cursor_show(dinfo);
1602
1603	return 0;
1604}
1605
1606static int
1607intelfb_sync(struct fb_info *info)
1608{
1609        struct intelfb_info *dinfo = GET_DINFO(info);
1610
1611#if VERBOSE > 0
1612	DBG_MSG("intelfb_sync\n");
1613#endif
1614
1615	if (dinfo->ring_lockup)
1616		return 0;
1617
1618	intelfbhw_do_sync(dinfo);
1619	return 0;
1620}
1621