2 Copyright © 2004, The AROS Development Team. All rights reserved.
8 #include "radeon_reg.h"
9 #include "radeon_bios.h"
10 #include "radeon_accel.h"
11 #include "radeon_macros.h"
16 #include <aros/debug.h>
18 #define MAX(a,b) ((a) > (b) ? (a) : (b))
20 static void usleep(ULONG usec
)
23 for (i
=0; i
< usec
; i
++)
24 for (j
=0; j
< 500; j
++)
28 /* Compute n/d with rounding */
29 static int RADEONDiv(int n
, int d
)
31 return (n
+ (d
/ 2)) / d
;
34 /* This function is required to workaround a hardware bug in some (all?)
35 * revisions of the R300. This workaround should be called after every
36 * CLOCK_CNTL_INDEX register access. If not, register reads afterward
39 void R300CGWorkaround(struct ati_staticdata
*sd
)
43 save
= INREG(RADEON_CLOCK_CNTL_INDEX
);
44 tmp
= save
& ~(0x3f | RADEON_PLL_WR_EN
);
45 OUTREG(RADEON_CLOCK_CNTL_INDEX
, tmp
);
46 tmp
= INREG(RADEON_CLOCK_CNTL_DATA
);
47 OUTREG(RADEON_CLOCK_CNTL_INDEX
, save
);
50 /* Read PLL information */
51 unsigned RADEONINPLL(struct ati_staticdata
*sd
, int addr
)
55 OUTREG8(RADEON_CLOCK_CNTL_INDEX
, addr
& 0x3f);
56 data
= INREG(RADEON_CLOCK_CNTL_DATA
);
57 if (sd
->Card
.R300CGWorkaround
) R300CGWorkaround(sd
);
63 static void RADEONBlank(struct ati_staticdata
*sd
)
65 if (!sd
->Card
.IsSecondary
) {
66 switch(sd
->Card
.MonType2
) {
70 OUTREGP(RADEON_CRTC_EXT_CNTL
,
71 RADEON_CRTC_DISPLAY_DIS
,
72 ~(RADEON_CRTC_DISPLAY_DIS
));
80 OUTREGP(RADEON_CRTC2_GEN_CNTL
,
81 RADEON_CRTC2_DISP_DIS
,
82 ~(RADEON_CRTC2_DISP_DIS
));
87 static void RADEONUnblank(struct ati_staticdata
*sd
)
89 if (!sd
->Card
.IsSecondary
) {
90 switch (sd
->Card
.MonType2
) {
94 OUTREGP(RADEON_CRTC_EXT_CNTL
,
96 ~(RADEON_CRTC_DISPLAY_DIS
));
104 switch (sd
->Card
.MonType1
) {
108 OUTREGP(RADEON_CRTC2_GEN_CNTL
,
110 ~(RADEON_CRTC2_DISP_DIS
));
120 static void RADEONPLLWaitForReadUpdateComplete(struct ati_staticdata
*sd
)
124 /* FIXME: Certain revisions of R300 can't recover here. Not sure of
125 the cause yet, but this workaround will mask the problem for now.
126 Other chips usually will pass at the very first test, so the
127 workaround shouldn't have any effect on them. */
130 RADEONINPLL(sd
, RADEON_PPLL_REF_DIV
) & RADEON_PPLL_ATOMIC_UPDATE_R
);
134 static void RADEONPLLWriteUpdate(struct ati_staticdata
*sd
)
136 while (INPLL(sd
, RADEON_PPLL_REF_DIV
) & RADEON_PPLL_ATOMIC_UPDATE_R
);
138 OUTPLLP(sd
, RADEON_PPLL_REF_DIV
,
139 RADEON_PPLL_ATOMIC_UPDATE_W
,
140 ~(RADEON_PPLL_ATOMIC_UPDATE_W
));
143 /* Calculate display buffer watermark to prevent buffer underflow */
144 static void RADEONInitDispBandwidth(struct ati_staticdata
*sd
, struct CardState
*mode
)
146 ULONG temp
, data
, mem_trcd
, mem_trp
, mem_tras
, mem_trbs
=0;
149 ULONG MemTrcdExtMemCntl
[4] = {1, 2, 3, 4};
150 ULONG MemTrpExtMemCntl
[4] = {1, 2, 3, 4};
151 ULONG MemTrasExtMemCntl
[8] = {1, 2, 3, 4, 5, 6, 7, 8};
153 ULONG MemTrcdMemTimingCntl
[8] = {1, 2, 3, 4, 5, 6, 7, 8};
154 ULONG MemTrpMemTimingCntl
[8] = {1, 2, 3, 4, 5, 6, 7, 8};
155 ULONG MemTrasMemTimingCntl
[16] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
157 float MemTcas
[8] = {0, 1, 2, 3, 0, 1.5, 2.5, 0};
158 float MemTcas2
[8] = {0, 1, 2, 3, 4, 5, 6, 7};
159 float MemTrbs
[8] = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5};
161 float mem_bw
, peak_disp_bw
;
162 float min_mem_eff
= 0.8;
163 float sclk_eff
, sclk_delay
;
164 float mc_latency_mclk
, mc_latency_sclk
, cur_latency_mclk
, cur_latency_sclk
;
165 float disp_latency
, disp_latency_overhead
, disp_drain_rate
, disp_drain_rate2
;
166 float pix_clk
, pix_clk2
; /* in MHz */
167 int cur_size
= 16; /* in octawords */
169 int stop_req
, max_stop_req
;
171 /* R420 family not supported yet */
172 if (sd
->Card
.Type
== R420
) return;
175 * Determine if there is enough bandwidth for current display mode
177 mem_bw
= sd
->Card
.mclk
* (sd
->Card
.RamWidth
/ 8) * (sd
->Card
.IsDDR
? 2 : 1);
179 pix_clk
= mode
->pixelc
/1000.0;
182 peak_disp_bw
= (pix_clk
* mode
->bpp
);
184 D(bug("[ATI] mem_bw=%d peak_disp_bw=%d mode->bpp=%d mode->pixelc=%d mode->HDisplay=%d\n", (ULONG
)mem_bw
, (ULONG
)peak_disp_bw
,
185 mode
->bpp
, mode
->pixelc
, mode
->HDisplay
));
187 if (peak_disp_bw
>= mem_bw
* min_mem_eff
) {
188 D(bug("[ATI] You may not have enough display bandwidth for current mode\n"
189 "[ATI] If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"));
193 Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
194 GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
196 stop_req
= mode
->HDisplay
* mode
->bpp
/ 16;
198 /* setup Max GRPH_STOP_REQ default value */
199 if (IS_RV100_VARIANT
)
203 if (stop_req
> max_stop_req
)
204 stop_req
= max_stop_req
;
206 /* Get values from the EXT_MEM_CNTL register...converting its contents. */
207 temp
= INREG(RADEON_MEM_TIMING_CNTL
);
208 if ((sd
->Card
.Type
== RV100
) || sd
->Card
.IsIGP
) { /* RV100, M6, IGPs */
209 mem_trcd
= MemTrcdExtMemCntl
[(temp
& 0x0c) >> 2];
210 mem_trp
= MemTrpExtMemCntl
[ (temp
& 0x03) >> 0];
211 mem_tras
= MemTrasExtMemCntl
[(temp
& 0x70) >> 4];
212 } else { /* RV200 and later */
213 mem_trcd
= MemTrcdMemTimingCntl
[(temp
& 0x07) >> 0];
214 mem_trp
= MemTrpMemTimingCntl
[ (temp
& 0x700) >> 8];
215 mem_tras
= MemTrasMemTimingCntl
[(temp
& 0xf000) >> 12];
218 /* Get values from the MEM_SDRAM_MODE_REG register...converting its */
219 temp
= INREG(RADEON_MEM_SDRAM_MODE_REG
);
220 data
= (temp
& (7<<20)) >> 20;
221 if ((sd
->Card
.Type
== RV100
) || sd
->Card
.IsIGP
) { /* RV100, M6, IGPs */
222 mem_tcas
= MemTcas
[data
];
224 mem_tcas
= MemTcas2
[data
];
227 if (IS_R300_VARIANT
) {
229 /* on the R300, Tcas is included in Trbs.
231 temp
= INREG(RADEON_MEM_CNTL
);
232 data
= (R300_MEM_NUM_CHANNELS_MASK
& temp
);
234 if (R300_MEM_USE_CD_CH_ONLY
& temp
) {
235 temp
= INREG(R300_MC_IND_INDEX
);
236 temp
&= ~R300_MC_IND_ADDR_MASK
;
237 temp
|= R300_MC_READ_CNTL_CD_mcind
;
238 OUTREG(R300_MC_IND_INDEX
, temp
);
239 temp
= INREG(R300_MC_IND_DATA
);
240 data
= (R300_MEM_RBS_POSITION_C_MASK
& temp
);
242 temp
= INREG(R300_MC_READ_CNTL_AB
);
243 data
= (R300_MEM_RBS_POSITION_A_MASK
& temp
);
246 temp
= INREG(R300_MC_READ_CNTL_AB
);
247 data
= (R300_MEM_RBS_POSITION_A_MASK
& temp
);
250 mem_trbs
= MemTrbs
[data
];
251 mem_tcas
+= mem_trbs
;
254 if ((sd
->Card
.Type
== RV100
) || sd
->Card
.IsIGP
) { /* RV100, M6, IGPs */
255 /* DDR64 SCLK_EFF = SCLK for analysis */
256 sclk_eff
= sd
->Card
.sclk
;
258 sclk_eff
= sd
->Card
.sclk
;
261 /* Find the memory controller latency for the display client.
263 if (IS_R300_VARIANT
) {
264 /*not enough for R350 ???*/
266 if (!mode2) sclk_delay = 150;
268 if (info->RamWidth == 256) sclk_delay = 87;
269 else sclk_delay = 97;
274 if ((sd
->Card
.Type
== RV100
) || sd
->Card
.IsIGP
) {
275 if (sd
->Card
.IsDDR
) sclk_delay
= 41;
276 else sclk_delay
= 33;
278 if (sd
->Card
.RamWidth
== 128) sclk_delay
= 57;
279 else sclk_delay
= 41;
283 mc_latency_sclk
= sclk_delay
/ sclk_eff
;
285 if (sd
->Card
.IsDDR
) {
286 if (sd
->Card
.RamWidth
== 32) {
297 mc_latency_mclk
= ((2.0*mem_trcd
+ mem_tcas
*c
+ 4.0*mem_tras
+ 4.0*mem_trp
+ k1
) /
298 sd
->Card
.mclk
) + (4.0 / sclk_eff
);
301 HW cursor time assuming worst case of full size colour cursor.
303 cur_latency_mclk
= (mem_trp
+ MAX(mem_tras
, (mem_trcd
+ 2*(cur_size
- (sd
->Card
.IsDDR
+1))))) / sd
->Card
.mclk
;
304 cur_latency_sclk
= cur_size
/ sclk_eff
;
307 Find the total latency for the display data.
309 disp_latency_overhead
= 8.0 / sd
->Card
.sclk
;
310 mc_latency_mclk
= mc_latency_mclk
+ disp_latency_overhead
+ cur_latency_mclk
;
311 mc_latency_sclk
= mc_latency_sclk
+ disp_latency_overhead
+ cur_latency_sclk
;
312 disp_latency
= MAX(mc_latency_mclk
, mc_latency_sclk
);
315 Find the drain rate of the display buffer.
317 disp_drain_rate
= pix_clk
/ (16.0/mode
->bpp
);
318 disp_drain_rate2
= 0;
321 Find the critical point of the display buffer.
323 critical_point
= (ULONG
)(disp_drain_rate
* disp_latency
+ 0.5);
327 temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
328 if (critical_point < temp) critical_point = temp;
332 The critical point should never be above max_stop_req-4. Setting
333 GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
335 if (max_stop_req
- critical_point
< 4) critical_point
= 0;
337 temp
= sd
->poweron_state
->grph_buffer_cntl
;
338 temp
&= ~(RADEON_GRPH_STOP_REQ_MASK
);
339 temp
|= (stop_req
<< RADEON_GRPH_STOP_REQ_SHIFT
);
340 temp
&= ~(RADEON_GRPH_START_REQ_MASK
);
341 if ((sd
->Card
.Type
== R350
) &&
345 temp
|= (stop_req
<< RADEON_GRPH_START_REQ_SHIFT
);
347 temp
|= RADEON_GRPH_BUFFER_SIZE
;
348 temp
&= ~(RADEON_GRPH_CRITICAL_CNTL
|
349 RADEON_GRPH_CRITICAL_AT_SOF
|
350 RADEON_GRPH_STOP_CNTL
);
352 Write the result into the register.
354 OUTREG(RADEON_GRPH_BUFFER_CNTL
, ((temp
& ~RADEON_GRPH_CRITICAL_POINT_MASK
) |
355 (critical_point
<< RADEON_GRPH_CRITICAL_POINT_SHIFT
)));
357 D(bug("[ATI] GRPH_BUFFER_CNTL from %x to %x\n",
358 sd
->poweron_state
->grph_buffer_cntl
, INREG(RADEON_GRPH_BUFFER_CNTL
)));
363 * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
365 * Note for current DAC mapping when calling this function:
367 * single CRT: Driver doesn't change the existing CRTC->DAC mapping,
368 * CRTC1 could be driving either DAC or both DACs.
369 * CRT+CRT: CRTC1->TV DAC, CRTC2->Primary DAC
370 * DFP/LCD+CRT: CRTC2->TV DAC, CRTC2->Primary DAC.
371 * Some boards have two DACs reversed or don't even have a primary DAC,
372 * this is reflected in pRADEONEnt->ReversedDAC. And radeon 7200 doesn't
374 * It's kind of messy, we'll need to redo DAC mapping part some day.
376 static void RADEONDacPowerSet(struct ati_staticdata
*sd
, BOOL IsOn
, BOOL IsPrimaryDAC
)
380 ULONG dac_macro_cntl
= 0;
381 dac_cntl
= INREG(RADEON_DAC_CNTL
);
382 if ((!sd
->Card
.IsMobility
) || (sd
->Card
.Type
== RV350
))
383 dac_macro_cntl
= INREG(RADEON_DAC_MACRO_CNTL
);
385 dac_cntl
&= ~RADEON_DAC_PDWN
;
386 dac_macro_cntl
&= ~(RADEON_DAC_PDWN_R
|
390 dac_cntl
|= RADEON_DAC_PDWN
;
391 dac_macro_cntl
|= (RADEON_DAC_PDWN_R
|
395 OUTREG(RADEON_DAC_CNTL
, dac_cntl
);
396 if ((!sd
->Card
.IsMobility
) || (sd
->Card
.Type
== RV350
))
397 OUTREG(RADEON_DAC_MACRO_CNTL
, dac_macro_cntl
);
399 if (sd
->Card
.Type
!= R200
) {
400 ULONG tv_dac_cntl
= INREG(RADEON_TV_DAC_CNTL
);
402 tv_dac_cntl
&= ~(RADEON_TV_DAC_RDACPD
|
403 RADEON_TV_DAC_GDACPD
|
404 RADEON_TV_DAC_BDACPD
|
405 RADEON_TV_DAC_BGSLEEP
);
407 tv_dac_cntl
|= (RADEON_TV_DAC_RDACPD
|
408 RADEON_TV_DAC_GDACPD
|
409 RADEON_TV_DAC_BDACPD
|
410 RADEON_TV_DAC_BGSLEEP
);
412 OUTREG(RADEON_TV_DAC_CNTL
, tv_dac_cntl
);
414 ULONG fp2_gen_cntl
= INREG(RADEON_FP2_GEN_CNTL
);
416 fp2_gen_cntl
|= RADEON_FP2_DVO_EN
;
418 fp2_gen_cntl
&= ~RADEON_FP2_DVO_EN
;
420 OUTREG(RADEON_FP2_GEN_CNTL
, fp2_gen_cntl
);
425 /* Define common registers for requested video mode */
426 static void RADEONInitCommonRegisters(struct ati_staticdata
*sd
, struct CardState
*save
, RADEONModeInfo
*info
)
429 save
->ovr_wid_left_right
= 0;
430 save
->ovr_wid_top_bottom
= 0;
431 save
->ov0_scale_cntl
= 0;
432 save
->subpic_cntl
= 0;
433 save
->viph_control
= 0;
434 save
->i2c_cntl_1
= 0;
435 save
->rbbm_soft_reset
= 0;
436 save
->cap0_trig_cntl
= 0;
437 save
->cap1_trig_cntl
= 0;
438 save
->bus_cntl
= sd
->Card
.BusCntl
;
440 * If bursts are enabled, turn on discards
441 * Radeon doesn't have write bursts
443 if (save
->bus_cntl
& (RADEON_BUS_READ_BURST
))
444 save
->bus_cntl
|= RADEON_BUS_RD_DISCARD_EN
;
447 /* Define CRTC registers for requested video mode */
448 static BOOL
RADEONInitCrtcRegisters(struct ati_staticdata
*sd
, struct CardState
*save
, RADEONModeInfo
*mode
)
456 case 15: format
= 3; mode
->bpp
= 16; break; /* 555 */
457 case 16: format
= 4; break; /* 565 */
458 case 24: format
= 5; mode
->bpp
= 32; break; /* RGB */
459 case 32: format
= 6; break; /* xRGB */
469 if ((sd
->Card
.MonType1
== MT_DFP
) ||
470 (sd
->Card
.MonType1
== MT_LCD
))
472 if (mode
->Flags
& RADEON_USE_RMX
)
474 mode
->HTotal
= mode
->HDisplay
+ sd
->Card
.HBlank
;
475 mode
->HSyncStart
= mode
->HDisplay
+ sd
->Card
.HOverPlus
;
476 mode
->HSyncEnd
= mode
->HSyncStart
+ sd
->Card
.HSyncWidth
;
478 mode
->VTotal
= mode
->VDisplay
+ sd
->Card
.VBlank
;
479 mode
->VSyncStart
= mode
->VDisplay
+ sd
->Card
.VOverPlus
;
480 mode
->VSyncEnd
= mode
->VSyncStart
+ sd
->Card
.VSyncWidth
;
482 mode
->pixelc
= sd
->Card
.DotClock
;
483 mode
->Flags
= sd
->Card
.Flags
| RADEON_USE_RMX
;
487 save
->crtc_gen_cntl
= (RADEON_CRTC_EXT_DISP_EN
489 | RADEON_CRTC_ARGB_EN
491 | ((mode
->height
< 400)
492 ? RADEON_CRTC_DBL_SCAN_EN
495 if ((sd
->Card
.MonType1
== MT_DFP
) ||
496 (sd
->Card
.MonType1
== MT_LCD
)) {
497 save
->crtc_ext_cntl
= RADEON_VGA_ATI_LINEAR
| RADEON_XCRT_CNT_EN
;
498 save
->crtc_gen_cntl
&= ~(RADEON_CRTC_DBL_SCAN_EN
|
499 RADEON_CRTC_CSYNC_EN
|
500 RADEON_CRTC_INTERLACE_EN
);
502 save
->crtc_ext_cntl
= (RADEON_VGA_ATI_LINEAR
|
507 save
->dac_cntl
= (RADEON_DAC_MASK_ALL
508 | RADEON_DAC_VGA_ADR_EN
509 | RADEON_DAC_8BIT_EN
);
511 save
->crtc_h_total_disp
= ((((mode
->HTotal
/ 8) - 1) & 0x3ff)
512 | ((((mode
->HDisplay
/ 8) - 1) & 0x1ff) << 16));
514 hsync_wid
= (mode
->HSyncEnd
- mode
->HSyncStart
) / 8;
515 if (!hsync_wid
) hsync_wid
= 1;
516 hsync_start
= mode
->HSyncStart
- 8;
518 save
->crtc_h_sync_strt_wid
= ((hsync_start
& 0x1fff)
519 | ((hsync_wid
& 0x3f) << 16));
521 /* This works for double scan mode. */
522 save
->crtc_v_total_disp
= (((mode
->VTotal
- 1) & 0xffff)
523 | ((mode
->VDisplay
- 1) << 16));
525 vsync_wid
= mode
->VSyncEnd
- mode
->VSyncStart
;
526 if (!vsync_wid
) vsync_wid
= 1;
528 save
->crtc_v_sync_strt_wid
= (((mode
->VSyncStart
- 1) & 0xfff)
529 | ((vsync_wid
& 0x1f) << 16));
531 save
->crtc_offset
= mode
->base
;
532 save
->crtc_offset_cntl
= INREG(RADEON_CRTC_OFFSET_CNTL
);
534 save
->crtc_pitch
= (((mode
->width
* mode
->bpp
) +
535 ((mode
->bpp
* 8) -1)) /
538 D(bug("[RADEON] crtc_pitch = %08x\n", save
->crtc_pitch
));
540 save
->crtc_pitch
|= save
->crtc_pitch
<< 16;
542 save
->crtc_more_cntl
= 0;
543 if ((sd
->Card
.Type
== RS100
) ||
544 (sd
->Card
.Type
== RS200
)) {
545 /* This is to workaround the asic bug for RMX, some versions
546 of BIOS dosen't have this register initialized correctly.
548 save
->crtc_more_cntl
|= RADEON_CRTC_H_CUTOFF_ACTIVE_EN
;
551 save
->surface_cntl
= 0;
552 save
->disp_merge_cntl
= sd
->poweron_state
->disp_merge_cntl
;
553 save
->disp_merge_cntl
&= ~RADEON_DISP_RGB_OFFSET_EN
;
556 /* Alhought we current onlu use aperture 0, also setting aperture 1 should not harm -ReneR */
559 save
->surface_cntl
|= RADEON_NONSURF_AP0_SWP_16BPP
;
560 save
->surface_cntl
|= RADEON_NONSURF_AP1_SWP_16BPP
;
564 save
->surface_cntl
|= RADEON_NONSURF_AP0_SWP_32BPP
;
565 save
->surface_cntl
|= RADEON_NONSURF_AP1_SWP_32BPP
;
573 /* Define CRTC registers for requested video mode */
574 static BOOL
RADEONInitCrtc2Registers(struct ati_staticdata
*sd
, struct CardState
*save
, RADEONModeInfo
*mode
)
582 case 15: format
= 3; mode
->bpp
= 16; break; /* 555 */
583 case 16: format
= 4; break; /* 565 */
584 case 24: format
= 5; mode
->bpp
= 32; break; /* RGB */
585 case 32: format
= 6; break; /* xRGB */
595 save
->crtc2_gen_cntl
= (RADEON_CRTC2_EN
596 | RADEON_CRTC2_CRT2_ON
597 | RADEON_CRTC_ARGB_EN
599 | ((mode
->height
< 400)
600 ? RADEON_CRTC2_DBL_SCAN_EN
603 /* Turn CRT on in case the first head is a DFP */
604 save
->crtc_ext_cntl
|= RADEON_CRTC_CRT_ON
;
605 save
->dac2_cntl
= sd
->poweron_state
->dac2_cntl
;
606 /* always let TVDAC drive CRT2, we don't support tvout yet */
607 save
->dac2_cntl
|= RADEON_DAC2_DAC2_CLK_SEL
;
608 save
->disp_output_cntl
= sd
->poweron_state
->disp_output_cntl
;
609 if (sd
->Card
.Type
== R200
|| IS_R300_VARIANT
) {
610 save
->disp_output_cntl
&= ~(RADEON_DISP_DAC_SOURCE_MASK
|
611 RADEON_DISP_DAC2_SOURCE_MASK
);
612 if (sd
->Card
.MonType2
!= MT_CRT
) {
613 save
->disp_output_cntl
|= (RADEON_DISP_DAC_SOURCE_CRTC2
|
614 RADEON_DISP_DAC2_SOURCE_CRTC2
);
616 if (sd
->Card
.ReversedDAC
) {
617 save
->disp_output_cntl
|= RADEON_DISP_DAC2_SOURCE_CRTC2
;
619 save
->disp_output_cntl
|= RADEON_DISP_DAC_SOURCE_CRTC2
;
623 save
->disp_hw_debug
= sd
->poweron_state
->disp_hw_debug
;
624 /* Turn on 2nd CRT */
625 if (sd
->Card
.MonType2
!= MT_CRT
) {
626 /* This is for some sample boards with the VGA port
627 connected to the TVDAC, but BIOS doesn't reflect this.
628 Here we configure both DACs to use CRTC2.
629 Not sure if this happens in any retail board.
631 save
->disp_hw_debug
&= ~RADEON_CRT2_DISP1_SEL
;
632 save
->dac2_cntl
|= RADEON_DAC2_DAC_CLK_SEL
;
634 if (sd
->Card
.ReversedDAC
) {
635 save
->disp_hw_debug
&= ~RADEON_CRT2_DISP1_SEL
;
636 save
->dac2_cntl
&= ~RADEON_DAC2_DAC_CLK_SEL
;
638 save
->disp_hw_debug
|= RADEON_CRT2_DISP1_SEL
;
639 save
->dac2_cntl
|= RADEON_DAC2_DAC_CLK_SEL
;
644 save
->crtc2_h_total_disp
=
645 ((((mode
->HTotal
/ 8) - 1) & 0x3ff)
646 | ((((mode
->HDisplay
/ 8) - 1) & 0x1ff) << 16));
648 hsync_wid
= (mode
->HSyncEnd
- mode
->HSyncStart
) / 8;
649 if (!hsync_wid
) hsync_wid
= 1;
650 hsync_start
= mode
->HSyncStart
- 8;
652 save
->crtc2_h_sync_strt_wid
= ((hsync_start
& 0x1fff)
653 | ((hsync_wid
& 0x3f) << 16));
655 /* This works for double scan mode. */
656 save
->crtc2_v_total_disp
= (((mode
->VTotal
- 1) & 0xffff)
657 | ((mode
->VDisplay
- 1) << 16));
659 vsync_wid
= mode
->VSyncEnd
- mode
->VSyncStart
;
660 if (!vsync_wid
) vsync_wid
= 1;
662 save
->crtc2_v_sync_strt_wid
= (((mode
->VSyncStart
- 1) & 0xfff)
663 | ((vsync_wid
& 0x1f) << 16));
665 save
->crtc2_offset
= mode
->base
;
666 save
->crtc2_offset_cntl
= INREG(RADEON_CRTC2_OFFSET_CNTL
);
667 /* this should be right */
668 save
->crtc2_pitch
= (((mode
->width
* mode
->bpp
) +
669 ((mode
->bpp
* 8) -1)) /
671 save
->crtc2_pitch
|= save
->crtc2_pitch
<< 16;
673 save
->disp2_merge_cntl
= sd
->poweron_state
->disp2_merge_cntl
;
674 save
->disp2_merge_cntl
&= ~(RADEON_DISP2_RGB_OFFSET_EN
);
676 if (sd
->Card
.MonType2
== MT_DFP
&& sd
->Card
.IsSecondary
) {
677 save
->crtc2_gen_cntl
= (RADEON_CRTC2_EN
| (format
<< 8));
678 save
->fp2_h_sync_strt_wid
= save
->crtc2_h_sync_strt_wid
;
679 save
->fp2_v_sync_strt_wid
= save
->crtc2_v_sync_strt_wid
;
680 save
->fp2_gen_cntl
= sd
->poweron_state
->fp2_gen_cntl
| RADEON_FP2_ON
;
682 if (sd
->Card
.Type
== R200
|| IS_R300_VARIANT
) {
683 save
->fp2_gen_cntl
&= ~(R200_FP2_SOURCE_SEL_MASK
|
684 RADEON_FP2_DVO_RATE_SEL_SDR
);
686 save
->fp2_gen_cntl
|= (R200_FP2_SOURCE_SEL_CRTC2
|
689 save
->fp2_gen_cntl
&= ~RADEON_FP2_SRC_SEL_MASK
;
690 save
->fp2_gen_cntl
|= RADEON_FP2_SRC_SEL_CRTC2
;
693 save
->fp2_gen_cntl
|= RADEON_FP2_PANEL_FORMAT
; /* 24 bit format */
699 /* Define CRTC registers for requested video mode */
700 static void RADEONInitFPRegisters(struct ati_staticdata
*sd
, struct CardState
*save
, RADEONModeInfo
*mode
)
702 int xres
= mode
->HDisplay
;
703 int yres
= mode
->VDisplay
;
704 float Hratio
, Vratio
;
706 /* If the FP registers have been initialized before for a panel,
707 * but the primary port is a CRT, we need to reinitialize
708 * FP registers in order for CRT to work properly
711 if ((sd
->Card
.MonType1
!= MT_DFP
) && (sd
->Card
.MonType1
!= MT_LCD
)) {
712 save
->fp_crtc_h_total_disp
= sd
->poweron_state
->fp_crtc_h_total_disp
;
713 save
->fp_crtc_v_total_disp
= sd
->poweron_state
->fp_crtc_v_total_disp
;
714 save
->fp_gen_cntl
= 0;
715 save
->fp_h_sync_strt_wid
= sd
->poweron_state
->fp_h_sync_strt_wid
;
716 save
->fp_horz_stretch
= 0;
717 save
->fp_v_sync_strt_wid
= sd
->poweron_state
->fp_v_sync_strt_wid
;
718 save
->fp_vert_stretch
= 0;
719 save
->lvds_gen_cntl
= sd
->poweron_state
->lvds_gen_cntl
;
720 save
->lvds_pll_cntl
= sd
->poweron_state
->lvds_pll_cntl
;
721 save
->tmds_pll_cntl
= sd
->poweron_state
->tmds_pll_cntl
;
722 save
->tmds_transmitter_cntl
= sd
->poweron_state
->tmds_transmitter_cntl
;
724 save
->lvds_gen_cntl
|= ( RADEON_LVDS_DISPLAY_DIS
| (1 << 23));
725 save
->lvds_gen_cntl
&= ~(RADEON_LVDS_BLON
| RADEON_LVDS_ON
);
726 save
->fp_gen_cntl
&= ~(RADEON_FP_FPON
| RADEON_FP_TMDS_EN
);
731 if (sd
->Card
.PanelXRes
== 0 || sd
->Card
.PanelYRes
== 0) {
735 if (xres
> sd
->Card
.PanelXRes
) xres
= sd
->Card
.PanelXRes
;
736 if (yres
> sd
->Card
.PanelYRes
) yres
= sd
->Card
.PanelYRes
;
738 Hratio
= (float)xres
/(float)sd
->Card
.PanelXRes
;
739 Vratio
= (float)yres
/(float)sd
->Card
.PanelYRes
;
742 if (Hratio
== 1.0 || !(mode
->Flags
& RADEON_USE_RMX
)) {
743 save
->fp_horz_stretch
= sd
->poweron_state
->fp_horz_stretch
;
744 save
->fp_horz_stretch
&= ~(RADEON_HORZ_STRETCH_BLEND
|
745 RADEON_HORZ_STRETCH_ENABLE
);
746 save
->fp_horz_stretch
&= ~(RADEON_HORZ_AUTO_RATIO
|
747 RADEON_HORZ_PANEL_SIZE
);
748 save
->fp_horz_stretch
|= ((xres
/8-1)<<16);
750 save
->fp_horz_stretch
=
751 ((((unsigned long)(Hratio
* RADEON_HORZ_STRETCH_RATIO_MAX
+
752 0.5)) & RADEON_HORZ_STRETCH_RATIO_MASK
)) |
753 (sd
->poweron_state
->fp_horz_stretch
& (RADEON_HORZ_PANEL_SIZE
|
754 RADEON_HORZ_FP_LOOP_STRETCH
|
755 RADEON_HORZ_AUTO_RATIO_INC
));
756 save
->fp_horz_stretch
|= (RADEON_HORZ_STRETCH_BLEND
|
757 RADEON_HORZ_STRETCH_ENABLE
);
759 save
->fp_horz_stretch
&= ~(RADEON_HORZ_AUTO_RATIO
|
760 RADEON_HORZ_PANEL_SIZE
);
761 save
->fp_horz_stretch
|= ((sd
->Card
.PanelXRes
/ 8 - 1) << 16);
764 if (Vratio
== 1.0 || !(mode
->Flags
& RADEON_USE_RMX
)) {
765 save
->fp_vert_stretch
= sd
->poweron_state
->fp_vert_stretch
;
766 save
->fp_vert_stretch
&= ~(RADEON_VERT_STRETCH_ENABLE
|
767 RADEON_VERT_STRETCH_BLEND
);
768 save
->fp_vert_stretch
&= ~(RADEON_VERT_AUTO_RATIO_EN
|
769 RADEON_VERT_PANEL_SIZE
);
770 save
->fp_vert_stretch
|= ((yres
-1) << 12);
772 save
->fp_vert_stretch
=
773 (((((unsigned long)(Vratio
* RADEON_VERT_STRETCH_RATIO_MAX
+
774 0.5)) & RADEON_VERT_STRETCH_RATIO_MASK
)) |
775 (sd
->poweron_state
->fp_vert_stretch
& (RADEON_VERT_PANEL_SIZE
|
776 RADEON_VERT_STRETCH_RESERVED
)));
777 save
->fp_vert_stretch
|= (RADEON_VERT_STRETCH_ENABLE
|
778 RADEON_VERT_STRETCH_BLEND
);
780 save
->fp_vert_stretch
&= ~(RADEON_VERT_AUTO_RATIO_EN
|
781 RADEON_VERT_PANEL_SIZE
);
782 save
->fp_vert_stretch
|= ((sd
->Card
.PanelYRes
-1) << 12);
785 save
->fp_gen_cntl
= (sd
->poweron_state
->fp_gen_cntl
& (ULONG
)
786 ~(RADEON_FP_SEL_CRTC2
|
787 RADEON_FP_RMX_HVSYNC_CONTROL_EN
|
788 RADEON_FP_DFP_SYNC_SEL
|
789 RADEON_FP_CRT_SYNC_SEL
|
790 RADEON_FP_CRTC_LOCK_8DOT
|
791 RADEON_FP_USE_SHADOW_EN
|
792 RADEON_FP_CRTC_USE_SHADOW_VEND
|
793 RADEON_FP_CRT_SYNC_ALT
));
794 save
->fp_gen_cntl
|= (RADEON_FP_CRTC_DONT_SHADOW_VPAR
|
795 RADEON_FP_CRTC_DONT_SHADOW_HEND
);
797 save
->fp_gen_cntl
|= RADEON_FP_PANEL_FORMAT
; /* 24 bit format */
799 if (IS_R300_VARIANT
|| (sd
->Card
.Type
== R200
)) {
800 save
->fp_gen_cntl
&= ~R200_FP_SOURCE_SEL_MASK
;
801 if (sd
->Card
.Flags
& RADEON_USE_RMX
)
802 save
->fp_gen_cntl
|= R200_FP_SOURCE_SEL_RMX
;
804 save
->fp_gen_cntl
|= R200_FP_SOURCE_SEL_CRTC1
;
806 save
->fp_gen_cntl
|= RADEON_FP_SEL_CRTC1
;
808 save
->lvds_gen_cntl
= sd
->poweron_state
->lvds_gen_cntl
;
809 save
->lvds_pll_cntl
= sd
->poweron_state
->lvds_pll_cntl
;
811 save
->tmds_pll_cntl
= sd
->poweron_state
->tmds_pll_cntl
;
812 save
->tmds_transmitter_cntl
= sd
->poweron_state
->tmds_transmitter_cntl
;
814 if (sd
->Card
.MonType1
== MT_LCD
) {
816 save
->lvds_gen_cntl
|= (RADEON_LVDS_ON
| RADEON_LVDS_BLON
);
817 save
->fp_gen_cntl
&= ~(RADEON_FP_FPON
| RADEON_FP_TMDS_EN
);
819 } else if (sd
->Card
.MonType1
== MT_DFP
) {
821 ULONG tmp
= sd
->poweron_state
->tmds_pll_cntl
& 0xfffff;
822 for (i
=0; i
<4; i
++) {
823 if (sd
->Card
.tmds_pll
[i
].freq
== 0) break;
824 if (save
->dot_clock_freq
< sd
->Card
.tmds_pll
[i
].freq
) {
825 tmp
= sd
->Card
.tmds_pll
[i
].value
;
829 if (IS_R300_VARIANT
|| (sd
->Card
.Type
== RV280
)) {
830 if (tmp
& 0xfff00000)
831 save
->tmds_pll_cntl
= tmp
;
833 save
->tmds_pll_cntl
= (sd
->poweron_state
->tmds_pll_cntl
& 0xfff00000) | tmp
;
834 } else save
->tmds_pll_cntl
= tmp
;
836 D(bug("[ATI] TMDS_PLL from %x to %x\n",
837 sd
->poweron_state
->tmds_pll_cntl
,
838 save
->tmds_pll_cntl
));
840 save
->tmds_transmitter_cntl
&= ~(RADEON_TMDS_TRANSMITTER_PLLRST
);
842 if (IS_R300_VARIANT
|| (sd
->Card
.Type
== R200
) || !sd
->Card
.HasCRTC2
)
843 save
->tmds_transmitter_cntl
&= ~(RADEON_TMDS_TRANSMITTER_PLLEN
);
844 else /* weird, RV chips got this bit reversed? */
845 save
->tmds_transmitter_cntl
|= (RADEON_TMDS_TRANSMITTER_PLLEN
);
847 save
->fp_gen_cntl
|= (RADEON_FP_FPON
| RADEON_FP_TMDS_EN
);
850 if (sd
->Card
.IsMobility
) {
851 /* To work correctly with laptop hotkeys.
852 * Since there is no machnism for accessing ACPI evnets
853 * and the driver currently doesn't know how to validate
854 * a mode dynamically, we have to tell BIOS don't do
855 * display switching after X has started.
856 * If LCD is on, lid close/open should still work
857 * with below settings
859 if (sd
->Card
.MonType1
== MT_LCD
) {
860 if (sd
->Card
.MonType2
== MT_CRT
)
861 save
->bios_5_scratch
= 0x0201;
862 else if (sd
->Card
.MonType2
== MT_DFP
)
863 save
->bios_5_scratch
= 0x0801;
865 save
->bios_5_scratch
= sd
->poweron_state
->bios_5_scratch
;
867 if (sd
->Card
.MonType2
== MT_CRT
)
868 save
->bios_5_scratch
= 0x0200;
869 else if (sd
->Card
.MonType2
== MT_DFP
)
870 save
->bios_5_scratch
= 0x0800;
872 save
->bios_5_scratch
= 0x0;
874 save
->bios_4_scratch
= 0x4;
875 save
->bios_6_scratch
= sd
->poweron_state
->bios_6_scratch
| 0x40000000;
878 save
->fp_crtc_h_total_disp
= save
->crtc_h_total_disp
;
879 save
->fp_crtc_v_total_disp
= save
->crtc_v_total_disp
;
880 save
->fp_h_sync_strt_wid
= save
->crtc_h_sync_strt_wid
;
881 save
->fp_v_sync_strt_wid
= save
->crtc_v_sync_strt_wid
;
884 static void RADEONInitPLLRegisters(struct ati_staticdata
*sd
, struct CardState
*save
, RADEONModeInfo
*mode
)
886 double freq
= mode
->pixelc
/10.0;
891 } *post_div
, post_divs
[] = {
892 /* From RAGE 128 VR/RAGE 128 GL Register
893 * Reference Manual (Technical Reference
894 * Manual P/N RRG-G04100-C Rev. 0.04), page
895 * 3-17 (PLL_DIV_[3:0]).
897 { 1, 0 }, /* VCLK_SRC */
898 { 2, 1 }, /* VCLK_SRC/2 */
899 { 4, 2 }, /* VCLK_SRC/4 */
900 { 8, 3 }, /* VCLK_SRC/8 */
901 { 3, 4 }, /* VCLK_SRC/3 */
902 { 16, 5 }, /* VCLK_SRC/16 */
903 { 6, 6 }, /* VCLK_SRC/6 */
904 { 12, 7 }, /* VCLK_SRC/12 */
908 if (freq
> sd
->Card
.pll
.max_pll_freq
) freq
= sd
->Card
.pll
.max_pll_freq
;
909 if (freq
* 12 < sd
->Card
.pll
.min_pll_freq
) freq
= sd
->Card
.pll
.min_pll_freq
/ 12;
911 for (post_div
= &post_divs
[0]; post_div
->divider
; ++post_div
) {
912 save
->pll_output_freq
= post_div
->divider
* freq
;
914 if (save
->pll_output_freq
>= sd
->Card
.pll
.min_pll_freq
915 && save
->pll_output_freq
<= sd
->Card
.pll
.max_pll_freq
) break;
918 if (!post_div
->divider
) {
919 save
->pll_output_freq
= freq
;
920 post_div
= &post_divs
[0];
923 save
->dot_clock_freq
= freq
;
924 save
->feedback_div
= RADEONDiv(sd
->Card
.pll
.reference_div
925 * save
->pll_output_freq
,
926 sd
->Card
.pll
.reference_freq
);
927 save
->post_div
= post_div
->divider
;
929 D(bug("[ATI] dc=%d, of=%d, fd=%d, pd=%d\n",
930 save
->dot_clock_freq
,
931 save
->pll_output_freq
,
935 save
->ppll_ref_div
= sd
->Card
.pll
.reference_div
;
936 save
->ppll_div_3
= (save
->feedback_div
| (post_div
->bitvalue
<< 16));
937 save
->htotal_cntl
= 0;
940 /* Define PLL2 registers for requested video mode */
941 static void RADEONInitPLL2Registers(struct ati_staticdata
*sd
, struct CardState
*save
, RADEONModeInfo
*mode
)
943 double freq
= mode
->pixelc
/10.0;
948 } *post_div
, post_divs
[] = {
949 /* From RAGE 128 VR/RAGE 128 GL Register
950 * Reference Manual (Technical Reference
951 * Manual P/N RRG-G04100-C Rev. 0.04), page
952 * 3-17 (PLL_DIV_[3:0]).
954 { 1, 0 }, /* VCLK_SRC */
955 { 2, 1 }, /* VCLK_SRC/2 */
956 { 4, 2 }, /* VCLK_SRC/4 */
957 { 8, 3 }, /* VCLK_SRC/8 */
958 { 3, 4 }, /* VCLK_SRC/3 */
959 { 6, 6 }, /* VCLK_SRC/6 */
960 { 12, 7 }, /* VCLK_SRC/12 */
964 if (freq
> sd
->Card
.pll
.max_pll_freq
) freq
= sd
->Card
.pll
.max_pll_freq
;
965 if (freq
* 12 < sd
->Card
.pll
.min_pll_freq
) freq
= sd
->Card
.pll
.min_pll_freq
/ 12;
967 for (post_div
= &post_divs
[0]; post_div
->divider
; ++post_div
) {
968 save
->pll_output_freq_2
= post_div
->divider
* freq
;
969 if (save
->pll_output_freq_2
>= sd
->Card
.pll
.min_pll_freq
970 && save
->pll_output_freq_2
<= sd
->Card
.pll
.max_pll_freq
) break;
973 if (!post_div
->divider
) {
974 save
->pll_output_freq_2
= freq
;
975 post_div
= &post_divs
[0];
978 save
->dot_clock_freq_2
= freq
;
979 save
->feedback_div_2
= RADEONDiv(sd
->Card
.pll
.reference_div
980 * save
->pll_output_freq_2
,
981 sd
->Card
.pll
.reference_freq
);
982 save
->post_div_2
= post_div
->divider
;
984 D(bug("[ATI] dc=%d, of=%d, fd=%d, pd=%d\n",
985 save
->dot_clock_freq_2
,
986 save
->pll_output_freq_2
,
987 save
->feedback_div_2
,
990 save
->p2pll_ref_div
= sd
->Card
.pll
.reference_div
;
991 save
->p2pll_div_0
= (save
->feedback_div_2
|
992 (post_div
->bitvalue
<< 16));
993 save
->htotal_cntl2
= 0;
996 static void RADEONGetVRamType(struct ati_staticdata
*sd
)
1000 if (sd
->Card
.IsIGP
|| (sd
->Card
.Type
>= R300
) ||
1001 (INREG(RADEON_MEM_SDRAM_MODE_REG
) & (1<<30)))
1002 sd
->Card
.IsDDR
= TRUE
;
1004 sd
->Card
.IsDDR
= FALSE
;
1006 tmp
= INREG(RADEON_MEM_CNTL
);
1007 if (IS_R300_VARIANT
) {
1008 tmp
&= R300_MEM_NUM_CHANNELS_MASK
;
1010 case 0: sd
->Card
.RamWidth
= 64; break;
1011 case 1: sd
->Card
.RamWidth
= 128; break;
1012 case 2: sd
->Card
.RamWidth
= 256; break;
1013 default: sd
->Card
.RamWidth
= 128; break;
1015 } else if ((sd
->Card
.Type
== RV100
) ||
1016 (sd
->Card
.Type
== RS100
) ||
1017 (sd
->Card
.Type
== RS200
)){
1018 if (tmp
& RV100_HALF_MODE
) sd
->Card
.RamWidth
= 32;
1019 else sd
->Card
.RamWidth
= 64;
1021 if (tmp
& RADEON_MEM_NUM_CHANNELS_MASK
) sd
->Card
.RamWidth
= 128;
1022 else sd
->Card
.RamWidth
= 64;
1025 /* This may not be correct, as some cards can have half of channel disabled
1026 * ToDo: identify these cases
1030 struct RADEONInt10Save
{
1033 ULONG MPP_TB_CONFIG
;
1036 static void RADEONPreInt10Save(struct ati_staticdata
*sd
, void **pPtr
)
1039 static struct RADEONInt10Save SaveStruct
= { 0, 0, 0 };
1041 /* Save the values and zap MEM_CNTL */
1042 SaveStruct
.MEM_CNTL
= INREG(RADEON_MEM_CNTL
);
1043 SaveStruct
.MEMSIZE
= INREG(RADEON_CONFIG_MEMSIZE
);
1044 SaveStruct
.MPP_TB_CONFIG
= INREG(RADEON_MPP_TB_CONFIG
);
1047 * Zap MEM_CNTL and set MPP_TB_CONFIG<31:24> to 4
1049 OUTREG(RADEON_MEM_CNTL
, 0);
1050 CardTmp
= SaveStruct
.MPP_TB_CONFIG
& 0x00ffffffu
;
1051 CardTmp
|= 0x04 << 24;
1052 OUTREG(RADEON_MPP_TB_CONFIG
, CardTmp
);
1054 *pPtr
= (void *)&SaveStruct
;
1057 static void RADEONPostInt10Check(struct ati_staticdata
*sd
, void *ptr
)
1059 struct RADEONInt10Save
*pSave
= ptr
;
1062 /* If we don't have a valid (non-zero) saved MEM_CNTL, get out now */
1063 if (!pSave
|| !pSave
->MEM_CNTL
)
1067 * If either MEM_CNTL is currently zero or inconistent (configured for
1068 * two channels with the two channels configured differently), restore
1069 * the saved registers.
1071 CardTmp
= INREG(RADEON_MEM_CNTL
);
1074 (((CardTmp
>> 8) & 0xff) != ((CardTmp
>> 24) & 0xff)))) {
1075 /* Restore the saved registers */
1076 D(bug("[ATI] Restoring MEM_CNTL (%08lx), setting to %08lx\n",
1077 (unsigned long)CardTmp
, (unsigned long)pSave
->MEM_CNTL
));
1078 OUTREG(RADEON_MEM_CNTL
, pSave
->MEM_CNTL
);
1080 CardTmp
= INREG(RADEON_CONFIG_MEMSIZE
);
1081 if (CardTmp
!= pSave
->MEMSIZE
) {
1082 D(bug("[ATI] Restoring CONFIG_MEMSIZE (%08lx), setting to %08lx\n",
1083 (unsigned long)CardTmp
, (unsigned long)pSave
->MEMSIZE
));
1084 OUTREG(RADEON_CONFIG_MEMSIZE
, pSave
->MEMSIZE
);
1088 CardTmp
= INREG(RADEON_MPP_TB_CONFIG
);
1089 if ((CardTmp
& 0xff000000u
) != (pSave
->MPP_TB_CONFIG
& 0xff000000u
)) {
1090 D(bug("[ATI] Restoring MPP_TB_CONFIG<31:24> (%02lx), setting to %02lx\n",
1091 (unsigned long)CardTmp
>> 24,
1092 (unsigned long)pSave
->MPP_TB_CONFIG
>> 24));
1093 CardTmp
&= 0x00ffffffu
;
1094 CardTmp
|= (pSave
->MPP_TB_CONFIG
& 0xff000000u
);
1095 OUTREG(RADEON_MPP_TB_CONFIG
, CardTmp
);
1099 static void RADEONGetPanelInfo(struct ati_staticdata
*sd
)
1103 static void RADEONGetClockInfo(struct ati_staticdata
*sd
)
1105 RADEONPLLRec
*pll
= &sd
->Card
.pll
;
1106 double min_dotclock
;
1108 if (RADEONGetClockInfoFromBIOS(sd
)) {
1109 if (pll
->reference_div
< 2) {
1110 /* retrive it from register setting for fitting into current PLL algorithm.
1111 We'll probably need a new routine to calculate the best ref_div from BIOS
1112 provided min_input_pll and max_input_pll
1115 tmp
= RADEONINPLL(sd
, RADEON_PPLL_REF_DIV
);
1116 if (IS_R300_VARIANT
||
1117 (sd
->Card
.Type
== RS300
)) {
1118 pll
->reference_div
= (tmp
& R300_PPLL_REF_DIV_ACC_MASK
) >> R300_PPLL_REF_DIV_ACC_SHIFT
;
1120 pll
->reference_div
= tmp
& RADEON_PPLL_REF_DIV_MASK
;
1123 if (pll
->reference_div
< 2) pll
->reference_div
= 12;
1127 D(bug("[ATI] Video BIOS not detected, using default clock settings!\n"));
1130 pll
->reference_freq
= 1432;
1132 pll
->reference_freq
= 2700;
1134 pll
->reference_div
= 12;
1135 pll
->min_pll_freq
= 12500;
1136 pll
->max_pll_freq
= 35000;
1139 sd
->Card
.sclk
= 200.00;
1140 sd
->Card
.mclk
= 200.00;
1143 D(bug("[ATI] PLL parameters: rf=%d rd=%d min=%ld max=%ld; xclk=%d\n",
1144 pll
->reference_freq
,
1146 pll
->min_pll_freq
, pll
->max_pll_freq
, pll
->xclk
));
1149 static BOOL
RADEONQueryConnectedMonitors(struct ati_staticdata
*sd
)
1152 BOOL ignore_edid
= TRUE
;
1153 int i
= 0, second
= 0, max_mt
;
1155 const char *MonTypeName
[7] =
1166 const RADEONMonitorType MonTypeID
[7] =
1168 MT_UNKNOWN
, /* this is just a dummy value for AUTO DETECTION */
1169 MT_NONE
, /* NONE -> NONE */
1170 MT_CRT
, /* CRT -> CRT */
1171 MT_LCD
, /* Laptop LCDs are driven via LVDS port */
1172 MT_DFP
, /* DFPs are driven via TMDS */
1173 MT_CTV
, /* CTV -> CTV */
1174 MT_STV
, /* STV -> STV */
1177 const char *TMDSTypeName
[3] =
1184 const char *DDCTypeName
[5] =
1193 const char *DACTypeName
[3] =
1200 const char *ConnectorTypeName
[8] =
1212 const char *ConnectorTypeNameATOM
[10] =
1229 if(info->IsSecondary) {
1230 info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType2;
1231 if(info->DisplayType == MT_NONE) return FALSE;
1236 /* We first get the information about all connectors from BIOS.
1237 * This is how the card is phyiscally wired up.
1238 * The information should be correct even on a OEM card.
1239 * If not, we may have problem -- need to use MonitorLayout option.
1241 for (i
= 0; i
< 2; i
++) {
1242 sd
->Card
.PortInfo
[i
].MonType
= MT_UNKNOWN
;
1243 // sd->Card.PortInfo[i].MonInfo = NULL;
1244 sd
->Card
.PortInfo
[i
].DDCType
= DDC_NONE_DETECTED
;
1245 sd
->Card
.PortInfo
[i
].DACType
= DAC_UNKNOWN
;
1246 sd
->Card
.PortInfo
[i
].TMDSType
= TMDS_UNKNOWN
;
1247 sd
->Card
.PortInfo
[i
].ConnectorType
= CONNECTOR_NONE
;
1250 if (!RADEONGetConnectorInfoFromBIOS(sd
)) {
1251 /* Below is the most common setting, but may not be true */
1252 sd
->Card
.PortInfo
[0].MonType
= MT_UNKNOWN
;
1253 // sd->Card.PortInfo[0].MonInfo = NULL;
1254 sd
->Card
.PortInfo
[0].DDCType
= DDC_DVI
;
1255 sd
->Card
.PortInfo
[0].DACType
= DAC_TVDAC
;
1256 sd
->Card
.PortInfo
[0].TMDSType
= TMDS_INT
;
1257 sd
->Card
.PortInfo
[0].ConnectorType
= CONNECTOR_DVI_D
;
1259 sd
->Card
.PortInfo
[1].MonType
= MT_UNKNOWN
;
1260 // sd->Card.PortInfo[1].MonInfo = NULL;
1261 sd
->Card
.PortInfo
[1].DDCType
= DDC_VGA
;
1262 sd
->Card
.PortInfo
[1].DACType
= DAC_PRIMARY
;
1263 sd
->Card
.PortInfo
[1].TMDSType
= TMDS_EXT
;
1264 sd
->Card
.PortInfo
[1].ConnectorType
= CONNECTOR_CRT
;
1267 /* always make TMDS_INT port first*/
1268 if (sd
->Card
.PortInfo
[1].TMDSType
== TMDS_INT
) {
1269 RADEONConnector connector
;
1270 connector
= sd
->Card
.PortInfo
[0];
1271 sd
->Card
.PortInfo
[0] = sd
->Card
.PortInfo
[1];
1272 sd
->Card
.PortInfo
[1] = connector
;
1273 } else if ((sd
->Card
.PortInfo
[0].TMDSType
!= TMDS_INT
&&
1274 sd
->Card
.PortInfo
[1].TMDSType
!= TMDS_INT
)) {
1275 /* no TMDS_INT port, make primary DAC port first */
1276 if (sd
->Card
.PortInfo
[1].DACType
== DAC_PRIMARY
) {
1277 RADEONConnector connector
;
1278 connector
= sd
->Card
.PortInfo
[0];
1279 sd
->Card
.PortInfo
[0] = sd
->Card
.PortInfo
[1];
1280 sd
->Card
.PortInfo
[1] = connector
;
1284 if (sd
->Card
.HasSingleDAC
) {
1285 /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
1286 if (sd
->Card
.PortInfo
[0].ConnectorType
== CONNECTOR_CRT
) {
1287 sd
->Card
.PortInfo
[0].DACType
= DAC_TVDAC
;
1288 sd
->Card
.PortInfo
[1].DACType
= DAC_PRIMARY
;
1290 sd
->Card
.PortInfo
[1].DACType
= DAC_TVDAC
;
1291 sd
->Card
.PortInfo
[0].DACType
= DAC_PRIMARY
;
1293 } else if (!sd
->Card
.HasCRTC2
) {
1294 sd
->Card
.PortInfo
[0].DACType
= DAC_PRIMARY
;
1297 if(((!sd
->Card
.HasCRTC2
) || sd
->Card
.IsDellServer
)) {
1298 if (sd
->Card
.PortInfo
[0].MonType
== MT_UNKNOWN
) {
1300 if((sd->Card.PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &sd->Card.PortInfo[0])));
1301 else if((sd->Card.PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_VGA, &sd->Card.PortInfo[0])));
1302 else if((sd->Card.PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_CRT2, &sd->Card.PortInfo[0])));
1305 sd
->Card
.PortInfo
[0].MonType
= MT_CRT
;
1307 sd
->Card
.MonType1
= sd
->Card
.PortInfo
[0].MonType
;
1308 // pRADEONEnt->MonInfo1 = sd->Card.PortInfo[0]. .MonInfo;
1309 sd
->Card
.MonType2
= MT_NONE
;
1310 // pRADEONEnt->MonInfo2 = NULL;
1312 D(bug("[ATI] Primary:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n",
1313 MonTypeName
[sd
->Card
.PortInfo
[0].MonType
+1],
1314 sd
->Card
.IsAtomBios
?
1315 ConnectorTypeNameATOM
[sd
->Card
.PortInfo
[0].ConnectorType
]:
1316 ConnectorTypeName
[sd
->Card
.PortInfo
[0].ConnectorType
],
1317 DACTypeName
[sd
->Card
.PortInfo
[0].DACType
+1],
1318 TMDSTypeName
[sd
->Card
.PortInfo
[0].TMDSType
+1],
1319 DDCTypeName
[sd
->Card
.PortInfo
[0].DDCType
]));
1324 if (sd
->Card
.PortInfo
[0].MonType
== MT_UNKNOWN
|| sd
->Card
.PortInfo
[1].MonType
== MT_UNKNOWN
) {
1326 /* Primary Head (DVI or Laptop Int. panel)*/
1327 /* A ddc capable display connected on DVI port */
1328 if (sd
->Card
.PortInfo
[0].MonType
== MT_UNKNOWN
) {
1329 // if((sd->Card.PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[0].DDCType, &pRADEONEnt->PortInfo[0])));
1331 if (sd
->Card
.IsMobility
&&
1332 (INREG(RADEON_BIOS_4_SCRATCH
) & 4)) {
1333 /* non-DDC laptop panel connected on primary */
1334 sd
->Card
.PortInfo
[0].MonType
= MT_LCD
;
1336 /* CRT on DVI, TODO: not reliable, make it always return false for now*/
1337 // sd->Card.PortInfo[0].MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRADEONEnt->PortInfo[0].DACType));
1341 /* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
1342 if (sd
->Card
.PortInfo
[1].MonType
== MT_UNKNOWN
) {
1343 // if((sd->Card.PortInfo[1].MonType =
1344 // RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[1].DDCType, &pRADEONEnt->PortInfo[1])));
1346 if (sd
->Card
.IsMobility
&&
1347 (INREG(RADEON_FP2_GEN_CNTL
) & RADEON_FP2_ON
)) {
1348 /* non-DDC TMDS panel connected through DVO */
1349 sd
->Card
.PortInfo
[1].MonType
= MT_DFP
;
1352 // sd->Card.PortInfo[1].MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRADEONEnt->PortInfo[1].DACType));
1357 sd
->Card
.MonType1
= sd
->Card
.PortInfo
[0].MonType
;
1358 sd
->Card
.MonType2
= sd
->Card
.PortInfo
[1].MonType
;
1359 if (sd
->Card
.PortInfo
[0].MonType
== MT_NONE
) {
1360 if (sd
->Card
.PortInfo
[1].MonType
== MT_NONE
) {
1361 sd
->Card
.MonType1
= MT_CRT
;
1363 RADEONConnector tmp
;
1364 sd
->Card
.MonType1
= sd
->Card
.PortInfo
[1].MonType
;
1365 tmp
= sd
->Card
.PortInfo
[0];
1366 sd
->Card
.PortInfo
[0] = sd
->Card
.PortInfo
[1];
1367 sd
->Card
.PortInfo
[1] = tmp
;
1369 sd
->Card
.MonType2
= MT_NONE
;
1371 sd
->Card
.ReversedDAC
= FALSE
;
1372 sd
->Card
.OverlayOnCRTC2
= FALSE
;
1374 if (sd
->Card
.MonType2
!= MT_NONE
) {
1376 if (sd
->Card
.PortInfo
[1].DACType
== DAC_TVDAC
) {
1377 D(bug("[ATI] Reversed DAC decteced\n"));
1378 sd
->Card
.ReversedDAC
= TRUE
;
1381 sd
->Card
.HasSecondary
= FALSE
;
1383 D(bug("[ATI] Primary:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n",
1384 MonTypeName
[sd
->Card
.PortInfo
[0].MonType
+1],
1385 sd
->Card
.IsAtomBios
?
1386 ConnectorTypeNameATOM
[sd
->Card
.PortInfo
[0].ConnectorType
]:
1387 ConnectorTypeName
[sd
->Card
.PortInfo
[0].ConnectorType
],
1388 DACTypeName
[sd
->Card
.PortInfo
[0].DACType
+1],
1389 TMDSTypeName
[sd
->Card
.PortInfo
[0].TMDSType
+1],
1390 DDCTypeName
[sd
->Card
.PortInfo
[0].DDCType
]));
1392 D(bug("[ATI] Secondary:\n Monitor -- %s\n Connector -- %s\n DAC Type -- %s\n TMDS Type -- %s\n DDC Type -- %s\n",
1393 MonTypeName
[sd
->Card
.PortInfo
[1].MonType
+1],
1394 sd
->Card
.IsAtomBios
?
1395 ConnectorTypeNameATOM
[sd
->Card
.PortInfo
[1].ConnectorType
]:
1396 ConnectorTypeName
[sd
->Card
.PortInfo
[1].ConnectorType
],
1397 DACTypeName
[sd
->Card
.PortInfo
[1].DACType
+1],
1398 TMDSTypeName
[sd
->Card
.PortInfo
[1].TMDSType
+1],
1399 DDCTypeName
[sd
->Card
.PortInfo
[1].DDCType
]));
1408 * Accesible functions
1411 void InitMode(struct ati_staticdata
*sd
, struct CardState
*save
,
1412 ULONG width
, ULONG height
, UBYTE bpp
, ULONG pixelc
, IPTR base
,
1413 ULONG HDisplay
, ULONG VDisplay
,
1414 ULONG HSyncStart
, ULONG HSyncEnd
, ULONG HTotal
,
1415 ULONG VSyncStart
, ULONG VSyncEnd
, ULONG VTotal
)
1417 RADEONModeInfo info
= {
1418 width
, height
, bpp
, pixelc
, base
,
1419 HDisplay
, VDisplay
, HSyncStart
, HSyncEnd
, HTotal
,
1420 VSyncStart
, VSyncEnd
, VTotal
};
1422 RADEONInitCommonRegisters(sd
, save
, &info
);
1424 if (sd
->Card
.IsSecondary
)
1426 RADEONInitCrtc2Registers(sd
, save
, &info
);
1427 RADEONInitPLL2Registers(sd
, save
, &info
);
1431 RADEONInitCrtcRegisters(sd
, save
, &info
);
1432 RADEONInitPLLRegisters(sd
, save
, &info
);
1434 RADEONInitFPRegisters(sd
, save
, &info
);
1436 save
->pixelc
= info
.pixelc
;
1437 save
->HDisplay
= info
.HDisplay
;
1440 void ShowHideCursor(struct ati_staticdata
*sd
, BOOL visible
)
1442 D(bug("[ATI] ShowHideCursor: %s\n", visible
? "show":"hide"));
1446 if (sd
->Card
.IsSecondary
)
1447 OUTREGP(RADEON_CRTC2_GEN_CNTL
, RADEON_CRTC2_CUR_EN
, ~RADEON_CRTC2_CUR_EN
);
1449 OUTREGP(RADEON_CRTC_GEN_CNTL
, RADEON_CRTC_CUR_EN
, ~RADEON_CRTC_CUR_EN
);
1453 if (sd
->Card
.IsSecondary
)
1454 OUTREGP(RADEON_CRTC2_GEN_CNTL
, 0, ~RADEON_CRTC2_CUR_EN
);
1456 OUTREGP(RADEON_CRTC_GEN_CNTL
, 0, ~RADEON_CRTC_CUR_EN
);
1460 void SaveState(struct ati_staticdata
*sd
, struct CardState
*save
)
1462 save
->dp_datatype
= INREG(RADEON_DP_DATATYPE
);
1463 save
->rbbm_soft_reset
= INREG(RADEON_RBBM_SOFT_RESET
);
1464 save
->clock_cntl_index
= INREG(RADEON_CLOCK_CNTL_INDEX
);
1465 if (sd
->Card
.R300CGWorkaround
) R300CGWorkaround(sd
);
1468 save
->ovr_clr
= INREG(RADEON_OVR_CLR
);
1469 save
->ovr_wid_left_right
= INREG(RADEON_OVR_WID_LEFT_RIGHT
);
1470 save
->ovr_wid_top_bottom
= INREG(RADEON_OVR_WID_TOP_BOTTOM
);
1471 save
->ov0_scale_cntl
= INREG(RADEON_OV0_SCALE_CNTL
);
1472 save
->subpic_cntl
= INREG(RADEON_SUBPIC_CNTL
);
1473 save
->viph_control
= INREG(RADEON_VIPH_CONTROL
);
1474 save
->i2c_cntl_1
= INREG(RADEON_I2C_CNTL_1
);
1475 save
->gen_int_cntl
= INREG(RADEON_GEN_INT_CNTL
);
1476 save
->cap0_trig_cntl
= INREG(RADEON_CAP0_TRIG_CNTL
);
1477 save
->cap1_trig_cntl
= INREG(RADEON_CAP1_TRIG_CNTL
);
1478 save
->bus_cntl
= INREG(RADEON_BUS_CNTL
);
1479 save
->surface_cntl
= INREG(RADEON_SURFACE_CNTL
);
1480 save
->grph_buffer_cntl
= INREG(RADEON_GRPH_BUFFER_CNTL
);
1481 save
->grph2_buffer_cntl
= INREG(RADEON_GRPH2_BUFFER_CNTL
);
1483 if (!sd
->Card
.IsSecondary
)
1486 save
->ppll_ref_div
= RADEONINPLL(sd
, RADEON_PPLL_REF_DIV
);
1487 save
->ppll_div_3
= RADEONINPLL(sd
, RADEON_PPLL_DIV_3
);
1488 save
->htotal_cntl
= RADEONINPLL(sd
, RADEON_HTOTAL_CNTL
);
1491 save
->crtc_gen_cntl
= INREG(RADEON_CRTC_GEN_CNTL
);
1492 save
->crtc_ext_cntl
= INREG(RADEON_CRTC_EXT_CNTL
);
1493 save
->dac_cntl
= INREG(RADEON_DAC_CNTL
);
1494 save
->crtc_h_total_disp
= INREG(RADEON_CRTC_H_TOTAL_DISP
);
1495 save
->crtc_h_sync_strt_wid
= INREG(RADEON_CRTC_H_SYNC_STRT_WID
);
1496 save
->crtc_v_total_disp
= INREG(RADEON_CRTC_V_TOTAL_DISP
);
1497 save
->crtc_v_sync_strt_wid
= INREG(RADEON_CRTC_V_SYNC_STRT_WID
);
1498 save
->crtc_offset
= INREG(RADEON_CRTC_OFFSET
);
1499 save
->crtc_offset_cntl
= INREG(RADEON_CRTC_OFFSET_CNTL
);
1500 save
->crtc_pitch
= INREG(RADEON_CRTC_PITCH
);
1501 save
->disp_merge_cntl
= INREG(RADEON_DISP_MERGE_CNTL
);
1502 save
->crtc_more_cntl
= INREG(RADEON_CRTC_MORE_CNTL
);
1504 if (sd
->Card
.IsDellServer
) {
1505 save
->tv_dac_cntl
= INREG(RADEON_TV_DAC_CNTL
);
1506 save
->dac2_cntl
= INREG(RADEON_DAC_CNTL2
);
1507 save
->disp_hw_debug
= INREG (RADEON_DISP_HW_DEBUG
);
1508 save
->crtc2_gen_cntl
= INREG(RADEON_CRTC2_GEN_CNTL
);
1512 save
->fp_crtc_h_total_disp
= INREG(RADEON_FP_CRTC_H_TOTAL_DISP
);
1513 save
->fp_crtc_v_total_disp
= INREG(RADEON_FP_CRTC_V_TOTAL_DISP
);
1514 save
->fp_gen_cntl
= INREG(RADEON_FP_GEN_CNTL
);
1515 save
->fp_h_sync_strt_wid
= INREG(RADEON_FP_H_SYNC_STRT_WID
);
1516 save
->fp_horz_stretch
= INREG(RADEON_FP_HORZ_STRETCH
);
1517 save
->fp_v_sync_strt_wid
= INREG(RADEON_FP_V_SYNC_STRT_WID
);
1518 save
->fp_vert_stretch
= INREG(RADEON_FP_VERT_STRETCH
);
1519 save
->lvds_gen_cntl
= INREG(RADEON_LVDS_GEN_CNTL
);
1520 save
->lvds_pll_cntl
= INREG(RADEON_LVDS_PLL_CNTL
);
1521 save
->tmds_pll_cntl
= INREG(RADEON_TMDS_PLL_CNTL
);
1522 save
->tmds_transmitter_cntl
= INREG(RADEON_TMDS_TRANSMITTER_CNTL
);
1523 save
->bios_4_scratch
= INREG(RADEON_BIOS_4_SCRATCH
);
1524 save
->bios_5_scratch
= INREG(RADEON_BIOS_5_SCRATCH
);
1525 save
->bios_6_scratch
= INREG(RADEON_BIOS_6_SCRATCH
);
1527 if (sd
->Card
.Type
== RV280
) {
1528 /* bit 22 of TMDS_PLL_CNTL is read-back inverted */
1529 save
->tmds_pll_cntl
^= (1 << 22);
1535 save
->dac2_cntl
= INREG(RADEON_DAC_CNTL2
);
1536 save
->disp_output_cntl
= INREG(RADEON_DISP_OUTPUT_CNTL
);
1537 save
->disp_hw_debug
= INREG (RADEON_DISP_HW_DEBUG
);
1539 save
->crtc2_gen_cntl
= INREG(RADEON_CRTC2_GEN_CNTL
);
1540 save
->crtc2_h_total_disp
= INREG(RADEON_CRTC2_H_TOTAL_DISP
);
1541 save
->crtc2_h_sync_strt_wid
= INREG(RADEON_CRTC2_H_SYNC_STRT_WID
);
1542 save
->crtc2_v_total_disp
= INREG(RADEON_CRTC2_V_TOTAL_DISP
);
1543 save
->crtc2_v_sync_strt_wid
= INREG(RADEON_CRTC2_V_SYNC_STRT_WID
);
1544 save
->crtc2_offset
= INREG(RADEON_CRTC2_OFFSET
);
1545 save
->crtc2_offset_cntl
= INREG(RADEON_CRTC2_OFFSET_CNTL
);
1546 save
->crtc2_pitch
= INREG(RADEON_CRTC2_PITCH
);
1548 save
->fp2_h_sync_strt_wid
= INREG (RADEON_FP_H2_SYNC_STRT_WID
);
1549 save
->fp2_v_sync_strt_wid
= INREG (RADEON_FP_V2_SYNC_STRT_WID
);
1550 save
->fp2_gen_cntl
= INREG (RADEON_FP2_GEN_CNTL
);
1551 save
->disp2_merge_cntl
= INREG(RADEON_DISP2_MERGE_CNTL
);
1554 save
->p2pll_ref_div
= RADEONINPLL(sd
, RADEON_P2PLL_REF_DIV
);
1555 save
->p2pll_div_0
= RADEONINPLL(sd
, RADEON_P2PLL_DIV_0
);
1556 save
->htotal_cntl2
= RADEONINPLL(sd
, RADEON_HTOTAL2_CNTL
);
1560 void LoadState(struct ati_staticdata
*sd
, struct CardState
*restore
)
1563 RADEONWaitForFifo(sd
, 1);
1564 OUTREG(RADEON_RBBM_GUICNTL
, RADEON_HOST_DATA_SWAP_NONE
);
1569 OUTREG(RADEON_CLOCK_CNTL_INDEX
, restore
->clock_cntl_index
);
1570 if (sd
->Card
.R300CGWorkaround
) R300CGWorkaround(sd
);
1571 OUTREG(RADEON_RBBM_SOFT_RESET
, restore
->rbbm_soft_reset
);
1572 OUTREG(RADEON_DP_DATATYPE
, restore
->dp_datatype
);
1573 OUTREG(RADEON_GRPH_BUFFER_CNTL
, restore
->grph_buffer_cntl
);
1574 OUTREG(RADEON_GRPH2_BUFFER_CNTL
, restore
->grph2_buffer_cntl
);
1576 OUTREG(RADEON_SURFACE_CNTL
, restore
->surface_cntl
);
1578 if (!sd
->Card
.HasCRTC2
)
1581 OUTREG(RADEON_OVR_CLR
, restore
->ovr_clr
);
1582 OUTREG(RADEON_OVR_WID_LEFT_RIGHT
, restore
->ovr_wid_left_right
);
1583 OUTREG(RADEON_OVR_WID_TOP_BOTTOM
, restore
->ovr_wid_top_bottom
);
1584 OUTREG(RADEON_OV0_SCALE_CNTL
, restore
->ov0_scale_cntl
);
1585 OUTREG(RADEON_SUBPIC_CNTL
, restore
->subpic_cntl
);
1586 OUTREG(RADEON_VIPH_CONTROL
, restore
->viph_control
);
1587 OUTREG(RADEON_I2C_CNTL_1
, restore
->i2c_cntl_1
);
1588 OUTREG(RADEON_GEN_INT_CNTL
, restore
->gen_int_cntl
);
1589 OUTREG(RADEON_CAP0_TRIG_CNTL
, restore
->cap0_trig_cntl
);
1590 OUTREG(RADEON_CAP1_TRIG_CNTL
, restore
->cap1_trig_cntl
);
1591 OUTREG(RADEON_BUS_CNTL
, restore
->bus_cntl
);
1594 OUTREG(RADEON_CRTC_GEN_CNTL
, restore
->crtc_gen_cntl
);
1596 OUTREGP(RADEON_CRTC_EXT_CNTL
,
1597 restore
->crtc_ext_cntl
,
1598 RADEON_CRTC_VSYNC_DIS
|
1599 RADEON_CRTC_HSYNC_DIS
|
1600 RADEON_CRTC_DISPLAY_DIS
);
1602 OUTREGP(RADEON_DAC_CNTL
,
1604 RADEON_DAC_RANGE_CNTL
|
1605 RADEON_DAC_BLANKING
);
1607 OUTREG(RADEON_CRTC_H_TOTAL_DISP
, restore
->crtc_h_total_disp
);
1608 OUTREG(RADEON_CRTC_H_SYNC_STRT_WID
, restore
->crtc_h_sync_strt_wid
);
1609 OUTREG(RADEON_CRTC_V_TOTAL_DISP
, restore
->crtc_v_total_disp
);
1610 OUTREG(RADEON_CRTC_V_SYNC_STRT_WID
, restore
->crtc_v_sync_strt_wid
);
1611 OUTREG(RADEON_CRTC_OFFSET
, restore
->crtc_offset
);
1612 OUTREG(RADEON_CRTC_OFFSET_CNTL
, restore
->crtc_offset_cntl
);
1613 OUTREG(RADEON_CRTC_PITCH
, restore
->crtc_pitch
);
1614 OUTREG(RADEON_DISP_MERGE_CNTL
, restore
->disp_merge_cntl
);
1615 OUTREG(RADEON_CRTC_MORE_CNTL
, restore
->crtc_more_cntl
);
1617 if (sd
->Card
.IsDellServer
) {
1618 OUTREG(RADEON_TV_DAC_CNTL
, restore
->tv_dac_cntl
);
1619 OUTREG(RADEON_DISP_HW_DEBUG
, restore
->disp_hw_debug
);
1620 OUTREG(RADEON_DAC_CNTL2
, restore
->dac2_cntl
);
1621 OUTREG(RADEON_CRTC2_GEN_CNTL
, restore
->crtc2_gen_cntl
);
1627 OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP
, restore
->fp_crtc_h_total_disp
);
1628 OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP
, restore
->fp_crtc_v_total_disp
);
1629 OUTREG(RADEON_FP_H_SYNC_STRT_WID
, restore
->fp_h_sync_strt_wid
);
1630 OUTREG(RADEON_FP_V_SYNC_STRT_WID
, restore
->fp_v_sync_strt_wid
);
1631 OUTREG(RADEON_TMDS_PLL_CNTL
, restore
->tmds_pll_cntl
);
1632 OUTREG(RADEON_TMDS_TRANSMITTER_CNTL
,restore
->tmds_transmitter_cntl
);
1633 OUTREG(RADEON_FP_HORZ_STRETCH
, restore
->fp_horz_stretch
);
1634 OUTREG(RADEON_FP_VERT_STRETCH
, restore
->fp_vert_stretch
);
1635 OUTREG(RADEON_FP_GEN_CNTL
, restore
->fp_gen_cntl
);
1636 OUTREG(RADEON_GRPH_BUFFER_CNTL
,
1637 INREG(RADEON_GRPH_BUFFER_CNTL
) & ~0x7f0000);
1639 if (sd
->Card
.IsMobility
) {
1640 OUTREG(RADEON_BIOS_4_SCRATCH
, restore
->bios_4_scratch
);
1641 OUTREG(RADEON_BIOS_5_SCRATCH
, restore
->bios_5_scratch
);
1642 OUTREG(RADEON_BIOS_6_SCRATCH
, restore
->bios_6_scratch
);
1645 if (sd
->Card
.MonType1
!= MT_DFP
) {
1646 unsigned long tmpPixclksCntl
= RADEONINPLL(sd
, RADEON_PIXCLKS_CNTL
);
1648 if (sd
->Card
.IsMobility
|| sd
->Card
.IsIGP
) {
1649 /* Asic bug, when turning off LVDS_ON, we have to make sure
1650 RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
1652 if (!(restore
->lvds_gen_cntl
& RADEON_LVDS_ON
)) {
1653 OUTPLLP(sd
, RADEON_PIXCLKS_CNTL
, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb
);
1657 tmp
= INREG(RADEON_LVDS_GEN_CNTL
);
1658 if ((tmp
& (RADEON_LVDS_ON
| RADEON_LVDS_BLON
)) ==
1659 (restore
->lvds_gen_cntl
& (RADEON_LVDS_ON
| RADEON_LVDS_BLON
))) {
1660 OUTREG(RADEON_LVDS_GEN_CNTL
, restore
->lvds_gen_cntl
);
1662 if (restore
->lvds_gen_cntl
& (RADEON_LVDS_ON
| RADEON_LVDS_BLON
)) {
1663 usleep(sd
->Card
.PanelPwrDly
* 1000);
1664 OUTREG(RADEON_LVDS_GEN_CNTL
, restore
->lvds_gen_cntl
);
1666 OUTREG(RADEON_LVDS_GEN_CNTL
,
1667 restore
->lvds_gen_cntl
| RADEON_LVDS_BLON
);
1668 usleep(sd
->Card
.PanelPwrDly
* 1000);
1669 OUTREG(RADEON_LVDS_GEN_CNTL
, restore
->lvds_gen_cntl
);
1673 if (sd
->Card
.IsMobility
|| sd
->Card
.IsIGP
) {
1674 if (!(restore
->lvds_gen_cntl
& RADEON_LVDS_ON
)) {
1675 OUTPLL(RADEON_PIXCLKS_CNTL
, tmpPixclksCntl
);
1682 if (sd
->Card
.IsMobility
) {
1683 /* A temporal workaround for the occational blanking on certain laptop panels.
1684 This appears to related to the PLL divider registers (fail to lock?).
1685 It occurs even when all dividers are the same with their old settings.
1686 In this case we really don't need to fiddle with PLL registers.
1687 By doing this we can avoid the blanking problem with some panels.
1689 if ((restore
->ppll_ref_div
== (RADEONINPLL(sd
, RADEON_PPLL_REF_DIV
) & RADEON_PPLL_REF_DIV_MASK
)) &&
1690 (restore
->ppll_div_3
== (RADEONINPLL(sd
, RADEON_PPLL_DIV_3
) & (RADEON_PPLL_POST3_DIV_MASK
| RADEON_PPLL_FB3_DIV_MASK
))))
1694 OUTPLLP(sd
, RADEON_VCLK_ECP_CNTL
,
1695 RADEON_VCLK_SRC_SEL_CPUCLK
,
1696 ~(RADEON_VCLK_SRC_SEL_MASK
));
1701 | RADEON_PPLL_ATOMIC_UPDATE_EN
1702 | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
,
1704 | RADEON_PPLL_ATOMIC_UPDATE_EN
1705 | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
));
1707 OUTREGP(RADEON_CLOCK_CNTL_INDEX
,
1709 ~(RADEON_PLL_DIV_SEL
));
1711 if (IS_R300_VARIANT
||
1712 (sd
->Card
.Type
== RS300
)) {
1713 if (restore
->ppll_ref_div
& R300_PPLL_REF_DIV_ACC_MASK
) {
1714 /* When restoring console mode, use saved PPLL_REF_DIV
1717 OUTPLLP(sd
, RADEON_PPLL_REF_DIV
,
1718 restore
->ppll_ref_div
,
1721 /* R300 uses ref_div_acc field as real ref divider */
1722 OUTPLLP(sd
, RADEON_PPLL_REF_DIV
,
1723 (restore
->ppll_ref_div
<< R300_PPLL_REF_DIV_ACC_SHIFT
),
1724 ~R300_PPLL_REF_DIV_ACC_MASK
);
1727 OUTPLLP(sd
, RADEON_PPLL_REF_DIV
,
1728 restore
->ppll_ref_div
,
1729 ~RADEON_PPLL_REF_DIV_MASK
);
1732 OUTPLLP(sd
, RADEON_PPLL_DIV_3
,
1733 restore
->ppll_div_3
,
1734 ~RADEON_PPLL_FB3_DIV_MASK
);
1736 OUTPLLP(sd
, RADEON_PPLL_DIV_3
,
1737 restore
->ppll_div_3
,
1738 ~RADEON_PPLL_POST3_DIV_MASK
);
1740 RADEONPLLWriteUpdate(sd
);
1741 RADEONPLLWaitForReadUpdateComplete(sd
);
1743 OUTPLL(RADEON_HTOTAL_CNTL
, restore
->htotal_cntl
);
1745 OUTPLLP(sd
, RADEON_PPLL_CNTL
,
1749 | RADEON_PPLL_ATOMIC_UPDATE_EN
1750 | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
));
1752 usleep(50000); /* Let the clock to lock */
1754 OUTPLLP(sd
, RADEON_VCLK_ECP_CNTL
,
1755 RADEON_VCLK_SRC_SEL_PPLLCLK
,
1756 ~(RADEON_VCLK_SRC_SEL_MASK
));
1764 RADEONInitDispBandwidth(sd
, restore
);
1766 SetGamma(sd
, 1.0, 1.0, 1.0);
1771 void DPMS(struct ati_staticdata
*sd
, HIDDT_DPMSLevel level
)
1773 int mask1
= (RADEON_CRTC_DISPLAY_DIS
|
1774 RADEON_CRTC_HSYNC_DIS
|
1775 RADEON_CRTC_VSYNC_DIS
);
1776 int mask2
= (RADEON_CRTC2_DISP_DIS
|
1777 RADEON_CRTC2_VSYNC_DIS
|
1778 RADEON_CRTC2_HSYNC_DIS
);
1782 case vHidd_Gfx_DPMSLevel_On
:
1783 /* Screen: On; HSync: On, VSync: On */
1784 if (sd
->Card
.IsSecondary
)
1785 OUTREGP(RADEON_CRTC2_GEN_CNTL
, 0, ~mask2
);
1787 OUTREGP(RADEON_CRTC_EXT_CNTL
, 0, ~mask1
);
1791 case vHidd_Gfx_DPMSLevel_Standby
:
1792 /* Screen: Off; HSync: Off, VSync: On */
1793 if (sd
->Card
.IsSecondary
)
1794 OUTREGP(RADEON_CRTC2_GEN_CNTL
,
1795 RADEON_CRTC2_DISP_DIS
| RADEON_CRTC2_HSYNC_DIS
,
1798 OUTREGP(RADEON_CRTC_EXT_CNTL
,
1799 RADEON_CRTC_DISPLAY_DIS
| RADEON_CRTC_HSYNC_DIS
,
1804 case vHidd_Gfx_DPMSLevel_Suspend
:
1805 /* Screen: Off; HSync: On, VSync: Off */
1806 if (sd
->Card
.IsSecondary
)
1807 OUTREGP(RADEON_CRTC2_GEN_CNTL
,
1808 RADEON_CRTC2_DISP_DIS
| RADEON_CRTC2_VSYNC_DIS
,
1811 OUTREGP(RADEON_CRTC_EXT_CNTL
,
1812 RADEON_CRTC_DISPLAY_DIS
| RADEON_CRTC_VSYNC_DIS
,
1817 case vHidd_Gfx_DPMSLevel_Off
:
1818 /* Screen: Off; HSync: Off, VSync: Off */
1819 if (sd
->Card
.IsSecondary
)
1820 OUTREGP(RADEON_CRTC2_GEN_CNTL
, mask2
, ~mask2
);
1822 OUTREGP(RADEON_CRTC_EXT_CNTL
, mask1
, ~mask1
);
1826 if (level
== vHidd_Gfx_DPMSLevel_On
)
1828 if (sd
->Card
.IsSecondary
) {
1829 if (sd
->Card
.MonType2
== MT_DFP
) {
1830 OUTREGP (RADEON_FP2_GEN_CNTL
, 0, ~RADEON_FP2_BLANK_EN
);
1831 OUTREGP (RADEON_FP2_GEN_CNTL
, RADEON_FP2_ON
, ~RADEON_FP2_ON
);
1832 if (sd
->Card
.Type
>= R200
) {
1833 OUTREGP (RADEON_FP2_GEN_CNTL
, RADEON_FP2_DVO_EN
, ~RADEON_FP2_DVO_EN
);
1835 } else if (sd
->Card
.MonType2
== MT_CRT
) {
1836 RADEONDacPowerSet(sd
, TRUE
, !sd
->Card
.ReversedDAC
);
1839 if (sd
->Card
.MonType1
== MT_DFP
) {
1840 OUTREGP (RADEON_FP_GEN_CNTL
, (RADEON_FP_FPON
| RADEON_FP_TMDS_EN
),
1841 ~(RADEON_FP_FPON
| RADEON_FP_TMDS_EN
));
1842 } else if (sd
->Card
.MonType1
== MT_LCD
) {
1844 OUTREGP (RADEON_LVDS_GEN_CNTL
, RADEON_LVDS_BLON
, ~RADEON_LVDS_BLON
);
1845 usleep (sd
->Card
.PanelPwrDly
* 1000);
1846 OUTREGP (RADEON_LVDS_GEN_CNTL
, RADEON_LVDS_ON
, ~RADEON_LVDS_ON
);
1847 } else if (sd
->Card
.MonType1
== MT_CRT
) {
1848 if (sd
->Card
.HasSecondary
) {
1849 RADEONDacPowerSet(sd
, TRUE
, sd
->Card
.ReversedDAC
);
1851 RADEONDacPowerSet(sd
, TRUE
, TRUE
);
1852 if (sd
->Card
.HasCRTC2
)
1853 RADEONDacPowerSet(sd
, TRUE
, FALSE
);
1858 else if ((level
== vHidd_Gfx_DPMSLevel_Off
) ||
1859 (level
== vHidd_Gfx_DPMSLevel_Suspend
) ||
1860 (level
== vHidd_Gfx_DPMSLevel_Standby
))
1862 if (sd
->Card
.IsSecondary
) {
1863 if (sd
->Card
.MonType2
== MT_DFP
) {
1864 OUTREGP (RADEON_FP2_GEN_CNTL
, RADEON_FP2_BLANK_EN
, ~RADEON_FP2_BLANK_EN
);
1865 OUTREGP (RADEON_FP2_GEN_CNTL
, 0, ~RADEON_FP2_ON
);
1866 if (sd
->Card
.Type
>= R200
) {
1867 OUTREGP (RADEON_FP2_GEN_CNTL
, 0, ~RADEON_FP2_DVO_EN
);
1869 } else if (sd
->Card
.Type
== MT_CRT
) {
1870 RADEONDacPowerSet(sd
, FALSE
, !sd
->Card
.ReversedDAC
);
1873 if (sd
->Card
.MonType1
== MT_DFP
) {
1874 OUTREGP (RADEON_FP_GEN_CNTL
, 0, ~(RADEON_FP_FPON
| RADEON_FP_TMDS_EN
));
1875 } else if (sd
->Card
.MonType1
== MT_LCD
) {
1876 unsigned long tmpPixclksCntl
= RADEONINPLL(sd
, RADEON_PIXCLKS_CNTL
);
1878 if (sd
->Card
.IsMobility
|| sd
->Card
.IsIGP
) {
1879 /* Asic bug, when turning off LVDS_ON, we have to make sure
1880 RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
1882 OUTPLLP(sd
, RADEON_PIXCLKS_CNTL
, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb
);
1885 OUTREGP (RADEON_LVDS_GEN_CNTL
, 0,
1886 ~(RADEON_LVDS_BLON
| RADEON_LVDS_ON
));
1888 if (sd
->Card
.IsMobility
|| sd
->Card
.IsIGP
) {
1889 OUTPLL(RADEON_PIXCLKS_CNTL
, tmpPixclksCntl
);
1891 } else if (sd
->Card
.MonType1
== MT_CRT
) {
1892 if (sd
->Card
.HasSecondary
) {
1893 RADEONDacPowerSet(sd
, FALSE
, sd
->Card
.ReversedDAC
);
1895 /* single CRT, turning both DACs off, we don't really know
1896 * which DAC is actually connected.
1898 RADEONDacPowerSet(sd
, FALSE
, TRUE
);
1899 if (sd
->Card
.HasCRTC2
) /* don't apply this to old radeon (singel CRTC) card */
1900 RADEONDacPowerSet(sd
, FALSE
, FALSE
);
1907 BOOL
RADEONInit(struct ati_staticdata
*sd
)
1909 APTR int10_save
= NULL
;
1911 sd
->Card
.IsSecondary
= FALSE
;
1913 RADEONPreInt10Save(sd
, &int10_save
);
1914 RADEONPostInt10Check(sd
, int10_save
);
1916 D(bug("[ATI] Radeon init\n"));
1918 sd
->Card
.HasCRTC2
= TRUE
;
1919 sd
->Card
.IsMobility
= FALSE
;
1920 sd
->Card
.IsIGP
= FALSE
;
1921 sd
->Card
.IsDellServer
= FALSE
;
1922 sd
->Card
.HasSingleDAC
= FALSE
;
1924 D(bug("[ATI] flags:"));
1926 switch (sd
->Card
.ProductID
)
1948 sd
->Card
.IsMobility
= TRUE
;
1949 D(bug(" IsMobility\n"));
1954 sd
->Card
.IsMobility
= TRUE
;
1955 D(bug(" IsMobility\n"));
1958 sd
->Card
.IsIGP
= TRUE
;
1964 sd
->Card
.IsMobility
= TRUE
;
1965 D(bug(" IsMobility\n"));
1968 sd
->Card
.IsIGP
= TRUE
;
1969 sd
->Card
.HasSingleDAC
= TRUE
;
1970 D(bug(" IsIGP HasSingleDAC\n"));
1974 sd
->Card
.HasCRTC2
= FALSE
;
1978 if ((sd
->Card
.Type
== RS100
) ||
1979 (sd
->Card
.Type
== RS200
) ||
1980 (sd
->Card
.Type
== RS300
)) {
1981 ULONG tom
= INREG(RADEON_NB_TOM
);
1983 sd
->Card
.FbUsableSize
= (((tom
>> 16) -
1984 (tom
& 0xffff) + 1) << 6) * 1024;
1986 OUTREG(RADEON_CONFIG_MEMSIZE
, sd
->Card
.FbUsableSize
);
1988 /* There are different HDP mapping schemes depending on single/multi funciton setting,
1989 * chip family, HDP mode, and the generation of HDP mapping scheme.
1990 * To make things simple, we only allow maximum 128M addressable FB. Anything more than
1991 * 128M is configured as invisible FB to CPU that can only be accessed from chip side.
1993 sd
->Card
.FbUsableSize
= INREG(RADEON_CONFIG_MEMSIZE
);
1994 if (sd
->Card
.FbUsableSize
> 128*1024*1024) sd
->Card
.FbUsableSize
= 128*1024*1024;
1995 if ((sd
->Card
.Type
== RV350
) ||
1996 (sd
->Card
.Type
== RV380
) ||
1997 (sd
->Card
.Type
== R420
)) {
1998 OUTREGP (RADEON_HOST_PATH_CNTL
, (1<<23), ~(1<<23));
2002 /* Some production boards of m6 will return 0 if it's 8 MB */
2003 if (sd
->Card
.FbUsableSize
== 0) sd
->Card
.FbUsableSize
= 8192*1024;
2006 if (sd
->Card
.IsSecondary
) {
2007 /* FIXME: For now, split FB into two equal sections. This should
2008 * be able to be adjusted by user with a config option. */
2009 RADEONEntPtr pRADEONEnt
= RADEONEntPriv(pScrn
);
2010 RADEONInfoPtr info1
;
2012 pScrn
->videoRam
/= 2;
2013 pRADEONEnt
->pPrimaryScrn
->videoRam
= pScrn
->videoRam
;
2015 info1
= RADEONPTR(pRADEONEnt
->pPrimaryScrn
);
2016 info1
->FbMapSize
= pScrn
->videoRam
* 1024;
2017 info
->LinearAddr
+= pScrn
->videoRam
* 1024;
2018 info1
->MergedFB
= FALSE
;
2022 sd
->Card
.R300CGWorkaround
= (sd
->Card
.Type
== R300
&&
2023 (INREG(RADEON_CONFIG_CNTL
) & RADEON_CFG_ATI_REV_ID_MASK
)
2024 == RADEON_CFG_ATI_REV_A11
);
2026 D(bug("[ATI] R300CGWorkaroung = %s\n", sd
->Card
.R300CGWorkaround
? "Yes":"No"));
2028 sd
->Card
.MemCntl
= INREG(RADEON_SDRAM_MODE_REG
);
2029 sd
->Card
.BusCntl
= INREG(RADEON_BUS_CNTL
);
2031 sd
->Card
.DDCReg
= RADEON_GPIO_DVI_DDC
;
2033 RADEONGetVRamType(sd
);
2035 D(bug("[ATI] Video memory = %dMiB (%d bit %s SDRAM)\n", sd
->Card
.FbUsableSize
>> 20,
2036 sd
->Card
.RamWidth
, sd
->Card
.IsDDR
? "DDR":"SDR"));
2038 /* RADEONPreInitDDC */
2039 sd
->Card
.DDC1
= FALSE
;
2040 sd
->Card
.DDC2
= FALSE
;
2041 sd
->Card
.DDCBios
= FALSE
;
2043 RADEONGetBIOSInfo(sd
);
2044 RADEONQueryConnectedMonitors(sd
);
2045 RADEONGetClockInfo(sd
);
2046 RADEONGetPanelInfo(sd
);
2048 if (sd
->Card
.MonType1
== MT_UNKNOWN
)
2049 sd
->Card
.MonType1
= MT_CRT
;
2055 Allocates some memory area on GFX card, which may be sufficient for bitmap
2056 with given size and depth. The must_have bit may be defined but doesn't
2057 have to. If it is TRUE, the allocator will do everything to get the memory -
2058 eg. it will throw other bitmaps away from it or it will shift them within
2062 IPTR
AllocBitmapArea(struct ati_staticdata
*sd
, ULONG width
, ULONG height
,
2063 ULONG bpp
, BOOL must_have
)
2066 ULONG size
= (((width
* bpp
+ 63) & ~63) * height
+ 1023) & ~1023;
2071 result
= (IPTR
)Allocate(&sd
->CardMem
, size
);
2075 If Allocate failed, make the 0xffffffff as return. If it succeeded, make
2076 the memory pointer relative to the begin of GFX memory
2078 if (result
== 0) --result
;
2079 else result
-= (IPTR
)sd
->Card
.FrameBuffer
;
2081 D(bug("[ATI] AllocBitmapArea(%dx%d@%d) = %p\n", width
, height
, bpp
, result
));
2085 /* Generic thing. Will be extended later */
2089 VOID
FreeBitmapArea(struct ati_staticdata
*sd
, IPTR bmp
, ULONG width
, ULONG height
, ULONG bpp
)
2091 APTR ptr
= (APTR
)(bmp
+ sd
->Card
.FrameBuffer
);
2092 ULONG size
= (((width
* bpp
+ 63) & ~63) * height
+ 1023) & ~1023;
2096 D(bug("[ATI] FreeBitmapArea(%p,%dx%d@%d)\n",
2097 bmp
, width
, height
, bpp
));
2100 Deallocate(&sd
->CardMem
, ptr
, size
);
2106 VOID
SetGamma(struct ati_staticdata
*sd
, float r
, float g
, float b
)
2110 if (sd
->Card
.IsSecondary
)
2115 for (i
=0; i
< 256; i
++)
2117 int ri
= 256.0*pow((double)i
/ 256.0, 1/r
);
2118 int gi
= 256.0*pow((double)i
/ 256.0, 1/g
);
2119 int bi
= 256.0*pow((double)i
/ 256.0, 1/b
);
2121 RADEONWaitForFifo(sd
, 32);
2122 OUTPAL(i
, ri
, gi
, bi
);