GIT 7a532c69c37dbb46bfd0276160e624f06552adfc git+ssh://master.kernel.org/pub/scm/linux/kernel/git/airlied/intelfb-2.6#i915fb commit 7a532c69c37dbb46bfd0276160e624f06552adfc Author: Dennis Munsie Date: Mon May 29 18:58:09 2006 +1000 intelfb: use regular modedb table instead of VESA intelfb driver -- use the regular modedb table instead of the VESA modedb table. Ideally, the 9xx stride patch should be applied first, since there are modes in the VESA table that won't work without that patch. Signed-off-by: Dennis Munsie Signed-off-by: Dave Airlie commit 56e004e5435c008728b1444b51d757da2e098976 Author: Antonino A. Daplas Date: Mon May 29 18:49:08 2006 +1000 intelfb: use firmware EDID for mode database Use firmware EDID for the driver's private mode database. Signed-off-by: Antonino Daplas Cc: Sylvain Meyer Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie commit 080a416802153dbbb20ab4f4fa1225867096d071 Author: Dave Airlie Date: Mon May 29 18:45:19 2006 +1000 Revert "intelfb driver -- use the regular modedb table instead of the VESA" This reverts 2c47430a03bbcc3c9a623a07eca5baf92c7d20c8 commit. This conflicts with a patch in -mm from Antonino reapply later. Signed-off-by: Dave Airlie commit 65eb2f97db17f6f6a92cad3aad93b531f991ebf1 Author: Eric Hustvedt Date: Mon May 29 18:38:55 2006 +1000 intelfb: int option fix Fix integer option parsing in the intelfb driver. The macro wasn't accounting for the equal sign past the option name. As a result, the vram option always returned 0. Signed-off-by: Eric Hustvedt Signed-off-by: Dennis Munsie commit f728377f6786bcdf1dbf33394360164e86f40094 Author: Dave Airlie Date: Sat May 27 18:56:02 2006 +1000 sync modesetting code with X.org Signed-off-by: Dave Airlie commit c9daa873c3a7c769821ec6c8258adf098bb0435c Author: Dave Airlie Date: Sat May 27 18:44:02 2006 +1000 intelfb: align with changes from my X driver. This just realigns the PLL calculation routines with the ones from my X.org driver. Signed-off-by: Dave Airlie commit 2c47430a03bbcc3c9a623a07eca5baf92c7d20c8 Author: Dennis Munsie Date: Sat May 27 18:33:35 2006 +1000 intelfb driver -- use the regular modedb table instead of the VESA modedb table. Ideally, the 9xx stride patch should be applied first, since there are modes in the VESA table that won't work without that patch. Signed-off-by: Dennis Munsie Signed-off-by: Dave Airlie commit 1aecb393091d3c0787f92445420d96ef58c9782a Author: Eric Hustvedt Date: Sat May 27 18:30:00 2006 +1000 Adds support for 256MB aperture on 945 chipsets to the intelfb driver and corrects calculation of stolen memory overhead. Signed-off-by: Eric Hustvedt Signed-off-by: Dennis Munsie Signed-off-by: Dave Airlie commit df7df8ab7b38ca80bbaf5ffafd401d6c739fd45f Author: Dennis Munsie Date: Sat May 27 18:17:52 2006 +1000 intelfb -- uses stride alignment of 64 on the 9xx chipsets. Signed-off-by: Dennis Munsie Signed-off-by: Dave Airlie commit 51d797474f87b375819d084f7583a2864c5656c4 Author: Dave Airlie Date: Mon Apr 3 16:19:26 2006 +1000 intelfb: some cleanups for intelfbhw Signed-off-by: Dave Airlie commit 3587c50991b96fee2d26942f380e36e4f40fad71 Author: Dave Airlie Date: Mon Apr 3 14:46:55 2006 +1000 intelfb: fixup pitch calculation like X does Signed-off-by: Dave Airlie commit 3aff13cfb8810cc228e8fdcb92103ed0b11ee38e Author: Dave Airlie Date: Fri Mar 31 17:08:52 2006 +1000 intelfb: fixup p calculation This fixes up the p calculation of p1 and p2 for the i9xx chipsets. This seems to work a lot better for lower pixel clocks.. Signed-off-by: Dave Airlie commit 46f60b8e67e6fceede851dc69cdee2d7c0de27b9 Author: Dave Airlie Date: Fri Mar 24 12:31:14 2006 +1100 This patch makes a needlessly global struct static. Signed-off-by: Adrian Bunk Signed-off-by: Dave Airlie commit 9a90603f65dd5046ddcd586158abcad7784892b6 Author: Dave Airlie Date: Thu Mar 23 21:53:05 2006 +1100 intelfb: add i945GM support Untested i945GM support just add the framework. Signed-off-by: Dave Airlie commit 8b91b0b4f2d731b92f59bc82492769a09b4955a6 Author: Dave Airlie Date: Thu Mar 23 19:23:48 2006 +1100 intelfb: fixup whitespace.. repeat after me, I must not take code from X without reformatting... Signed-off-by: Dave Airlie commit 8bb91f6a2d1db8031bfbb367df075f041d0cdfe2 Author: Dave Airlie Date: Thu Mar 23 13:06:32 2006 +1100 intelfb: add hw cursor support for i9xx This adds hw cursor support for the i9xx chipsets. Signed-off-by: Dave Airlie commit 7679f4d69296de97a7f62458cc4d1c6c884dfcfb Author: Dave Airlie Date: Thu Mar 23 12:30:05 2006 +1100 intelfb: make i915 modeset This takes the modeset and pll code from my X driver. Signed-off-by: Dave Airlie commit 9639d5ec07a490134f05ac890506a367aaf8663b Author: Dave Airlie Date: Thu Mar 23 11:23:55 2006 +1100 intelfb: add support for i945G This just adds the defines and structure for i945G Signed-off-by: Dave Airlie commit 0c187addabbaf93512902442b4a90140a21b0ddc Author: Dave Airlie Date: Thu Mar 23 11:20:08 2006 +1100 intelfb: enable on x86_64 i945G chipsets supports 64-bit. Signed-off-by: Dave Airlie commit 16109b3f4c1f2635afd32eb6d49348590de2cb25 Author: Dave Airlie Date: Mon Mar 20 21:22:09 2006 +1100 intelfb: add p divisor increments for i9xx. Signed-off-by: Dave Airlie commit 8492f081e5552ff388068f612eae6f55f7210ed4 Author: Dave Airlie Date: Mon Mar 20 20:54:12 2006 +1100 intelfb: change splitm to be brute force The old splitm didn't always work use a brute force. Signed-off-by: Dave Airlie commit d024960cff5173bef6e83c01cf9cd2763c2c0ab0 Author: Dave Airlie Date: Mon Mar 20 20:26:45 2006 +1100 intelfb: add pll index to the intelfb structure Add the pll index into the information structure, change get_chipset to take only the info structure, use plls in correct places commit 7258b11d2e9a47d2b01620622579f22906960e1a Author: Dave Airlie Date: Mon Mar 20 20:02:24 2006 +1100 intelfb: prepare for i9xx support. This code just moves the PLL min/max calculations variables into a structure, it doesn't change or add any new functionality. Signed-off-by: Dave Airlie --- diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index f87c017..190adce 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -741,7 +741,7 @@ config FB_I810_I2C config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" - depends on FB && EXPERIMENTAL && PCI && X86_32 + depends on FB && EXPERIMENTAL && PCI && X86 select AGP select AGP_INTEL select FB_MODE_HELPERS diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index da29d00..469b06c 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -8,9 +8,9 @@ #include /*** Version/name ***/ -#define INTELFB_VERSION "0.9.2" +#define INTELFB_VERSION "0.9.4" #define INTELFB_MODULE_NAME "intelfb" -#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM" +#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM" /*** Debug/feature defines ***/ @@ -52,11 +52,14 @@ #define PCI_DEVICE_ID_INTEL_85XGM 0x3582 #define PCI_DEVICE_ID_INTEL_865G 0x2572 #define PCI_DEVICE_ID_INTEL_915G 0x2582 #define PCI_DEVICE_ID_INTEL_915GM 0x2592 +#define PCI_DEVICE_ID_INTEL_945G 0x2772 +#define PCI_DEVICE_ID_INTEL_945GM 0x27A2 /* Size of MMIO region */ #define INTEL_REG_SIZE 0x80000 #define STRIDE_ALIGNMENT 16 +#define STRIDE_ALIGNMENT_I9XX 64 #define PALETTE_8_ENTRIES 256 @@ -125,7 +128,9 @@ enum intel_chips { INTEL_855GME, INTEL_865G, INTEL_915G, - INTEL_915GM + INTEL_915GM, + INTEL_945G, + INTEL_945GM, }; struct intelfb_hwstate { @@ -277,8 +282,13 @@ struct intelfb_info { /* driver registered */ int registered; + + /* index into plls */ + int pll_index; }; +#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) + /*** function prototypes ***/ extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 995b47c..85bf558 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -1,11 +1,12 @@ /* * intelfb * - * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM - * integrated graphics chips. + * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/ + * 945G/945GM integrated graphics chips. * * Copyright © 2002, 2003 David Dawes * 2004 Sylvain Meyer + * 2006 David Airlie * * This driver consists of two parts. The first part (intelfbdrv.c) provides * the basic fbdev interfaces, is derived in part from the radeonfb and @@ -131,6 +132,7 @@ #endif #include "intelfb.h" #include "intelfbhw.h" +#include "../edid.h" static void __devinit get_initial_mode(struct intelfb_info *dinfo); static void update_dinfo(struct intelfb_info *dinfo, @@ -182,6 +184,8 @@ static struct pci_device_id intelfb_pci_ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM }, { 0, } }; @@ -261,7 +265,7 @@ MODULE_PARM_DESC(mode, #ifndef MODULE #define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) -#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name), NULL, 0) +#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0) #define OPT_STRVAL(opt, name) (opt + strlen(name)) static __inline__ char * @@ -546,11 +550,11 @@ intelfb_pci_register(struct pci_dev *pde /* Set base addresses. */ if ((ent->device == PCI_DEVICE_ID_INTEL_915G) || - (ent->device == PCI_DEVICE_ID_INTEL_915GM)) { + (ent->device == PCI_DEVICE_ID_INTEL_915GM) || + (ent->device == PCI_DEVICE_ID_INTEL_945G) || + (ent->device == PCI_DEVICE_ID_INTEL_945GM)) { aperture_bar = 2; mmio_bar = 0; - /* Disable HW cursor on 915G/M (not implemented yet) */ - hwcursor = 0; } dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); dinfo->aperture.size = pci_resource_len(pdev, aperture_bar); @@ -584,8 +588,7 @@ intelfb_pci_register(struct pci_dev *pde /* Get the chipset info. */ dinfo->pci_chipset = pdev->device; - if (intelfbhw_get_chipset(pdev, &dinfo->name, &dinfo->chipset, - &dinfo->mobile)) { + if (intelfbhw_get_chipset(pdev, dinfo)) { cleanup(dinfo); return -ENODEV; } @@ -1029,17 +1032,44 @@ intelfb_init_var(struct intelfb_info *di sizeof(struct fb_var_screeninfo)); msrc = 5; } else { + const u8 *edid_s = fb_firmware_edid(&dinfo->pdev->dev); + u8 *edid_d = NULL; + + if (edid_s) { + edid_d = kmalloc(128, GFP_KERNEL); + + if (edid_d) { + memcpy(edid_d, edid_s, 128); + fb_edid_to_monspecs(edid_d, + &dinfo->info->monspecs); + kfree(edid_d); + } + } + if (mode) { + printk("intelfb: Looking for mode in private " + "database\n"); msrc = fb_find_mode(var, dinfo->info, mode, - vesa_modes, VESA_MODEDB_SIZE, + dinfo->info->monspecs.modedb, + dinfo->info->monspecs.modedb_len, NULL, 0); - if (msrc) - msrc |= 8; + + if (msrc && msrc > 1) { + printk("intelfb: No mode in private database, " + "intelfb: looking for mode in global " + "database "); + msrc = fb_find_mode(var, dinfo->info, mode, + NULL, 0, NULL, 0); + + if (msrc) + msrc |= 8; + } + } + if (!msrc) { msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, - vesa_modes, VESA_MODEDB_SIZE, - NULL, 0); + NULL, 0, NULL, 0); } } @@ -1139,7 +1169,10 @@ update_dinfo(struct intelfb_info *dinfo, } /* Make sure the line length is a aligned correctly. */ - dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); + if (IS_I9XX(dinfo)) + dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX); + else + dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); if (FIXED_MODE(dinfo)) dinfo->pitch = dinfo->initial_pitch; @@ -1162,16 +1195,33 @@ intelfb_check_var(struct fb_var_screenin struct fb_var_screeninfo v; struct intelfb_info *dinfo; static int first = 1; + int i; + /* Good pitches to allow tiling. Don't care about pitches < 1024. */ + static const int pitches[] = { + 128 * 8, + 128 * 16, + 128 * 32, + 128 * 64, + 0 + }; DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags); dinfo = GET_DINFO(info); + /* update the pitch */ if (intelfbhw_validate_mode(dinfo, var) != 0) return -EINVAL; v = *var; + for (i = 0; pitches[i] != 0; i++) { + if (pitches[i] >= v.xres_virtual) { + v.xres_virtual = pitches[i]; + break; + } + } + /* Check for a supported bpp. */ if (v.bits_per_pixel <= 8) { v.bits_per_pixel = 8; @@ -1467,7 +1517,7 @@ static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct intelfb_info *dinfo = GET_DINFO(info); - + u32 physical; #if VERBOSE > 0 DBG_MSG("intelfb_cursor\n"); #endif @@ -1478,7 +1528,10 @@ #endif intelfbhw_cursor_hide(dinfo); /* If XFree killed the cursor - restore it */ - if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.offset << 12) { + physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical : + (dinfo->cursor.offset << 12); + + if (INREG(CURSOR_A_BASEADDR) != physical) { u32 fg, bg; DBG_MSG("the cursor was killed - restore it !!\n"); diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 624c4bc..16c9c19 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -40,68 +40,110 @@ #include #include "intelfb.h" #include "intelfbhw.h" +struct pll_min_max { + int min_m, max_m, min_m1, max_m1; + int min_m2, max_m2, min_n, max_n; + int min_p, max_p, min_p1, max_p1; + int min_vco, max_vco, p_transition_clk, ref_clk; + int p_inc_lo, p_inc_hi; +}; + +#define PLLS_I8xx 0 +#define PLLS_I9xx 1 +#define PLLS_MAX 2 + +static struct pll_min_max plls[PLLS_MAX] = { + { 108, 140, 18, 26, + 6, 16, 3, 16, + 4, 128, 0, 31, + 930000, 1400000, 165000, 48000, + 4, 2 }, //I8xx + + { 75, 120, 10, 20, + 5, 9, 4, 7, + 5, 80, 1, 8, + 1400000, 2800000, 200000, 96000, + 10, 5 } //I9xx +}; + int -intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset, - int *mobile) +intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo) { u32 tmp; - - if (!pdev || !name || !chipset || !mobile) + if (!pdev || !dinfo) return 1; switch (pdev->device) { case PCI_DEVICE_ID_INTEL_830M: - *name = "Intel(R) 830M"; - *chipset = INTEL_830M; - *mobile = 1; + dinfo->name = "Intel(R) 830M"; + dinfo->chipset = INTEL_830M; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I8xx; return 0; case PCI_DEVICE_ID_INTEL_845G: - *name = "Intel(R) 845G"; - *chipset = INTEL_845G; - *mobile = 0; + dinfo->name = "Intel(R) 845G"; + dinfo->chipset = INTEL_845G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I8xx; return 0; case PCI_DEVICE_ID_INTEL_85XGM: tmp = 0; - *mobile = 1; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I8xx; pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp); switch ((tmp >> INTEL_85X_VARIANT_SHIFT) & INTEL_85X_VARIANT_MASK) { case INTEL_VAR_855GME: - *name = "Intel(R) 855GME"; - *chipset = INTEL_855GME; + dinfo->name = "Intel(R) 855GME"; + dinfo->chipset = INTEL_855GME; return 0; case INTEL_VAR_855GM: - *name = "Intel(R) 855GM"; - *chipset = INTEL_855GM; + dinfo->name = "Intel(R) 855GM"; + dinfo->chipset = INTEL_855GM; return 0; case INTEL_VAR_852GME: - *name = "Intel(R) 852GME"; - *chipset = INTEL_852GME; + dinfo->name = "Intel(R) 852GME"; + dinfo->chipset = INTEL_852GME; return 0; case INTEL_VAR_852GM: - *name = "Intel(R) 852GM"; - *chipset = INTEL_852GM; + dinfo->name = "Intel(R) 852GM"; + dinfo->chipset = INTEL_852GM; return 0; default: - *name = "Intel(R) 852GM/855GM"; - *chipset = INTEL_85XGM; + dinfo->name = "Intel(R) 852GM/855GM"; + dinfo->chipset = INTEL_85XGM; return 0; } break; case PCI_DEVICE_ID_INTEL_865G: - *name = "Intel(R) 865G"; - *chipset = INTEL_865G; - *mobile = 0; + dinfo->name = "Intel(R) 865G"; + dinfo->chipset = INTEL_865G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I8xx; return 0; case PCI_DEVICE_ID_INTEL_915G: - *name = "Intel(R) 915G"; - *chipset = INTEL_915G; - *mobile = 0; + dinfo->name = "Intel(R) 915G"; + dinfo->chipset = INTEL_915G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I9xx; return 0; case PCI_DEVICE_ID_INTEL_915GM: - *name = "Intel(R) 915GM"; - *chipset = INTEL_915GM; - *mobile = 1; + dinfo->name = "Intel(R) 915GM"; + dinfo->chipset = INTEL_915GM; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I9xx; + return 0; + case PCI_DEVICE_ID_INTEL_945G: + dinfo->name = "Intel(R) 945G"; + dinfo->chipset = INTEL_945G; + dinfo->mobile = 0; + dinfo->pll_index = PLLS_I9xx; + return 0; + case PCI_DEVICE_ID_INTEL_945GM: + dinfo->name = "Intel(R) 945GM"; + dinfo->chipset = INTEL_945GM; + dinfo->mobile = 1; + dinfo->pll_index = PLLS_I9xx; return 0; default: return 1; @@ -114,6 +156,7 @@ intelfbhw_get_memory(struct pci_dev *pde { struct pci_dev *bridge_dev; u16 tmp; + int stolen_overhead; if (!pdev || !aperture_size || !stolen_size) return 1; @@ -128,21 +171,41 @@ intelfbhw_get_memory(struct pci_dev *pde tmp = 0; pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); switch (pdev->device) { - case PCI_DEVICE_ID_INTEL_830M: - case PCI_DEVICE_ID_INTEL_845G: + case PCI_DEVICE_ID_INTEL_915G: + case PCI_DEVICE_ID_INTEL_915GM: + case PCI_DEVICE_ID_INTEL_945G: + case PCI_DEVICE_ID_INTEL_945GM: + /* 915 and 945 chipsets support a 256MB aperture. + Aperture size is determined by inspected the + base address of the aperture. */ + if (pci_resource_start(pdev, 2) & 0x08000000) + *aperture_size = MB(128); + else + *aperture_size = MB(256); + break; + default: if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) *aperture_size = MB(64); else *aperture_size = MB(128); + break; + } + + /* Stolen memory size is reduced by the GTT and the popup. + GTT is 1K per MB of aperture size, and popup is 4K. */ + stolen_overhead = (*aperture_size / MB(1)) + 4; + switch(pdev->device) { + case PCI_DEVICE_ID_INTEL_830M: + case PCI_DEVICE_ID_INTEL_845G: switch (tmp & INTEL_830_GMCH_GMS_MASK) { case INTEL_830_GMCH_GMS_STOLEN_512: - *stolen_size = KB(512) - KB(132); + *stolen_size = KB(512) - KB(stolen_overhead); return 0; case INTEL_830_GMCH_GMS_STOLEN_1024: - *stolen_size = MB(1) - KB(132); + *stolen_size = MB(1) - KB(stolen_overhead); return 0; case INTEL_830_GMCH_GMS_STOLEN_8192: - *stolen_size = MB(8) - KB(132); + *stolen_size = MB(8) - KB(stolen_overhead); return 0; case INTEL_830_GMCH_GMS_LOCAL: ERR_MSG("only local memory found\n"); @@ -157,28 +220,27 @@ intelfbhw_get_memory(struct pci_dev *pde } break; default: - *aperture_size = MB(128); switch (tmp & INTEL_855_GMCH_GMS_MASK) { case INTEL_855_GMCH_GMS_STOLEN_1M: - *stolen_size = MB(1) - KB(132); + *stolen_size = MB(1) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_4M: - *stolen_size = MB(4) - KB(132); + *stolen_size = MB(4) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_8M: - *stolen_size = MB(8) - KB(132); + *stolen_size = MB(8) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_16M: - *stolen_size = MB(16) - KB(132); + *stolen_size = MB(16) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_STOLEN_32M: - *stolen_size = MB(32) - KB(132); + *stolen_size = MB(32) - KB(stolen_overhead); return 0; case INTEL_915G_GMCH_GMS_STOLEN_48M: - *stolen_size = MB(48) - KB(132); + *stolen_size = MB(48) - KB(stolen_overhead); return 0; case INTEL_915G_GMCH_GMS_STOLEN_64M: - *stolen_size = MB(64) - KB(132); + *stolen_size = MB(64) - KB(stolen_overhead); return 0; case INTEL_855_GMCH_GMS_DISABLED: ERR_MSG("video memory is disabled\n"); @@ -529,12 +591,36 @@ #endif } +static int calc_vclock3(int index, int m, int n, int p) +{ + if (p == 0 || n == 0) + return 0; + return plls[index].ref_clk * m / n / p; +} + +static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds) +{ + struct pll_min_max *pll = &plls[index]; + u32 m, vco, p; + + m = (5 * (m1 + 2)) + (m2 + 2); + n += 2; + vco = pll->ref_clk * m / n; + + if (index == PLLS_I8xx) { + p = ((p1 + 2) * (1 << (p2 + 1))); + } else { + p = ((p1) * (p2 ? 5 : 10)); + } + return vco / p; +} + void intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) { #if REGDUMP int i, m1, m2, n, p1, p2; - + int index = dinfo->pll_index; DBG_MSG("intelfbhw_print_hw_state\n"); if (!hw || !dinfo) @@ -551,10 +637,13 @@ #if REGDUMP p1 = 0; else p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK; + p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK; + printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" VGA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" VGA0: clock is %d\n", + calc_vclock(index, m1, m2, n, p1, p2, 0)); n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; @@ -565,8 +654,8 @@ #if REGDUMP p1 = (hw->vga_pd >> VGAPD_1_P1_SHIFT) & DPLL_P1_MASK; p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK; printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" VGA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); printk(" DPLL_A: 0x%08x\n", hw->dpll_a); printk(" DPLL_B: 0x%08x\n", hw->dpll_b); @@ -578,34 +667,90 @@ #if REGDUMP n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; - if (hw->dpll_a & DPLL_P1_FORCE_DIV2) - p1 = 0; - else - p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; - p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + + if (IS_I9XX(dinfo)) { + int tmpp1; + + if (hw->dpll_a & DPLL_P1_FORCE_DIV2) + p1 = 0; + else + p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & 0xff; + + tmpp1 = p1; + + switch (tmpp1) + { + case 0x1: p1 = 1; break; + case 0x2: p1 = 2; break; + case 0x4: p1 = 3; break; + case 0x8: p1 = 4; break; + case 0x10: p1 = 5; break; + case 0x20: p1 = 6; break; + case 0x40: p1 = 7; break; + case 0x80: p1 = 8; break; + default: break; + } + + p2 = (hw->dpll_a >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; + + } else { + if (hw->dpll_a & DPLL_P1_FORCE_DIV2) + p1 = 0; + else + p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; + p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + } + printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" PLLA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; - if (hw->dpll_a & DPLL_P1_FORCE_DIV2) - p1 = 0; - else - p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; - p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + + if (IS_I9XX(dinfo)) { + int tmpp1; + + if (hw->dpll_a & DPLL_P1_FORCE_DIV2) + p1 = 0; + else + p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & 0xff; + + tmpp1 = p1; + + switch (tmpp1) { + case 0x1: p1 = 1; break; + case 0x2: p1 = 2; break; + case 0x4: p1 = 3; break; + case 0x8: p1 = 4; break; + case 0x10: p1 = 5; break; + case 0x20: p1 = 6; break; + case 0x40: p1 = 7; break; + case 0x80: p1 = 8; break; + default: break; + } + + p2 = (hw->dpll_a >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; + + } else { + if (hw->dpll_a & DPLL_P1_FORCE_DIV2) + p1 = 0; + else + p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK; + p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK; + } printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", - m1, m2, n, p1, p2); - printk(" PLLA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); + m1, m2, n, p1, p2); + printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); #if 0 printk(" PALETTE_A:\n"); for (i = 0; i < PALETTE_8_ENTRIES) - printk(" %3d: 0x%08x\n", i, hw->palette_a[i]; + printk(" %3d: 0x%08x\n", i, hw->palette_a[i]); printk(" PALETTE_B:\n"); for (i = 0; i < PALETTE_8_ENTRIES) - printk(" %3d: 0x%08x\n", i, hw->palette_b[i]; + printk(" %3d: 0x%08x\n", i, hw->palette_b[i]); #endif printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a); @@ -680,11 +825,11 @@ #endif } for (i = 0; i < 3; i++) { printk(" SWF3%d 0x%08x\n", i, - hw->swf3x[i]); + hw->swf3x[i]); } for (i = 0; i < 8; i++) printk(" FENCE%d 0x%08x\n", i, - hw->fence[i]); + hw->fence[i]); printk(" INSTPM 0x%08x\n", hw->instpm); printk(" MEM_MODE 0x%08x\n", hw->mem_mode); @@ -695,43 +840,58 @@ #endif #endif } + + /* Split the M parameter into M1 and M2. */ static int -splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2) +splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2) { int m1, m2; - - m1 = (m - 2 - (MIN_M2 + MAX_M2) / 2) / 5 - 2; - if (m1 < MIN_M1) - m1 = MIN_M1; - if (m1 > MAX_M1) - m1 = MAX_M1; - m2 = m - 5 * (m1 + 2) - 2; - if (m2 < MIN_M2 || m2 > MAX_M2 || m2 >= m1) { - return 1; - } else { - *retm1 = (unsigned int)m1; - *retm2 = (unsigned int)m2; - return 0; + int testm; + struct pll_min_max *pll = &plls[index]; + + /* no point optimising too much - brute force m */ + for (m1 = pll->min_m1; m1 < pll->max_m1 + 1; m1++) { + for (m2 = pll->min_m2; m2 < pll->max_m2 + 1; m2++) { + testm = (5 * (m1 + 2)) + (m2 + 2); + if (testm == m) { + *retm1 = (unsigned int)m1; + *retm2 = (unsigned int)m2; + return 0; + } + } } + return 1; } /* Split the P parameter into P1 and P2. */ static int -splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2) +splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2) { int p1, p2; + struct pll_min_max *pll = &plls[index]; + + if (index == PLLS_I9xx) { + p2 = (p % 10) ? 1 : 0; + + p1 = p / (p2 ? 5 : 10); + + *retp1 = (unsigned int)p1; + *retp2 = (unsigned int)p2; + return 0; + } if (p % 4 == 0) p2 = 1; else p2 = 0; p1 = (p / (1 << (p2 + 1))) - 2; - if (p % 4 == 0 && p1 < MIN_P1) { + if (p % 4 == 0 && p1 < pll->min_p1) { p2 = 0; p1 = (p / (1 << (p2 + 1))) - 2; } - if (p1 < MIN_P1 || p1 > MAX_P1 || (p1 + 2) * (1 << (p2 + 1)) != p) { + if (p1 < pll->min_p1 || p1 > pll->max_p1 || + (p1 + 2) * (1 << (p2 + 1)) != p) { return 1; } else { *retp1 = (unsigned int)p1; @@ -741,14 +901,15 @@ splitp(unsigned int p, unsigned int *ret } static int -calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, +calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock) { - u32 m1, m2, n, p1, p2, n1; - u32 f_vco, p, p_best = 0, m, f_out; + u32 m1, m2, n, p1, p2, n1, testm; + u32 f_vco, p, p_best = 0, m, f_out = 0; u32 err_max, err_target, err_best = 10000000; u32 n_best = 0, m_best = 0, f_best, f_err; - u32 p_min, p_max, p_inc, div_min, div_max; + u32 p_min, p_max, p_inc, div_max; + struct pll_min_max *pll = &plls[index]; /* Accept 0.5% difference, but aim for 0.1% */ err_max = 5 * clock / 1000; @@ -756,58 +917,56 @@ calc_pll_params(int clock, u32 *retm1, u DBG_MSG("Clock is %d\n", clock); - div_max = MAX_VCO_FREQ / clock; - div_min = ROUND_UP_TO(MIN_VCO_FREQ, clock) / clock; + div_max = pll->max_vco / clock; - if (clock <= P_TRANSITION_CLOCK) - p_inc = 4; - else - p_inc = 2; - p_min = ROUND_UP_TO(div_min, p_inc); + p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi; + p_min = p_inc; p_max = ROUND_DOWN_TO(div_max, p_inc); - if (p_min < MIN_P) - p_min = 4; - if (p_max > MAX_P) - p_max = 128; + if (p_min < pll->min_p) + p_min = pll->min_p; + if (p_max > pll->max_p) + p_max = pll->max_p; DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); p = p_min; do { - if (splitp(p, &p1, &p2)) { + if (splitp(index, p, &p1, &p2)) { WRN_MSG("cannot split p = %d\n", p); p += p_inc; continue; } - n = MIN_N; + n = pll->min_n; f_vco = clock * p; do { - m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK; - if (m < MIN_M) - m = MIN_M; - if (m > MAX_M) - m = MAX_M; - f_out = CALC_VCLOCK3(m, n, p); - if (splitm(m, &m1, &m2)) { - WRN_MSG("cannot split m = %d\n", m); - n++; - continue; - } - if (clock > f_out) - f_err = clock - f_out; - else - f_err = f_out - clock; - - if (f_err < err_best) { - m_best = m; - n_best = n; - p_best = p; - f_best = f_out; - err_best = f_err; + m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk; + if (m < pll->min_m) + m = pll->min_m + 1; + if (m > pll->max_m) + m = pll->max_m - 1; + for (testm = m - 1; testm <= m; testm++) { + f_out = calc_vclock3(index, m, n, p); + if (splitm(index, testm, &m1, &m2)) { + WRN_MSG("cannot split m = %d\n", m); + n++; + continue; + } + if (clock > f_out) + f_err = clock - f_out; + else/* slightly bias the error for bigger clocks */ + f_err = f_out - clock + 1; + + if (f_err < err_best) { + m_best = testm; + n_best = n; + p_best = p; + f_best = f_out; + err_best = f_err; + } } n++; - } while ((n <= MAX_N) && (f_out >= clock)); + } while ((n <= pll->max_n) && (f_out >= clock)); p += p_inc; } while ((p <= p_max)); @@ -818,21 +977,22 @@ calc_pll_params(int clock, u32 *retm1, u m = m_best; n = n_best; p = p_best; - splitm(m, &m1, &m2); - splitp(p, &p1, &p2); + splitm(index, m, &m1, &m2); + splitp(index, p, &p1, &p2); n1 = n - 2; DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " "f: %d (%d), VCO: %d\n", m, m1, m2, n, n1, p, p1, p2, - CALC_VCLOCK3(m, n, p), CALC_VCLOCK(m1, m2, n1, p1, p2), - CALC_VCLOCK3(m, n, p) * p); + calc_vclock3(index, m, n, p), + calc_vclock(index, m1, m2, n1, p1, p2, 0), + calc_vclock3(index, m, n, p) * p); *retm1 = m1; *retm2 = m2; *retn = n1; *retp1 = p1; *retp2 = p2; - *retclock = CALC_VCLOCK(m1, m2, n1, p1, p2); + *retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0); return 0; } @@ -860,6 +1020,7 @@ intelfbhw_mode_to_hw(struct intelfb_info u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive; u32 vsync_pol, hsync_pol; u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf; + u32 stride_alignment; DBG_MSG("intelfbhw_mode_to_hw\n"); @@ -929,7 +1090,8 @@ intelfbhw_mode_to_hw(struct intelfb_info /* Desired clock in kHz */ clock_target = 1000000000 / var->pixclock; - if (calc_pll_params(clock_target, &m1, &m2, &n, &p1, &p2, &clock)) { + if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2, + &n, &p1, &p2, &clock)) { WRN_MSG("calc_pll_params failed\n"); return 1; } @@ -949,7 +1111,14 @@ intelfbhw_mode_to_hw(struct intelfb_info *dpll &= ~DPLL_P1_FORCE_DIV2; *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | (DPLL_P1_MASK << DPLL_P1_SHIFT)); - *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); + + if (IS_I9XX(dinfo)) { + *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); + *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; + } else { + *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); + } + *fp0 = (n << FP_N_DIVISOR_SHIFT) | (m1 << FP_M1_DIVISOR_SHIFT) | (m2 << FP_M2_DIVISOR_SHIFT); @@ -1054,7 +1223,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) | (vactive << SRC_SIZE_VERT_SHIFT); - hw->disp_a_stride = var->xres_virtual * var->bits_per_pixel / 8; + hw->disp_a_stride = dinfo->pitch; DBG_MSG("pitch is %d\n", hw->disp_a_stride); hw->disp_a_base = hw->disp_a_stride * var->yoffset + @@ -1063,9 +1232,11 @@ intelfbhw_mode_to_hw(struct intelfb_info hw->disp_a_base += dinfo->fb.offset << 12; /* Check stride alignment. */ - if (hw->disp_a_stride % STRIDE_ALIGNMENT != 0) { + stride_alignment = IS_I9XX(dinfo) ? STRIDE_ALIGNMENT_I9XX : + STRIDE_ALIGNMENT; + if (hw->disp_a_stride % stride_alignment != 0) { WRN_MSG("display stride %d has bad alignment %d\n", - hw->disp_a_stride, STRIDE_ALIGNMENT); + hw->disp_a_stride, stride_alignment); return 1; } @@ -1087,6 +1258,7 @@ intelfbhw_program_mode(struct intelfb_in u32 hsync_reg, htotal_reg, hblank_reg; u32 vsync_reg, vtotal_reg, vblank_reg; u32 src_size_reg; + u32 count, tmp_val[3]; /* Assume single pipe, display plane A, analog CRT. */ @@ -1155,6 +1327,27 @@ #endif src_size_reg = SRC_SIZE_A; } + /* turn off pipe */ + tmp = INREG(pipe_conf_reg); + tmp &= ~PIPECONF_ENABLE; + OUTREG(pipe_conf_reg, tmp); + + count = 0; + do { + tmp_val[count%3] = INREG(0x70000); + if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2])) + break; + count++; + udelay(1); + if (count % 200 == 0) { + tmp = INREG(pipe_conf_reg); + tmp &= ~PIPECONF_ENABLE; + OUTREG(pipe_conf_reg, tmp); + } + } while(count < 2000); + + OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); + /* Disable planes A and B. */ tmp = INREG(DSPACNTR); tmp &= ~DISPPLANE_PLANE_ENABLE; @@ -1163,19 +1356,21 @@ #endif tmp &= ~DISPPLANE_PLANE_ENABLE; OUTREG(DSPBCNTR, tmp); - /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ + /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ mdelay(20); + OUTREG(DVOB, INREG(DVOB) & ~PORT_ENABLE); + OUTREG(DVOC, INREG(DVOC) & ~PORT_ENABLE); + OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); + /* Disable Sync */ tmp = INREG(ADPA); tmp &= ~ADPA_DPMS_CONTROL_MASK; tmp |= ADPA_DPMS_D3; OUTREG(ADPA, tmp); - /* turn off pipe */ - tmp = INREG(pipe_conf_reg); - tmp &= ~PIPECONF_ENABLE; - OUTREG(pipe_conf_reg, tmp); + /* do some funky magic - xyzzy */ + OUTREG(0x61204, 0xabcd0000); /* turn off PLL */ tmp = INREG(dpll_reg); @@ -1183,30 +1378,31 @@ #endif OUTREG(dpll_reg, tmp); /* Set PLL parameters */ - OUTREG(dpll_reg, *dpll & ~DPLL_VCO_ENABLE); OUTREG(fp0_reg, *fp0); OUTREG(fp1_reg, *fp1); - /* Set pipe parameters */ - OUTREG(hsync_reg, *hs); - OUTREG(hblank_reg, *hb); - OUTREG(htotal_reg, *ht); - OUTREG(vsync_reg, *vs); - OUTREG(vblank_reg, *vb); - OUTREG(vtotal_reg, *vt); - OUTREG(src_size_reg, *ss); + /* Enable PLL */ + OUTREG(dpll_reg, *dpll); /* Set DVOs B/C */ OUTREG(DVOB, hw->dvob); OUTREG(DVOC, hw->dvoc); + /* undo funky magic */ + OUTREG(0x61204, 0x00000000); + /* Set ADPA */ + OUTREG(ADPA, INREG(ADPA) | ADPA_DAC_ENABLE); OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3); - /* Enable PLL */ - tmp = INREG(dpll_reg); - tmp |= DPLL_VCO_ENABLE; - OUTREG(dpll_reg, tmp); + /* Set pipe parameters */ + OUTREG(hsync_reg, *hs); + OUTREG(hblank_reg, *hb); + OUTREG(htotal_reg, *ht); + OUTREG(vsync_reg, *vs); + OUTREG(vblank_reg, *vb); + OUTREG(vtotal_reg, *vt); + OUTREG(src_size_reg, *ss); /* Enable pipe */ OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); @@ -1231,7 +1427,7 @@ #endif OUTREG(DSPACNTR, hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); mdelay(1); - } + } } OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); @@ -1616,7 +1812,7 @@ #if VERBOSE > 0 DBG_MSG("intelfbhw_cursor_init\n"); #endif - if (dinfo->mobile) { + if (dinfo->mobile || IS_I9XX(dinfo)) { if (!dinfo->cursor.physical) return; tmp = INREG(CURSOR_A_CONTROL); @@ -1649,7 +1845,7 @@ #if VERBOSE > 0 #endif dinfo->cursor_on = 0; - if (dinfo->mobile) { + if (dinfo->mobile || IS_I9XX(dinfo)) { if (!dinfo->cursor.physical) return; tmp = INREG(CURSOR_A_CONTROL); @@ -1679,7 +1875,7 @@ #endif if (dinfo->cursor_blanked) return; - if (dinfo->mobile) { + if (dinfo->mobile || IS_I9XX(dinfo)) { if (!dinfo->cursor.physical) return; tmp = INREG(CURSOR_A_CONTROL); @@ -1705,14 +1901,18 @@ #if VERBOSE > 0 #endif /* - * Sets the position. The coordinates are assumed to already - * have any offset adjusted. Assume that the cursor is never + * Sets the position. The coordinates are assumed to already + * have any offset adjusted. Assume that the cursor is never * completely off-screen, and that x, y are always >= 0. */ tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); OUTREG(CURSOR_A_POSITION, tmp); + + if (IS_I9XX(dinfo)) { + OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); + } } void diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h index ba19201..10acda0 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/intelfb/intelfbhw.h @@ -133,6 +133,7 @@ #define DPLL_SYNCLOCK_ENABLE (1 << 29) #define DPLL_VGA_MODE_DISABLE (1 << 28) #define DPLL_P2_MASK 1 #define DPLL_P2_SHIFT 23 +#define DPLL_I9XX_P2_SHIFT 24 #define DPLL_P1_FORCE_DIV2 (1 << 21) #define DPLL_P1_MASK 0x1f #define DPLL_P1_SHIFT 16 @@ -155,29 +156,8 @@ #define FP_M2_DIVISOR_SHIFT 0 /* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */ /* Clock values are in units of kHz */ #define PLL_REFCLK 48000 -#define MIN_VCO_FREQ 930000 -#define MAX_VCO_FREQ 1400000 #define MIN_CLOCK 25000 #define MAX_CLOCK 350000 -#define P_TRANSITION_CLOCK 165000 -#define MIN_M 108 -#define MAX_M 140 -#define MIN_M1 18 -#define MAX_M1 26 -#define MIN_M2 6 -#define MAX_M2 16 -#define MIN_P 4 -#define MAX_P 128 -#define MIN_P1 0 -#define MAX_P1 31 -#define MIN_N 3 -#define MAX_N 16 - -#define CALC_VCLOCK(m1, m2, n, p1, p2) \ - ((PLL_REFCLK * (5 * ((m1) + 2) + ((m2) + 2)) / ((n) + 2)) / \ - (((p1) + 2) * (1 << (p2 + 1)))) - -#define CALC_VCLOCK3(m, n, p) ((PLL_REFCLK * (m) / (n)) / (p)) /* Two pipes */ #define PIPE_A 0 @@ -522,8 +502,7 @@ #define DO_RING_IDLE() do { \ /* function protoypes */ -extern int intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, - int *chipset, int *mobile); +extern int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo); extern int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, int *stolen_size); extern int intelfbhw_check_non_crt(struct intelfb_info *dinfo);