• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * intelfb
3  *
4  * Linux framebuffer driver for Intel(R) 865G integrated graphics chips.
5  *
6  * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
7  *                   2004 Sylvain Meyer
8  *
9  * This driver consists of two parts.  The first part (intelfbdrv.c) provides
10  * the basic fbdev interfaces, is derived in part from the radeonfb and
11  * vesafb drivers, and is covered by the GPL.  The second part (intelfbhw.c)
12  * provides the code to program the hardware.  Most of it is derived from
13  * the i810/i830 XFree86 driver.  The HW-specific code is covered here
14  * under a dual license (GPL and MIT/XFree86 license).
15  *
16  * Author: David Dawes
17  *
18  */
19 
20 /* $DHD: intelfb/intelfbhw.c,v 1.9 2003/06/27 15:06:25 dawes Exp $ */
21 
22 #include <linux/module.h>
23 #include <linux/kernel.h>
24 #include <linux/errno.h>
25 #include <linux/string.h>
26 #include <linux/mm.h>
27 #include <linux/slab.h>
28 #include <linux/delay.h>
29 #include <linux/fb.h>
30 #include <linux/ioport.h>
31 #include <linux/init.h>
32 #include <linux/pci.h>
33 #include <linux/vmalloc.h>
34 #include <linux/pagemap.h>
35 #include <linux/interrupt.h>
36 
37 #include <asm/io.h>
38 
39 #include "intelfb.h"
40 #include "intelfbhw.h"
41 
42 struct pll_min_max {
43 	int min_m, max_m, min_m1, max_m1;
44 	int min_m2, max_m2, min_n, max_n;
45 	int min_p, max_p, min_p1, max_p1;
46 	int min_vco, max_vco, p_transition_clk, ref_clk;
47 	int p_inc_lo, p_inc_hi;
48 };
49 
50 #define PLLS_I8xx 0
51 #define PLLS_I9xx 1
52 #define PLLS_MAX 2
53 
54 static struct pll_min_max plls[PLLS_MAX] = {
55 	{ 108, 140, 18, 26,
56 	  6, 16, 3, 16,
57 	  4, 128, 0, 31,
58 	  930000, 1400000, 165000, 48000,
59 	  4, 2 },		/* I8xx */
60 
61 	{ 75, 120, 10, 20,
62 	  5, 9, 4, 7,
63 	  5, 80, 1, 8,
64 	  1400000, 2800000, 200000, 96000,
65 	  10, 5 }		/* I9xx */
66 };
67 
intelfbhw_get_chipset(struct pci_dev * pdev,struct intelfb_info * dinfo)68 int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
69 {
70 	u32 tmp;
71 	if (!pdev || !dinfo)
72 		return 1;
73 
74 	switch (pdev->device) {
75 	case PCI_DEVICE_ID_INTEL_830M:
76 		dinfo->name = "Intel(R) 830M";
77 		dinfo->chipset = INTEL_830M;
78 		dinfo->mobile = 1;
79 		dinfo->pll_index = PLLS_I8xx;
80 		return 0;
81 	case PCI_DEVICE_ID_INTEL_845G:
82 		dinfo->name = "Intel(R) 845G";
83 		dinfo->chipset = INTEL_845G;
84 		dinfo->mobile = 0;
85 		dinfo->pll_index = PLLS_I8xx;
86 		return 0;
87 	case PCI_DEVICE_ID_INTEL_85XGM:
88 		tmp = 0;
89 		dinfo->mobile = 1;
90 		dinfo->pll_index = PLLS_I8xx;
91 		pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp);
92 		switch ((tmp >> INTEL_85X_VARIANT_SHIFT) &
93 			INTEL_85X_VARIANT_MASK) {
94 		case INTEL_VAR_855GME:
95 			dinfo->name = "Intel(R) 855GME";
96 			dinfo->chipset = INTEL_855GME;
97 			return 0;
98 		case INTEL_VAR_855GM:
99 			dinfo->name = "Intel(R) 855GM";
100 			dinfo->chipset = INTEL_855GM;
101 			return 0;
102 		case INTEL_VAR_852GME:
103 			dinfo->name = "Intel(R) 852GME";
104 			dinfo->chipset = INTEL_852GME;
105 			return 0;
106 		case INTEL_VAR_852GM:
107 			dinfo->name = "Intel(R) 852GM";
108 			dinfo->chipset = INTEL_852GM;
109 			return 0;
110 		default:
111 			dinfo->name = "Intel(R) 852GM/855GM";
112 			dinfo->chipset = INTEL_85XGM;
113 			return 0;
114 		}
115 		break;
116 	case PCI_DEVICE_ID_INTEL_865G:
117 		dinfo->name = "Intel(R) 865G";
118 		dinfo->chipset = INTEL_865G;
119 		dinfo->mobile = 0;
120 		dinfo->pll_index = PLLS_I8xx;
121 		return 0;
122 	case PCI_DEVICE_ID_INTEL_915G:
123 		dinfo->name = "Intel(R) 915G";
124 		dinfo->chipset = INTEL_915G;
125 		dinfo->mobile = 0;
126 		dinfo->pll_index = PLLS_I9xx;
127 		return 0;
128 	case PCI_DEVICE_ID_INTEL_915GM:
129 		dinfo->name = "Intel(R) 915GM";
130 		dinfo->chipset = INTEL_915GM;
131 		dinfo->mobile = 1;
132 		dinfo->pll_index = PLLS_I9xx;
133 		return 0;
134 	case PCI_DEVICE_ID_INTEL_945G:
135 		dinfo->name = "Intel(R) 945G";
136 		dinfo->chipset = INTEL_945G;
137 		dinfo->mobile = 0;
138 		dinfo->pll_index = PLLS_I9xx;
139 		return 0;
140 	case PCI_DEVICE_ID_INTEL_945GM:
141 		dinfo->name = "Intel(R) 945GM";
142 		dinfo->chipset = INTEL_945GM;
143 		dinfo->mobile = 1;
144 		dinfo->pll_index = PLLS_I9xx;
145 		return 0;
146 	case PCI_DEVICE_ID_INTEL_945GME:
147 		dinfo->name = "Intel(R) 945GME";
148 		dinfo->chipset = INTEL_945GME;
149 		dinfo->mobile = 1;
150 		dinfo->pll_index = PLLS_I9xx;
151 		return 0;
152 	case PCI_DEVICE_ID_INTEL_965G:
153 		dinfo->name = "Intel(R) 965G";
154 		dinfo->chipset = INTEL_965G;
155 		dinfo->mobile = 0;
156 		dinfo->pll_index = PLLS_I9xx;
157 		return 0;
158 	case PCI_DEVICE_ID_INTEL_965GM:
159 		dinfo->name = "Intel(R) 965GM";
160 		dinfo->chipset = INTEL_965GM;
161 		dinfo->mobile = 1;
162 		dinfo->pll_index = PLLS_I9xx;
163 		return 0;
164 	default:
165 		return 1;
166 	}
167 }
168 
intelfbhw_get_memory(struct pci_dev * pdev,int * aperture_size,int * stolen_size)169 int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
170 			 int *stolen_size)
171 {
172 	struct pci_dev *bridge_dev;
173 	u16 tmp;
174 	int stolen_overhead;
175 
176 	if (!pdev || !aperture_size || !stolen_size)
177 		return 1;
178 
179 	/* Find the bridge device.  It is always 0:0.0 */
180 	if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) {
181 		ERR_MSG("cannot find bridge device\n");
182 		return 1;
183 	}
184 
185 	/* Get the fb aperture size and "stolen" memory amount. */
186 	tmp = 0;
187 	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
188 	pci_dev_put(bridge_dev);
189 
190 	switch (pdev->device) {
191 	case PCI_DEVICE_ID_INTEL_915G:
192 	case PCI_DEVICE_ID_INTEL_915GM:
193 	case PCI_DEVICE_ID_INTEL_945G:
194 	case PCI_DEVICE_ID_INTEL_945GM:
195 	case PCI_DEVICE_ID_INTEL_945GME:
196 	case PCI_DEVICE_ID_INTEL_965G:
197 	case PCI_DEVICE_ID_INTEL_965GM:
198 		/* 915, 945 and 965 chipsets support a 256MB aperture.
199 		   Aperture size is determined by inspected the
200 		   base address of the aperture. */
201 		if (pci_resource_start(pdev, 2) & 0x08000000)
202 			*aperture_size = MB(128);
203 		else
204 			*aperture_size = MB(256);
205 		break;
206 	default:
207 		if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
208 			*aperture_size = MB(64);
209 		else
210 			*aperture_size = MB(128);
211 		break;
212 	}
213 
214 	/* Stolen memory size is reduced by the GTT and the popup.
215 	   GTT is 1K per MB of aperture size, and popup is 4K. */
216 	stolen_overhead = (*aperture_size / MB(1)) + 4;
217 	switch(pdev->device) {
218 	case PCI_DEVICE_ID_INTEL_830M:
219 	case PCI_DEVICE_ID_INTEL_845G:
220 		switch (tmp & INTEL_830_GMCH_GMS_MASK) {
221 		case INTEL_830_GMCH_GMS_STOLEN_512:
222 			*stolen_size = KB(512) - KB(stolen_overhead);
223 			return 0;
224 		case INTEL_830_GMCH_GMS_STOLEN_1024:
225 			*stolen_size = MB(1) - KB(stolen_overhead);
226 			return 0;
227 		case INTEL_830_GMCH_GMS_STOLEN_8192:
228 			*stolen_size = MB(8) - KB(stolen_overhead);
229 			return 0;
230 		case INTEL_830_GMCH_GMS_LOCAL:
231 			ERR_MSG("only local memory found\n");
232 			return 1;
233 		case INTEL_830_GMCH_GMS_DISABLED:
234 			ERR_MSG("video memory is disabled\n");
235 			return 1;
236 		default:
237 			ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n",
238 				tmp & INTEL_830_GMCH_GMS_MASK);
239 			return 1;
240 		}
241 		break;
242 	default:
243 		switch (tmp & INTEL_855_GMCH_GMS_MASK) {
244 		case INTEL_855_GMCH_GMS_STOLEN_1M:
245 			*stolen_size = MB(1) - KB(stolen_overhead);
246 			return 0;
247 		case INTEL_855_GMCH_GMS_STOLEN_4M:
248 			*stolen_size = MB(4) - KB(stolen_overhead);
249 			return 0;
250 		case INTEL_855_GMCH_GMS_STOLEN_8M:
251 			*stolen_size = MB(8) - KB(stolen_overhead);
252 			return 0;
253 		case INTEL_855_GMCH_GMS_STOLEN_16M:
254 			*stolen_size = MB(16) - KB(stolen_overhead);
255 			return 0;
256 		case INTEL_855_GMCH_GMS_STOLEN_32M:
257 			*stolen_size = MB(32) - KB(stolen_overhead);
258 			return 0;
259 		case INTEL_915G_GMCH_GMS_STOLEN_48M:
260 			*stolen_size = MB(48) - KB(stolen_overhead);
261 			return 0;
262 		case INTEL_915G_GMCH_GMS_STOLEN_64M:
263 			*stolen_size = MB(64) - KB(stolen_overhead);
264 			return 0;
265 		case INTEL_855_GMCH_GMS_DISABLED:
266 			ERR_MSG("video memory is disabled\n");
267 			return 0;
268 		default:
269 			ERR_MSG("unexpected GMCH_GMS value: 0x%02x\n",
270 				tmp & INTEL_855_GMCH_GMS_MASK);
271 			return 1;
272 		}
273 	}
274 }
275 
intelfbhw_check_non_crt(struct intelfb_info * dinfo)276 int intelfbhw_check_non_crt(struct intelfb_info *dinfo)
277 {
278 	int dvo = 0;
279 
280 	if (INREG(LVDS) & PORT_ENABLE)
281 		dvo |= LVDS_PORT;
282 	if (INREG(DVOA) & PORT_ENABLE)
283 		dvo |= DVOA_PORT;
284 	if (INREG(DVOB) & PORT_ENABLE)
285 		dvo |= DVOB_PORT;
286 	if (INREG(DVOC) & PORT_ENABLE)
287 		dvo |= DVOC_PORT;
288 
289 	return dvo;
290 }
291 
intelfbhw_dvo_to_string(int dvo)292 const char * intelfbhw_dvo_to_string(int dvo)
293 {
294 	if (dvo & DVOA_PORT)
295 		return "DVO port A";
296 	else if (dvo & DVOB_PORT)
297 		return "DVO port B";
298 	else if (dvo & DVOC_PORT)
299 		return "DVO port C";
300 	else if (dvo & LVDS_PORT)
301 		return "LVDS port";
302 	else
303 		return NULL;
304 }
305 
306 
intelfbhw_validate_mode(struct intelfb_info * dinfo,struct fb_var_screeninfo * var)307 int intelfbhw_validate_mode(struct intelfb_info *dinfo,
308 			    struct fb_var_screeninfo *var)
309 {
310 	int bytes_per_pixel;
311 	int tmp;
312 
313 #if VERBOSE > 0
314 	DBG_MSG("intelfbhw_validate_mode\n");
315 #endif
316 
317 	bytes_per_pixel = var->bits_per_pixel / 8;
318 	if (bytes_per_pixel == 3)
319 		bytes_per_pixel = 4;
320 
321 	/* Check if enough video memory. */
322 	tmp = var->yres_virtual * var->xres_virtual * bytes_per_pixel;
323 	if (tmp > dinfo->fb.size) {
324 		WRN_MSG("Not enough video ram for mode "
325 			"(%d KByte vs %d KByte).\n",
326 			BtoKB(tmp), BtoKB(dinfo->fb.size));
327 		return 1;
328 	}
329 
330 	/* Check if x/y limits are OK. */
331 	if (var->xres - 1 > HACTIVE_MASK) {
332 		WRN_MSG("X resolution too large (%d vs %d).\n",
333 			var->xres, HACTIVE_MASK + 1);
334 		return 1;
335 	}
336 	if (var->yres - 1 > VACTIVE_MASK) {
337 		WRN_MSG("Y resolution too large (%d vs %d).\n",
338 			var->yres, VACTIVE_MASK + 1);
339 		return 1;
340 	}
341 	if (var->xres < 4) {
342 		WRN_MSG("X resolution too small (%d vs 4).\n", var->xres);
343 		return 1;
344 	}
345 	if (var->yres < 4) {
346 		WRN_MSG("Y resolution too small (%d vs 4).\n", var->yres);
347 		return 1;
348 	}
349 
350 	/* Check for doublescan modes. */
351 	if (var->vmode & FB_VMODE_DOUBLE) {
352 		WRN_MSG("Mode is double-scan.\n");
353 		return 1;
354 	}
355 
356 	if ((var->vmode & FB_VMODE_INTERLACED) && (var->yres & 1)) {
357 		WRN_MSG("Odd number of lines in interlaced mode\n");
358 		return 1;
359 	}
360 
361 	/* Check if clock is OK. */
362 	tmp = 1000000000 / var->pixclock;
363 	if (tmp < MIN_CLOCK) {
364 		WRN_MSG("Pixel clock is too low (%d MHz vs %d MHz).\n",
365 			(tmp + 500) / 1000, MIN_CLOCK / 1000);
366 		return 1;
367 	}
368 	if (tmp > MAX_CLOCK) {
369 		WRN_MSG("Pixel clock is too high (%d MHz vs %d MHz).\n",
370 			(tmp + 500) / 1000, MAX_CLOCK / 1000);
371 		return 1;
372 	}
373 
374 	return 0;
375 }
376 
intelfbhw_pan_display(struct fb_var_screeninfo * var,struct fb_info * info)377 int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
378 {
379 	struct intelfb_info *dinfo = GET_DINFO(info);
380 	u32 offset, xoffset, yoffset;
381 
382 #if VERBOSE > 0
383 	DBG_MSG("intelfbhw_pan_display\n");
384 #endif
385 
386 	xoffset = ROUND_DOWN_TO(var->xoffset, 8);
387 	yoffset = var->yoffset;
388 
389 	if ((xoffset + var->xres > var->xres_virtual) ||
390 	    (yoffset + var->yres > var->yres_virtual))
391 		return -EINVAL;
392 
393 	offset = (yoffset * dinfo->pitch) +
394 		 (xoffset * var->bits_per_pixel) / 8;
395 
396 	offset += dinfo->fb.offset << 12;
397 
398 	dinfo->vsync.pan_offset = offset;
399 	if ((var->activate & FB_ACTIVATE_VBL) &&
400 	    !intelfbhw_enable_irq(dinfo))
401 		dinfo->vsync.pan_display = 1;
402 	else {
403 		dinfo->vsync.pan_display = 0;
404 		OUTREG(DSPABASE, offset);
405 	}
406 
407 	return 0;
408 }
409 
410 /* Blank the screen. */
intelfbhw_do_blank(int blank,struct fb_info * info)411 void intelfbhw_do_blank(int blank, struct fb_info *info)
412 {
413 	struct intelfb_info *dinfo = GET_DINFO(info);
414 	u32 tmp;
415 
416 #if VERBOSE > 0
417 	DBG_MSG("intelfbhw_do_blank: blank is %d\n", blank);
418 #endif
419 
420 	/* Turn plane A on or off */
421 	tmp = INREG(DSPACNTR);
422 	if (blank)
423 		tmp &= ~DISPPLANE_PLANE_ENABLE;
424 	else
425 		tmp |= DISPPLANE_PLANE_ENABLE;
426 	OUTREG(DSPACNTR, tmp);
427 	/* Flush */
428 	tmp = INREG(DSPABASE);
429 	OUTREG(DSPABASE, tmp);
430 
431 	/* Turn off/on the HW cursor */
432 #if VERBOSE > 0
433 	DBG_MSG("cursor_on is %d\n", dinfo->cursor_on);
434 #endif
435 	if (dinfo->cursor_on) {
436 		if (blank)
437 			intelfbhw_cursor_hide(dinfo);
438 		else
439 			intelfbhw_cursor_show(dinfo);
440 		dinfo->cursor_on = 1;
441 	}
442 	dinfo->cursor_blanked = blank;
443 
444 	/* Set DPMS level */
445 	tmp = INREG(ADPA) & ~ADPA_DPMS_CONTROL_MASK;
446 	switch (blank) {
447 	case FB_BLANK_UNBLANK:
448 	case FB_BLANK_NORMAL:
449 		tmp |= ADPA_DPMS_D0;
450 		break;
451 	case FB_BLANK_VSYNC_SUSPEND:
452 		tmp |= ADPA_DPMS_D1;
453 		break;
454 	case FB_BLANK_HSYNC_SUSPEND:
455 		tmp |= ADPA_DPMS_D2;
456 		break;
457 	case FB_BLANK_POWERDOWN:
458 		tmp |= ADPA_DPMS_D3;
459 		break;
460 	}
461 	OUTREG(ADPA, tmp);
462 
463 	return;
464 }
465 
466 
intelfbhw_setcolreg(struct intelfb_info * dinfo,unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp)467 void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
468 			 unsigned red, unsigned green, unsigned blue,
469 			 unsigned transp)
470 {
471 	u32 palette_reg = (dinfo->pipe == PIPE_A) ?
472 			  PALETTE_A : PALETTE_B;
473 
474 #if VERBOSE > 0
475 	DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n",
476 		regno, red, green, blue);
477 #endif
478 
479 	OUTREG(palette_reg + (regno << 2),
480 	       (red << PALETTE_8_RED_SHIFT) |
481 	       (green << PALETTE_8_GREEN_SHIFT) |
482 	       (blue << PALETTE_8_BLUE_SHIFT));
483 }
484 
485 
intelfbhw_read_hw_state(struct intelfb_info * dinfo,struct intelfb_hwstate * hw,int flag)486 int intelfbhw_read_hw_state(struct intelfb_info *dinfo,
487 			    struct intelfb_hwstate *hw, int flag)
488 {
489 	int i;
490 
491 #if VERBOSE > 0
492 	DBG_MSG("intelfbhw_read_hw_state\n");
493 #endif
494 
495 	if (!hw || !dinfo)
496 		return -1;
497 
498 	/* Read in as much of the HW state as possible. */
499 	hw->vga0_divisor = INREG(VGA0_DIVISOR);
500 	hw->vga1_divisor = INREG(VGA1_DIVISOR);
501 	hw->vga_pd = INREG(VGAPD);
502 	hw->dpll_a = INREG(DPLL_A);
503 	hw->dpll_b = INREG(DPLL_B);
504 	hw->fpa0 = INREG(FPA0);
505 	hw->fpa1 = INREG(FPA1);
506 	hw->fpb0 = INREG(FPB0);
507 	hw->fpb1 = INREG(FPB1);
508 
509 	if (flag == 1)
510 		return flag;
511 
512 #if 0
513 	/* This seems to be a problem with the 852GM/855GM */
514 	for (i = 0; i < PALETTE_8_ENTRIES; i++) {
515 		hw->palette_a[i] = INREG(PALETTE_A + (i << 2));
516 		hw->palette_b[i] = INREG(PALETTE_B + (i << 2));
517 	}
518 #endif
519 
520 	if (flag == 2)
521 		return flag;
522 
523 	hw->htotal_a = INREG(HTOTAL_A);
524 	hw->hblank_a = INREG(HBLANK_A);
525 	hw->hsync_a = INREG(HSYNC_A);
526 	hw->vtotal_a = INREG(VTOTAL_A);
527 	hw->vblank_a = INREG(VBLANK_A);
528 	hw->vsync_a = INREG(VSYNC_A);
529 	hw->src_size_a = INREG(SRC_SIZE_A);
530 	hw->bclrpat_a = INREG(BCLRPAT_A);
531 	hw->htotal_b = INREG(HTOTAL_B);
532 	hw->hblank_b = INREG(HBLANK_B);
533 	hw->hsync_b = INREG(HSYNC_B);
534 	hw->vtotal_b = INREG(VTOTAL_B);
535 	hw->vblank_b = INREG(VBLANK_B);
536 	hw->vsync_b = INREG(VSYNC_B);
537 	hw->src_size_b = INREG(SRC_SIZE_B);
538 	hw->bclrpat_b = INREG(BCLRPAT_B);
539 
540 	if (flag == 3)
541 		return flag;
542 
543 	hw->adpa = INREG(ADPA);
544 	hw->dvoa = INREG(DVOA);
545 	hw->dvob = INREG(DVOB);
546 	hw->dvoc = INREG(DVOC);
547 	hw->dvoa_srcdim = INREG(DVOA_SRCDIM);
548 	hw->dvob_srcdim = INREG(DVOB_SRCDIM);
549 	hw->dvoc_srcdim = INREG(DVOC_SRCDIM);
550 	hw->lvds = INREG(LVDS);
551 
552 	if (flag == 4)
553 		return flag;
554 
555 	hw->pipe_a_conf = INREG(PIPEACONF);
556 	hw->pipe_b_conf = INREG(PIPEBCONF);
557 	hw->disp_arb = INREG(DISPARB);
558 
559 	if (flag == 5)
560 		return flag;
561 
562 	hw->cursor_a_control = INREG(CURSOR_A_CONTROL);
563 	hw->cursor_b_control = INREG(CURSOR_B_CONTROL);
564 	hw->cursor_a_base = INREG(CURSOR_A_BASEADDR);
565 	hw->cursor_b_base = INREG(CURSOR_B_BASEADDR);
566 
567 	if (flag == 6)
568 		return flag;
569 
570 	for (i = 0; i < 4; i++) {
571 		hw->cursor_a_palette[i] = INREG(CURSOR_A_PALETTE0 + (i << 2));
572 		hw->cursor_b_palette[i] = INREG(CURSOR_B_PALETTE0 + (i << 2));
573 	}
574 
575 	if (flag == 7)
576 		return flag;
577 
578 	hw->cursor_size = INREG(CURSOR_SIZE);
579 
580 	if (flag == 8)
581 		return flag;
582 
583 	hw->disp_a_ctrl = INREG(DSPACNTR);
584 	hw->disp_b_ctrl = INREG(DSPBCNTR);
585 	hw->disp_a_base = INREG(DSPABASE);
586 	hw->disp_b_base = INREG(DSPBBASE);
587 	hw->disp_a_stride = INREG(DSPASTRIDE);
588 	hw->disp_b_stride = INREG(DSPBSTRIDE);
589 
590 	if (flag == 9)
591 		return flag;
592 
593 	hw->vgacntrl = INREG(VGACNTRL);
594 
595 	if (flag == 10)
596 		return flag;
597 
598 	hw->add_id = INREG(ADD_ID);
599 
600 	if (flag == 11)
601 		return flag;
602 
603 	for (i = 0; i < 7; i++) {
604 		hw->swf0x[i] = INREG(SWF00 + (i << 2));
605 		hw->swf1x[i] = INREG(SWF10 + (i << 2));
606 		if (i < 3)
607 			hw->swf3x[i] = INREG(SWF30 + (i << 2));
608 	}
609 
610 	for (i = 0; i < 8; i++)
611 		hw->fence[i] = INREG(FENCE + (i << 2));
612 
613 	hw->instpm = INREG(INSTPM);
614 	hw->mem_mode = INREG(MEM_MODE);
615 	hw->fw_blc_0 = INREG(FW_BLC_0);
616 	hw->fw_blc_1 = INREG(FW_BLC_1);
617 
618 	hw->hwstam = INREG16(HWSTAM);
619 	hw->ier = INREG16(IER);
620 	hw->iir = INREG16(IIR);
621 	hw->imr = INREG16(IMR);
622 
623 	return 0;
624 }
625 
626 
calc_vclock3(int index,int m,int n,int p)627 static int calc_vclock3(int index, int m, int n, int p)
628 {
629 	if (p == 0 || n == 0)
630 		return 0;
631 	return plls[index].ref_clk * m / n / p;
632 }
633 
calc_vclock(int index,int m1,int m2,int n,int p1,int p2,int lvds)634 static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2,
635 		       int lvds)
636 {
637 	struct pll_min_max *pll = &plls[index];
638 	u32 m, vco, p;
639 
640 	m = (5 * (m1 + 2)) + (m2 + 2);
641 	n += 2;
642 	vco = pll->ref_clk * m / n;
643 
644 	if (index == PLLS_I8xx)
645 		p = ((p1 + 2) * (1 << (p2 + 1)));
646 	else
647 		p = ((p1) * (p2 ? 5 : 10));
648 	return vco / p;
649 }
650 
651 #if REGDUMP
intelfbhw_get_p1p2(struct intelfb_info * dinfo,int dpll,int * o_p1,int * o_p2)652 static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll,
653 			       int *o_p1, int *o_p2)
654 {
655 	int p1, p2;
656 
657 	if (IS_I9XX(dinfo)) {
658 		if (dpll & DPLL_P1_FORCE_DIV2)
659 			p1 = 1;
660 		else
661 			p1 = (dpll >> DPLL_P1_SHIFT) & 0xff;
662 
663 		p1 = ffs(p1);
664 
665 		p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK;
666 	} else {
667 		if (dpll & DPLL_P1_FORCE_DIV2)
668 			p1 = 0;
669 		else
670 			p1 = (dpll >> DPLL_P1_SHIFT) & DPLL_P1_MASK;
671 		p2 = (dpll >> DPLL_P2_SHIFT) & DPLL_P2_MASK;
672 	}
673 
674 	*o_p1 = p1;
675 	*o_p2 = p2;
676 }
677 #endif
678 
679 
intelfbhw_print_hw_state(struct intelfb_info * dinfo,struct intelfb_hwstate * hw)680 void intelfbhw_print_hw_state(struct intelfb_info *dinfo,
681 			      struct intelfb_hwstate *hw)
682 {
683 #if REGDUMP
684 	int i, m1, m2, n, p1, p2;
685 	int index = dinfo->pll_index;
686 	DBG_MSG("intelfbhw_print_hw_state\n");
687 
688 	if (!hw)
689 		return;
690 	/* Read in as much of the HW state as possible. */
691 	printk("hw state dump start\n");
692 	printk("	VGA0_DIVISOR:		0x%08x\n", hw->vga0_divisor);
693 	printk("	VGA1_DIVISOR:		0x%08x\n", hw->vga1_divisor);
694 	printk("	VGAPD:			0x%08x\n", hw->vga_pd);
695 	n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
696 	m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
697 	m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
698 
699 	intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
700 
701 	printk("	VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
702 	       m1, m2, n, p1, p2);
703 	printk("	VGA0: clock is %d\n",
704 	       calc_vclock(index, m1, m2, n, p1, p2, 0));
705 
706 	n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
707 	m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
708 	m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
709 
710 	intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
711 	printk("	VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
712 	       m1, m2, n, p1, p2);
713 	printk("	VGA1: clock is %d\n",
714 	       calc_vclock(index, m1, m2, n, p1, p2, 0));
715 
716 	printk("	DPLL_A:			0x%08x\n", hw->dpll_a);
717 	printk("	DPLL_B:			0x%08x\n", hw->dpll_b);
718 	printk("	FPA0:			0x%08x\n", hw->fpa0);
719 	printk("	FPA1:			0x%08x\n", hw->fpa1);
720 	printk("	FPB0:			0x%08x\n", hw->fpb0);
721 	printk("	FPB1:			0x%08x\n", hw->fpb1);
722 
723 	n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
724 	m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
725 	m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
726 
727 	intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2);
728 
729 	printk("	PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
730 	       m1, m2, n, p1, p2);
731 	printk("	PLLA0: clock is %d\n",
732 	       calc_vclock(index, m1, m2, n, p1, p2, 0));
733 
734 	n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
735 	m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
736 	m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
737 
738 	intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2);
739 
740 	printk("	PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
741 	       m1, m2, n, p1, p2);
742 	printk("	PLLA1: clock is %d\n",
743 	       calc_vclock(index, m1, m2, n, p1, p2, 0));
744 
745 #if 0
746 	printk("	PALETTE_A:\n");
747 	for (i = 0; i < PALETTE_8_ENTRIES)
748 		printk("	%3d:	0x%08x\n", i, hw->palette_a[i]);
749 	printk("	PALETTE_B:\n");
750 	for (i = 0; i < PALETTE_8_ENTRIES)
751 		printk("	%3d:	0x%08x\n", i, hw->palette_b[i]);
752 #endif
753 
754 	printk("	HTOTAL_A:		0x%08x\n", hw->htotal_a);
755 	printk("	HBLANK_A:		0x%08x\n", hw->hblank_a);
756 	printk("	HSYNC_A:		0x%08x\n", hw->hsync_a);
757 	printk("	VTOTAL_A:		0x%08x\n", hw->vtotal_a);
758 	printk("	VBLANK_A:		0x%08x\n", hw->vblank_a);
759 	printk("	VSYNC_A:		0x%08x\n", hw->vsync_a);
760 	printk("	SRC_SIZE_A:		0x%08x\n", hw->src_size_a);
761 	printk("	BCLRPAT_A:		0x%08x\n", hw->bclrpat_a);
762 	printk("	HTOTAL_B:		0x%08x\n", hw->htotal_b);
763 	printk("	HBLANK_B:		0x%08x\n", hw->hblank_b);
764 	printk("	HSYNC_B:		0x%08x\n", hw->hsync_b);
765 	printk("	VTOTAL_B:		0x%08x\n", hw->vtotal_b);
766 	printk("	VBLANK_B:		0x%08x\n", hw->vblank_b);
767 	printk("	VSYNC_B:		0x%08x\n", hw->vsync_b);
768 	printk("	SRC_SIZE_B:		0x%08x\n", hw->src_size_b);
769 	printk("	BCLRPAT_B:		0x%08x\n", hw->bclrpat_b);
770 
771 	printk("	ADPA:			0x%08x\n", hw->adpa);
772 	printk("	DVOA:			0x%08x\n", hw->dvoa);
773 	printk("	DVOB:			0x%08x\n", hw->dvob);
774 	printk("	DVOC:			0x%08x\n", hw->dvoc);
775 	printk("	DVOA_SRCDIM:		0x%08x\n", hw->dvoa_srcdim);
776 	printk("	DVOB_SRCDIM:		0x%08x\n", hw->dvob_srcdim);
777 	printk("	DVOC_SRCDIM:		0x%08x\n", hw->dvoc_srcdim);
778 	printk("	LVDS:			0x%08x\n", hw->lvds);
779 
780 	printk("	PIPEACONF:		0x%08x\n", hw->pipe_a_conf);
781 	printk("	PIPEBCONF:		0x%08x\n", hw->pipe_b_conf);
782 	printk("	DISPARB:		0x%08x\n", hw->disp_arb);
783 
784 	printk("	CURSOR_A_CONTROL:	0x%08x\n", hw->cursor_a_control);
785 	printk("	CURSOR_B_CONTROL:	0x%08x\n", hw->cursor_b_control);
786 	printk("	CURSOR_A_BASEADDR:	0x%08x\n", hw->cursor_a_base);
787 	printk("	CURSOR_B_BASEADDR:	0x%08x\n", hw->cursor_b_base);
788 
789 	printk("	CURSOR_A_PALETTE:	");
790 	for (i = 0; i < 4; i++) {
791 		printk("0x%08x", hw->cursor_a_palette[i]);
792 		if (i < 3)
793 			printk(", ");
794 	}
795 	printk("\n");
796 	printk("	CURSOR_B_PALETTE:	");
797 	for (i = 0; i < 4; i++) {
798 		printk("0x%08x", hw->cursor_b_palette[i]);
799 		if (i < 3)
800 			printk(", ");
801 	}
802 	printk("\n");
803 
804 	printk("	CURSOR_SIZE:		0x%08x\n", hw->cursor_size);
805 
806 	printk("	DSPACNTR:		0x%08x\n", hw->disp_a_ctrl);
807 	printk("	DSPBCNTR:		0x%08x\n", hw->disp_b_ctrl);
808 	printk("	DSPABASE:		0x%08x\n", hw->disp_a_base);
809 	printk("	DSPBBASE:		0x%08x\n", hw->disp_b_base);
810 	printk("	DSPASTRIDE:		0x%08x\n", hw->disp_a_stride);
811 	printk("	DSPBSTRIDE:		0x%08x\n", hw->disp_b_stride);
812 
813 	printk("	VGACNTRL:		0x%08x\n", hw->vgacntrl);
814 	printk("	ADD_ID:			0x%08x\n", hw->add_id);
815 
816 	for (i = 0; i < 7; i++) {
817 		printk("	SWF0%d			0x%08x\n", i,
818 			hw->swf0x[i]);
819 	}
820 	for (i = 0; i < 7; i++) {
821 		printk("	SWF1%d			0x%08x\n", i,
822 			hw->swf1x[i]);
823 	}
824 	for (i = 0; i < 3; i++) {
825 		printk("	SWF3%d			0x%08x\n", i,
826 		       hw->swf3x[i]);
827 	}
828 	for (i = 0; i < 8; i++)
829 		printk("	FENCE%d			0x%08x\n", i,
830 		       hw->fence[i]);
831 
832 	printk("	INSTPM			0x%08x\n", hw->instpm);
833 	printk("	MEM_MODE		0x%08x\n", hw->mem_mode);
834 	printk("	FW_BLC_0		0x%08x\n", hw->fw_blc_0);
835 	printk("	FW_BLC_1		0x%08x\n", hw->fw_blc_1);
836 
837 	printk("	HWSTAM			0x%04x\n", hw->hwstam);
838 	printk("	IER			0x%04x\n", hw->ier);
839 	printk("	IIR			0x%04x\n", hw->iir);
840 	printk("	IMR			0x%04x\n", hw->imr);
841 	printk("hw state dump end\n");
842 #endif
843 }
844 
845 
846 
847 /* Split the M parameter into M1 and M2. */
splitm(int index,unsigned int m,unsigned int * retm1,unsigned int * retm2)848 static int splitm(int index, unsigned int m, unsigned int *retm1,
849 		  unsigned int *retm2)
850 {
851 	int m1, m2;
852 	int testm;
853 	struct pll_min_max *pll = &plls[index];
854 
855 	/* no point optimising too much - brute force m */
856 	for (m1 = pll->min_m1; m1 < pll->max_m1 + 1; m1++) {
857 		for (m2 = pll->min_m2; m2 < pll->max_m2 + 1; m2++) {
858 			testm = (5 * (m1 + 2)) + (m2 + 2);
859 			if (testm == m) {
860 				*retm1 = (unsigned int)m1;
861 				*retm2 = (unsigned int)m2;
862 				return 0;
863 			}
864 		}
865 	}
866 	return 1;
867 }
868 
869 /* Split the P parameter into P1 and P2. */
splitp(int index,unsigned int p,unsigned int * retp1,unsigned int * retp2)870 static int splitp(int index, unsigned int p, unsigned int *retp1,
871 		  unsigned int *retp2)
872 {
873 	int p1, p2;
874 	struct pll_min_max *pll = &plls[index];
875 
876 	if (index == PLLS_I9xx) {
877 		p2 = (p % 10) ? 1 : 0;
878 
879 		p1 = p / (p2 ? 5 : 10);
880 
881 		*retp1 = (unsigned int)p1;
882 		*retp2 = (unsigned int)p2;
883 		return 0;
884 	}
885 
886 	if (p % 4 == 0)
887 		p2 = 1;
888 	else
889 		p2 = 0;
890 	p1 = (p / (1 << (p2 + 1))) - 2;
891 	if (p % 4 == 0 && p1 < pll->min_p1) {
892 		p2 = 0;
893 		p1 = (p / (1 << (p2 + 1))) - 2;
894 	}
895 	if (p1 < pll->min_p1 || p1 > pll->max_p1 ||
896 	    (p1 + 2) * (1 << (p2 + 1)) != p) {
897 		return 1;
898 	} else {
899 		*retp1 = (unsigned int)p1;
900 		*retp2 = (unsigned int)p2;
901 		return 0;
902 	}
903 }
904 
calc_pll_params(int index,int clock,u32 * retm1,u32 * retm2,u32 * retn,u32 * retp1,u32 * retp2,u32 * retclock)905 static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2,
906 			   u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock)
907 {
908 	u32 m1, m2, n, p1, p2, n1, testm;
909 	u32 f_vco, p, p_best = 0, m, f_out = 0;
910 	u32 err_max, err_target, err_best = 10000000;
911 	u32 n_best = 0, m_best = 0, f_best, f_err;
912 	u32 p_min, p_max, p_inc, div_max;
913 	struct pll_min_max *pll = &plls[index];
914 
915 	/* Accept 0.5% difference, but aim for 0.1% */
916 	err_max = 5 * clock / 1000;
917 	err_target = clock / 1000;
918 
919 	DBG_MSG("Clock is %d\n", clock);
920 
921 	div_max = pll->max_vco / clock;
922 
923 	p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi;
924 	p_min = p_inc;
925 	p_max = ROUND_DOWN_TO(div_max, p_inc);
926 	if (p_min < pll->min_p)
927 		p_min = pll->min_p;
928 	if (p_max > pll->max_p)
929 		p_max = pll->max_p;
930 
931 	DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc);
932 
933 	p = p_min;
934 	do {
935 		if (splitp(index, p, &p1, &p2)) {
936 			WRN_MSG("cannot split p = %d\n", p);
937 			p += p_inc;
938 			continue;
939 		}
940 		n = pll->min_n;
941 		f_vco = clock * p;
942 
943 		do {
944 			m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk;
945 			if (m < pll->min_m)
946 				m = pll->min_m + 1;
947 			if (m > pll->max_m)
948 				m = pll->max_m - 1;
949 			for (testm = m - 1; testm <= m; testm++) {
950 				f_out = calc_vclock3(index, testm, n, p);
951 				if (splitm(index, testm, &m1, &m2)) {
952 					WRN_MSG("cannot split m = %d\n",
953 						testm);
954 					continue;
955 				}
956 				if (clock > f_out)
957 					f_err = clock - f_out;
958 				else/* slightly bias the error for bigger clocks */
959 					f_err = f_out - clock + 1;
960 
961 				if (f_err < err_best) {
962 					m_best = testm;
963 					n_best = n;
964 					p_best = p;
965 					f_best = f_out;
966 					err_best = f_err;
967 				}
968 			}
969 			n++;
970 		} while ((n <= pll->max_n) && (f_out >= clock));
971 		p += p_inc;
972 	} while ((p <= p_max));
973 
974 	if (!m_best) {
975 		WRN_MSG("cannot find parameters for clock %d\n", clock);
976 		return 1;
977 	}
978 	m = m_best;
979 	n = n_best;
980 	p = p_best;
981 	splitm(index, m, &m1, &m2);
982 	splitp(index, p, &p1, &p2);
983 	n1 = n - 2;
984 
985 	DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), "
986 		"f: %d (%d), VCO: %d\n",
987 		m, m1, m2, n, n1, p, p1, p2,
988 		calc_vclock3(index, m, n, p),
989 		calc_vclock(index, m1, m2, n1, p1, p2, 0),
990 		calc_vclock3(index, m, n, p) * p);
991 	*retm1 = m1;
992 	*retm2 = m2;
993 	*retn = n1;
994 	*retp1 = p1;
995 	*retp2 = p2;
996 	*retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0);
997 
998 	return 0;
999 }
1000 
check_overflow(u32 value,u32 limit,const char * description)1001 static __inline__ int check_overflow(u32 value, u32 limit,
1002 				     const char *description)
1003 {
1004 	if (value > limit) {
1005 		WRN_MSG("%s value %d exceeds limit %d\n",
1006 			description, value, limit);
1007 		return 1;
1008 	}
1009 	return 0;
1010 }
1011 
1012 /* It is assumed that hw is filled in with the initial state information. */
intelfbhw_mode_to_hw(struct intelfb_info * dinfo,struct intelfb_hwstate * hw,struct fb_var_screeninfo * var)1013 int intelfbhw_mode_to_hw(struct intelfb_info *dinfo,
1014 			 struct intelfb_hwstate *hw,
1015 			 struct fb_var_screeninfo *var)
1016 {
1017 	int pipe = PIPE_A;
1018 	u32 *dpll, *fp0, *fp1;
1019 	u32 m1, m2, n, p1, p2, clock_target, clock;
1020 	u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive;
1021 	u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive;
1022 	u32 vsync_pol, hsync_pol;
1023 	u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf;
1024 	u32 stride_alignment;
1025 
1026 	DBG_MSG("intelfbhw_mode_to_hw\n");
1027 
1028 	/* Disable VGA */
1029 	hw->vgacntrl |= VGA_DISABLE;
1030 
1031 	/* Check whether pipe A or pipe B is enabled. */
1032 	if (hw->pipe_a_conf & PIPECONF_ENABLE)
1033 		pipe = PIPE_A;
1034 	else if (hw->pipe_b_conf & PIPECONF_ENABLE)
1035 		pipe = PIPE_B;
1036 
1037 	/* Set which pipe's registers will be set. */
1038 	if (pipe == PIPE_B) {
1039 		dpll = &hw->dpll_b;
1040 		fp0 = &hw->fpb0;
1041 		fp1 = &hw->fpb1;
1042 		hs = &hw->hsync_b;
1043 		hb = &hw->hblank_b;
1044 		ht = &hw->htotal_b;
1045 		vs = &hw->vsync_b;
1046 		vb = &hw->vblank_b;
1047 		vt = &hw->vtotal_b;
1048 		ss = &hw->src_size_b;
1049 		pipe_conf = &hw->pipe_b_conf;
1050 	} else {
1051 		dpll = &hw->dpll_a;
1052 		fp0 = &hw->fpa0;
1053 		fp1 = &hw->fpa1;
1054 		hs = &hw->hsync_a;
1055 		hb = &hw->hblank_a;
1056 		ht = &hw->htotal_a;
1057 		vs = &hw->vsync_a;
1058 		vb = &hw->vblank_a;
1059 		vt = &hw->vtotal_a;
1060 		ss = &hw->src_size_a;
1061 		pipe_conf = &hw->pipe_a_conf;
1062 	}
1063 
1064 	/* Use ADPA register for sync control. */
1065 	hw->adpa &= ~ADPA_USE_VGA_HVPOLARITY;
1066 
1067 	/* sync polarity */
1068 	hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ?
1069 			ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW;
1070 	vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ?
1071 			ADPA_SYNC_ACTIVE_HIGH : ADPA_SYNC_ACTIVE_LOW;
1072 	hw->adpa &= ~((ADPA_SYNC_ACTIVE_MASK << ADPA_VSYNC_ACTIVE_SHIFT) |
1073 		      (ADPA_SYNC_ACTIVE_MASK << ADPA_HSYNC_ACTIVE_SHIFT));
1074 	hw->adpa |= (hsync_pol << ADPA_HSYNC_ACTIVE_SHIFT) |
1075 		    (vsync_pol << ADPA_VSYNC_ACTIVE_SHIFT);
1076 
1077 	/* Connect correct pipe to the analog port DAC */
1078 	hw->adpa &= ~(PIPE_MASK << ADPA_PIPE_SELECT_SHIFT);
1079 	hw->adpa |= (pipe << ADPA_PIPE_SELECT_SHIFT);
1080 
1081 	/* Set DPMS state to D0 (on) */
1082 	hw->adpa &= ~ADPA_DPMS_CONTROL_MASK;
1083 	hw->adpa |= ADPA_DPMS_D0;
1084 
1085 	hw->adpa |= ADPA_DAC_ENABLE;
1086 
1087 	*dpll |= (DPLL_VCO_ENABLE | DPLL_VGA_MODE_DISABLE);
1088 	*dpll &= ~(DPLL_RATE_SELECT_MASK | DPLL_REFERENCE_SELECT_MASK);
1089 	*dpll |= (DPLL_REFERENCE_DEFAULT | DPLL_RATE_SELECT_FP0);
1090 
1091 	/* Desired clock in kHz */
1092 	clock_target = 1000000000 / var->pixclock;
1093 
1094 	if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2,
1095 			    &n, &p1, &p2, &clock)) {
1096 		WRN_MSG("calc_pll_params failed\n");
1097 		return 1;
1098 	}
1099 
1100 	/* Check for overflow. */
1101 	if (check_overflow(p1, DPLL_P1_MASK, "PLL P1 parameter"))
1102 		return 1;
1103 	if (check_overflow(p2, DPLL_P2_MASK, "PLL P2 parameter"))
1104 		return 1;
1105 	if (check_overflow(m1, FP_DIVISOR_MASK, "PLL M1 parameter"))
1106 		return 1;
1107 	if (check_overflow(m2, FP_DIVISOR_MASK, "PLL M2 parameter"))
1108 		return 1;
1109 	if (check_overflow(n, FP_DIVISOR_MASK, "PLL N parameter"))
1110 		return 1;
1111 
1112 	*dpll &= ~DPLL_P1_FORCE_DIV2;
1113 	*dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) |
1114 		   (DPLL_P1_MASK << DPLL_P1_SHIFT));
1115 
1116 	if (IS_I9XX(dinfo)) {
1117 		*dpll |= (p2 << DPLL_I9XX_P2_SHIFT);
1118 		*dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT;
1119 	} else
1120 		*dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT);
1121 
1122 	*fp0 = (n << FP_N_DIVISOR_SHIFT) |
1123 	       (m1 << FP_M1_DIVISOR_SHIFT) |
1124 	       (m2 << FP_M2_DIVISOR_SHIFT);
1125 	*fp1 = *fp0;
1126 
1127 	hw->dvob &= ~PORT_ENABLE;
1128 	hw->dvoc &= ~PORT_ENABLE;
1129 
1130 	/* Use display plane A. */
1131 	hw->disp_a_ctrl |= DISPPLANE_PLANE_ENABLE;
1132 	hw->disp_a_ctrl &= ~DISPPLANE_GAMMA_ENABLE;
1133 	hw->disp_a_ctrl &= ~DISPPLANE_PIXFORMAT_MASK;
1134 	switch (intelfb_var_to_depth(var)) {
1135 	case 8:
1136 		hw->disp_a_ctrl |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE;
1137 		break;
1138 	case 15:
1139 		hw->disp_a_ctrl |= DISPPLANE_15_16BPP;
1140 		break;
1141 	case 16:
1142 		hw->disp_a_ctrl |= DISPPLANE_16BPP;
1143 		break;
1144 	case 24:
1145 		hw->disp_a_ctrl |= DISPPLANE_32BPP_NO_ALPHA;
1146 		break;
1147 	}
1148 	hw->disp_a_ctrl &= ~(PIPE_MASK << DISPPLANE_SEL_PIPE_SHIFT);
1149 	hw->disp_a_ctrl |= (pipe << DISPPLANE_SEL_PIPE_SHIFT);
1150 
1151 	/* Set CRTC registers. */
1152 	hactive = var->xres;
1153 	hsync_start = hactive + var->right_margin;
1154 	hsync_end = hsync_start + var->hsync_len;
1155 	htotal = hsync_end + var->left_margin;
1156 	hblank_start = hactive;
1157 	hblank_end = htotal;
1158 
1159 	DBG_MSG("H: act %d, ss %d, se %d, tot %d bs %d, be %d\n",
1160 		hactive, hsync_start, hsync_end, htotal, hblank_start,
1161 		hblank_end);
1162 
1163 	vactive = var->yres;
1164 	if (var->vmode & FB_VMODE_INTERLACED)
1165 		vactive--; /* the chip adds 2 halflines automatically */
1166 	vsync_start = vactive + var->lower_margin;
1167 	vsync_end = vsync_start + var->vsync_len;
1168 	vtotal = vsync_end + var->upper_margin;
1169 	vblank_start = vactive;
1170 	vblank_end = vtotal;
1171 	vblank_end = vsync_end + 1;
1172 
1173 	DBG_MSG("V: act %d, ss %d, se %d, tot %d bs %d, be %d\n",
1174 		vactive, vsync_start, vsync_end, vtotal, vblank_start,
1175 		vblank_end);
1176 
1177 	/* Adjust for register values, and check for overflow. */
1178 	hactive--;
1179 	if (check_overflow(hactive, HACTIVE_MASK, "CRTC hactive"))
1180 		return 1;
1181 	hsync_start--;
1182 	if (check_overflow(hsync_start, HSYNCSTART_MASK, "CRTC hsync_start"))
1183 		return 1;
1184 	hsync_end--;
1185 	if (check_overflow(hsync_end, HSYNCEND_MASK, "CRTC hsync_end"))
1186 		return 1;
1187 	htotal--;
1188 	if (check_overflow(htotal, HTOTAL_MASK, "CRTC htotal"))
1189 		return 1;
1190 	hblank_start--;
1191 	if (check_overflow(hblank_start, HBLANKSTART_MASK, "CRTC hblank_start"))
1192 		return 1;
1193 	hblank_end--;
1194 	if (check_overflow(hblank_end, HBLANKEND_MASK, "CRTC hblank_end"))
1195 		return 1;
1196 
1197 	vactive--;
1198 	if (check_overflow(vactive, VACTIVE_MASK, "CRTC vactive"))
1199 		return 1;
1200 	vsync_start--;
1201 	if (check_overflow(vsync_start, VSYNCSTART_MASK, "CRTC vsync_start"))
1202 		return 1;
1203 	vsync_end--;
1204 	if (check_overflow(vsync_end, VSYNCEND_MASK, "CRTC vsync_end"))
1205 		return 1;
1206 	vtotal--;
1207 	if (check_overflow(vtotal, VTOTAL_MASK, "CRTC vtotal"))
1208 		return 1;
1209 	vblank_start--;
1210 	if (check_overflow(vblank_start, VBLANKSTART_MASK, "CRTC vblank_start"))
1211 		return 1;
1212 	vblank_end--;
1213 	if (check_overflow(vblank_end, VBLANKEND_MASK, "CRTC vblank_end"))
1214 		return 1;
1215 
1216 	*ht = (htotal << HTOTAL_SHIFT) | (hactive << HACTIVE_SHIFT);
1217 	*hb = (hblank_start << HBLANKSTART_SHIFT) |
1218 	      (hblank_end << HSYNCEND_SHIFT);
1219 	*hs = (hsync_start << HSYNCSTART_SHIFT) | (hsync_end << HSYNCEND_SHIFT);
1220 
1221 	*vt = (vtotal << VTOTAL_SHIFT) | (vactive << VACTIVE_SHIFT);
1222 	*vb = (vblank_start << VBLANKSTART_SHIFT) |
1223 	      (vblank_end << VSYNCEND_SHIFT);
1224 	*vs = (vsync_start << VSYNCSTART_SHIFT) | (vsync_end << VSYNCEND_SHIFT);
1225 	*ss = (hactive << SRC_SIZE_HORIZ_SHIFT) |
1226 	      (vactive << SRC_SIZE_VERT_SHIFT);
1227 
1228 	hw->disp_a_stride = dinfo->pitch;
1229 	DBG_MSG("pitch is %d\n", hw->disp_a_stride);
1230 
1231 	hw->disp_a_base = hw->disp_a_stride * var->yoffset +
1232 			  var->xoffset * var->bits_per_pixel / 8;
1233 
1234 	hw->disp_a_base += dinfo->fb.offset << 12;
1235 
1236 	/* Check stride alignment. */
1237 	stride_alignment = IS_I9XX(dinfo) ? STRIDE_ALIGNMENT_I9XX :
1238 					    STRIDE_ALIGNMENT;
1239 	if (hw->disp_a_stride % stride_alignment != 0) {
1240 		WRN_MSG("display stride %d has bad alignment %d\n",
1241 			hw->disp_a_stride, stride_alignment);
1242 		return 1;
1243 	}
1244 
1245 	/* Set the palette to 8-bit mode. */
1246 	*pipe_conf &= ~PIPECONF_GAMMA;
1247 
1248 	if (var->vmode & FB_VMODE_INTERLACED)
1249 		*pipe_conf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
1250 	else
1251 		*pipe_conf &= ~PIPECONF_INTERLACE_MASK;
1252 
1253 	return 0;
1254 }
1255 
1256 /* Program a (non-VGA) video mode. */
intelfbhw_program_mode(struct intelfb_info * dinfo,const struct intelfb_hwstate * hw,int blank)1257 int intelfbhw_program_mode(struct intelfb_info *dinfo,
1258 			   const struct intelfb_hwstate *hw, int blank)
1259 {
1260 	int pipe = PIPE_A;
1261 	u32 tmp;
1262 	const u32 *dpll, *fp0, *fp1, *pipe_conf;
1263 	const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss;
1264 	u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg, pipe_stat_reg;
1265 	u32 hsync_reg, htotal_reg, hblank_reg;
1266 	u32 vsync_reg, vtotal_reg, vblank_reg;
1267 	u32 src_size_reg;
1268 	u32 count, tmp_val[3];
1269 
1270 	/* Assume single pipe, display plane A, analog CRT. */
1271 
1272 #if VERBOSE > 0
1273 	DBG_MSG("intelfbhw_program_mode\n");
1274 #endif
1275 
1276 	/* Disable VGA */
1277 	tmp = INREG(VGACNTRL);
1278 	tmp |= VGA_DISABLE;
1279 	OUTREG(VGACNTRL, tmp);
1280 
1281 	/* Check whether pipe A or pipe B is enabled. */
1282 	if (hw->pipe_a_conf & PIPECONF_ENABLE)
1283 		pipe = PIPE_A;
1284 	else if (hw->pipe_b_conf & PIPECONF_ENABLE)
1285 		pipe = PIPE_B;
1286 
1287 	dinfo->pipe = pipe;
1288 
1289 	if (pipe == PIPE_B) {
1290 		dpll = &hw->dpll_b;
1291 		fp0 = &hw->fpb0;
1292 		fp1 = &hw->fpb1;
1293 		pipe_conf = &hw->pipe_b_conf;
1294 		hs = &hw->hsync_b;
1295 		hb = &hw->hblank_b;
1296 		ht = &hw->htotal_b;
1297 		vs = &hw->vsync_b;
1298 		vb = &hw->vblank_b;
1299 		vt = &hw->vtotal_b;
1300 		ss = &hw->src_size_b;
1301 		dpll_reg = DPLL_B;
1302 		fp0_reg = FPB0;
1303 		fp1_reg = FPB1;
1304 		pipe_conf_reg = PIPEBCONF;
1305 		pipe_stat_reg = PIPEBSTAT;
1306 		hsync_reg = HSYNC_B;
1307 		htotal_reg = HTOTAL_B;
1308 		hblank_reg = HBLANK_B;
1309 		vsync_reg = VSYNC_B;
1310 		vtotal_reg = VTOTAL_B;
1311 		vblank_reg = VBLANK_B;
1312 		src_size_reg = SRC_SIZE_B;
1313 	} else {
1314 		dpll = &hw->dpll_a;
1315 		fp0 = &hw->fpa0;
1316 		fp1 = &hw->fpa1;
1317 		pipe_conf = &hw->pipe_a_conf;
1318 		hs = &hw->hsync_a;
1319 		hb = &hw->hblank_a;
1320 		ht = &hw->htotal_a;
1321 		vs = &hw->vsync_a;
1322 		vb = &hw->vblank_a;
1323 		vt = &hw->vtotal_a;
1324 		ss = &hw->src_size_a;
1325 		dpll_reg = DPLL_A;
1326 		fp0_reg = FPA0;
1327 		fp1_reg = FPA1;
1328 		pipe_conf_reg = PIPEACONF;
1329 		pipe_stat_reg = PIPEASTAT;
1330 		hsync_reg = HSYNC_A;
1331 		htotal_reg = HTOTAL_A;
1332 		hblank_reg = HBLANK_A;
1333 		vsync_reg = VSYNC_A;
1334 		vtotal_reg = VTOTAL_A;
1335 		vblank_reg = VBLANK_A;
1336 		src_size_reg = SRC_SIZE_A;
1337 	}
1338 
1339 	/* turn off pipe */
1340 	tmp = INREG(pipe_conf_reg);
1341 	tmp &= ~PIPECONF_ENABLE;
1342 	OUTREG(pipe_conf_reg, tmp);
1343 
1344 	count = 0;
1345 	do {
1346 		tmp_val[count % 3] = INREG(PIPEA_DSL);
1347 		if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1] == tmp_val[2]))
1348 			break;
1349 		count++;
1350 		udelay(1);
1351 		if (count % 200 == 0) {
1352 			tmp = INREG(pipe_conf_reg);
1353 			tmp &= ~PIPECONF_ENABLE;
1354 			OUTREG(pipe_conf_reg, tmp);
1355 		}
1356 	} while (count < 2000);
1357 
1358 	OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
1359 
1360 	/* Disable planes A and B. */
1361 	tmp = INREG(DSPACNTR);
1362 	tmp &= ~DISPPLANE_PLANE_ENABLE;
1363 	OUTREG(DSPACNTR, tmp);
1364 	tmp = INREG(DSPBCNTR);
1365 	tmp &= ~DISPPLANE_PLANE_ENABLE;
1366 	OUTREG(DSPBCNTR, tmp);
1367 
1368 	/* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
1369 	mdelay(20);
1370 
1371 	OUTREG(DVOB, INREG(DVOB) & ~PORT_ENABLE);
1372 	OUTREG(DVOC, INREG(DVOC) & ~PORT_ENABLE);
1373 	OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
1374 
1375 	/* Disable Sync */
1376 	tmp = INREG(ADPA);
1377 	tmp &= ~ADPA_DPMS_CONTROL_MASK;
1378 	tmp |= ADPA_DPMS_D3;
1379 	OUTREG(ADPA, tmp);
1380 
1381 	/* do some funky magic - xyzzy */
1382 	OUTREG(0x61204, 0xabcd0000);
1383 
1384 	/* turn off PLL */
1385 	tmp = INREG(dpll_reg);
1386 	tmp &= ~DPLL_VCO_ENABLE;
1387 	OUTREG(dpll_reg, tmp);
1388 
1389 	/* Set PLL parameters */
1390 	OUTREG(fp0_reg, *fp0);
1391 	OUTREG(fp1_reg, *fp1);
1392 
1393 	/* Enable PLL */
1394 	OUTREG(dpll_reg, *dpll);
1395 
1396 	/* Set DVOs B/C */
1397 	OUTREG(DVOB, hw->dvob);
1398 	OUTREG(DVOC, hw->dvoc);
1399 
1400 	/* undo funky magic */
1401 	OUTREG(0x61204, 0x00000000);
1402 
1403 	/* Set ADPA */
1404 	OUTREG(ADPA, INREG(ADPA) | ADPA_DAC_ENABLE);
1405 	OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3);
1406 
1407 	/* Set pipe parameters */
1408 	OUTREG(hsync_reg, *hs);
1409 	OUTREG(hblank_reg, *hb);
1410 	OUTREG(htotal_reg, *ht);
1411 	OUTREG(vsync_reg, *vs);
1412 	OUTREG(vblank_reg, *vb);
1413 	OUTREG(vtotal_reg, *vt);
1414 	OUTREG(src_size_reg, *ss);
1415 
1416 	switch (dinfo->info->var.vmode & (FB_VMODE_INTERLACED |
1417 					  FB_VMODE_ODD_FLD_FIRST)) {
1418 	case FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST:
1419 		OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_ODD_EN);
1420 		break;
1421 	case FB_VMODE_INTERLACED: /* even lines first */
1422 		OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_EVEN_EN);
1423 		break;
1424 	default:		/* non-interlaced */
1425 		OUTREG(pipe_stat_reg, 0xFFFF); /* clear all status bits only */
1426 	}
1427 	/* Enable pipe */
1428 	OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE);
1429 
1430 	/* Enable sync */
1431 	tmp = INREG(ADPA);
1432 	tmp &= ~ADPA_DPMS_CONTROL_MASK;
1433 	tmp |= ADPA_DPMS_D0;
1434 	OUTREG(ADPA, tmp);
1435 
1436 	/* setup display plane */
1437 	if (dinfo->pdev->device == PCI_DEVICE_ID_INTEL_830M) {
1438 		/*
1439 		 *      i830M errata: the display plane must be enabled
1440 		 *      to allow writes to the other bits in the plane
1441 		 *      control register.
1442 		 */
1443 		tmp = INREG(DSPACNTR);
1444 		if ((tmp & DISPPLANE_PLANE_ENABLE) != DISPPLANE_PLANE_ENABLE) {
1445 			tmp |= DISPPLANE_PLANE_ENABLE;
1446 			OUTREG(DSPACNTR, tmp);
1447 			OUTREG(DSPACNTR,
1448 			       hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE);
1449 			mdelay(1);
1450 		}
1451 	}
1452 
1453 	OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE);
1454 	OUTREG(DSPASTRIDE, hw->disp_a_stride);
1455 	OUTREG(DSPABASE, hw->disp_a_base);
1456 
1457 	/* Enable plane */
1458 	if (!blank) {
1459 		tmp = INREG(DSPACNTR);
1460 		tmp |= DISPPLANE_PLANE_ENABLE;
1461 		OUTREG(DSPACNTR, tmp);
1462 		OUTREG(DSPABASE, hw->disp_a_base);
1463 	}
1464 
1465 	return 0;
1466 }
1467 
1468 /* forward declarations */
1469 static void refresh_ring(struct intelfb_info *dinfo);
1470 static void reset_state(struct intelfb_info *dinfo);
1471 static void do_flush(struct intelfb_info *dinfo);
1472 
get_ring_space(struct intelfb_info * dinfo)1473 static  u32 get_ring_space(struct intelfb_info *dinfo)
1474 {
1475 	u32 ring_space;
1476 
1477 	if (dinfo->ring_tail >= dinfo->ring_head)
1478 		ring_space = dinfo->ring.size -
1479 			(dinfo->ring_tail - dinfo->ring_head);
1480 	else
1481 		ring_space = dinfo->ring_head - dinfo->ring_tail;
1482 
1483 	if (ring_space > RING_MIN_FREE)
1484 		ring_space -= RING_MIN_FREE;
1485 	else
1486 		ring_space = 0;
1487 
1488 	return ring_space;
1489 }
1490 
wait_ring(struct intelfb_info * dinfo,int n)1491 static int wait_ring(struct intelfb_info *dinfo, int n)
1492 {
1493 	int i = 0;
1494 	unsigned long end;
1495 	u32 last_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1496 
1497 #if VERBOSE > 0
1498 	DBG_MSG("wait_ring: %d\n", n);
1499 #endif
1500 
1501 	end = jiffies + (HZ * 3);
1502 	while (dinfo->ring_space < n) {
1503 		dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1504 		dinfo->ring_space = get_ring_space(dinfo);
1505 
1506 		if (dinfo->ring_head != last_head) {
1507 			end = jiffies + (HZ * 3);
1508 			last_head = dinfo->ring_head;
1509 		}
1510 		i++;
1511 		if (time_before(end, jiffies)) {
1512 			if (!i) {
1513 				/* Try again */
1514 				reset_state(dinfo);
1515 				refresh_ring(dinfo);
1516 				do_flush(dinfo);
1517 				end = jiffies + (HZ * 3);
1518 				i = 1;
1519 			} else {
1520 				WRN_MSG("ring buffer : space: %d wanted %d\n",
1521 					dinfo->ring_space, n);
1522 				WRN_MSG("lockup - turning off hardware "
1523 					"acceleration\n");
1524 				dinfo->ring_lockup = 1;
1525 				break;
1526 			}
1527 		}
1528 		udelay(1);
1529 	}
1530 	return i;
1531 }
1532 
do_flush(struct intelfb_info * dinfo)1533 static void do_flush(struct intelfb_info *dinfo)
1534 {
1535 	START_RING(2);
1536 	OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
1537 	OUT_RING(MI_NOOP);
1538 	ADVANCE_RING();
1539 }
1540 
intelfbhw_do_sync(struct intelfb_info * dinfo)1541 void intelfbhw_do_sync(struct intelfb_info *dinfo)
1542 {
1543 #if VERBOSE > 0
1544 	DBG_MSG("intelfbhw_do_sync\n");
1545 #endif
1546 
1547 	if (!dinfo->accel)
1548 		return;
1549 
1550 	/*
1551 	 * Send a flush, then wait until the ring is empty.  This is what
1552 	 * the XFree86 driver does, and actually it doesn't seem a lot worse
1553 	 * than the recommended method (both have problems).
1554 	 */
1555 	do_flush(dinfo);
1556 	wait_ring(dinfo, dinfo->ring.size - RING_MIN_FREE);
1557 	dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE;
1558 }
1559 
refresh_ring(struct intelfb_info * dinfo)1560 static void refresh_ring(struct intelfb_info *dinfo)
1561 {
1562 #if VERBOSE > 0
1563 	DBG_MSG("refresh_ring\n");
1564 #endif
1565 
1566 	dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1567 	dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
1568 	dinfo->ring_space = get_ring_space(dinfo);
1569 }
1570 
reset_state(struct intelfb_info * dinfo)1571 static void reset_state(struct intelfb_info *dinfo)
1572 {
1573 	int i;
1574 	u32 tmp;
1575 
1576 #if VERBOSE > 0
1577 	DBG_MSG("reset_state\n");
1578 #endif
1579 
1580 	for (i = 0; i < FENCE_NUM; i++)
1581 		OUTREG(FENCE + (i << 2), 0);
1582 
1583 	/* Flush the ring buffer if it's enabled. */
1584 	tmp = INREG(PRI_RING_LENGTH);
1585 	if (tmp & RING_ENABLE) {
1586 #if VERBOSE > 0
1587 		DBG_MSG("reset_state: ring was enabled\n");
1588 #endif
1589 		refresh_ring(dinfo);
1590 		intelfbhw_do_sync(dinfo);
1591 		DO_RING_IDLE();
1592 	}
1593 
1594 	OUTREG(PRI_RING_LENGTH, 0);
1595 	OUTREG(PRI_RING_HEAD, 0);
1596 	OUTREG(PRI_RING_TAIL, 0);
1597 	OUTREG(PRI_RING_START, 0);
1598 }
1599 
1600 /* Stop the 2D engine, and turn off the ring buffer. */
intelfbhw_2d_stop(struct intelfb_info * dinfo)1601 void intelfbhw_2d_stop(struct intelfb_info *dinfo)
1602 {
1603 #if VERBOSE > 0
1604 	DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n",
1605 		dinfo->accel, dinfo->ring_active);
1606 #endif
1607 
1608 	if (!dinfo->accel)
1609 		return;
1610 
1611 	dinfo->ring_active = 0;
1612 	reset_state(dinfo);
1613 }
1614 
1615 /*
1616  * Enable the ring buffer, and initialise the 2D engine.
1617  * It is assumed that the graphics engine has been stopped by previously
1618  * calling intelfb_2d_stop().
1619  */
intelfbhw_2d_start(struct intelfb_info * dinfo)1620 void intelfbhw_2d_start(struct intelfb_info *dinfo)
1621 {
1622 #if VERBOSE > 0
1623 	DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n",
1624 		dinfo->accel, dinfo->ring_active);
1625 #endif
1626 
1627 	if (!dinfo->accel)
1628 		return;
1629 
1630 	/* Initialise the primary ring buffer. */
1631 	OUTREG(PRI_RING_LENGTH, 0);
1632 	OUTREG(PRI_RING_TAIL, 0);
1633 	OUTREG(PRI_RING_HEAD, 0);
1634 
1635 	OUTREG(PRI_RING_START, dinfo->ring.physical & RING_START_MASK);
1636 	OUTREG(PRI_RING_LENGTH,
1637 		((dinfo->ring.size - GTT_PAGE_SIZE) & RING_LENGTH_MASK) |
1638 		RING_NO_REPORT | RING_ENABLE);
1639 	refresh_ring(dinfo);
1640 	dinfo->ring_active = 1;
1641 }
1642 
1643 /* 2D fillrect (solid fill or invert) */
intelfbhw_do_fillrect(struct intelfb_info * dinfo,u32 x,u32 y,u32 w,u32 h,u32 color,u32 pitch,u32 bpp,u32 rop)1644 void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w,
1645 			   u32 h, u32 color, u32 pitch, u32 bpp, u32 rop)
1646 {
1647 	u32 br00, br09, br13, br14, br16;
1648 
1649 #if VERBOSE > 0
1650 	DBG_MSG("intelfbhw_do_fillrect: (%d,%d) %dx%d, c 0x%06x, p %d bpp %d, "
1651 		"rop 0x%02x\n", x, y, w, h, color, pitch, bpp, rop);
1652 #endif
1653 
1654 	br00 = COLOR_BLT_CMD;
1655 	br09 = dinfo->fb_start + (y * pitch + x * (bpp / 8));
1656 	br13 = (rop << ROP_SHIFT) | pitch;
1657 	br14 = (h << HEIGHT_SHIFT) | ((w * (bpp / 8)) << WIDTH_SHIFT);
1658 	br16 = color;
1659 
1660 	switch (bpp) {
1661 	case 8:
1662 		br13 |= COLOR_DEPTH_8;
1663 		break;
1664 	case 16:
1665 		br13 |= COLOR_DEPTH_16;
1666 		break;
1667 	case 32:
1668 		br13 |= COLOR_DEPTH_32;
1669 		br00 |= WRITE_ALPHA | WRITE_RGB;
1670 		break;
1671 	}
1672 
1673 	START_RING(6);
1674 	OUT_RING(br00);
1675 	OUT_RING(br13);
1676 	OUT_RING(br14);
1677 	OUT_RING(br09);
1678 	OUT_RING(br16);
1679 	OUT_RING(MI_NOOP);
1680 	ADVANCE_RING();
1681 
1682 #if VERBOSE > 0
1683 	DBG_MSG("ring = 0x%08x, 0x%08x (%d)\n", dinfo->ring_head,
1684 		dinfo->ring_tail, dinfo->ring_space);
1685 #endif
1686 }
1687 
1688 void
intelfbhw_do_bitblt(struct intelfb_info * dinfo,u32 curx,u32 cury,u32 dstx,u32 dsty,u32 w,u32 h,u32 pitch,u32 bpp)1689 intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,
1690 		    u32 dstx, u32 dsty, u32 w, u32 h, u32 pitch, u32 bpp)
1691 {
1692 	u32 br00, br09, br11, br12, br13, br22, br23, br26;
1693 
1694 #if VERBOSE > 0
1695 	DBG_MSG("intelfbhw_do_bitblt: (%d,%d)->(%d,%d) %dx%d, p %d bpp %d\n",
1696 		curx, cury, dstx, dsty, w, h, pitch, bpp);
1697 #endif
1698 
1699 	br00 = XY_SRC_COPY_BLT_CMD;
1700 	br09 = dinfo->fb_start;
1701 	br11 = (pitch << PITCH_SHIFT);
1702 	br12 = dinfo->fb_start;
1703 	br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT);
1704 	br22 = (dstx << WIDTH_SHIFT) | (dsty << HEIGHT_SHIFT);
1705 	br23 = ((dstx + w) << WIDTH_SHIFT) |
1706 	       ((dsty + h) << HEIGHT_SHIFT);
1707 	br26 = (curx << WIDTH_SHIFT) | (cury << HEIGHT_SHIFT);
1708 
1709 	switch (bpp) {
1710 	case 8:
1711 		br13 |= COLOR_DEPTH_8;
1712 		break;
1713 	case 16:
1714 		br13 |= COLOR_DEPTH_16;
1715 		break;
1716 	case 32:
1717 		br13 |= COLOR_DEPTH_32;
1718 		br00 |= WRITE_ALPHA | WRITE_RGB;
1719 		break;
1720 	}
1721 
1722 	START_RING(8);
1723 	OUT_RING(br00);
1724 	OUT_RING(br13);
1725 	OUT_RING(br22);
1726 	OUT_RING(br23);
1727 	OUT_RING(br09);
1728 	OUT_RING(br26);
1729 	OUT_RING(br11);
1730 	OUT_RING(br12);
1731 	ADVANCE_RING();
1732 }
1733 
intelfbhw_do_drawglyph(struct intelfb_info * dinfo,u32 fg,u32 bg,u32 w,u32 h,const u8 * cdat,u32 x,u32 y,u32 pitch,u32 bpp)1734 int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
1735 			   u32 h, const u8* cdat, u32 x, u32 y, u32 pitch,
1736 			   u32 bpp)
1737 {
1738 	int nbytes, ndwords, pad, tmp;
1739 	u32 br00, br09, br13, br18, br19, br22, br23;
1740 	int dat, ix, iy, iw;
1741 	int i, j;
1742 
1743 #if VERBOSE > 0
1744 	DBG_MSG("intelfbhw_do_drawglyph: (%d,%d) %dx%d\n", x, y, w, h);
1745 #endif
1746 
1747 	/* size in bytes of a padded scanline */
1748 	nbytes = ROUND_UP_TO(w, 16) / 8;
1749 
1750 	/* Total bytes of padded scanline data to write out. */
1751 	nbytes = nbytes * h;
1752 
1753 	/*
1754 	 * Check if the glyph data exceeds the immediate mode limit.
1755 	 * It would take a large font (1K pixels) to hit this limit.
1756 	 */
1757 	if (nbytes > MAX_MONO_IMM_SIZE)
1758 		return 0;
1759 
1760 	/* Src data is packaged a dword (32-bit) at a time. */
1761 	ndwords = ROUND_UP_TO(nbytes, 4) / 4;
1762 
1763 	/*
1764 	 * Ring has to be padded to a quad word. But because the command starts
1765 	   with 7 bytes, pad only if there is an even number of ndwords
1766 	 */
1767 	pad = !(ndwords % 2);
1768 
1769 	tmp = (XY_MONO_SRC_IMM_BLT_CMD & DW_LENGTH_MASK) + ndwords;
1770 	br00 = (XY_MONO_SRC_IMM_BLT_CMD & ~DW_LENGTH_MASK) | tmp;
1771 	br09 = dinfo->fb_start;
1772 	br13 = (SRC_ROP_GXCOPY << ROP_SHIFT) | (pitch << PITCH_SHIFT);
1773 	br18 = bg;
1774 	br19 = fg;
1775 	br22 = (x << WIDTH_SHIFT) | (y << HEIGHT_SHIFT);
1776 	br23 = ((x + w) << WIDTH_SHIFT) | ((y + h) << HEIGHT_SHIFT);
1777 
1778 	switch (bpp) {
1779 	case 8:
1780 		br13 |= COLOR_DEPTH_8;
1781 		break;
1782 	case 16:
1783 		br13 |= COLOR_DEPTH_16;
1784 		break;
1785 	case 32:
1786 		br13 |= COLOR_DEPTH_32;
1787 		br00 |= WRITE_ALPHA | WRITE_RGB;
1788 		break;
1789 	}
1790 
1791 	START_RING(8 + ndwords);
1792 	OUT_RING(br00);
1793 	OUT_RING(br13);
1794 	OUT_RING(br22);
1795 	OUT_RING(br23);
1796 	OUT_RING(br09);
1797 	OUT_RING(br18);
1798 	OUT_RING(br19);
1799 	ix = iy = 0;
1800 	iw = ROUND_UP_TO(w, 8) / 8;
1801 	while (ndwords--) {
1802 		dat = 0;
1803 		for (j = 0; j < 2; ++j) {
1804 			for (i = 0; i < 2; ++i) {
1805 				if (ix != iw || i == 0)
1806 					dat |= cdat[iy*iw + ix++] << (i+j*2)*8;
1807 			}
1808 			if (ix == iw && iy != (h-1)) {
1809 				ix = 0;
1810 				++iy;
1811 			}
1812 		}
1813 		OUT_RING(dat);
1814 	}
1815 	if (pad)
1816 		OUT_RING(MI_NOOP);
1817 	ADVANCE_RING();
1818 
1819 	return 1;
1820 }
1821 
1822 /* HW cursor functions. */
intelfbhw_cursor_init(struct intelfb_info * dinfo)1823 void intelfbhw_cursor_init(struct intelfb_info *dinfo)
1824 {
1825 	u32 tmp;
1826 
1827 #if VERBOSE > 0
1828 	DBG_MSG("intelfbhw_cursor_init\n");
1829 #endif
1830 
1831 	if (dinfo->mobile || IS_I9XX(dinfo)) {
1832 		if (!dinfo->cursor.physical)
1833 			return;
1834 		tmp = INREG(CURSOR_A_CONTROL);
1835 		tmp &= ~(CURSOR_MODE_MASK | CURSOR_MOBILE_GAMMA_ENABLE |
1836 			 CURSOR_MEM_TYPE_LOCAL |
1837 			 (1 << CURSOR_PIPE_SELECT_SHIFT));
1838 		tmp |= CURSOR_MODE_DISABLE;
1839 		OUTREG(CURSOR_A_CONTROL, tmp);
1840 		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1841 	} else {
1842 		tmp = INREG(CURSOR_CONTROL);
1843 		tmp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
1844 			 CURSOR_ENABLE | CURSOR_STRIDE_MASK);
1845 		tmp = CURSOR_FORMAT_3C;
1846 		OUTREG(CURSOR_CONTROL, tmp);
1847 		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12);
1848 		tmp = (64 << CURSOR_SIZE_H_SHIFT) |
1849 		      (64 << CURSOR_SIZE_V_SHIFT);
1850 		OUTREG(CURSOR_SIZE, tmp);
1851 	}
1852 }
1853 
intelfbhw_cursor_hide(struct intelfb_info * dinfo)1854 void intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1855 {
1856 	u32 tmp;
1857 
1858 #if VERBOSE > 0
1859 	DBG_MSG("intelfbhw_cursor_hide\n");
1860 #endif
1861 
1862 	dinfo->cursor_on = 0;
1863 	if (dinfo->mobile || IS_I9XX(dinfo)) {
1864 		if (!dinfo->cursor.physical)
1865 			return;
1866 		tmp = INREG(CURSOR_A_CONTROL);
1867 		tmp &= ~CURSOR_MODE_MASK;
1868 		tmp |= CURSOR_MODE_DISABLE;
1869 		OUTREG(CURSOR_A_CONTROL, tmp);
1870 		/* Flush changes */
1871 		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1872 	} else {
1873 		tmp = INREG(CURSOR_CONTROL);
1874 		tmp &= ~CURSOR_ENABLE;
1875 		OUTREG(CURSOR_CONTROL, tmp);
1876 	}
1877 }
1878 
intelfbhw_cursor_show(struct intelfb_info * dinfo)1879 void intelfbhw_cursor_show(struct intelfb_info *dinfo)
1880 {
1881 	u32 tmp;
1882 
1883 #if VERBOSE > 0
1884 	DBG_MSG("intelfbhw_cursor_show\n");
1885 #endif
1886 
1887 	dinfo->cursor_on = 1;
1888 
1889 	if (dinfo->cursor_blanked)
1890 		return;
1891 
1892 	if (dinfo->mobile || IS_I9XX(dinfo)) {
1893 		if (!dinfo->cursor.physical)
1894 			return;
1895 		tmp = INREG(CURSOR_A_CONTROL);
1896 		tmp &= ~CURSOR_MODE_MASK;
1897 		tmp |= CURSOR_MODE_64_4C_AX;
1898 		OUTREG(CURSOR_A_CONTROL, tmp);
1899 		/* Flush changes */
1900 		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1901 	} else {
1902 		tmp = INREG(CURSOR_CONTROL);
1903 		tmp |= CURSOR_ENABLE;
1904 		OUTREG(CURSOR_CONTROL, tmp);
1905 	}
1906 }
1907 
intelfbhw_cursor_setpos(struct intelfb_info * dinfo,int x,int y)1908 void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1909 {
1910 	u32 tmp;
1911 
1912 #if VERBOSE > 0
1913 	DBG_MSG("intelfbhw_cursor_setpos: (%d, %d)\n", x, y);
1914 #endif
1915 
1916 	/*
1917 	 * Sets the position. The coordinates are assumed to already
1918 	 * have any offset adjusted. Assume that the cursor is never
1919 	 * completely off-screen, and that x, y are always >= 0.
1920 	 */
1921 
1922 	tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
1923 	      ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1924 	OUTREG(CURSOR_A_POSITION, tmp);
1925 
1926 	if (IS_I9XX(dinfo))
1927 		OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1928 }
1929 
intelfbhw_cursor_setcolor(struct intelfb_info * dinfo,u32 bg,u32 fg)1930 void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1931 {
1932 #if VERBOSE > 0
1933 	DBG_MSG("intelfbhw_cursor_setcolor\n");
1934 #endif
1935 
1936 	OUTREG(CURSOR_A_PALETTE0, bg & CURSOR_PALETTE_MASK);
1937 	OUTREG(CURSOR_A_PALETTE1, fg & CURSOR_PALETTE_MASK);
1938 	OUTREG(CURSOR_A_PALETTE2, fg & CURSOR_PALETTE_MASK);
1939 	OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK);
1940 }
1941 
intelfbhw_cursor_load(struct intelfb_info * dinfo,int width,int height,u8 * data)1942 void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
1943 			   u8 *data)
1944 {
1945 	u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1946 	int i, j, w = width / 8;
1947 	int mod = width % 8, t_mask, d_mask;
1948 
1949 #if VERBOSE > 0
1950 	DBG_MSG("intelfbhw_cursor_load\n");
1951 #endif
1952 
1953 	if (!dinfo->cursor.virtual)
1954 		return;
1955 
1956 	t_mask = 0xff >> mod;
1957 	d_mask = ~(0xff >> mod);
1958 	for (i = height; i--; ) {
1959 		for (j = 0; j < w; j++) {
1960 			writeb(0x00, addr + j);
1961 			writeb(*(data++), addr + j+8);
1962 		}
1963 		if (mod) {
1964 			writeb(t_mask, addr + j);
1965 			writeb(*(data++) & d_mask, addr + j+8);
1966 		}
1967 		addr += 16;
1968 	}
1969 }
1970 
intelfbhw_cursor_reset(struct intelfb_info * dinfo)1971 void intelfbhw_cursor_reset(struct intelfb_info *dinfo)
1972 {
1973 	u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1974 	int i, j;
1975 
1976 #if VERBOSE > 0
1977 	DBG_MSG("intelfbhw_cursor_reset\n");
1978 #endif
1979 
1980 	if (!dinfo->cursor.virtual)
1981 		return;
1982 
1983 	for (i = 64; i--; ) {
1984 		for (j = 0; j < 8; j++) {
1985 			writeb(0xff, addr + j+0);
1986 			writeb(0x00, addr + j+8);
1987 		}
1988 		addr += 16;
1989 	}
1990 }
1991 
intelfbhw_irq(int irq,void * dev_id)1992 static irqreturn_t intelfbhw_irq(int irq, void *dev_id)
1993 {
1994 	u16 tmp;
1995 	struct intelfb_info *dinfo = dev_id;
1996 
1997 	spin_lock(&dinfo->int_lock);
1998 
1999 	tmp = INREG16(IIR);
2000 	if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
2001 		tmp &= PIPE_A_EVENT_INTERRUPT;
2002 	else
2003 		tmp &= VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
2004 
2005 	if (tmp == 0) {
2006 		spin_unlock(&dinfo->int_lock);
2007 		return IRQ_RETVAL(0); /* not us */
2008 	}
2009 
2010 	/* clear status bits 0-15 ASAP and don't touch bits 16-31 */
2011 	OUTREG(PIPEASTAT, INREG(PIPEASTAT));
2012 
2013 	OUTREG16(IIR, tmp);
2014 	if (dinfo->vsync.pan_display) {
2015 		dinfo->vsync.pan_display = 0;
2016 		OUTREG(DSPABASE, dinfo->vsync.pan_offset);
2017 	}
2018 
2019 	dinfo->vsync.count++;
2020 	wake_up_interruptible(&dinfo->vsync.wait);
2021 
2022 	spin_unlock(&dinfo->int_lock);
2023 
2024 	return IRQ_RETVAL(1);
2025 }
2026 
intelfbhw_enable_irq(struct intelfb_info * dinfo)2027 int intelfbhw_enable_irq(struct intelfb_info *dinfo)
2028 {
2029 	u16 tmp;
2030 	if (!test_and_set_bit(0, &dinfo->irq_flags)) {
2031 		if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED,
2032 				"intelfb", dinfo)) {
2033 			clear_bit(0, &dinfo->irq_flags);
2034 			return -EINVAL;
2035 		}
2036 
2037 		spin_lock_irq(&dinfo->int_lock);
2038 		OUTREG16(HWSTAM, 0xfffe); /* i830 DRM uses ffff */
2039 		OUTREG16(IMR, 0);
2040 	} else
2041 		spin_lock_irq(&dinfo->int_lock);
2042 
2043 	if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
2044 		tmp = PIPE_A_EVENT_INTERRUPT;
2045 	else
2046 		tmp = VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
2047 	if (tmp != INREG16(IER)) {
2048 		DBG_MSG("changing IER to 0x%X\n", tmp);
2049 		OUTREG16(IER, tmp);
2050 	}
2051 
2052 	spin_unlock_irq(&dinfo->int_lock);
2053 	return 0;
2054 }
2055 
intelfbhw_disable_irq(struct intelfb_info * dinfo)2056 void intelfbhw_disable_irq(struct intelfb_info *dinfo)
2057 {
2058 	if (test_and_clear_bit(0, &dinfo->irq_flags)) {
2059 		if (dinfo->vsync.pan_display) {
2060 			dinfo->vsync.pan_display = 0;
2061 			OUTREG(DSPABASE, dinfo->vsync.pan_offset);
2062 		}
2063 		spin_lock_irq(&dinfo->int_lock);
2064 		OUTREG16(HWSTAM, 0xffff);
2065 		OUTREG16(IMR, 0xffff);
2066 		OUTREG16(IER, 0x0);
2067 
2068 		OUTREG16(IIR, INREG16(IIR)); /* clear IRQ requests */
2069 		spin_unlock_irq(&dinfo->int_lock);
2070 
2071 		free_irq(dinfo->pdev->irq, dinfo);
2072 	}
2073 }
2074 
intelfbhw_wait_for_vsync(struct intelfb_info * dinfo,u32 pipe)2075 int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe)
2076 {
2077 	struct intelfb_vsync *vsync;
2078 	unsigned int count;
2079 	int ret;
2080 
2081 	switch (pipe) {
2082 		case 0:
2083 			vsync = &dinfo->vsync;
2084 			break;
2085 		default:
2086 			return -ENODEV;
2087 	}
2088 
2089 	ret = intelfbhw_enable_irq(dinfo);
2090 	if (ret)
2091 		return ret;
2092 
2093 	count = vsync->count;
2094 	ret = wait_event_interruptible_timeout(vsync->wait,
2095 					       count != vsync->count, HZ / 10);
2096 	if (ret < 0)
2097 		return ret;
2098 	if (ret == 0) {
2099 		DBG_MSG("wait_for_vsync timed out!\n");
2100 		return -ETIMEDOUT;
2101 	}
2102 
2103 	return 0;
2104 }
2105