aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/intelfb/intelfbhw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/intelfb/intelfbhw.c')
-rw-r--r--drivers/video/intelfb/intelfbhw.c494
1 files changed, 327 insertions, 167 deletions
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