cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

intelfbhw.c (52352B)


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