aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-19 21:53:20 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-19 21:53:20 -0400
commitd90125bfe958ed0451c6b98f831c86aba08b43d5 (patch)
tree3a9ea24091f958a92e1d0d12f5135e50adf71b31 /drivers/video
parentbfd189a8e944dd0b8135dea2c23ac399bbe34535 (diff)
parent2abac1db3522d9f56c695d1b42e77f3e52d4c51a (diff)
Merge branch 'i915fb' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/intelfb-2.6
* 'i915fb' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/intelfb-2.6: (25 commits) intelfb: fixup clock calculation debugging. Removed hard coded EDID buffer size. intelfb: use regular modedb table instead of VESA intelfb: use firmware EDID for mode database Revert "intelfb driver -- use the regular modedb table instead of the VESA" intelfb: int option fix sync modesetting code with X.org intelfb: align with changes from my X driver. intelfb driver -- use the regular modedb table instead of the VESA Adds support for 256MB aperture on 945 chipsets to the intelfb driver intelfb -- uses stride alignment of 64 on the 9xx chipsets. intelfb: some cleanups for intelfbhw intelfb: fixup pitch calculation like X does intelfb: fixup p calculation This patch makes a needlessly global struct static. intelfb: add i945GM support intelfb: fixup whitespace.. intelfb: add hw cursor support for i9xx intelfb: make i915 modeset intelfb: add support for i945G ...
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig2
-rw-r--r--drivers/video/intelfb/intelfb.h16
-rw-r--r--drivers/video/intelfb/intelfbdrv.c85
-rw-r--r--drivers/video/intelfb/intelfbhw.c494
-rw-r--r--drivers/video/intelfb/intelfbhw.h25
5 files changed, 412 insertions, 210 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4587087d777a..5641498725d0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -743,7 +743,7 @@ config FB_I810_I2C
743 743
744config FB_INTEL 744config FB_INTEL
745 tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)" 745 tristate "Intel 830M/845G/852GM/855GM/865G support (EXPERIMENTAL)"
746 depends on FB && EXPERIMENTAL && PCI && X86_32 746 depends on FB && EXPERIMENTAL && PCI && X86
747 select AGP 747 select AGP
748 select AGP_INTEL 748 select AGP_INTEL
749 select FB_MODE_HELPERS 749 select FB_MODE_HELPERS
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index da29d007f215..469b06c29180 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -8,9 +8,9 @@
8 8
9 9
10/*** Version/name ***/ 10/*** Version/name ***/
11#define INTELFB_VERSION "0.9.2" 11#define INTELFB_VERSION "0.9.4"
12#define INTELFB_MODULE_NAME "intelfb" 12#define INTELFB_MODULE_NAME "intelfb"
13#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM" 13#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM"
14 14
15 15
16/*** Debug/feature defines ***/ 16/*** Debug/feature defines ***/
@@ -52,11 +52,14 @@
52#define PCI_DEVICE_ID_INTEL_865G 0x2572 52#define PCI_DEVICE_ID_INTEL_865G 0x2572
53#define PCI_DEVICE_ID_INTEL_915G 0x2582 53#define PCI_DEVICE_ID_INTEL_915G 0x2582
54#define PCI_DEVICE_ID_INTEL_915GM 0x2592 54#define PCI_DEVICE_ID_INTEL_915GM 0x2592
55#define PCI_DEVICE_ID_INTEL_945G 0x2772
56#define PCI_DEVICE_ID_INTEL_945GM 0x27A2
55 57
56/* Size of MMIO region */ 58/* Size of MMIO region */
57#define INTEL_REG_SIZE 0x80000 59#define INTEL_REG_SIZE 0x80000
58 60
59#define STRIDE_ALIGNMENT 16 61#define STRIDE_ALIGNMENT 16
62#define STRIDE_ALIGNMENT_I9XX 64
60 63
61#define PALETTE_8_ENTRIES 256 64#define PALETTE_8_ENTRIES 256
62 65
@@ -125,7 +128,9 @@ enum intel_chips {
125 INTEL_855GME, 128 INTEL_855GME,
126 INTEL_865G, 129 INTEL_865G,
127 INTEL_915G, 130 INTEL_915G,
128 INTEL_915GM 131 INTEL_915GM,
132 INTEL_945G,
133 INTEL_945GM,
129}; 134};
130 135
131struct intelfb_hwstate { 136struct intelfb_hwstate {
@@ -277,8 +282,13 @@ struct intelfb_info {
277 282
278 /* driver registered */ 283 /* driver registered */
279 int registered; 284 int registered;
285
286 /* index into plls */
287 int pll_index;
280}; 288};
281 289
290#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM))
291
282/*** function prototypes ***/ 292/*** function prototypes ***/
283 293
284extern int intelfb_var_to_depth(const struct fb_var_screeninfo *var); 294extern 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 995b47c165a7..076fa56be192 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1,11 +1,12 @@
1/* 1/*
2 * intelfb 2 * intelfb
3 * 3 *
4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM 4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
5 * integrated graphics chips. 5 * 945G/945GM integrated graphics chips.
6 * 6 *
7 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> 7 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
8 * 2004 Sylvain Meyer 8 * 2004 Sylvain Meyer
9 * 2006 David Airlie
9 * 10 *
10 * This driver consists of two parts. The first part (intelfbdrv.c) provides 11 * This driver consists of two parts. The first part (intelfbdrv.c) provides
11 * the basic fbdev interfaces, is derived in part from the radeonfb and 12 * the basic fbdev interfaces, is derived in part from the radeonfb and
@@ -131,6 +132,7 @@
131 132
132#include "intelfb.h" 133#include "intelfb.h"
133#include "intelfbhw.h" 134#include "intelfbhw.h"
135#include "../edid.h"
134 136
135static void __devinit get_initial_mode(struct intelfb_info *dinfo); 137static void __devinit get_initial_mode(struct intelfb_info *dinfo);
136static void update_dinfo(struct intelfb_info *dinfo, 138static void update_dinfo(struct intelfb_info *dinfo,
@@ -182,6 +184,8 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
182 { 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 }, 184 { 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 },
183 { 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 }, 185 { 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 },
184 { 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 }, 186 { 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 },
187 { 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 },
188 { 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 },
185 { 0, } 189 { 0, }
186}; 190};
187 191
@@ -261,7 +265,7 @@ MODULE_PARM_DESC(mode,
261 265
262#ifndef MODULE 266#ifndef MODULE
263#define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) 267#define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name)))
264#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name), NULL, 0) 268#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0)
265#define OPT_STRVAL(opt, name) (opt + strlen(name)) 269#define OPT_STRVAL(opt, name) (opt + strlen(name))
266 270
267static __inline__ char * 271static __inline__ char *
@@ -546,11 +550,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
546 550
547 /* Set base addresses. */ 551 /* Set base addresses. */
548 if ((ent->device == PCI_DEVICE_ID_INTEL_915G) || 552 if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
549 (ent->device == PCI_DEVICE_ID_INTEL_915GM)) { 553 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
554 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
555 (ent->device == PCI_DEVICE_ID_INTEL_945GM)) {
550 aperture_bar = 2; 556 aperture_bar = 2;
551 mmio_bar = 0; 557 mmio_bar = 0;
552 /* Disable HW cursor on 915G/M (not implemented yet) */
553 hwcursor = 0;
554 } 558 }
555 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); 559 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
556 dinfo->aperture.size = pci_resource_len(pdev, aperture_bar); 560 dinfo->aperture.size = pci_resource_len(pdev, aperture_bar);
@@ -584,8 +588,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
584 /* Get the chipset info. */ 588 /* Get the chipset info. */
585 dinfo->pci_chipset = pdev->device; 589 dinfo->pci_chipset = pdev->device;
586 590
587 if (intelfbhw_get_chipset(pdev, &dinfo->name, &dinfo->chipset, 591 if (intelfbhw_get_chipset(pdev, dinfo)) {
588 &dinfo->mobile)) {
589 cleanup(dinfo); 592 cleanup(dinfo);
590 return -ENODEV; 593 return -ENODEV;
591 } 594 }
@@ -1029,17 +1032,44 @@ intelfb_init_var(struct intelfb_info *dinfo)
1029 sizeof(struct fb_var_screeninfo)); 1032 sizeof(struct fb_var_screeninfo));
1030 msrc = 5; 1033 msrc = 5;
1031 } else { 1034 } else {
1035 const u8 *edid_s = fb_firmware_edid(&dinfo->pdev->dev);
1036 u8 *edid_d = NULL;
1037
1038 if (edid_s) {
1039 edid_d = kmalloc(EDID_LENGTH, GFP_KERNEL);
1040
1041 if (edid_d) {
1042 memcpy(edid_d, edid_s, EDID_LENGTH);
1043 fb_edid_to_monspecs(edid_d,
1044 &dinfo->info->monspecs);
1045 kfree(edid_d);
1046 }
1047 }
1048
1032 if (mode) { 1049 if (mode) {
1050 printk("intelfb: Looking for mode in private "
1051 "database\n");
1033 msrc = fb_find_mode(var, dinfo->info, mode, 1052 msrc = fb_find_mode(var, dinfo->info, mode,
1034 vesa_modes, VESA_MODEDB_SIZE, 1053 dinfo->info->monspecs.modedb,
1054 dinfo->info->monspecs.modedb_len,
1035 NULL, 0); 1055 NULL, 0);
1036 if (msrc) 1056
1037 msrc |= 8; 1057 if (msrc && msrc > 1) {
1058 printk("intelfb: No mode in private database, "
1059 "intelfb: looking for mode in global "
1060 "database ");
1061 msrc = fb_find_mode(var, dinfo->info, mode,
1062 NULL, 0, NULL, 0);
1063
1064 if (msrc)
1065 msrc |= 8;
1066 }
1067
1038 } 1068 }
1069
1039 if (!msrc) { 1070 if (!msrc) {
1040 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, 1071 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE,
1041 vesa_modes, VESA_MODEDB_SIZE, 1072 NULL, 0, NULL, 0);
1042 NULL, 0);
1043 } 1073 }
1044 } 1074 }
1045 1075
@@ -1139,7 +1169,10 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
1139 } 1169 }
1140 1170
1141 /* Make sure the line length is a aligned correctly. */ 1171 /* Make sure the line length is a aligned correctly. */
1142 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT); 1172 if (IS_I9XX(dinfo))
1173 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX);
1174 else
1175 dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT);
1143 1176
1144 if (FIXED_MODE(dinfo)) 1177 if (FIXED_MODE(dinfo))
1145 dinfo->pitch = dinfo->initial_pitch; 1178 dinfo->pitch = dinfo->initial_pitch;
@@ -1162,16 +1195,33 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1162 struct fb_var_screeninfo v; 1195 struct fb_var_screeninfo v;
1163 struct intelfb_info *dinfo; 1196 struct intelfb_info *dinfo;
1164 static int first = 1; 1197 static int first = 1;
1198 int i;
1199 /* Good pitches to allow tiling. Don't care about pitches < 1024. */
1200 static const int pitches[] = {
1201 128 * 8,
1202 128 * 16,
1203 128 * 32,
1204 128 * 64,
1205 0
1206 };
1165 1207
1166 DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags); 1208 DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags);
1167 1209
1168 dinfo = GET_DINFO(info); 1210 dinfo = GET_DINFO(info);
1169 1211
1212 /* update the pitch */
1170 if (intelfbhw_validate_mode(dinfo, var) != 0) 1213 if (intelfbhw_validate_mode(dinfo, var) != 0)
1171 return -EINVAL; 1214 return -EINVAL;
1172 1215
1173 v = *var; 1216 v = *var;
1174 1217
1218 for (i = 0; pitches[i] != 0; i++) {
1219 if (pitches[i] >= v.xres_virtual) {
1220 v.xres_virtual = pitches[i];
1221 break;
1222 }
1223 }
1224
1175 /* Check for a supported bpp. */ 1225 /* Check for a supported bpp. */
1176 if (v.bits_per_pixel <= 8) { 1226 if (v.bits_per_pixel <= 8) {
1177 v.bits_per_pixel = 8; 1227 v.bits_per_pixel = 8;
@@ -1467,7 +1517,7 @@ static int
1467intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1517intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1468{ 1518{
1469 struct intelfb_info *dinfo = GET_DINFO(info); 1519 struct intelfb_info *dinfo = GET_DINFO(info);
1470 1520 u32 physical;
1471#if VERBOSE > 0 1521#if VERBOSE > 0
1472 DBG_MSG("intelfb_cursor\n"); 1522 DBG_MSG("intelfb_cursor\n");
1473#endif 1523#endif
@@ -1478,7 +1528,10 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1478 intelfbhw_cursor_hide(dinfo); 1528 intelfbhw_cursor_hide(dinfo);
1479 1529
1480 /* If XFree killed the cursor - restore it */ 1530 /* If XFree killed the cursor - restore it */
1481 if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.offset << 12) { 1531 physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical :
1532 (dinfo->cursor.offset << 12);
1533
1534 if (INREG(CURSOR_A_BASEADDR) != physical) {
1482 u32 fg, bg; 1535 u32 fg, bg;
1483 1536
1484 DBG_MSG("the cursor was killed - restore it !!\n"); 1537 DBG_MSG("the cursor was killed - restore it !!\n");
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 624c4bc96f0d..426b7430b125 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -40,68 +40,110 @@
40#include "intelfb.h" 40#include "intelfb.h"
41#include "intelfbhw.h" 41#include "intelfbhw.h"
42 42
43struct pll_min_max {
44 int min_m, max_m, min_m1, max_m1;
45 int min_m2, max_m2, min_n, max_n;
46 int min_p, max_p, min_p1, max_p1;
47 int min_vco, max_vco, p_transition_clk, ref_clk;
48 int p_inc_lo, p_inc_hi;
49};
50
51#define PLLS_I8xx 0
52#define PLLS_I9xx 1
53#define PLLS_MAX 2
54
55static struct pll_min_max plls[PLLS_MAX] = {
56 { 108, 140, 18, 26,
57 6, 16, 3, 16,
58 4, 128, 0, 31,
59 930000, 1400000, 165000, 48000,
60 4, 2 }, //I8xx
61
62 { 75, 120, 10, 20,
63 5, 9, 4, 7,
64 5, 80, 1, 8,
65 1400000, 2800000, 200000, 96000,
66 10, 5 } //I9xx
67};
68
43int 69int
44intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset, 70intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
45 int *mobile)
46{ 71{
47 u32 tmp; 72 u32 tmp;
48 73 if (!pdev || !dinfo)
49 if (!pdev || !name || !chipset || !mobile)
50 return 1; 74 return 1;
51 75
52 switch (pdev->device) { 76 switch (pdev->device) {
53 case PCI_DEVICE_ID_INTEL_830M: 77 case PCI_DEVICE_ID_INTEL_830M:
54 *name = "Intel(R) 830M"; 78 dinfo->name = "Intel(R) 830M";
55 *chipset = INTEL_830M; 79 dinfo->chipset = INTEL_830M;
56 *mobile = 1; 80 dinfo->mobile = 1;
81 dinfo->pll_index = PLLS_I8xx;
57 return 0; 82 return 0;
58 case PCI_DEVICE_ID_INTEL_845G: 83 case PCI_DEVICE_ID_INTEL_845G:
59 *name = "Intel(R) 845G"; 84 dinfo->name = "Intel(R) 845G";
60 *chipset = INTEL_845G; 85 dinfo->chipset = INTEL_845G;
61 *mobile = 0; 86 dinfo->mobile = 0;
87 dinfo->pll_index = PLLS_I8xx;
62 return 0; 88 return 0;
63 case PCI_DEVICE_ID_INTEL_85XGM: 89 case PCI_DEVICE_ID_INTEL_85XGM:
64 tmp = 0; 90 tmp = 0;
65 *mobile = 1; 91 dinfo->mobile = 1;
92 dinfo->pll_index = PLLS_I8xx;
66 pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp); 93 pci_read_config_dword(pdev, INTEL_85X_CAPID, &tmp);
67 switch ((tmp >> INTEL_85X_VARIANT_SHIFT) & 94 switch ((tmp >> INTEL_85X_VARIANT_SHIFT) &
68 INTEL_85X_VARIANT_MASK) { 95 INTEL_85X_VARIANT_MASK) {
69 case INTEL_VAR_855GME: 96 case INTEL_VAR_855GME:
70 *name = "Intel(R) 855GME"; 97 dinfo->name = "Intel(R) 855GME";
71 *chipset = INTEL_855GME; 98 dinfo->chipset = INTEL_855GME;
72 return 0; 99 return 0;
73 case INTEL_VAR_855GM: 100 case INTEL_VAR_855GM:
74 *name = "Intel(R) 855GM"; 101 dinfo->name = "Intel(R) 855GM";
75 *chipset = INTEL_855GM; 102 dinfo->chipset = INTEL_855GM;
76 return 0; 103 return 0;
77 case INTEL_VAR_852GME: 104 case INTEL_VAR_852GME:
78 *name = "Intel(R) 852GME"; 105 dinfo->name = "Intel(R) 852GME";
79 *chipset = INTEL_852GME; 106 dinfo->chipset = INTEL_852GME;
80 return 0; 107 return 0;
81 case INTEL_VAR_852GM: 108 case INTEL_VAR_852GM:
82 *name = "Intel(R) 852GM"; 109 dinfo->name = "Intel(R) 852GM";
83 *chipset = INTEL_852GM; 110 dinfo->chipset = INTEL_852GM;
84 return 0; 111 return 0;
85 default: 112 default:
86 *name = "Intel(R) 852GM/855GM"; 113 dinfo->name = "Intel(R) 852GM/855GM";
87 *chipset = INTEL_85XGM; 114 dinfo->chipset = INTEL_85XGM;
88 return 0; 115 return 0;
89 } 116 }
90 break; 117 break;
91 case PCI_DEVICE_ID_INTEL_865G: 118 case PCI_DEVICE_ID_INTEL_865G:
92 *name = "Intel(R) 865G"; 119 dinfo->name = "Intel(R) 865G";
93 *chipset = INTEL_865G; 120 dinfo->chipset = INTEL_865G;
94 *mobile = 0; 121 dinfo->mobile = 0;
122 dinfo->pll_index = PLLS_I8xx;
95 return 0; 123 return 0;
96 case PCI_DEVICE_ID_INTEL_915G: 124 case PCI_DEVICE_ID_INTEL_915G:
97 *name = "Intel(R) 915G"; 125 dinfo->name = "Intel(R) 915G";
98 *chipset = INTEL_915G; 126 dinfo->chipset = INTEL_915G;
99 *mobile = 0; 127 dinfo->mobile = 0;
128 dinfo->pll_index = PLLS_I9xx;
100 return 0; 129 return 0;
101 case PCI_DEVICE_ID_INTEL_915GM: 130 case PCI_DEVICE_ID_INTEL_915GM:
102 *name = "Intel(R) 915GM"; 131 dinfo->name = "Intel(R) 915GM";
103 *chipset = INTEL_915GM; 132 dinfo->chipset = INTEL_915GM;
104 *mobile = 1; 133 dinfo->mobile = 1;
134 dinfo->pll_index = PLLS_I9xx;
135 return 0;
136 case PCI_DEVICE_ID_INTEL_945G:
137 dinfo->name = "Intel(R) 945G";
138 dinfo->chipset = INTEL_945G;
139 dinfo->mobile = 0;
140 dinfo->pll_index = PLLS_I9xx;
141 return 0;
142 case PCI_DEVICE_ID_INTEL_945GM:
143 dinfo->name = "Intel(R) 945GM";
144 dinfo->chipset = INTEL_945GM;
145 dinfo->mobile = 1;
146 dinfo->pll_index = PLLS_I9xx;
105 return 0; 147 return 0;
106 default: 148 default:
107 return 1; 149 return 1;
@@ -114,6 +156,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
114{ 156{
115 struct pci_dev *bridge_dev; 157 struct pci_dev *bridge_dev;
116 u16 tmp; 158 u16 tmp;
159 int stolen_overhead;
117 160
118 if (!pdev || !aperture_size || !stolen_size) 161 if (!pdev || !aperture_size || !stolen_size)
119 return 1; 162 return 1;
@@ -128,21 +171,41 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
128 tmp = 0; 171 tmp = 0;
129 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); 172 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
130 switch (pdev->device) { 173 switch (pdev->device) {
131 case PCI_DEVICE_ID_INTEL_830M: 174 case PCI_DEVICE_ID_INTEL_915G:
132 case PCI_DEVICE_ID_INTEL_845G: 175 case PCI_DEVICE_ID_INTEL_915GM:
176 case PCI_DEVICE_ID_INTEL_945G:
177 case PCI_DEVICE_ID_INTEL_945GM:
178 /* 915 and 945 chipsets support a 256MB aperture.
179 Aperture size is determined by inspected the
180 base address of the aperture. */
181 if (pci_resource_start(pdev, 2) & 0x08000000)
182 *aperture_size = MB(128);
183 else
184 *aperture_size = MB(256);
185 break;
186 default:
133 if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M) 187 if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
134 *aperture_size = MB(64); 188 *aperture_size = MB(64);
135 else 189 else
136 *aperture_size = MB(128); 190 *aperture_size = MB(128);
191 break;
192 }
193
194 /* Stolen memory size is reduced by the GTT and the popup.
195 GTT is 1K per MB of aperture size, and popup is 4K. */
196 stolen_overhead = (*aperture_size / MB(1)) + 4;
197 switch(pdev->device) {
198 case PCI_DEVICE_ID_INTEL_830M:
199 case PCI_DEVICE_ID_INTEL_845G:
137 switch (tmp & INTEL_830_GMCH_GMS_MASK) { 200 switch (tmp & INTEL_830_GMCH_GMS_MASK) {
138 case INTEL_830_GMCH_GMS_STOLEN_512: 201 case INTEL_830_GMCH_GMS_STOLEN_512:
139 *stolen_size = KB(512) - KB(132); 202 *stolen_size = KB(512) - KB(stolen_overhead);
140 return 0; 203 return 0;
141 case INTEL_830_GMCH_GMS_STOLEN_1024: 204 case INTEL_830_GMCH_GMS_STOLEN_1024:
142 *stolen_size = MB(1) - KB(132); 205 *stolen_size = MB(1) - KB(stolen_overhead);
143 return 0; 206 return 0;
144 case INTEL_830_GMCH_GMS_STOLEN_8192: 207 case INTEL_830_GMCH_GMS_STOLEN_8192:
145 *stolen_size = MB(8) - KB(132); 208 *stolen_size = MB(8) - KB(stolen_overhead);
146 return 0; 209 return 0;
147 case INTEL_830_GMCH_GMS_LOCAL: 210 case INTEL_830_GMCH_GMS_LOCAL:
148 ERR_MSG("only local memory found\n"); 211 ERR_MSG("only local memory found\n");
@@ -157,28 +220,27 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
157 } 220 }
158 break; 221 break;
159 default: 222 default:
160 *aperture_size = MB(128);
161 switch (tmp & INTEL_855_GMCH_GMS_MASK) { 223 switch (tmp & INTEL_855_GMCH_GMS_MASK) {
162 case INTEL_855_GMCH_GMS_STOLEN_1M: 224 case INTEL_855_GMCH_GMS_STOLEN_1M:
163 *stolen_size = MB(1) - KB(132); 225 *stolen_size = MB(1) - KB(stolen_overhead);
164 return 0; 226 return 0;
165 case INTEL_855_GMCH_GMS_STOLEN_4M: 227 case INTEL_855_GMCH_GMS_STOLEN_4M:
166 *stolen_size = MB(4) - KB(132); 228 *stolen_size = MB(4) - KB(stolen_overhead);
167 return 0; 229 return 0;
168 case INTEL_855_GMCH_GMS_STOLEN_8M: 230 case INTEL_855_GMCH_GMS_STOLEN_8M:
169 *stolen_size = MB(8) - KB(132); 231 *stolen_size = MB(8) - KB(stolen_overhead);
170 return 0; 232 return 0;
171 case INTEL_855_GMCH_GMS_STOLEN_16M: 233 case INTEL_855_GMCH_GMS_STOLEN_16M:
172 *stolen_size = MB(16) - KB(132); 234 *stolen_size = MB(16) - KB(stolen_overhead);
173 return 0; 235 return 0;
174 case INTEL_855_GMCH_GMS_STOLEN_32M: 236 case INTEL_855_GMCH_GMS_STOLEN_32M:
175 *stolen_size = MB(32) - KB(132); 237 *stolen_size = MB(32) - KB(stolen_overhead);
176 return 0; 238 return 0;
177 case INTEL_915G_GMCH_GMS_STOLEN_48M: 239 case INTEL_915G_GMCH_GMS_STOLEN_48M:
178 *stolen_size = MB(48) - KB(132); 240 *stolen_size = MB(48) - KB(stolen_overhead);
179 return 0; 241 return 0;
180 case INTEL_915G_GMCH_GMS_STOLEN_64M: 242 case INTEL_915G_GMCH_GMS_STOLEN_64M:
181 *stolen_size = MB(64) - KB(132); 243 *stolen_size = MB(64) - KB(stolen_overhead);
182 return 0; 244 return 0;
183 case INTEL_855_GMCH_GMS_DISABLED: 245 case INTEL_855_GMCH_GMS_DISABLED:
184 ERR_MSG("video memory is disabled\n"); 246 ERR_MSG("video memory is disabled\n");
@@ -529,12 +591,63 @@ intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
529} 591}
530 592
531 593
594static int calc_vclock3(int index, int m, int n, int p)
595{
596 if (p == 0 || n == 0)
597 return 0;
598 return plls[index].ref_clk * m / n / p;
599}
600
601static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds)
602{
603 struct pll_min_max *pll = &plls[index];
604 u32 m, vco, p;
605
606 m = (5 * (m1 + 2)) + (m2 + 2);
607 n += 2;
608 vco = pll->ref_clk * m / n;
609
610 if (index == PLLS_I8xx) {
611 p = ((p1 + 2) * (1 << (p2 + 1)));
612 } else {
613 p = ((p1) * (p2 ? 5 : 10));
614 }
615 return vco / p;
616}
617
618static void
619intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
620{
621 int p1, p2;
622
623 if (IS_I9XX(dinfo)) {
624 if (dpll & DPLL_P1_FORCE_DIV2)
625 p1 = 1;
626 else
627 p1 = (dpll >> DPLL_P1_SHIFT) & 0xff;
628
629 p1 = ffs(p1);
630
631 p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK;
632 } else {
633 if (dpll & DPLL_P1_FORCE_DIV2)
634 p1 = 0;
635 else
636 p1 = (dpll >> DPLL_P1_SHIFT) & DPLL_P1_MASK;
637 p2 = (dpll >> DPLL_P2_SHIFT) & DPLL_P2_MASK;
638 }
639
640 *o_p1 = p1;
641 *o_p2 = p2;
642}
643
644
532void 645void
533intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) 646intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
534{ 647{
535#if REGDUMP 648#if REGDUMP
536 int i, m1, m2, n, p1, p2; 649 int i, m1, m2, n, p1, p2;
537 650 int index = dinfo->pll_index;
538 DBG_MSG("intelfbhw_print_hw_state\n"); 651 DBG_MSG("intelfbhw_print_hw_state\n");
539 652
540 if (!hw || !dinfo) 653 if (!hw || !dinfo)
@@ -547,26 +660,22 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
547 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 660 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
548 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 661 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
549 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 662 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
550 if (hw->vga_pd & VGAPD_0_P1_FORCE_DIV2) 663
551 p1 = 0; 664 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
552 else 665
553 p1 = (hw->vga_pd >> VGAPD_0_P1_SHIFT) & DPLL_P1_MASK;
554 p2 = (hw->vga_pd >> VGAPD_0_P2_SHIFT) & DPLL_P2_MASK;
555 printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 666 printk(" VGA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
556 m1, m2, n, p1, p2); 667 m1, m2, n, p1, p2);
557 printk(" VGA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 668 printk(" VGA0: clock is %d\n",
669 calc_vclock(index, m1, m2, n, p1, p2, 0));
558 670
559 n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 671 n = (hw->vga1_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
560 m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 672 m1 = (hw->vga1_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
561 m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 673 m2 = (hw->vga1_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
562 if (hw->vga_pd & VGAPD_1_P1_FORCE_DIV2) 674
563 p1 = 0; 675 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
564 else
565 p1 = (hw->vga_pd >> VGAPD_1_P1_SHIFT) & DPLL_P1_MASK;
566 p2 = (hw->vga_pd >> VGAPD_1_P2_SHIFT) & DPLL_P2_MASK;
567 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 676 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
568 m1, m2, n, p1, p2); 677 m1, m2, n, p1, p2);
569 printk(" VGA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 678 printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0));
570 679
571 printk(" DPLL_A: 0x%08x\n", hw->dpll_a); 680 printk(" DPLL_A: 0x%08x\n", hw->dpll_a);
572 printk(" DPLL_B: 0x%08x\n", hw->dpll_b); 681 printk(" DPLL_B: 0x%08x\n", hw->dpll_b);
@@ -578,34 +687,30 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
578 n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 687 n = (hw->fpa0 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
579 m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 688 m1 = (hw->fpa0 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
580 m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 689 m2 = (hw->fpa0 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
581 if (hw->dpll_a & DPLL_P1_FORCE_DIV2) 690
582 p1 = 0; 691 intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2);
583 else 692
584 p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK;
585 p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK;
586 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 693 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
587 m1, m2, n, p1, p2); 694 m1, m2, n, p1, p2);
588 printk(" PLLA0: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 695 printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0));
589 696
590 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 697 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
591 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 698 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
592 m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 699 m2 = (hw->fpa1 >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
593 if (hw->dpll_a & DPLL_P1_FORCE_DIV2) 700
594 p1 = 0; 701 intelfbhw_get_p1p2(dinfo, hw->dpll_a, &p1, &p2);
595 else 702
596 p1 = (hw->dpll_a >> DPLL_P1_SHIFT) & DPLL_P1_MASK;
597 p2 = (hw->dpll_a >> DPLL_P2_SHIFT) & DPLL_P2_MASK;
598 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 703 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
599 m1, m2, n, p1, p2); 704 m1, m2, n, p1, p2);
600 printk(" PLLA1: clock is %d\n", CALC_VCLOCK(m1, m2, n, p1, p2)); 705 printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0));
601 706
602#if 0 707#if 0
603 printk(" PALETTE_A:\n"); 708 printk(" PALETTE_A:\n");
604 for (i = 0; i < PALETTE_8_ENTRIES) 709 for (i = 0; i < PALETTE_8_ENTRIES)
605 printk(" %3d: 0x%08x\n", i, hw->palette_a[i]; 710 printk(" %3d: 0x%08x\n", i, hw->palette_a[i]);
606 printk(" PALETTE_B:\n"); 711 printk(" PALETTE_B:\n");
607 for (i = 0; i < PALETTE_8_ENTRIES) 712 for (i = 0; i < PALETTE_8_ENTRIES)
608 printk(" %3d: 0x%08x\n", i, hw->palette_b[i]; 713 printk(" %3d: 0x%08x\n", i, hw->palette_b[i]);
609#endif 714#endif
610 715
611 printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a); 716 printk(" HTOTAL_A: 0x%08x\n", hw->htotal_a);
@@ -680,11 +785,11 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
680 } 785 }
681 for (i = 0; i < 3; i++) { 786 for (i = 0; i < 3; i++) {
682 printk(" SWF3%d 0x%08x\n", i, 787 printk(" SWF3%d 0x%08x\n", i,
683 hw->swf3x[i]); 788 hw->swf3x[i]);
684 } 789 }
685 for (i = 0; i < 8; i++) 790 for (i = 0; i < 8; i++)
686 printk(" FENCE%d 0x%08x\n", i, 791 printk(" FENCE%d 0x%08x\n", i,
687 hw->fence[i]); 792 hw->fence[i]);
688 793
689 printk(" INSTPM 0x%08x\n", hw->instpm); 794 printk(" INSTPM 0x%08x\n", hw->instpm);
690 printk(" MEM_MODE 0x%08x\n", hw->mem_mode); 795 printk(" MEM_MODE 0x%08x\n", hw->mem_mode);
@@ -695,43 +800,58 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
695#endif 800#endif
696} 801}
697 802
803
804
698/* Split the M parameter into M1 and M2. */ 805/* Split the M parameter into M1 and M2. */
699static int 806static int
700splitm(unsigned int m, unsigned int *retm1, unsigned int *retm2) 807splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2)
701{ 808{
702 int m1, m2; 809 int m1, m2;
703 810 int testm;
704 m1 = (m - 2 - (MIN_M2 + MAX_M2) / 2) / 5 - 2; 811 struct pll_min_max *pll = &plls[index];
705 if (m1 < MIN_M1) 812
706 m1 = MIN_M1; 813 /* no point optimising too much - brute force m */
707 if (m1 > MAX_M1) 814 for (m1 = pll->min_m1; m1 < pll->max_m1 + 1; m1++) {
708 m1 = MAX_M1; 815 for (m2 = pll->min_m2; m2 < pll->max_m2 + 1; m2++) {
709 m2 = m - 5 * (m1 + 2) - 2; 816 testm = (5 * (m1 + 2)) + (m2 + 2);
710 if (m2 < MIN_M2 || m2 > MAX_M2 || m2 >= m1) { 817 if (testm == m) {
711 return 1; 818 *retm1 = (unsigned int)m1;
712 } else { 819 *retm2 = (unsigned int)m2;
713 *retm1 = (unsigned int)m1; 820 return 0;
714 *retm2 = (unsigned int)m2; 821 }
715 return 0; 822 }
716 } 823 }
824 return 1;
717} 825}
718 826
719/* Split the P parameter into P1 and P2. */ 827/* Split the P parameter into P1 and P2. */
720static int 828static int
721splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2) 829splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
722{ 830{
723 int p1, p2; 831 int p1, p2;
832 struct pll_min_max *pll = &plls[index];
833
834 if (index == PLLS_I9xx) {
835 p2 = (p % 10) ? 1 : 0;
836
837 p1 = p / (p2 ? 5 : 10);
838
839 *retp1 = (unsigned int)p1;
840 *retp2 = (unsigned int)p2;
841 return 0;
842 }
724 843
725 if (p % 4 == 0) 844 if (p % 4 == 0)
726 p2 = 1; 845 p2 = 1;
727 else 846 else
728 p2 = 0; 847 p2 = 0;
729 p1 = (p / (1 << (p2 + 1))) - 2; 848 p1 = (p / (1 << (p2 + 1))) - 2;
730 if (p % 4 == 0 && p1 < MIN_P1) { 849 if (p % 4 == 0 && p1 < pll->min_p1) {
731 p2 = 0; 850 p2 = 0;
732 p1 = (p / (1 << (p2 + 1))) - 2; 851 p1 = (p / (1 << (p2 + 1))) - 2;
733 } 852 }
734 if (p1 < MIN_P1 || p1 > MAX_P1 || (p1 + 2) * (1 << (p2 + 1)) != p) { 853 if (p1 < pll->min_p1 || p1 > pll->max_p1 ||
854 (p1 + 2) * (1 << (p2 + 1)) != p) {
735 return 1; 855 return 1;
736 } else { 856 } else {
737 *retp1 = (unsigned int)p1; 857 *retp1 = (unsigned int)p1;
@@ -741,14 +861,15 @@ splitp(unsigned int p, unsigned int *retp1, unsigned int *retp2)
741} 861}
742 862
743static int 863static int
744calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, 864calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
745 u32 *retp2, u32 *retclock) 865 u32 *retp2, u32 *retclock)
746{ 866{
747 u32 m1, m2, n, p1, p2, n1; 867 u32 m1, m2, n, p1, p2, n1, testm;
748 u32 f_vco, p, p_best = 0, m, f_out; 868 u32 f_vco, p, p_best = 0, m, f_out = 0;
749 u32 err_max, err_target, err_best = 10000000; 869 u32 err_max, err_target, err_best = 10000000;
750 u32 n_best = 0, m_best = 0, f_best, f_err; 870 u32 n_best = 0, m_best = 0, f_best, f_err;
751 u32 p_min, p_max, p_inc, div_min, div_max; 871 u32 p_min, p_max, p_inc, div_max;
872 struct pll_min_max *pll = &plls[index];
752 873
753 /* Accept 0.5% difference, but aim for 0.1% */ 874 /* Accept 0.5% difference, but aim for 0.1% */
754 err_max = 5 * clock / 1000; 875 err_max = 5 * clock / 1000;
@@ -756,58 +877,56 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
756 877
757 DBG_MSG("Clock is %d\n", clock); 878 DBG_MSG("Clock is %d\n", clock);
758 879
759 div_max = MAX_VCO_FREQ / clock; 880 div_max = pll->max_vco / clock;
760 div_min = ROUND_UP_TO(MIN_VCO_FREQ, clock) / clock;
761 881
762 if (clock <= P_TRANSITION_CLOCK) 882 p_inc = (clock <= pll->p_transition_clk) ? pll->p_inc_lo : pll->p_inc_hi;
763 p_inc = 4; 883 p_min = p_inc;
764 else
765 p_inc = 2;
766 p_min = ROUND_UP_TO(div_min, p_inc);
767 p_max = ROUND_DOWN_TO(div_max, p_inc); 884 p_max = ROUND_DOWN_TO(div_max, p_inc);
768 if (p_min < MIN_P) 885 if (p_min < pll->min_p)
769 p_min = 4; 886 p_min = pll->min_p;
770 if (p_max > MAX_P) 887 if (p_max > pll->max_p)
771 p_max = 128; 888 p_max = pll->max_p;
772 889
773 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc); 890 DBG_MSG("p range is %d-%d (%d)\n", p_min, p_max, p_inc);
774 891
775 p = p_min; 892 p = p_min;
776 do { 893 do {
777 if (splitp(p, &p1, &p2)) { 894 if (splitp(index, p, &p1, &p2)) {
778 WRN_MSG("cannot split p = %d\n", p); 895 WRN_MSG("cannot split p = %d\n", p);
779 p += p_inc; 896 p += p_inc;
780 continue; 897 continue;
781 } 898 }
782 n = MIN_N; 899 n = pll->min_n;
783 f_vco = clock * p; 900 f_vco = clock * p;
784 901
785 do { 902 do {
786 m = ROUND_UP_TO(f_vco * n, PLL_REFCLK) / PLL_REFCLK; 903 m = ROUND_UP_TO(f_vco * n, pll->ref_clk) / pll->ref_clk;
787 if (m < MIN_M) 904 if (m < pll->min_m)
788 m = MIN_M; 905 m = pll->min_m + 1;
789 if (m > MAX_M) 906 if (m > pll->max_m)
790 m = MAX_M; 907 m = pll->max_m - 1;
791 f_out = CALC_VCLOCK3(m, n, p); 908 for (testm = m - 1; testm <= m; testm++) {
792 if (splitm(m, &m1, &m2)) { 909 f_out = calc_vclock3(index, m, n, p);
793 WRN_MSG("cannot split m = %d\n", m); 910 if (splitm(index, testm, &m1, &m2)) {
794 n++; 911 WRN_MSG("cannot split m = %d\n", m);
795 continue; 912 n++;
796 } 913 continue;
797 if (clock > f_out) 914 }
798 f_err = clock - f_out; 915 if (clock > f_out)
799 else 916 f_err = clock - f_out;
800 f_err = f_out - clock; 917 else/* slightly bias the error for bigger clocks */
801 918 f_err = f_out - clock + 1;
802 if (f_err < err_best) { 919
803 m_best = m; 920 if (f_err < err_best) {
804 n_best = n; 921 m_best = testm;
805 p_best = p; 922 n_best = n;
806 f_best = f_out; 923 p_best = p;
807 err_best = f_err; 924 f_best = f_out;
925 err_best = f_err;
926 }
808 } 927 }
809 n++; 928 n++;
810 } while ((n <= MAX_N) && (f_out >= clock)); 929 } while ((n <= pll->max_n) && (f_out >= clock));
811 p += p_inc; 930 p += p_inc;
812 } while ((p <= p_max)); 931 } while ((p <= p_max));
813 932
@@ -818,21 +937,22 @@ calc_pll_params(int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1,
818 m = m_best; 937 m = m_best;
819 n = n_best; 938 n = n_best;
820 p = p_best; 939 p = p_best;
821 splitm(m, &m1, &m2); 940 splitm(index, m, &m1, &m2);
822 splitp(p, &p1, &p2); 941 splitp(index, p, &p1, &p2);
823 n1 = n - 2; 942 n1 = n - 2;
824 943
825 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), " 944 DBG_MSG("m, n, p: %d (%d,%d), %d (%d), %d (%d,%d), "
826 "f: %d (%d), VCO: %d\n", 945 "f: %d (%d), VCO: %d\n",
827 m, m1, m2, n, n1, p, p1, p2, 946 m, m1, m2, n, n1, p, p1, p2,
828 CALC_VCLOCK3(m, n, p), CALC_VCLOCK(m1, m2, n1, p1, p2), 947 calc_vclock3(index, m, n, p),
829 CALC_VCLOCK3(m, n, p) * p); 948 calc_vclock(index, m1, m2, n1, p1, p2, 0),
949 calc_vclock3(index, m, n, p) * p);
830 *retm1 = m1; 950 *retm1 = m1;
831 *retm2 = m2; 951 *retm2 = m2;
832 *retn = n1; 952 *retn = n1;
833 *retp1 = p1; 953 *retp1 = p1;
834 *retp2 = p2; 954 *retp2 = p2;
835 *retclock = CALC_VCLOCK(m1, m2, n1, p1, p2); 955 *retclock = calc_vclock(index, m1, m2, n1, p1, p2, 0);
836 956
837 return 0; 957 return 0;
838} 958}
@@ -860,6 +980,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
860 u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive; 980 u32 vsync_start, vsync_end, vblank_start, vblank_end, vtotal, vactive;
861 u32 vsync_pol, hsync_pol; 981 u32 vsync_pol, hsync_pol;
862 u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf; 982 u32 *vs, *vb, *vt, *hs, *hb, *ht, *ss, *pipe_conf;
983 u32 stride_alignment;
863 984
864 DBG_MSG("intelfbhw_mode_to_hw\n"); 985 DBG_MSG("intelfbhw_mode_to_hw\n");
865 986
@@ -929,7 +1050,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
929 /* Desired clock in kHz */ 1050 /* Desired clock in kHz */
930 clock_target = 1000000000 / var->pixclock; 1051 clock_target = 1000000000 / var->pixclock;
931 1052
932 if (calc_pll_params(clock_target, &m1, &m2, &n, &p1, &p2, &clock)) { 1053 if (calc_pll_params(dinfo->pll_index, clock_target, &m1, &m2,
1054 &n, &p1, &p2, &clock)) {
933 WRN_MSG("calc_pll_params failed\n"); 1055 WRN_MSG("calc_pll_params failed\n");
934 return 1; 1056 return 1;
935 } 1057 }
@@ -949,7 +1071,14 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
949 *dpll &= ~DPLL_P1_FORCE_DIV2; 1071 *dpll &= ~DPLL_P1_FORCE_DIV2;
950 *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) | 1072 *dpll &= ~((DPLL_P2_MASK << DPLL_P2_SHIFT) |
951 (DPLL_P1_MASK << DPLL_P1_SHIFT)); 1073 (DPLL_P1_MASK << DPLL_P1_SHIFT));
952 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); 1074
1075 if (IS_I9XX(dinfo)) {
1076 *dpll |= (p2 << DPLL_I9XX_P2_SHIFT);
1077 *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT;
1078 } else {
1079 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT);
1080 }
1081
953 *fp0 = (n << FP_N_DIVISOR_SHIFT) | 1082 *fp0 = (n << FP_N_DIVISOR_SHIFT) |
954 (m1 << FP_M1_DIVISOR_SHIFT) | 1083 (m1 << FP_M1_DIVISOR_SHIFT) |
955 (m2 << FP_M2_DIVISOR_SHIFT); 1084 (m2 << FP_M2_DIVISOR_SHIFT);
@@ -1054,7 +1183,7 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1054 *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) | 1183 *ss = (hactive << SRC_SIZE_HORIZ_SHIFT) |
1055 (vactive << SRC_SIZE_VERT_SHIFT); 1184 (vactive << SRC_SIZE_VERT_SHIFT);
1056 1185
1057 hw->disp_a_stride = var->xres_virtual * var->bits_per_pixel / 8; 1186 hw->disp_a_stride = dinfo->pitch;
1058 DBG_MSG("pitch is %d\n", hw->disp_a_stride); 1187 DBG_MSG("pitch is %d\n", hw->disp_a_stride);
1059 1188
1060 hw->disp_a_base = hw->disp_a_stride * var->yoffset + 1189 hw->disp_a_base = hw->disp_a_stride * var->yoffset +
@@ -1063,9 +1192,11 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1063 hw->disp_a_base += dinfo->fb.offset << 12; 1192 hw->disp_a_base += dinfo->fb.offset << 12;
1064 1193
1065 /* Check stride alignment. */ 1194 /* Check stride alignment. */
1066 if (hw->disp_a_stride % STRIDE_ALIGNMENT != 0) { 1195 stride_alignment = IS_I9XX(dinfo) ? STRIDE_ALIGNMENT_I9XX :
1196 STRIDE_ALIGNMENT;
1197 if (hw->disp_a_stride % stride_alignment != 0) {
1067 WRN_MSG("display stride %d has bad alignment %d\n", 1198 WRN_MSG("display stride %d has bad alignment %d\n",
1068 hw->disp_a_stride, STRIDE_ALIGNMENT); 1199 hw->disp_a_stride, stride_alignment);
1069 return 1; 1200 return 1;
1070 } 1201 }
1071 1202
@@ -1087,6 +1218,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1087 u32 hsync_reg, htotal_reg, hblank_reg; 1218 u32 hsync_reg, htotal_reg, hblank_reg;
1088 u32 vsync_reg, vtotal_reg, vblank_reg; 1219 u32 vsync_reg, vtotal_reg, vblank_reg;
1089 u32 src_size_reg; 1220 u32 src_size_reg;
1221 u32 count, tmp_val[3];
1090 1222
1091 /* Assume single pipe, display plane A, analog CRT. */ 1223 /* Assume single pipe, display plane A, analog CRT. */
1092 1224
@@ -1155,6 +1287,27 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1155 src_size_reg = SRC_SIZE_A; 1287 src_size_reg = SRC_SIZE_A;
1156 } 1288 }
1157 1289
1290 /* turn off pipe */
1291 tmp = INREG(pipe_conf_reg);
1292 tmp &= ~PIPECONF_ENABLE;
1293 OUTREG(pipe_conf_reg, tmp);
1294
1295 count = 0;
1296 do {
1297 tmp_val[count%3] = INREG(0x70000);
1298 if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2]))
1299 break;
1300 count++;
1301 udelay(1);
1302 if (count % 200 == 0) {
1303 tmp = INREG(pipe_conf_reg);
1304 tmp &= ~PIPECONF_ENABLE;
1305 OUTREG(pipe_conf_reg, tmp);
1306 }
1307 } while(count < 2000);
1308
1309 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
1310
1158 /* Disable planes A and B. */ 1311 /* Disable planes A and B. */
1159 tmp = INREG(DSPACNTR); 1312 tmp = INREG(DSPACNTR);
1160 tmp &= ~DISPPLANE_PLANE_ENABLE; 1313 tmp &= ~DISPPLANE_PLANE_ENABLE;
@@ -1163,19 +1316,21 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1163 tmp &= ~DISPPLANE_PLANE_ENABLE; 1316 tmp &= ~DISPPLANE_PLANE_ENABLE;
1164 OUTREG(DSPBCNTR, tmp); 1317 OUTREG(DSPBCNTR, tmp);
1165 1318
1166 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */ 1319 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
1167 mdelay(20); 1320 mdelay(20);
1168 1321
1322 OUTREG(DVOB, INREG(DVOB) & ~PORT_ENABLE);
1323 OUTREG(DVOC, INREG(DVOC) & ~PORT_ENABLE);
1324 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
1325
1169 /* Disable Sync */ 1326 /* Disable Sync */
1170 tmp = INREG(ADPA); 1327 tmp = INREG(ADPA);
1171 tmp &= ~ADPA_DPMS_CONTROL_MASK; 1328 tmp &= ~ADPA_DPMS_CONTROL_MASK;
1172 tmp |= ADPA_DPMS_D3; 1329 tmp |= ADPA_DPMS_D3;
1173 OUTREG(ADPA, tmp); 1330 OUTREG(ADPA, tmp);
1174 1331
1175 /* turn off pipe */ 1332 /* do some funky magic - xyzzy */
1176 tmp = INREG(pipe_conf_reg); 1333 OUTREG(0x61204, 0xabcd0000);
1177 tmp &= ~PIPECONF_ENABLE;
1178 OUTREG(pipe_conf_reg, tmp);
1179 1334
1180 /* turn off PLL */ 1335 /* turn off PLL */
1181 tmp = INREG(dpll_reg); 1336 tmp = INREG(dpll_reg);
@@ -1183,30 +1338,31 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1183 OUTREG(dpll_reg, tmp); 1338 OUTREG(dpll_reg, tmp);
1184 1339
1185 /* Set PLL parameters */ 1340 /* Set PLL parameters */
1186 OUTREG(dpll_reg, *dpll & ~DPLL_VCO_ENABLE);
1187 OUTREG(fp0_reg, *fp0); 1341 OUTREG(fp0_reg, *fp0);
1188 OUTREG(fp1_reg, *fp1); 1342 OUTREG(fp1_reg, *fp1);
1189 1343
1190 /* Set pipe parameters */ 1344 /* Enable PLL */
1191 OUTREG(hsync_reg, *hs); 1345 OUTREG(dpll_reg, *dpll);
1192 OUTREG(hblank_reg, *hb);
1193 OUTREG(htotal_reg, *ht);
1194 OUTREG(vsync_reg, *vs);
1195 OUTREG(vblank_reg, *vb);
1196 OUTREG(vtotal_reg, *vt);
1197 OUTREG(src_size_reg, *ss);
1198 1346
1199 /* Set DVOs B/C */ 1347 /* Set DVOs B/C */
1200 OUTREG(DVOB, hw->dvob); 1348 OUTREG(DVOB, hw->dvob);
1201 OUTREG(DVOC, hw->dvoc); 1349 OUTREG(DVOC, hw->dvoc);
1202 1350
1351 /* undo funky magic */
1352 OUTREG(0x61204, 0x00000000);
1353
1203 /* Set ADPA */ 1354 /* Set ADPA */
1355 OUTREG(ADPA, INREG(ADPA) | ADPA_DAC_ENABLE);
1204 OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3); 1356 OUTREG(ADPA, (hw->adpa & ~(ADPA_DPMS_CONTROL_MASK)) | ADPA_DPMS_D3);
1205 1357
1206 /* Enable PLL */ 1358 /* Set pipe parameters */
1207 tmp = INREG(dpll_reg); 1359 OUTREG(hsync_reg, *hs);
1208 tmp |= DPLL_VCO_ENABLE; 1360 OUTREG(hblank_reg, *hb);
1209 OUTREG(dpll_reg, tmp); 1361 OUTREG(htotal_reg, *ht);
1362 OUTREG(vsync_reg, *vs);
1363 OUTREG(vblank_reg, *vb);
1364 OUTREG(vtotal_reg, *vt);
1365 OUTREG(src_size_reg, *ss);
1210 1366
1211 /* Enable pipe */ 1367 /* Enable pipe */
1212 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); 1368 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE);
@@ -1231,7 +1387,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1231 OUTREG(DSPACNTR, 1387 OUTREG(DSPACNTR,
1232 hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE); 1388 hw->disp_a_ctrl|DISPPLANE_PLANE_ENABLE);
1233 mdelay(1); 1389 mdelay(1);
1234 } 1390 }
1235 } 1391 }
1236 1392
1237 OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE); 1393 OUTREG(DSPACNTR, hw->disp_a_ctrl & ~DISPPLANE_PLANE_ENABLE);
@@ -1616,7 +1772,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo)
1616 DBG_MSG("intelfbhw_cursor_init\n"); 1772 DBG_MSG("intelfbhw_cursor_init\n");
1617#endif 1773#endif
1618 1774
1619 if (dinfo->mobile) { 1775 if (dinfo->mobile || IS_I9XX(dinfo)) {
1620 if (!dinfo->cursor.physical) 1776 if (!dinfo->cursor.physical)
1621 return; 1777 return;
1622 tmp = INREG(CURSOR_A_CONTROL); 1778 tmp = INREG(CURSOR_A_CONTROL);
@@ -1649,7 +1805,7 @@ intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1649#endif 1805#endif
1650 1806
1651 dinfo->cursor_on = 0; 1807 dinfo->cursor_on = 0;
1652 if (dinfo->mobile) { 1808 if (dinfo->mobile || IS_I9XX(dinfo)) {
1653 if (!dinfo->cursor.physical) 1809 if (!dinfo->cursor.physical)
1654 return; 1810 return;
1655 tmp = INREG(CURSOR_A_CONTROL); 1811 tmp = INREG(CURSOR_A_CONTROL);
@@ -1679,7 +1835,7 @@ intelfbhw_cursor_show(struct intelfb_info *dinfo)
1679 if (dinfo->cursor_blanked) 1835 if (dinfo->cursor_blanked)
1680 return; 1836 return;
1681 1837
1682 if (dinfo->mobile) { 1838 if (dinfo->mobile || IS_I9XX(dinfo)) {
1683 if (!dinfo->cursor.physical) 1839 if (!dinfo->cursor.physical)
1684 return; 1840 return;
1685 tmp = INREG(CURSOR_A_CONTROL); 1841 tmp = INREG(CURSOR_A_CONTROL);
@@ -1705,14 +1861,18 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1705#endif 1861#endif
1706 1862
1707 /* 1863 /*
1708 * Sets the position. The coordinates are assumed to already 1864 * Sets the position. The coordinates are assumed to already
1709 * have any offset adjusted. Assume that the cursor is never 1865 * have any offset adjusted. Assume that the cursor is never
1710 * completely off-screen, and that x, y are always >= 0. 1866 * completely off-screen, and that x, y are always >= 0.
1711 */ 1867 */
1712 1868
1713 tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | 1869 tmp = ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) |
1714 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); 1870 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1715 OUTREG(CURSOR_A_POSITION, tmp); 1871 OUTREG(CURSOR_A_POSITION, tmp);
1872
1873 if (IS_I9XX(dinfo)) {
1874 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1875 }
1716} 1876}
1717 1877
1718void 1878void
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h
index ba1920159f52..10acda098b71 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/intelfb/intelfbhw.h
@@ -133,6 +133,7 @@
133#define DPLL_VGA_MODE_DISABLE (1 << 28) 133#define DPLL_VGA_MODE_DISABLE (1 << 28)
134#define DPLL_P2_MASK 1 134#define DPLL_P2_MASK 1
135#define DPLL_P2_SHIFT 23 135#define DPLL_P2_SHIFT 23
136#define DPLL_I9XX_P2_SHIFT 24
136#define DPLL_P1_FORCE_DIV2 (1 << 21) 137#define DPLL_P1_FORCE_DIV2 (1 << 21)
137#define DPLL_P1_MASK 0x1f 138#define DPLL_P1_MASK 0x1f
138#define DPLL_P1_SHIFT 16 139#define DPLL_P1_SHIFT 16
@@ -155,29 +156,8 @@
155/* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */ 156/* PLL parameters (these are for 852GM/855GM/865G, check earlier chips). */
156/* Clock values are in units of kHz */ 157/* Clock values are in units of kHz */
157#define PLL_REFCLK 48000 158#define PLL_REFCLK 48000
158#define MIN_VCO_FREQ 930000
159#define MAX_VCO_FREQ 1400000
160#define MIN_CLOCK 25000 159#define MIN_CLOCK 25000
161#define MAX_CLOCK 350000 160#define MAX_CLOCK 350000
162#define P_TRANSITION_CLOCK 165000
163#define MIN_M 108
164#define MAX_M 140
165#define MIN_M1 18
166#define MAX_M1 26
167#define MIN_M2 6
168#define MAX_M2 16
169#define MIN_P 4
170#define MAX_P 128
171#define MIN_P1 0
172#define MAX_P1 31
173#define MIN_N 3
174#define MAX_N 16
175
176#define CALC_VCLOCK(m1, m2, n, p1, p2) \
177 ((PLL_REFCLK * (5 * ((m1) + 2) + ((m2) + 2)) / ((n) + 2)) / \
178 (((p1) + 2) * (1 << (p2 + 1))))
179
180#define CALC_VCLOCK3(m, n, p) ((PLL_REFCLK * (m) / (n)) / (p))
181 161
182/* Two pipes */ 162/* Two pipes */
183#define PIPE_A 0 163#define PIPE_A 0
@@ -522,8 +502,7 @@
522 502
523 503
524/* function protoypes */ 504/* function protoypes */
525extern int intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, 505extern int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo);
526 int *chipset, int *mobile);
527extern int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 506extern int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
528 int *stolen_size); 507 int *stolen_size);
529extern int intelfbhw_check_non_crt(struct intelfb_info *dinfo); 508extern int intelfbhw_check_non_crt(struct intelfb_info *dinfo);