Annotation of /trunk/xorg-old/patches-6.8.2-r10/5160_all_6.8.1-benh-radeon-ppc-fixes-v2.patch
Parent Directory | Revision Log
Revision 167 -
(hide annotations)
(download)
Tue May 8 20:58:51 2007 UTC (17 years, 4 months ago) by niro
File size: 27590 byte(s)
Tue May 8 20:58:51 2007 UTC (17 years, 4 months ago) by niro
File size: 27590 byte(s)
-import
1 | niro | 167 | diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h |
2 | --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h 2005-01-13 21:41:05.000000000 -0800 | ||
3 | +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h 2005-01-13 21:50:45.919826968 -0800 | ||
4 | @@ -598,6 +598,7 @@ | ||
5 | Bool AtLeastOneNonClone; | ||
6 | int MergedFBXDPI, MergedFBYDPI; | ||
7 | Bool NoVirtual; | ||
8 | + Bool VGAAccess; | ||
9 | |||
10 | /* special handlings for DELL triple-head server */ | ||
11 | Bool IsDellServer; | ||
12 | diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.man xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.man | ||
13 | --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.man 2005-01-13 21:41:05.000000000 -0800 | ||
14 | +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.man 2005-01-13 21:50:45.919826968 -0800 | ||
15 | @@ -494,6 +494,34 @@ | ||
16 | with this enabled. The default is | ||
17 | .B off. | ||
18 | .TP | ||
19 | +.BI "Option \*qVGAAccess\*q \*q" boolean \*q | ||
20 | +Tell the driver if it can do legacy VGA IOs to the card. This is | ||
21 | +necessary for properly resuming consoles when in VGA text mode, but | ||
22 | +shouldn't be if the console is using radeonfb or some other graphic | ||
23 | +mode driver. Some platforms like PowerPC have issues with those, and they aren't | ||
24 | +necessary unless you have a real text mode in console. The default is | ||
25 | +.B off | ||
26 | +on PowerPC and | ||
27 | +.B on | ||
28 | +on other architectures. | ||
29 | +.TP | ||
30 | +.BI "Option \*qReverseDDC\*q \*q" boolean \*q | ||
31 | +When BIOS connector informations aren't available, use this option to | ||
32 | +reverse the mapping of the 2 main DDC ports. Use this if the X serve | ||
33 | +obviously detects the wrong display for each connector. This is | ||
34 | +typically needed on the Radeon 9600 cards bundled with Apple G5s. The | ||
35 | +default is | ||
36 | +.B off. | ||
37 | +.TP | ||
38 | +.BI "Option \*qLVDSProbePLL\*q \*q" boolean \*q | ||
39 | +When BIOS panel informations aren't available (like on PowerBooks), it | ||
40 | +may still be necessary to use the firmware provided PLL values for the | ||
41 | +panel or flickering will happen. This option will force probing of | ||
42 | +the current value programmed in the chip when X is launched in that | ||
43 | +case. This is only useful for LVDS panels (laptop internal panels). | ||
44 | +The default is | ||
45 | +.B on. | ||
46 | +.TP | ||
47 | |||
48 | .SH SEE ALSO | ||
49 | __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) | ||
50 | diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c | ||
51 | --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c 2005-01-13 21:41:05.000000000 -0800 | ||
52 | +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c 2005-01-13 21:50:45.920826816 -0800 | ||
53 | @@ -291,10 +291,8 @@ | ||
54 | OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN); | ||
55 | #endif | ||
56 | |||
57 | - /* Restore SURFACE_CNTL - only the first head contains valid data -ReneR */ | ||
58 | - if (!info->IsSecondary) { | ||
59 | - OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl); | ||
60 | - } | ||
61 | + /* Restore SURFACE_CNTL */ | ||
62 | + OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl); | ||
63 | |||
64 | RADEONWaitForFifo(pScrn, 1); | ||
65 | OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX | ||
66 | diff -urN xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c | ||
67 | --- xc.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 2005-01-13 21:41:05.000000000 -0800 | ||
68 | +++ xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 2005-01-13 21:50:51.158030640 -0800 | ||
69 | @@ -118,6 +118,7 @@ | ||
70 | static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn); | ||
71 | static int RADEONValidateMergeModes(ScrnInfoPtr pScrn); | ||
72 | static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode); | ||
73 | +static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn); | ||
74 | |||
75 | /* psuedo xinerama support */ | ||
76 | |||
77 | @@ -167,7 +168,10 @@ | ||
78 | OPTION_SUBPIXEL_ORDER, | ||
79 | #endif | ||
80 | OPTION_SHOWCACHE, | ||
81 | - OPTION_DYNAMIC_CLOCKS | ||
82 | + OPTION_DYNAMIC_CLOCKS, | ||
83 | + OPTION_VGA_ACCESS, | ||
84 | + OPTION_LVDS_PROBE_PLL, | ||
85 | + OPTION_REVERSE_DDC, | ||
86 | } RADEONOpts; | ||
87 | |||
88 | static const OptionInfoRec RADEONOptions[] = { | ||
89 | @@ -215,6 +219,9 @@ | ||
90 | #endif | ||
91 | { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE }, | ||
92 | { OPTION_DYNAMIC_CLOCKS, "DynamicClocks", OPTV_BOOLEAN, {0}, FALSE }, | ||
93 | + { OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE }, | ||
94 | + { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE }, | ||
95 | + { OPTION_REVERSE_DDC, "ReverseDDC", OPTV_BOOLEAN, {0}, FALSE }, | ||
96 | { -1, NULL, OPTV_NONE, {0}, FALSE } | ||
97 | }; | ||
98 | |||
99 | @@ -1190,41 +1197,55 @@ | ||
100 | return(bConnected ? MT_CRT : MT_NONE); | ||
101 | } | ||
102 | |||
103 | -#if defined(__powerpc__) | ||
104 | static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn) | ||
105 | { | ||
106 | RADEONInfoPtr info = RADEONPTR(pScrn); | ||
107 | RADEONPLLPtr pll = &info->pll; | ||
108 | unsigned char *RADEONMMIO = info->MMIO; | ||
109 | unsigned char ppll_div_sel; | ||
110 | - unsigned Nx, M; | ||
111 | + unsigned mpll_fb_div, spll_fb_div, M; | ||
112 | unsigned xclk, tmp, ref_div; | ||
113 | int hTotal, vTotal, num, denom, m, n; | ||
114 | - float hz, vclk, xtal; | ||
115 | + float hz, prev_xtal, vclk, xtal, mpll, spll; | ||
116 | long start_secs, start_usecs, stop_secs, stop_usecs, total_usecs; | ||
117 | - int i; | ||
118 | - | ||
119 | - for(i=0; i<1000000; i++) | ||
120 | - if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0) | ||
121 | + long to1_secs, to1_usecs, to2_secs, to2_usecs; | ||
122 | + unsigned int f1, f2, f3; | ||
123 | + int i, tries = 0; | ||
124 | + | ||
125 | + prev_xtal = 0; | ||
126 | + again: | ||
127 | + xtal = 0; | ||
128 | + if (++tries > 10) | ||
129 | + goto failed; | ||
130 | + | ||
131 | + xf86getsecs(&to1_secs, &to2_usecs); | ||
132 | + f1 = INREG(RADEON_CRTC_CRNT_FRAME); | ||
133 | + for (;;) { | ||
134 | + f2 = INREG(RADEON_CRTC_CRNT_FRAME); | ||
135 | + if (f1 != f2) | ||
136 | break; | ||
137 | - | ||
138 | + xf86getsecs(&to2_secs, &to2_usecs); | ||
139 | + if ((to2_secs - to1_secs) > 1) { | ||
140 | + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Clock not counting...\n"); | ||
141 | + goto failed; | ||
142 | + } | ||
143 | + } | ||
144 | xf86getsecs(&start_secs, &start_usecs); | ||
145 | - | ||
146 | - for(i=0; i<1000000; i++) | ||
147 | - if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0) | ||
148 | + for(;;) { | ||
149 | + f3 = INREG(RADEON_CRTC_CRNT_FRAME); | ||
150 | + if (f3 != f2) | ||
151 | break; | ||
152 | - | ||
153 | - for(i=0; i<1000000; i++) | ||
154 | - if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0) | ||
155 | - break; | ||
156 | - | ||
157 | + xf86getsecs(&to2_secs, &to2_usecs); | ||
158 | + if ((to2_secs - start_secs) > 1) | ||
159 | + goto failed; | ||
160 | + } | ||
161 | xf86getsecs(&stop_secs, &stop_usecs); | ||
162 | |||
163 | total_usecs = abs(stop_usecs - start_usecs); | ||
164 | hz = 1000000/total_usecs; | ||
165 | |||
166 | - hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; | ||
167 | - vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0x3ff) + 1); | ||
168 | + hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x3ff) + 1) * 8; | ||
169 | + vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0xfff) + 1); | ||
170 | vclk = (float)(hTotal * (float)(vTotal * hz)); | ||
171 | |||
172 | switch((INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x30000) >> 16) { | ||
173 | @@ -1286,23 +1307,79 @@ | ||
174 | else if ((xtal > 29400000) && (xtal < 29600000)) | ||
175 | xtal = 2950; | ||
176 | else | ||
177 | - return FALSE; | ||
178 | + goto again; | ||
179 | + failed: | ||
180 | + if (xtal == 0) { | ||
181 | + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to probe xtal value ! Using default 27Mhz\n"); | ||
182 | + xtal = 2700; | ||
183 | + } else { | ||
184 | + if (prev_xtal == 0) { | ||
185 | + prev_xtal = xtal; | ||
186 | + tries = 0; | ||
187 | + goto again; | ||
188 | + } else if (prev_xtal != xtal) { | ||
189 | + prev_xtal = 0; | ||
190 | + goto again; | ||
191 | + } | ||
192 | + } | ||
193 | |||
194 | tmp = INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV); | ||
195 | ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff; | ||
196 | |||
197 | - Nx = (tmp & 0xff00) >> 8; | ||
198 | + /* Calculate "base" xclk straight from MPLL, though that isn't | ||
199 | + * really useful (hopefully). This isn't called XCLK anymore on | ||
200 | + * radeon's... | ||
201 | + */ | ||
202 | + mpll_fb_div = (tmp & 0xff00) >> 8; | ||
203 | + spll_fb_div = (tmp & 0xff0000) >> 16; | ||
204 | M = (tmp & 0xff); | ||
205 | - xclk = RADEONDiv((2 * Nx * xtal), (2 * M)); | ||
206 | + xclk = RADEONDiv((2 * mpll_fb_div * xtal), (M)); | ||
207 | + | ||
208 | + /* | ||
209 | + * Calculate MCLK based on MCLK-A | ||
210 | + */ | ||
211 | + mpll = (2.0 * (float)mpll_fb_div * (xtal / 100.0)) / (float)M; | ||
212 | + spll = (2.0 * (float)spll_fb_div * (xtal / 100.0)) / (float)M; | ||
213 | + | ||
214 | + tmp = INPLL(pScrn, RADEON_MCLK_CNTL) & 0x7; | ||
215 | + switch(tmp) { | ||
216 | + case 1: info->mclk = mpll; break; | ||
217 | + case 2: info->mclk = mpll / 2.0; break; | ||
218 | + case 3: info->mclk = mpll / 4.0; break; | ||
219 | + case 4: info->mclk = mpll / 8.0; break; | ||
220 | + case 7: info->mclk = spll; break; | ||
221 | + default: | ||
222 | + info->mclk = 200.00; | ||
223 | + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported MCLKA source" | ||
224 | + " setting %d, can't probe MCLK value !\n", tmp); | ||
225 | + } | ||
226 | + | ||
227 | + /* | ||
228 | + * Calculate SCLK | ||
229 | + */ | ||
230 | + tmp = INPLL(pScrn, RADEON_SCLK_CNTL) & 0x7; | ||
231 | + switch(tmp) { | ||
232 | + case 1: info->sclk = spll; break; | ||
233 | + case 2: info->sclk = spll / 2.0; break; | ||
234 | + case 3: info->sclk = spll / 4.0; break; | ||
235 | + case 4: info->sclk = spll / 8.0; break; | ||
236 | + case 7: info->sclk = mpll; | ||
237 | + default: | ||
238 | + info->sclk = 200.00; | ||
239 | + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported SCLK source" | ||
240 | + " setting %d, can't probe SCLK value !\n", tmp); | ||
241 | + } | ||
242 | |||
243 | /* we're done, hopefully these are sane values */ | ||
244 | pll->reference_div = ref_div; | ||
245 | pll->xclk = xclk; | ||
246 | pll->reference_freq = xtal; | ||
247 | |||
248 | + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probed PLL values: xtal: %f Mhz, " | ||
249 | + "sclk: %f Mhz, mclk: %f Mhz\n", xtal/100.0, info->sclk, info->mclk); | ||
250 | + | ||
251 | return TRUE; | ||
252 | } | ||
253 | -#endif | ||
254 | |||
255 | static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn) | ||
256 | { | ||
257 | @@ -1318,7 +1395,7 @@ | ||
258 | info->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1; | ||
259 | } | ||
260 | if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) { | ||
261 | - info->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8; | ||
262 | + info->PanelXRes = ((fp_vert_stretch>>16) + 1) * 8; | ||
263 | } else { | ||
264 | info->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8; | ||
265 | } | ||
266 | @@ -1327,6 +1404,24 @@ | ||
267 | info->PanelXRes = 640; | ||
268 | info->PanelYRes = 480; | ||
269 | } | ||
270 | + | ||
271 | + if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) { | ||
272 | + CARD32 ppll_div_sel, ppll_val; | ||
273 | + | ||
274 | + OUTREG(RADEON_CLOCK_CNTL_INDEX, 1); | ||
275 | + ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_DATA + 1) & 0x3; | ||
276 | + ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel); | ||
277 | + if ((ppll_val & 0x000707ff) == 0x1bb) | ||
278 | + goto noprobe; | ||
279 | + info->FeedbackDivider = ppll_val & 0x7ff; | ||
280 | + info->PostDivider = (ppll_val >> 16) & 0x7; | ||
281 | + info->RefDivider = info->pll.reference_div; | ||
282 | + info->UseBiosDividers = TRUE; | ||
283 | + | ||
284 | + xf86DrvMsg(pScrn->scrnIndex, X_INFO, | ||
285 | + "Existing panel PLL dividers will be used.\n"); | ||
286 | + } | ||
287 | + noprobe: | ||
288 | |||
289 | xf86DrvMsg(pScrn->scrnIndex, X_WARNING, | ||
290 | "Panel size %dx%d is derived, this may not be correct.\n" | ||
291 | @@ -1341,17 +1436,24 @@ | ||
292 | if (!RADEONGetLVDSInfoFromBIOS(pScrn)) | ||
293 | RADEONGetPanelInfoFromReg(pScrn); | ||
294 | |||
295 | + /* The panel size we collected from BIOS may not be the | ||
296 | + * maximum size supported by the panel. If not, we update | ||
297 | + * it now. These will be used if no matching mode can be | ||
298 | + * found from EDID data. | ||
299 | + */ | ||
300 | + RADEONUpdatePanelSize(pScrn); | ||
301 | + | ||
302 | + /* No timing information for the native mode, | ||
303 | + * use whatever specified in the Modeline. | ||
304 | + * If no Modeline specified, we'll just pick | ||
305 | + * the VESA mode at 60Hz refresh rate which | ||
306 | + * is likely to be the best for a flat panel. | ||
307 | + */ | ||
308 | if (info->DotClock == 0) { | ||
309 | RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); | ||
310 | DisplayModePtr tmp_mode = NULL; | ||
311 | xf86DrvMsg(pScrn->scrnIndex, X_WARNING, | ||
312 | "No valid timing info from BIOS.\n"); | ||
313 | - /* No timing information for the native mode, | ||
314 | - use whatever specified in the Modeline. | ||
315 | - If no Modeline specified, we'll just pick | ||
316 | - the VESA mode at 60Hz refresh rate which | ||
317 | - is likely to be the best for a flat panel. | ||
318 | - */ | ||
319 | tmp_mode = pScrn->monitor->Modes; | ||
320 | while(tmp_mode) { | ||
321 | if ((tmp_mode->HDisplay == info->PanelXRes) && | ||
322 | @@ -1422,6 +1524,8 @@ | ||
323 | RADEONGetTMDSInfo(pScrn); | ||
324 | if (!pScrn->monitor->DDC) | ||
325 | RADEONGetHardCodedEDIDFromBIOS(pScrn); | ||
326 | + else if (!info->IsSecondary) | ||
327 | + RADEONUpdatePanelSize(pScrn); | ||
328 | } | ||
329 | } | ||
330 | } | ||
331 | @@ -1454,17 +1558,24 @@ | ||
332 | xf86DrvMsg (pScrn->scrnIndex, X_WARNING, | ||
333 | "Video BIOS not detected, using default clock settings!\n"); | ||
334 | |||
335 | -#if defined(__powerpc__) | ||
336 | - if (RADEONProbePLLParameters(pScrn)) return; | ||
337 | -#endif | ||
338 | + /* First, setup default PLL min/max */ | ||
339 | + if (info->ChipFamily >= CHIP_FAMILY_R420) { | ||
340 | + pll->min_pll_freq = 20000; | ||
341 | + pll->max_pll_freq = 50000; | ||
342 | + } else { | ||
343 | + pll->min_pll_freq = 12500; | ||
344 | + pll->max_pll_freq = 35000; | ||
345 | + } | ||
346 | + /* Try to probe the values from chip registers */ | ||
347 | + if (RADEONProbePLLParameters(pScrn)) | ||
348 | + return; | ||
349 | + | ||
350 | if (info->IsIGP) | ||
351 | pll->reference_freq = 1432; | ||
352 | else | ||
353 | pll->reference_freq = 2700; | ||
354 | |||
355 | pll->reference_div = 12; | ||
356 | - pll->min_pll_freq = 12500; | ||
357 | - pll->max_pll_freq = 35000; | ||
358 | pll->xclk = 10300; | ||
359 | |||
360 | info->sclk = 200.00; | ||
361 | @@ -1616,6 +1727,14 @@ | ||
362 | pRADEONEnt->PortInfo[1].DACType = DAC_PRIMARY; | ||
363 | pRADEONEnt->PortInfo[1].TMDSType = TMDS_EXT; | ||
364 | pRADEONEnt->PortInfo[1].ConnectorType = CONNECTOR_CRT; | ||
365 | + | ||
366 | + /* Some cards have the DDC lines swapped and we have no way to | ||
367 | + * detect it yet (Mac cards) | ||
368 | + */ | ||
369 | + if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) { | ||
370 | + pRADEONEnt->PortInfo[0].DDCType = DDC_VGA; | ||
371 | + pRADEONEnt->PortInfo[1].DDCType = DDC_DVI; | ||
372 | + } | ||
373 | } | ||
374 | |||
375 | /* always make TMDS_INT port first*/ | ||
376 | @@ -2618,16 +2737,35 @@ | ||
377 | xf86MonPtr ddc = pScrn->monitor->DDC; | ||
378 | DisplayModePtr p; | ||
379 | |||
380 | + if (info->UseBiosDividers && info->DotClock != 0) | ||
381 | + return; | ||
382 | + | ||
383 | /* Go thru detailed timing table first */ | ||
384 | for (j = 0; j < 4; j++) { | ||
385 | if (ddc->det_mon[j].type == 0) { | ||
386 | struct detailed_timings *d_timings = | ||
387 | &ddc->det_mon[j].section.d_timings; | ||
388 | + int match = 0; | ||
389 | + | ||
390 | + /* If we didn't get a panel clock or guessed one, try to match the | ||
391 | + * mode with the panel size. We do that because we _need_ a panel | ||
392 | + * clock, or ValidateFPModes will fail, even when UseBiosDividers | ||
393 | + * is set. | ||
394 | + */ | ||
395 | + if (info->DotClock == 0 && | ||
396 | + info->PanelXRes == d_timings->h_active && | ||
397 | + info->PanelYRes == d_timings->v_active) | ||
398 | + match = 1; | ||
399 | + | ||
400 | + /* If we don't have a BIOS provided panel data with fixed dividers, | ||
401 | + * check for a larger panel size | ||
402 | + */ | ||
403 | if (info->PanelXRes <= d_timings->h_active && | ||
404 | - info->PanelYRes <= d_timings->v_active) { | ||
405 | - | ||
406 | - if (info->DotClock) continue; /* Timings already inited */ | ||
407 | + info->PanelYRes < d_timings->v_active && | ||
408 | + !info->UseBiosDividers) | ||
409 | + match = 1; | ||
410 | |||
411 | + if (match) { | ||
412 | info->PanelXRes = d_timings->h_active; | ||
413 | info->PanelYRes = d_timings->v_active; | ||
414 | info->DotClock = d_timings->clock / 1000; | ||
415 | @@ -2637,10 +2775,24 @@ | ||
416 | info->VOverPlus = d_timings->v_sync_off; | ||
417 | info->VSyncWidth = d_timings->v_sync_width; | ||
418 | info->VBlank = d_timings->v_blanking; | ||
419 | + info->Flags = (d_timings->interlaced ? V_INTERLACE : 0); | ||
420 | + if (d_timings->sync == 3) { | ||
421 | + switch (d_timings->misc) { | ||
422 | + case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break; | ||
423 | + case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break; | ||
424 | + case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break; | ||
425 | + case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break; | ||
426 | + } | ||
427 | + } | ||
428 | + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n", | ||
429 | + info->PanelXRes, info->PanelYRes); | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | |||
434 | + if (info->UseBiosDividers && info->DotClock != 0) | ||
435 | + return; | ||
436 | + | ||
437 | /* Search thru standard VESA modes from EDID */ | ||
438 | for (j = 0; j < 8; j++) { | ||
439 | if ((info->PanelXRes < ddc->timings2[j].hsize) && | ||
440 | @@ -2662,28 +2814,16 @@ | ||
441 | info->VOverPlus = p->VSyncStart - p->VDisplay; | ||
442 | info->VSyncWidth = p->VSyncEnd - p->VSyncStart; | ||
443 | info->DotClock = p->Clock; | ||
444 | - info->Flags = | ||
445 | - (ddc->det_mon[j].section.d_timings.interlaced | ||
446 | - ? V_INTERLACE | ||
447 | - : 0); | ||
448 | - if (ddc->det_mon[j].section.d_timings.sync == 3) { | ||
449 | - switch (ddc->det_mon[j].section.d_timings.misc) { | ||
450 | - case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break; | ||
451 | - case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break; | ||
452 | - case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break; | ||
453 | - case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break; | ||
454 | - } | ||
455 | - } | ||
456 | + info->Flags = p->Flags; | ||
457 | + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n", | ||
458 | + info->PanelXRes, info->PanelYRes); | ||
459 | } | ||
460 | } | ||
461 | } | ||
462 | } | ||
463 | } | ||
464 | - | ||
465 | - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size found from DDC: %dx%d\n", | ||
466 | - info->PanelXRes, info->PanelYRes); | ||
467 | -} | ||
468 | - | ||
469 | + } | ||
470 | + | ||
471 | /* This function will sort all modes according to their resolution. | ||
472 | * Highest resolution first. | ||
473 | */ | ||
474 | @@ -2802,6 +2942,8 @@ | ||
475 | |||
476 | /* Search thru standard VESA modes from EDID */ | ||
477 | for (j = 0; j < 8; j++) { | ||
478 | + if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0) | ||
479 | + continue; | ||
480 | for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) { | ||
481 | /* Ignore all double scan modes */ | ||
482 | if ((ddc->timings2[j].hsize == p->HDisplay) && | ||
483 | @@ -2891,19 +3033,10 @@ | ||
484 | pScrn->virtualX = pScrn1->display->virtualX; | ||
485 | pScrn->virtualY = pScrn1->display->virtualY; | ||
486 | |||
487 | - if (pScrn->monitor->DDC && !info->UseBiosDividers) { | ||
488 | + if (pScrn->monitor->DDC) { | ||
489 | int maxVirtX = pScrn->virtualX; | ||
490 | int maxVirtY = pScrn->virtualY; | ||
491 | |||
492 | - if ((DisplayType != MT_CRT) && (!info->IsSecondary) && (!crtc2)) { | ||
493 | - /* The panel size we collected from BIOS may not be the | ||
494 | - * maximum size supported by the panel. If not, we update | ||
495 | - * it now. These will be used if no matching mode can be | ||
496 | - * found from EDID data. | ||
497 | - */ | ||
498 | - RADEONUpdatePanelSize(pScrn); | ||
499 | - } | ||
500 | - | ||
501 | /* Collect all of the DDC modes */ | ||
502 | first = last = ddcModes = RADEONDDCModes(pScrn); | ||
503 | |||
504 | @@ -3595,7 +3728,8 @@ | ||
505 | xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, | ||
506 | "Invalid PanelSize value: %s\n", s); | ||
507 | } | ||
508 | - } | ||
509 | + } else | ||
510 | + RADEONGetPanelInfo(pScrn); | ||
511 | } | ||
512 | |||
513 | if (pScrn->monitor->DDC) { | ||
514 | @@ -4162,15 +4296,6 @@ | ||
515 | return TRUE; | ||
516 | } | ||
517 | |||
518 | - if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; | ||
519 | - xf86LoaderReqSymLists(vgahwSymbols, NULL); | ||
520 | - if (!vgaHWGetHWRec(pScrn)) { | ||
521 | - RADEONFreeRec(pScrn); | ||
522 | - goto fail2; | ||
523 | - } | ||
524 | - | ||
525 | - vgaHWGetIOBase(VGAHWPTR(pScrn)); | ||
526 | - | ||
527 | xf86DrvMsg(pScrn->scrnIndex, X_INFO, | ||
528 | "PCI bus %d card %d func %d\n", | ||
529 | info->PciInfo->bus, | ||
530 | @@ -4198,6 +4323,32 @@ | ||
531 | memcpy(info->Options, RADEONOptions, sizeof(RADEONOptions)); | ||
532 | xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options); | ||
533 | |||
534 | + /* By default, don't do VGA IOs on ppc */ | ||
535 | +#ifdef __powerpc__ | ||
536 | + info->VGAAccess = FALSE; | ||
537 | +#else | ||
538 | + info->VGAAccess = TRUE; | ||
539 | +#endif | ||
540 | + | ||
541 | + xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess); | ||
542 | + if (info->VGAAccess) { | ||
543 | + if (!xf86LoadSubModule(pScrn, "vgahw")) | ||
544 | + info->VGAAccess = FALSE; | ||
545 | + else { | ||
546 | + xf86LoaderReqSymLists(vgahwSymbols, NULL); | ||
547 | + if (!vgaHWGetHWRec(pScrn)) | ||
548 | + info->VGAAccess = FALSE; | ||
549 | + } | ||
550 | + if (!info->VGAAccess) | ||
551 | + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed," | ||
552 | + " trying to run without it\n"); | ||
553 | + } else | ||
554 | + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE," | ||
555 | + " VGA module load skipped\n"); | ||
556 | + if (info->VGAAccess) | ||
557 | + vgaHWGetIOBase(VGAHWPTR(pScrn)); | ||
558 | + | ||
559 | + | ||
560 | if (!RADEONPreInitWeight(pScrn)) | ||
561 | goto fail; | ||
562 | |||
563 | @@ -4256,7 +4407,6 @@ | ||
564 | RADEONGetBIOSInfo(pScrn, pInt10); | ||
565 | if (!RADEONQueryConnectedMonitors(pScrn)) goto fail; | ||
566 | RADEONGetClockInfo(pScrn); | ||
567 | - RADEONGetPanelInfo(pScrn); | ||
568 | |||
569 | /* collect MergedFB options */ | ||
570 | /* only parse mergedfb options on the primary head. | ||
571 | @@ -4312,7 +4462,8 @@ | ||
572 | if (pInt10) | ||
573 | xf86FreeInt10(pInt10); | ||
574 | |||
575 | - vgaHWFreeHWRec(pScrn); | ||
576 | + if (info->VGAAccess) | ||
577 | + vgaHWFreeHWRec(pScrn); | ||
578 | |||
579 | fail2: | ||
580 | if(info->MMIO) RADEONUnmapMMIO(pScrn); | ||
581 | @@ -5716,10 +5867,6 @@ | ||
582 | unsigned char *RADEONMMIO = info->MMIO; | ||
583 | int i; | ||
584 | |||
585 | -#ifdef ENABLE_FLAT_PANEL | ||
586 | - /* Select palette 0 (main CRTC) if using FP-enabled chip */ | ||
587 | - /* if (info->Port1 == MT_DFP) PAL_SELECT(1); */ | ||
588 | -#endif | ||
589 | PAL_SELECT(1); | ||
590 | INPAL_START(0); | ||
591 | for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT(); | ||
592 | @@ -5760,7 +5907,6 @@ | ||
593 | RADEONInfoPtr info = RADEONPTR(pScrn); | ||
594 | unsigned char *RADEONMMIO = info->MMIO; | ||
595 | RADEONSavePtr save = &info->SavedReg; | ||
596 | - vgaHWPtr hwp = VGAHWPTR(pScrn); | ||
597 | |||
598 | RADEONTRACE(("RADEONSave\n")); | ||
599 | if (info->FBDev) { | ||
600 | @@ -5769,19 +5915,23 @@ | ||
601 | } | ||
602 | |||
603 | if (!info->IsSecondary) { | ||
604 | - vgaHWUnlock(hwp); | ||
605 | + if (info->VGAAccess) { | ||
606 | + vgaHWPtr hwp = VGAHWPTR(pScrn); | ||
607 | + | ||
608 | + vgaHWUnlock(hwp); | ||
609 | #if defined(__powerpc__) | ||
610 | - /* temporary hack to prevent crashing on PowerMacs when trying to | ||
611 | - * read VGA fonts and colormap, will find a better solution | ||
612 | - * in the future | ||
613 | - */ | ||
614 | - vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ | ||
615 | + /* temporary hack to prevent crashing on PowerMacs when trying to | ||
616 | + * read VGA fonts and colormap, will find a better solution | ||
617 | + * in the future. TODO: Check if there's actually some VGA stuff | ||
618 | + * setup in the card at all !! | ||
619 | + */ | ||
620 | + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */ | ||
621 | #else | ||
622 | - vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); /* Save mode | ||
623 | - * & fonts & cmap | ||
624 | - */ | ||
625 | + /* Save mode * & fonts & cmap */ | ||
626 | + vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); | ||
627 | #endif | ||
628 | - vgaHWLock(hwp); | ||
629 | + vgaHWLock(hwp); | ||
630 | + } | ||
631 | save->dp_datatype = INREG(RADEON_DP_DATATYPE); | ||
632 | save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); | ||
633 | save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); | ||
634 | @@ -5797,7 +5947,6 @@ | ||
635 | RADEONInfoPtr info = RADEONPTR(pScrn); | ||
636 | unsigned char *RADEONMMIO = info->MMIO; | ||
637 | RADEONSavePtr restore = &info->SavedReg; | ||
638 | - vgaHWPtr hwp = VGAHWPTR(pScrn); | ||
639 | |||
640 | RADEONTRACE(("RADEONRestore\n")); | ||
641 | |||
642 | @@ -5839,27 +5988,36 @@ | ||
643 | usleep(100000); | ||
644 | #endif | ||
645 | |||
646 | - if (!info->IsSecondary) { | ||
647 | - vgaHWUnlock(hwp); | ||
648 | + if (info->VGAAccess) { | ||
649 | + vgaHWPtr hwp = VGAHWPTR(pScrn); | ||
650 | + if (!info->IsSecondary) { | ||
651 | + vgaHWUnlock(hwp); | ||
652 | #if defined(__powerpc__) | ||
653 | - /* Temporary hack to prevent crashing on PowerMacs when trying to | ||
654 | - * write VGA fonts, will find a better solution in the future | ||
655 | - */ | ||
656 | - vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); | ||
657 | + /* Temporary hack to prevent crashing on PowerMacs when trying to | ||
658 | + * write VGA fonts, will find a better solution in the future | ||
659 | + */ | ||
660 | + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE ); | ||
661 | #else | ||
662 | - vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); | ||
663 | + vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); | ||
664 | #endif | ||
665 | - vgaHWLock(hwp); | ||
666 | - } else { | ||
667 | - RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); | ||
668 | - ScrnInfoPtr pScrn0; | ||
669 | - vgaHWPtr hwp0; | ||
670 | - | ||
671 | - pScrn0 = pRADEONEnt->pPrimaryScrn; | ||
672 | - hwp0 = VGAHWPTR(pScrn0); | ||
673 | - vgaHWUnlock(hwp0); | ||
674 | - vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); | ||
675 | - vgaHWLock(hwp0); | ||
676 | + vgaHWLock(hwp); | ||
677 | + } else { | ||
678 | + RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); | ||
679 | + ScrnInfoPtr pScrn0 = pRADEONEnt->pPrimaryScrn; | ||
680 | + RADEONInfoPtr info0 = RADEONPTR(pScrn0); | ||
681 | + vgaHWPtr hwp0; | ||
682 | + | ||
683 | + if (info0->VGAAccess) { | ||
684 | + hwp0 = VGAHWPTR(pScrn0); | ||
685 | + vgaHWUnlock(hwp0); | ||
686 | +#if defined(__powerpc__) | ||
687 | + vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE); | ||
688 | +#else | ||
689 | + vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS ); | ||
690 | +#endif | ||
691 | + vgaHWLock(hwp0); | ||
692 | + } | ||
693 | + } | ||
694 | } | ||
695 | RADEONUnblank(pScrn); | ||
696 | |||
697 | @@ -6007,7 +6165,7 @@ | ||
698 | */ | ||
699 | temp = INREG(RADEON_MEM_CNTL); | ||
700 | data = (R300_MEM_NUM_CHANNELS_MASK & temp); | ||
701 | - if (data == 2) { | ||
702 | + if (data == 1) { | ||
703 | if (R300_MEM_USE_CD_CH_ONLY & temp) { | ||
704 | temp = INREG(R300_MC_IND_INDEX); | ||
705 | temp &= ~R300_MC_IND_ADDR_MASK; | ||
706 | @@ -6488,8 +6646,13 @@ | ||
707 | ? RADEON_CRTC2_V_SYNC_POL | ||
708 | : 0)); | ||
709 | |||
710 | + /* We must make sure Tiling is disabled. It seem all other fancy | ||
711 | + * options in there can be safely disabled too | ||
712 | + */ | ||
713 | save->crtc2_offset = 0; | ||
714 | - save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL); | ||
715 | + save->crtc2_offset_cntl = 0; | ||
716 | + | ||
717 | + | ||
718 | /* this should be right */ | ||
719 | if (info->MergedFB) { | ||
720 | save->crtc2_pitch = (((info->CRT2pScrn->displayWidth * pScrn->bitsPerPixel) + | ||
721 | @@ -6531,6 +6694,23 @@ | ||
722 | |||
723 | } | ||
724 | |||
725 | + /* We must set SURFACE_CNTL properly on the second screen too */ | ||
726 | + save->surface_cntl = 0; | ||
727 | +#if X_BYTE_ORDER == X_BIG_ENDIAN | ||
728 | + /* Alhought we current onlu use aperture 0, also setting aperture 1 should not harm -ReneR */ | ||
729 | + switch (pScrn->bitsPerPixel) { | ||
730 | + case 16: | ||
731 | + save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP; | ||
732 | + save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP; | ||
733 | + break; | ||
734 | + | ||
735 | + case 32: | ||
736 | + save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP; | ||
737 | + save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP; | ||
738 | + break; | ||
739 | + } | ||
740 | +#endif | ||
741 | + | ||
742 | RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", | ||
743 | save->crtc2_pitch, pScrn->virtualX, | ||
744 | info->CurrentLayout.displayWidth)); | ||
745 | @@ -6815,7 +6995,7 @@ | ||
746 | |||
747 | /* Define PLL2 registers for requested video mode */ | ||
748 | static void RADEONInitPLL2Registers(RADEONSavePtr save, RADEONPLLPtr pll, | ||
749 | - double dot_clock) | ||
750 | + double dot_clock, int no_odd_postdiv) | ||
751 | { | ||
752 | unsigned long freq = dot_clock * 100; | ||
753 | |||
754 | @@ -6832,7 +7012,7 @@ | ||
755 | { 2, 1 }, /* VCLK_SRC/2 */ | ||
756 | { 4, 2 }, /* VCLK_SRC/4 */ | ||
757 | { 8, 3 }, /* VCLK_SRC/8 */ | ||
758 | - { 3, 4 }, /* VCLK_SRC/3 */ | ||
759 | + { 3, 4 }, /* VCLK_SRC/3 */ | ||
760 | { 6, 6 }, /* VCLK_SRC/6 */ | ||
761 | { 12, 7 }, /* VCLK_SRC/12 */ | ||
762 | { 0, 0 } | ||
763 | @@ -6842,6 +7022,11 @@ | ||
764 | if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12; | ||
765 | |||
766 | for (post_div = &post_divs[0]; post_div->divider; ++post_div) { | ||
767 | + /* Odd post divider value don't work properly on the second digital | ||
768 | + * output | ||
769 | + */ | ||
770 | + if (no_odd_postdiv && (post_div->divider & 1)) | ||
771 | + continue; | ||
772 | save->pll_output_freq_2 = post_div->divider * freq; | ||
773 | if (save->pll_output_freq_2 >= pll->min_pll_freq | ||
774 | && save->pll_output_freq_2 <= pll->max_pll_freq) break; | ||
775 | @@ -6942,7 +7127,7 @@ | ||
776 | if (info->IsSecondary) { | ||
777 | if (!RADEONInitCrtc2Registers(pScrn, save, mode, info)) | ||
778 | return FALSE; | ||
779 | - RADEONInitPLL2Registers(save, &info->pll, dot_clock); | ||
780 | + RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->DisplayType != MT_CRT); | ||
781 | } else if (info->MergedFB) { | ||
782 | RADEONInitCommonRegisters(save, info); | ||
783 | if (!RADEONInitCrtcRegisters(pScrn, save, | ||
784 | @@ -6959,7 +7144,8 @@ | ||
785 | RADEONInitCrtc2Registers(pScrn, save, | ||
786 | ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info); | ||
787 | dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT2)->Clock / 1000.0; | ||
788 | - RADEONInitPLL2Registers(save, &info->pll, dot_clock); | ||
789 | + RADEONInitPLL2Registers(save, &info->pll, dot_clock, | ||
790 | + info->MergeType != MT_CRT); | ||
791 | } else { | ||
792 | if (!RADEONInitCrtcRegisters(pScrn, save, mode, info)) | ||
793 | return FALSE; | ||
794 | @@ -7410,7 +7596,7 @@ | ||
795 | } | ||
796 | } | ||
797 | |||
798 | - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) | ||
799 | + if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec")) | ||
800 | vgaHWFreeHWRec(pScrn); | ||
801 | RADEONFreeRec(pScrn); | ||
802 | } |