atimach64.c revision 32b578d3
1/*
2 * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of Marc Aurele La France not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  Marc Aurele La France makes no representations
11 * about the suitability of this software for any purpose.  It is provided
12 * "as-is" without express or implied warranty.
13 *
14 * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO
16 * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22/*
23 * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas.
24 * All Rights Reserved.
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a copy
27 * of this software and associated documentation files (the "Software"), to
28 * deal in the Software without restriction, including without limitation the
29 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
30 * sell copies of the Software, and to permit persons to whom the Software is
31 * furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice (including the next
34 * paragraph) shall be included in all copies or substantial portions of the
35 * Software.
36 *
37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
40 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
41 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
42 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43 * DEALINGS IN THE SOFTWARE.
44 */
45/*
46 * DRI support by:
47 *    Manuel Teira
48 *    Leif Delgass <ldelgass@retinalburn.net>
49 */
50
51#ifdef HAVE_CONFIG_H
52#include "config.h"
53#endif
54
55#include <string.h>
56
57#include "ati.h"
58#include "atibus.h"
59#include "atichip.h"
60#include "atidac.h"
61#include "atimach64.h"
62#include "atimach64accel.h"
63#include "atimach64io.h"
64#include "atirgb514.h"
65
66#ifndef DPMS_SERVER
67# define DPMS_SERVER
68#endif
69#include <X11/extensions/dpms.h>
70
71/*
72 * ATIMach64PreInit --
73 *
74 * This function fills in the Mach64 portion of an ATIHWRec that is common to
75 * all video modes generated by the driver.
76 */
77void
78ATIMach64PreInit
79(
80    ScrnInfoPtr pScreenInfo,
81    ATIPtr      pATI,
82    ATIHWPtr    pATIHW
83)
84{
85    if ((pATI->LockData.crtc_gen_cntl & CRTC_CSYNC_EN) && !pATI->OptionCSync)
86    {
87        xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
88            "Using composite sync to match input timing.\n");
89        pATI->OptionCSync = TRUE;
90    }
91
92    pATIHW->bus_cntl = inr(BUS_CNTL);
93    if (pATI->Chip < ATI_CHIP_264VT4)
94        pATIHW->bus_cntl = (pATIHW->bus_cntl & ~BUS_HOST_ERR_INT_EN) |
95            BUS_HOST_ERR_INT;
96    if (pATI->Chip < ATI_CHIP_264VTB)
97    {
98        pATIHW->bus_cntl &= ~(BUS_FIFO_ERR_INT_EN | BUS_ROM_DIS);
99        pATIHW->bus_cntl |= SetBits(15, BUS_FIFO_WS) | BUS_FIFO_ERR_INT;
100    }
101    else if (pATI->MMIOInLinear)
102    {
103        pATIHW->bus_cntl &= ~BUS_APER_REG_DIS;
104    }
105    else
106    {
107        pATIHW->bus_cntl |= BUS_APER_REG_DIS;
108    }
109    if (pATI->Chip >= ATI_CHIP_264VT)
110        pATIHW->bus_cntl |= BUS_EXT_REG_EN;     /* Enable Block 1 */
111
112#ifdef AVOID_CPIO
113
114    pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) |
115        SetBits(1, MEM_VGA_WPS1);
116    pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) |
117        SetBits(1, MEM_VGA_RPS1);
118
119#else /* AVOID_CPIO */
120
121    pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) |
122        SetBits(pATIHW->nPlane, MEM_VGA_WPS1);
123    pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) |
124        SetBits(pATIHW->nPlane, MEM_VGA_RPS1);
125
126#endif /* AVOID_CPIO */
127
128    pATIHW->dac_cntl = inr(DAC_CNTL) &
129        ~(DAC1_CLK_SEL | DAC_PALETTE_ACCESS_CNTL | DAC_8BIT_EN);
130    if (pATI->Chip >= ATI_CHIP_264CT)
131        pATIHW->dac_cntl &= ~DAC_FEA_CON_EN;
132    if (pATI->rgbBits == 8)
133        pATIHW->dac_cntl |= DAC_8BIT_EN;
134
135    pATIHW->gen_test_cntl = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN;
136    if (pATI->DAC == ATI_DAC_IBMRGB514)
137        pATIHW->gen_test_cntl |= GEN_OVR_OUTPUT_EN;
138
139    pATIHW->config_cntl = inr(CONFIG_CNTL);
140
141#ifndef AVOID_CPIO
142
143    if (pATI->VGAAdapter)
144    {
145        pATIHW->config_cntl |= CFG_MEM_VGA_AP_EN;
146    }
147    else
148
149#endif /* AVOID_CPIO */
150
151    {
152        pATIHW->config_cntl &= ~CFG_MEM_VGA_AP_EN;
153    }
154
155    if ((pATI->Chip < ATI_CHIP_264CT))
156    {
157        /* Replace linear aperture size and address */
158        pATIHW->config_cntl &= ~(CFG_MEM_AP_LOC | CFG_MEM_AP_SIZE);
159        pATIHW->config_cntl |= SetBits(pATI->LinearBase >> 22, CFG_MEM_AP_LOC);
160        if ((pATI->Chip < ATI_CHIP_264CT) && (pATI->VideoRAM < 4096))
161            pATIHW->config_cntl |= SetBits(1, CFG_MEM_AP_SIZE);
162        else
163            pATIHW->config_cntl |= SetBits(2, CFG_MEM_AP_SIZE);
164    }
165
166    if (pATI->Chip >= ATI_CHIP_264VTB)
167    {
168        pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE;
169        pATIHW->mem_cntl = (pATI->LockData.mem_cntl &
170            ~(CTL_MEM_LOWER_APER_ENDIAN | CTL_MEM_UPPER_APER_ENDIAN)) |
171            SetBits(CTL_MEM_APER_BYTE_ENDIAN, CTL_MEM_LOWER_APER_ENDIAN);
172
173        switch (pATI->bitsPerPixel)
174        {
175            default:
176                pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_BYTE_ENDIAN,
177                    CTL_MEM_UPPER_APER_ENDIAN);
178                break;
179
180            case 16:
181                pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_WORD_ENDIAN,
182                    CTL_MEM_UPPER_APER_ENDIAN);
183                break;
184
185            case 32:
186                pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_LONG_ENDIAN,
187                    CTL_MEM_UPPER_APER_ENDIAN);
188                break;
189        }
190
191        pATIHW->mpp_config = inr(MPP_CONFIG);
192        pATIHW->mpp_config &=
193            ~(MPP_PRESCALE | MPP_NSTATES | MPP_FORMAT | MPP_WAIT_STATE |
194              MPP_INSERT_WAIT | MPP_TRISTATE_ADDR | MPP_AUTO_INC_EN |
195              MPP_CHKREQ_EN | MPP_BUFFER_SIZE | MPP_BUFFER_MODE | MPP_BUSY);
196        pATIHW->mpp_config |=
197            (MPP_NSTATES_8 | MPP_FORMAT_DA8 | SetBits(4, MPP_WAIT_STATE) |
198             MPP_CHKRDY_EN | MPP_READ_EARLY | MPP_RW_MODE | MPP_EN);
199        pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ);
200        pATIHW->mpp_strobe_seq &= ~(MPP_STB0_SEQ | MPP_STB1_SEQ);
201        pATIHW->mpp_strobe_seq |=
202            SetBits(0x0087U, MPP_STB0_SEQ) | SetBits(0x0083U, MPP_STB1_SEQ);
203        pATIHW->tvo_cntl = 0;
204    }
205
206    /* Draw engine setup */
207    if (pATI->Block0Base)
208    {
209        CARD32 bus_cntl = inr(BUS_CNTL);
210        CARD32 config_cntl = inr(CONFIG_CNTL);
211
212        /* Ensure apertures are enabled */
213        outr(BUS_CNTL, pATIHW->bus_cntl);
214        outr(CONFIG_CNTL, pATIHW->config_cntl);
215
216        /*
217         * When possible, max out command FIFO size.
218         */
219        if (pATI->Chip >= ATI_CHIP_264VT4)
220
221#ifdef XF86DRI_DEVEL
222
223	    /* Changing the FIFO depth seems to interfere with DMA, so use
224	     * default of 128 entries (0x01)
225	     */
226	    pATIHW->gui_cntl = (inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE) | 0x01;
227
228#else /* XF86DRI_DEVEL */
229
230            pATIHW->gui_cntl = inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE;
231
232#endif /* XF86DRI_DEVEL */
233
234        /* Initialise destination registers */
235        pATIHW->dst_off_pitch =
236            SetBits((pATI->displayWidth * pATI->XModifier) >> 3, DST_PITCH);
237        pATIHW->dst_cntl = DST_X_DIR | DST_Y_DIR | DST_LAST_PEL;
238
239        /* Initialise source registers */
240        pATIHW->src_off_pitch = pATIHW->dst_off_pitch;
241        pATIHW->src_width1 = pATIHW->src_height1 =
242            pATIHW->src_width2 = pATIHW->src_height2 = 1;
243        pATIHW->src_cntl = SRC_LINE_X_DIR;
244
245        /* Initialise scissor, allowing for offscreen areas */
246#ifdef USE_XAA
247        if (!pATI->useEXA)
248        {
249            int width, height, total;
250
251            pATIHW->sc_right = (pATI->displayWidth * pATI->XModifier) - 1;
252            width = pATI->displayWidth * pATI->bitsPerPixel;
253            total = pScreenInfo->videoRam * (1024 * 8);
254            height = (total + width - 1) / width;
255            if (height > ATIMach64MaxY + 1)
256                height = ATIMach64MaxY + 1;
257            pATIHW->sc_bottom = height - 1;
258        }
259#endif /* USE_XAA */
260
261#ifdef USE_EXA
262        if (pATI->useEXA)
263        {
264            pATIHW->sc_right = ATIMach64MaxX;
265            pATIHW->sc_bottom = ATIMach64MaxY;
266        }
267#endif /* USE_EXA */
268
269        pATI->sc_left_right = SetWord(pATI->NewHW.sc_right, 1) |
270            SetWord(pATI->NewHW.sc_left, 0);
271        pATI->sc_top_bottom = SetWord(pATI->NewHW.sc_bottom, 1) |
272            SetWord(pATI->NewHW.sc_top, 0);
273
274        /* Initialise data path */
275        pATIHW->dp_frgd_clr = (CARD32)(-1);
276        pATIHW->dp_write_mask = (CARD32)(-1);
277
278        switch (pATI->depth)
279        {
280            case 8:
281                pATIHW->dp_chain_mask = DP_CHAIN_8BPP;
282                pATIHW->dp_pix_width =
283                    SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
284                    SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
285                    SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
286                break;
287
288            case 15:
289                pATIHW->dp_chain_mask = DP_CHAIN_15BPP_1555;
290                pATIHW->dp_pix_width =
291                    SetBits(PIX_WIDTH_15BPP, DP_DST_PIX_WIDTH) |
292                    SetBits(PIX_WIDTH_15BPP, DP_SRC_PIX_WIDTH) |
293                    SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
294                break;
295
296            case 16:
297                pATIHW->dp_chain_mask = DP_CHAIN_16BPP_565;
298                pATIHW->dp_pix_width =
299                    SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) |
300                    SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) |
301                    SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
302                break;
303
304            case 24:
305                if (pATI->bitsPerPixel == 24)
306                {
307                    pATIHW->dp_chain_mask = DP_CHAIN_24BPP_888;
308                    pATIHW->dp_pix_width =
309                        SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) |
310                        SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) |
311                        SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
312                }
313                else
314                {
315                    pATIHW->dp_chain_mask = DP_CHAIN_32BPP_8888;
316                    pATIHW->dp_pix_width =
317                        SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) |
318                        SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) |
319                        SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH);
320                }
321                break;
322
323            default:
324                break;
325        }
326
327#if X_BYTE_ORDER == X_LITTLE_ENDIAN
328
329        pATIHW->dp_pix_width |= DP_BYTE_PIX_ORDER;
330
331#endif /* X_BYTE_ORDER */
332
333        pATIHW->dp_mix = SetBits(MIX_SRC, DP_FRGD_MIX) |
334            SetBits(MIX_DST, DP_BKGD_MIX);
335        pATIHW->dp_src = DP_MONO_SRC_ALLONES |
336            SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC);
337
338        /* Initialise colour compare */
339        pATIHW->clr_cmp_msk = (1 << pATI->depth) - 1;
340
341        if (pATI->Block1Base)
342        {
343            pATIHW->overlay_y_x_start = SetBits(0, OVERLAY_Y_START) |
344                SetBits(0, OVERLAY_X_START) | OVERLAY_LOCK_START;
345            pATIHW->overlay_y_x_end = SetBits(0, OVERLAY_Y_END) |
346                SetBits(0, OVERLAY_X_END) | OVERLAY_LOCK_END;
347
348            pATIHW->overlay_graphics_key_clr =
349                (3 << ((2 * pATI->depth) / 3)) |
350                (2 << ((1 * pATI->depth) / 3)) |
351                (1 << ((0 * pATI->depth) / 3));
352            pATIHW->overlay_graphics_key_msk = (1 << pATI->depth) - 1;
353
354            pATIHW->overlay_key_cntl =
355                SetBits(OVERLAY_MIX_FALSE, OVERLAY_VIDEO_FN) |
356                SetBits(OVERLAY_MIX_EQUAL, OVERLAY_GRAPHICS_FN);
357
358            pATIHW->overlay_scale_cntl = SCALE_EN;
359
360            pATIHW->video_format = VIDEO_IN_VYUY422 | SCALER_IN_VYUY422;
361
362            if (pATI->Chip >= ATI_CHIP_264GTPRO)
363            {
364                /* These values are documented voodoo */
365                pATIHW->scaler_h_coeff0 = SetByte(0x20U, 1);
366                pATIHW->scaler_h_coeff1 = SetByte(0x0DU, 0) |
367                    SetByte(0x20U, 1) | SetByte(0x06U, 2) | SetByte(0x0DU, 3);
368                pATIHW->scaler_h_coeff2 = SetByte(0x0DU, 0) |
369                    SetByte(0x1CU, 1) | SetByte(0x0AU, 2) | SetByte(0x0DU, 3);
370                pATIHW->scaler_h_coeff3 = SetByte(0x0CU, 0) |
371                    SetByte(0x1AU, 1) | SetByte(0x0EU, 2) | SetByte(0x0CU, 3);
372                pATIHW->scaler_h_coeff4 = SetByte(0x0CU, 0) |
373                    SetByte(0x14U, 1) | SetByte(0x14U, 2) | SetByte(0x0CU, 3);
374            }
375        }
376
377        /* Restore aperture enablement */
378        outr(BUS_CNTL, bus_cntl);
379        outr(CONFIG_CNTL, config_cntl);
380    }
381}
382
383/*
384 * ATIMach64Save --
385 *
386 * This function is called to save the Mach64 portion of the current video
387 * state.
388 */
389void
390ATIMach64Save
391(
392    ATIPtr      pATI,
393    ATIHWPtr    pATIHW
394)
395{
396    pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP);
397    pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID);
398    pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP);
399    pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID);
400
401    pATIHW->crtc_off_pitch = inr(CRTC_OFF_PITCH);
402
403    pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL);
404
405    pATIHW->ovr_clr = inr(OVR_CLR);
406    pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT);
407    pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM);
408
409    pATIHW->cur_clr0 = inr(CUR_CLR0);
410    pATIHW->cur_clr1 = inr(CUR_CLR1);
411    pATIHW->cur_offset = inr(CUR_OFFSET);
412    pATIHW->cur_horz_vert_posn = inr(CUR_HORZ_VERT_POSN);
413    pATIHW->cur_horz_vert_off = inr(CUR_HORZ_VERT_OFF);
414
415    pATIHW->clock_cntl = inr(CLOCK_CNTL);
416
417    pATIHW->bus_cntl = inr(BUS_CNTL);
418
419    pATIHW->mem_vga_wp_sel = inr(MEM_VGA_WP_SEL);
420    pATIHW->mem_vga_rp_sel = inr(MEM_VGA_RP_SEL);
421
422    pATIHW->dac_cntl = inr(DAC_CNTL);
423
424    pATIHW->config_cntl = inr(CONFIG_CNTL);
425
426    pATIHW->gen_test_cntl = inr(GEN_TEST_CNTL) & ~GEN_CUR_EN;
427
428    if (pATI->Chip >= ATI_CHIP_264VTB)
429    {
430        pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE;
431        pATIHW->mem_cntl = inr(MEM_CNTL);
432        pATIHW->mpp_config = inr(MPP_CONFIG);
433        pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ);
434        pATIHW->tvo_cntl = inr(TVO_CNTL);
435    }
436
437    /* Save draw engine state */
438    if (pATI->Block0Base && (pATIHW == &pATI->OldHW))
439    {
440        /* Ensure apertures are enabled */
441        outr(BUS_CNTL, pATI->NewHW.bus_cntl);
442        outr(CONFIG_CNTL, pATI->NewHW.config_cntl);
443
444        ATIMach64WaitForIdle(pATI);
445
446        /* Save FIFO size */
447        if (pATI->Chip >= ATI_CHIP_264VT4)
448            pATIHW->gui_cntl = inm(GUI_CNTL);
449
450        /* Save destination registers */
451        pATIHW->dst_off_pitch = inm(DST_OFF_PITCH);
452        pATIHW->dst_x = inm(DST_X);
453        pATIHW->dst_y = inm(DST_Y);
454        pATIHW->dst_height = inm(DST_HEIGHT);
455        pATIHW->dst_bres_err = inm(DST_BRES_ERR);
456        pATIHW->dst_bres_inc = inm(DST_BRES_INC);
457        pATIHW->dst_bres_dec = inm(DST_BRES_DEC);
458        pATIHW->dst_cntl = inm(DST_CNTL);
459
460        /* Save source registers */
461        pATIHW->src_off_pitch = inm(SRC_OFF_PITCH);
462        pATIHW->src_x = inm(SRC_X);
463        pATIHW->src_y = inm(SRC_Y);
464        pATIHW->src_width1 = inm(SRC_WIDTH1);
465        pATIHW->src_height1 = inm(SRC_HEIGHT1);
466        pATIHW->src_x_start = inm(SRC_X_START);
467        pATIHW->src_y_start = inm(SRC_Y_START);
468        pATIHW->src_width2 = inm(SRC_WIDTH2);
469        pATIHW->src_height2 = inm(SRC_HEIGHT2);
470        pATIHW->src_cntl = inm(SRC_CNTL);
471
472        if (pATI->Chip >= ATI_CHIP_264GTPRO)
473        {
474            CARD32 offset = TEX_LEVEL(inm(TEX_SIZE_PITCH));
475
476            /* Save 3D control & texture registers */
477            pATIHW->tex_offset = inm(TEX_0_OFF + offset);
478            pATIHW->scale_3d_cntl = inm(SCALE_3D_CNTL);
479        }
480
481        /* Save host data register */
482        pATIHW->host_cntl = inm(HOST_CNTL);
483
484        /* Save pattern registers */
485        pATIHW->pat_reg0 = inm(PAT_REG0);
486        pATIHW->pat_reg1 = inm(PAT_REG1);
487        pATIHW->pat_cntl = inm(PAT_CNTL);
488
489        /* Save scissor registers */
490        pATIHW->sc_left = pATI->sc_left = inm(SC_LEFT);
491        pATIHW->sc_right = pATI->sc_right = inm(SC_RIGHT);
492        pATIHW->sc_top = pATI->sc_top = inm(SC_TOP);
493        pATIHW->sc_bottom = pATI->sc_bottom = inm(SC_BOTTOM);
494
495        /* Save data path registers */
496        pATIHW->dp_bkgd_clr = inm(DP_BKGD_CLR);
497        pATIHW->dp_frgd_clr = inm(DP_FRGD_CLR);
498        pATIHW->dp_write_mask = inm(DP_WRITE_MASK);
499        pATIHW->dp_chain_mask = inm(DP_CHAIN_MASK);
500        pATIHW->dp_pix_width = inm(DP_PIX_WIDTH);
501        pATIHW->dp_mix = inm(DP_MIX);
502        pATIHW->dp_src = inm(DP_SRC);
503
504        /* Save colour compare registers */
505        pATIHW->clr_cmp_clr = inm(CLR_CMP_CLR);
506        pATIHW->clr_cmp_msk = inm(CLR_CMP_MSK);
507        pATIHW->clr_cmp_cntl = inm(CLR_CMP_CNTL);
508
509        /* Save context */
510        pATIHW->context_mask = inm(CONTEXT_MASK);
511
512        if (pATI->Chip >= ATI_CHIP_264GTPRO)
513        {
514            /* Save texture setup registers */
515            pATIHW->tex_size_pitch = inm(TEX_SIZE_PITCH);
516            pATIHW->tex_cntl = inm(TEX_CNTL);
517        }
518
519        if (pATI->Block1Base)
520        {
521            /* Save overlay & scaler registers */
522            pATIHW->overlay_y_x_start = inm(OVERLAY_Y_X_START);
523            pATIHW->overlay_y_x_end = inm(OVERLAY_Y_X_END);
524
525            pATIHW->overlay_graphics_key_clr = inm(OVERLAY_GRAPHICS_KEY_CLR);
526            pATIHW->overlay_graphics_key_msk = inm(OVERLAY_GRAPHICS_KEY_MSK);
527
528            pATIHW->overlay_key_cntl = inm(OVERLAY_KEY_CNTL);
529
530            pATIHW->overlay_scale_inc = inm(OVERLAY_SCALE_INC);
531            pATIHW->overlay_scale_cntl = inm(OVERLAY_SCALE_CNTL);
532
533            pATIHW->scaler_height_width = inm(SCALER_HEIGHT_WIDTH);
534
535            pATIHW->scaler_test = inm(SCALER_TEST);
536
537            pATIHW->video_format = inm(VIDEO_FORMAT);
538
539            if (pATI->Chip < ATI_CHIP_264VTB)
540            {
541                pATIHW->buf0_offset = inm(BUF0_OFFSET);
542                pATIHW->buf0_pitch = inm(BUF0_PITCH);
543                pATIHW->buf1_offset = inm(BUF1_OFFSET);
544                pATIHW->buf1_pitch = inm(BUF1_PITCH);
545            }
546            else
547            {
548                pATIHW->scaler_buf0_offset = inm(SCALER_BUF0_OFFSET);
549                pATIHW->scaler_buf1_offset = inm(SCALER_BUF1_OFFSET);
550                pATIHW->scaler_buf_pitch = inm(SCALER_BUF_PITCH);
551
552                pATIHW->overlay_exclusive_horz = inm(OVERLAY_EXCLUSIVE_HORZ);
553                pATIHW->overlay_exclusive_vert = inm(OVERLAY_EXCLUSIVE_VERT);
554
555                if (pATI->Chip >= ATI_CHIP_264GTPRO)
556                {
557                    pATIHW->scaler_colour_cntl = inm(SCALER_COLOUR_CNTL);
558
559                    pATIHW->scaler_h_coeff0 = inm(SCALER_H_COEFF0);
560                    pATIHW->scaler_h_coeff1 = inm(SCALER_H_COEFF1);
561                    pATIHW->scaler_h_coeff2 = inm(SCALER_H_COEFF2);
562                    pATIHW->scaler_h_coeff3 = inm(SCALER_H_COEFF3);
563                    pATIHW->scaler_h_coeff4 = inm(SCALER_H_COEFF4);
564
565                    pATIHW->scaler_buf0_offset_u = inm(SCALER_BUF0_OFFSET_U);
566                    pATIHW->scaler_buf0_offset_v = inm(SCALER_BUF0_OFFSET_V);
567                    pATIHW->scaler_buf1_offset_u = inm(SCALER_BUF1_OFFSET_U);
568                    pATIHW->scaler_buf1_offset_v = inm(SCALER_BUF1_OFFSET_V);
569                }
570            }
571        }
572
573        /* Restore aperture enablement */
574        outr(BUS_CNTL, pATIHW->bus_cntl);
575        outr(CONFIG_CNTL, pATIHW->config_cntl);
576    }
577}
578
579/*
580 * ATIMach64ModeAdjust --
581 *
582 * This function is called to adjust horizontal and vertical timings.
583 */
584static void
585ATIMach64ModeAdjust
586(
587    ATIPtr         pATI,
588    ATIHWPtr       pATIHW,
589    DisplayModePtr pMode
590)
591{
592    int VDisplay;
593
594    /* Clobber mode timings */
595    if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
596    {
597        if (!pMode->CrtcHAdjusted && !pMode->CrtcVAdjusted &&
598            (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN)))
599        {
600        int VScan;
601
602        pMode->Clock = pATI->LCDClock;
603        pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2);
604
605        pMode->VScan = 0;
606
607        /*
608         * Use doublescanning or multiscanning to get around vertical blending
609         * limitations.
610         */
611        VScan = pATI->LCDVertical / pMode->VDisplay;
612        if (VScan > 1)
613        {
614            VScan = 2;
615            pMode->Flags |= V_DBLSCAN;
616        }
617
618        pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart;
619        pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth;
620        pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth;
621
622        pMode->VSyncStart = pMode->VDisplay +
623            ATIDivide(pATI->LCDVSyncStart, VScan, 0, 0);
624        pMode->VSyncEnd = pMode->VSyncStart +
625            ATIDivide(pATI->LCDVSyncWidth, VScan, 0, 1);
626        pMode->VTotal = pMode->VDisplay +
627            ATIDivide(pATI->LCDVBlankWidth, VScan, 0, 0);
628        }
629    }
630
631    /* If not already done adjust horizontal timings */
632    if (!pMode->CrtcHAdjusted)
633    {
634        pMode->CrtcHAdjusted = TRUE;
635        /* XXX Deal with Blank Start/End and overscan later */
636        pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
637        pMode->CrtcHSyncStart = (pMode->HSyncStart >> 3) - 1;
638        pMode->CrtcHSyncEnd = (pMode->HSyncEnd >> 3) - 1;
639        pMode->CrtcHTotal = (pMode->HTotal >> 3) - 1;
640
641        /* Make adjustments if sync pulse width is out-of-bounds */
642        if ((pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart) >
643            (int)MaxBits(CRTC_H_SYNC_WID))
644        {
645            pMode->CrtcHSyncEnd =
646                pMode->CrtcHSyncStart + MaxBits(CRTC_H_SYNC_WID);
647        }
648        else if (pMode->CrtcHSyncStart == pMode->CrtcHSyncEnd)
649        {
650            if (pMode->CrtcHDisplay < pMode->CrtcHSyncStart)
651                pMode->CrtcHSyncStart--;
652            else if (pMode->CrtcHSyncEnd < pMode->CrtcHTotal)
653                pMode->CrtcHSyncEnd++;
654        }
655    }
656
657    /*
658     * Always re-do vertical adjustments.
659     */
660    pMode->CrtcVDisplay = pMode->VDisplay;
661    pMode->CrtcVSyncStart = pMode->VSyncStart;
662    pMode->CrtcVSyncEnd = pMode->VSyncEnd;
663    pMode->CrtcVTotal = pMode->VTotal;
664
665    if ((pATI->Chip >= ATI_CHIP_264CT) &&
666        ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1)))
667    {
668        pMode->CrtcVDisplay <<= 1;
669        pMode->CrtcVSyncStart <<= 1;
670        pMode->CrtcVSyncEnd <<= 1;
671        pMode->CrtcVTotal <<= 1;
672    }
673
674    /*
675     * Might as well default to the same as VGA with respect to sync
676     * polarities.
677     */
678    if ((!(pMode->Flags & (V_PHSYNC | V_NHSYNC))) ||
679        (!(pMode->Flags & (V_PVSYNC | V_NVSYNC))))
680    {
681        pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);
682
683        if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
684            VDisplay = pATI->LCDVertical;
685        else
686            VDisplay = pMode->CrtcVDisplay;
687
688#ifdef TV_OUT
689        if (pATI->tvActive)
690            VDisplay = pMode->CrtcVDisplay;
691#endif
692
693        if (VDisplay < 400)
694            pMode->Flags |= V_PHSYNC | V_NVSYNC;
695        else if (VDisplay < 480)
696            pMode->Flags |= V_NHSYNC | V_PVSYNC;
697        else if (VDisplay < 768)
698            pMode->Flags |= V_NHSYNC | V_NVSYNC;
699        else
700            pMode->Flags |= V_PHSYNC | V_PVSYNC;
701    }
702
703    pMode->CrtcVDisplay--;
704    pMode->CrtcVSyncStart--;
705    pMode->CrtcVSyncEnd--;
706    pMode->CrtcVTotal--;
707    /* Make sure sync pulse is not too wide */
708    if ((pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart) >
709         (int)MaxBits(CRTC_V_SYNC_WID))
710        pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + MaxBits(CRTC_V_SYNC_WID);
711    pMode->CrtcVAdjusted = TRUE;                /* Redundant */
712}
713
714/*
715 * ATIMach64Calculate --
716 *
717 * This function is called to fill in the Mach64 portion of an ATIHWRec.
718 */
719void
720ATIMach64Calculate
721(
722    ATIPtr         pATI,
723    ATIHWPtr       pATIHW,
724    DisplayModePtr pMode
725)
726{
727    ATIMach64ModeAdjust(pATI, pATIHW, pMode);
728
729    /* Build register contents */
730    pATIHW->crtc_h_total_disp =
731        SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) |
732        SetBits(pMode->CrtcHDisplay, CRTC_H_DISP);
733
734    pATIHW->crtc_h_sync_strt_wid =
735        SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) |
736        SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) |         /* ? */
737        SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U), CRTC_H_SYNC_STRT_HI) |
738        SetBits(pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart, CRTC_H_SYNC_WID);
739    if (pMode->Flags & V_NHSYNC)
740        pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL;
741
742    pATIHW->crtc_v_total_disp =
743        SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) |
744        SetBits(pMode->CrtcVDisplay, CRTC_V_DISP);
745
746    pATIHW->crtc_v_sync_strt_wid =
747        SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) |
748        SetBits(pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart, CRTC_V_SYNC_WID);
749    if (pMode->Flags & V_NVSYNC)
750        pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL;
751
752    pATIHW->crtc_off_pitch = SetBits(pATI->displayWidth >> 3, CRTC_PITCH);
753
754    pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL) &
755        ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN |
756          CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN |
757          CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS | CRTC_VGA_XOVERSCAN |
758          CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER |
759          CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE |
760          CRTC_LOCK_REGS |              /* Already off, but ... */
761          CRTC_SYNC_TRISTATE | CRTC_DISP_REQ_EN |
762          CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST);
763    pATIHW->crtc_gen_cntl |=
764        CRTC_EXT_DISP_EN | CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN;
765    switch (pATI->depth)
766    {
767        case 8:
768            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_8BPP, CRTC_PIX_WIDTH);
769            break;
770
771        case 15:
772            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_15BPP, CRTC_PIX_WIDTH);
773            break;
774
775        case 16:
776            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_16BPP, CRTC_PIX_WIDTH);
777            break;
778
779        case 24:
780            if (pATI->bitsPerPixel == 24)
781            {
782                pATIHW->crtc_gen_cntl |=
783                    SetBits(PIX_WIDTH_24BPP, CRTC_PIX_WIDTH);
784                break;
785            }
786            if (pATI->bitsPerPixel != 32)
787                break;
788            /* Fall through */
789
790        case 32:
791            pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_32BPP, CRTC_PIX_WIDTH);
792            break;
793
794        default:
795            break;
796    }
797    if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1))
798        pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;
799    if (pMode->Flags & V_INTERLACE)
800        pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN;
801    if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
802        pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN;
803    /* For now, set display FIFO low water mark as high as possible */
804    if (pATI->Chip < ATI_CHIP_264VTB)
805        pATIHW->crtc_gen_cntl |= CRTC_FIFO_LWM;
806}
807
808/*
809 * ATIMach64Set --
810 *
811 * This function is called to load a Mach64's accelerator CRTC and draw engine.
812 */
813void
814ATIMach64Set
815(
816    ATIPtr      pATI,
817    ATIHWPtr    pATIHW
818)
819{
820
821#ifndef AVOID_CPIO
822
823    if (pATIHW->crtc == ATI_CRTC_MACH64)
824
825#endif /* AVOID_CPIO */
826
827    {
828        if ((pATIHW->FeedbackDivider > 0))
829            ATIClockSet(pATI, pATIHW);          /* Programme clock */
830
831        if (pATI->DAC == ATI_DAC_IBMRGB514)
832            ATIRGB514Set(pATI, pATIHW);
833
834        /* Load Mach64 CRTC registers */
835        outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
836        outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
837        outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
838        outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
839
840        outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
841
842        /* Load overscan registers */
843        outr(OVR_CLR, pATIHW->ovr_clr);
844        outr(OVR_WID_LEFT_RIGHT, pATIHW->ovr_wid_left_right);
845        outr(OVR_WID_TOP_BOTTOM, pATIHW->ovr_wid_top_bottom);
846
847        /* Load hardware cursor registers */
848        outr(CUR_CLR0, pATIHW->cur_clr0);
849        outr(CUR_CLR1, pATIHW->cur_clr1);
850        outr(CUR_OFFSET, pATIHW->cur_offset);
851        outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn);
852        outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off);
853
854        /* Set pixel clock */
855        outr(CLOCK_CNTL, pATIHW->clock_cntl | CLOCK_STROBE);
856
857        outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
858        outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl);
859        outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN);
860
861        /* Finalise CRTC setup and turn on the screen */
862        outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
863    }
864
865    /* Load draw engine */
866    if (pATI->Block0Base)
867    {
868        /* Clobber MMIO cache */
869        (void)memset(pATI->MMIOCached, 0, SizeOf(pATI->MMIOCached));
870
871        /* Ensure apertures are enabled */
872        outr(BUS_CNTL, pATI->NewHW.bus_cntl);
873        outr(CONFIG_CNTL, pATI->NewHW.config_cntl);
874
875        pATI->EngineIsBusy = TRUE;      /* Force engine poll */
876        ATIMach64WaitForIdle(pATI);
877
878        /* Load FIFO size */
879        if (pATI->Chip >= ATI_CHIP_264VT4)
880        {
881            outm(GUI_CNTL, pATIHW->gui_cntl);
882            pATI->nAvailableFIFOEntries = 0;
883            ATIMach64PollEngineStatus(pATI);
884        }
885
886        /* Set FIFO depth */
887        pATI->nFIFOEntries = pATI->nAvailableFIFOEntries;
888
889        /* Load destination registers */
890        ATIMach64WaitForFIFO(pATI, 7);
891        outf(DST_OFF_PITCH, pATIHW->dst_off_pitch);
892        outf(DST_Y_X, SetWord(pATIHW->dst_x, 1) | SetWord(pATIHW->dst_y, 0));
893        outf(DST_HEIGHT, pATIHW->dst_height);
894        outf(DST_BRES_ERR, pATIHW->dst_bres_err);
895        outf(DST_BRES_INC, pATIHW->dst_bres_inc);
896        outf(DST_BRES_DEC, pATIHW->dst_bres_dec);
897        outf(DST_CNTL, pATIHW->dst_cntl);
898
899        if (pATI->Chip >= ATI_CHIP_264GTPRO)
900        {
901            /* Load ROP unit registers */
902            ATIMach64WaitForFIFO(pATI, 2);
903            outf(Z_CNTL, 0);
904            outf(ALPHA_TST_CNTL, 0);
905        }
906
907        /* Load source registers */
908        ATIMach64WaitForFIFO(pATI, 6);
909        outf(SRC_OFF_PITCH, pATIHW->src_off_pitch);
910        outf(SRC_Y_X, SetWord(pATIHW->src_x, 1) | SetWord(pATIHW->src_y, 0));
911        outf(SRC_HEIGHT1_WIDTH1,
912            SetWord(pATIHW->src_width1, 1) | SetWord(pATIHW->src_height1, 0));
913        outf(SRC_Y_X_START,
914            SetWord(pATIHW->src_x_start, 1) | SetWord(pATIHW->src_y_start, 0));
915        outf(SRC_HEIGHT2_WIDTH2,
916            SetWord(pATIHW->src_width2, 1) | SetWord(pATIHW->src_height2, 0));
917        outf(SRC_CNTL, pATIHW->src_cntl);
918
919        if (pATI->Chip >= ATI_CHIP_264GTPRO)
920        {
921            CARD32 offset = TEX_LEVEL(pATIHW->tex_size_pitch);
922
923            /* Load 3D control & texture registers */
924            ATIMach64WaitForFIFO(pATI, 2);
925            outf(TEX_0_OFF + offset, pATIHW->tex_offset);
926            outf(SCALE_3D_CNTL, pATIHW->scale_3d_cntl);
927        }
928
929        /* Load host data register */
930        ATIMach64WaitForFIFO(pATI, 1);
931        outf(HOST_CNTL, pATIHW->host_cntl);
932
933        /* Set host transfer window address and size clamp */
934        pATI->pHOST_DATA = ATIHostDataAddr(HOST_DATA_0);
935        pATI->nHostFIFOEntries = pATI->nFIFOEntries >> 1;
936        if (pATI->nHostFIFOEntries > 16)
937            pATI->nHostFIFOEntries = 16;
938
939        /* Load pattern registers */
940        ATIMach64WaitForFIFO(pATI, 3);
941        outf(PAT_REG0, pATIHW->pat_reg0);
942        outf(PAT_REG1, pATIHW->pat_reg1);
943        outf(PAT_CNTL, pATIHW->pat_cntl);
944
945        /* Load scissor registers */
946        ATIMach64WaitForFIFO(pATI, 2);
947        outf(SC_LEFT_RIGHT,
948            SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0));
949        outf(SC_TOP_BOTTOM,
950            SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0));
951        pATI->sc_left = pATIHW->sc_left;
952        pATI->sc_right = pATIHW->sc_right;
953        pATI->sc_top = pATIHW->sc_top;
954        pATI->sc_bottom = pATIHW->sc_bottom;
955
956        /* Load data path registers */
957        ATIMach64WaitForFIFO(pATI, 7);
958        outf(DP_BKGD_CLR, pATIHW->dp_bkgd_clr);
959        outf(DP_FRGD_CLR, pATIHW->dp_frgd_clr);
960        outf(DP_WRITE_MASK, pATIHW->dp_write_mask);
961        outf(DP_CHAIN_MASK, pATIHW->dp_chain_mask);
962        outf(DP_PIX_WIDTH, pATIHW->dp_pix_width);
963        outf(DP_MIX, pATIHW->dp_mix);
964        outf(DP_SRC, pATIHW->dp_src);
965
966        /* Load colour compare registers */
967        ATIMach64WaitForFIFO(pATI, 3);
968        outf(CLR_CMP_CLR, pATIHW->clr_cmp_clr);
969        outf(CLR_CMP_MSK, pATIHW->clr_cmp_msk);
970        outf(CLR_CMP_CNTL, pATIHW->clr_cmp_cntl);
971
972        /* Load context mask */
973        ATIMach64WaitForFIFO(pATI, 1);
974        outf(CONTEXT_MASK, pATIHW->context_mask);
975
976        if (pATI->Chip >= ATI_CHIP_264GTPRO)
977        {
978            /* Load texture setup registers */
979            ATIMach64WaitForFIFO(pATI, 2);
980            outf(TEX_SIZE_PITCH, pATIHW->tex_size_pitch);
981            outf(TEX_CNTL, pATIHW->tex_cntl);
982        }
983
984        if (pATI->Block1Base)
985        {
986            /* Load overlay & scaler registers */
987            ATIMach64WaitForFIFO(pATI, 10);
988            outf(OVERLAY_Y_X_START, pATIHW->overlay_y_x_start);
989            outf(OVERLAY_Y_X_END, pATIHW->overlay_y_x_end);
990
991            outf(OVERLAY_GRAPHICS_KEY_CLR, pATIHW->overlay_graphics_key_clr);
992            outf(OVERLAY_GRAPHICS_KEY_MSK, pATIHW->overlay_graphics_key_msk);
993
994            outf(OVERLAY_KEY_CNTL, pATIHW->overlay_key_cntl);
995
996            outf(OVERLAY_SCALE_INC, pATIHW->overlay_scale_inc);
997            outf(OVERLAY_SCALE_CNTL, pATIHW->overlay_scale_cntl);
998
999            outf(SCALER_HEIGHT_WIDTH, pATIHW->scaler_height_width);
1000
1001            outf(SCALER_TEST, pATIHW->scaler_test);
1002
1003            outf(VIDEO_FORMAT, pATIHW->video_format);
1004
1005            if (pATI->Chip < ATI_CHIP_264VTB)
1006            {
1007                ATIMach64WaitForFIFO(pATI, 4);
1008                outf(BUF0_OFFSET, pATIHW->buf0_offset);
1009                outf(BUF0_PITCH, pATIHW->buf0_pitch);
1010                outf(BUF1_OFFSET, pATIHW->buf1_offset);
1011                outf(BUF1_PITCH, pATIHW->buf1_pitch);
1012            }
1013            else
1014            {
1015                ATIMach64WaitForFIFO(pATI, 5);
1016                outf(SCALER_BUF0_OFFSET, pATIHW->scaler_buf0_offset);
1017                outf(SCALER_BUF1_OFFSET, pATIHW->scaler_buf1_offset);
1018                outf(SCALER_BUF_PITCH, pATIHW->scaler_buf_pitch);
1019
1020                outf(OVERLAY_EXCLUSIVE_HORZ, pATIHW->overlay_exclusive_horz);
1021                outf(OVERLAY_EXCLUSIVE_VERT, pATIHW->overlay_exclusive_vert);
1022
1023                if (pATI->Chip >= ATI_CHIP_264GTPRO)
1024                {
1025                    ATIMach64WaitForFIFO(pATI, 10);
1026                    outf(SCALER_COLOUR_CNTL, pATIHW->scaler_colour_cntl);
1027
1028                    outf(SCALER_H_COEFF0, pATIHW->scaler_h_coeff0);
1029                    outf(SCALER_H_COEFF1, pATIHW->scaler_h_coeff1);
1030                    outf(SCALER_H_COEFF2, pATIHW->scaler_h_coeff2);
1031                    outf(SCALER_H_COEFF3, pATIHW->scaler_h_coeff3);
1032                    outf(SCALER_H_COEFF4, pATIHW->scaler_h_coeff4);
1033
1034                    outf(SCALER_BUF0_OFFSET_U, pATIHW->scaler_buf0_offset_u);
1035                    outf(SCALER_BUF0_OFFSET_V, pATIHW->scaler_buf0_offset_v);
1036                    outf(SCALER_BUF1_OFFSET_U, pATIHW->scaler_buf1_offset_u);
1037                    outf(SCALER_BUF1_OFFSET_V, pATIHW->scaler_buf1_offset_v);
1038                }
1039            }
1040        }
1041
1042        ATIMach64WaitForIdle(pATI);
1043
1044        if (pATI->OptionMMIOCache)
1045        {
1046            /*
1047             * Enable write caching for selected MMIO registers.  This can only
1048             * be done for those registers whose value does not change without
1049             * driver intervention.
1050             */
1051
1052            CacheRegister(SRC_CNTL);
1053
1054            if (pATI->Chip >= ATI_CHIP_264GTPRO)
1055            {
1056                CacheRegister(SCALE_3D_CNTL);
1057            }
1058
1059            CacheRegister(HOST_CNTL);
1060
1061            CacheRegister(PAT_REG0);
1062            CacheRegister(PAT_REG1);
1063            CacheRegister(PAT_CNTL);
1064
1065            CacheRegister(SC_LEFT_RIGHT);
1066            CacheRegister(SC_TOP_BOTTOM);
1067
1068            CacheRegister(DP_BKGD_CLR);
1069            CacheRegister(DP_FRGD_CLR);
1070            CacheRegister(DP_PIX_WIDTH);
1071            CacheRegister(DP_MIX);
1072
1073            CacheRegister(CLR_CMP_CLR);
1074            CacheRegister(CLR_CMP_MSK);
1075            CacheRegister(CLR_CMP_CNTL);
1076
1077            if (pATI->Chip >= ATI_CHIP_264GTPRO)
1078            {
1079                CacheRegister(TEX_SIZE_PITCH);
1080            }
1081
1082            if (pATI->Block1Base)
1083            {
1084                CacheRegister(OVERLAY_Y_X_START);
1085                CacheRegister(OVERLAY_Y_X_END);
1086
1087                CacheRegister(OVERLAY_GRAPHICS_KEY_CLR);
1088                CacheRegister(OVERLAY_GRAPHICS_KEY_MSK);
1089
1090                CacheRegister(OVERLAY_KEY_CNTL);
1091
1092                CacheRegister(OVERLAY_SCALE_INC);
1093                CacheRegister(OVERLAY_SCALE_CNTL);
1094
1095                CacheRegister(SCALER_HEIGHT_WIDTH);
1096
1097                CacheRegister(SCALER_TEST);
1098
1099                CacheRegister(VIDEO_FORMAT);
1100
1101                if (pATI->Chip < ATI_CHIP_264VTB)
1102                {
1103                    CacheRegister(BUF0_OFFSET);
1104                    CacheRegister(BUF0_PITCH);
1105                    CacheRegister(BUF1_OFFSET);
1106                    CacheRegister(BUF1_PITCH);
1107                }
1108                else
1109                {
1110                    CacheRegister(SCALER_BUF0_OFFSET);
1111                    CacheRegister(SCALER_BUF1_OFFSET);
1112                    CacheRegister(SCALER_BUF_PITCH);
1113
1114                    CacheRegister(OVERLAY_EXCLUSIVE_HORZ);
1115                    CacheRegister(OVERLAY_EXCLUSIVE_VERT);
1116
1117                    if (pATI->Chip >= ATI_CHIP_264GTPRO)
1118                    {
1119                        CacheRegister(SCALER_COLOUR_CNTL);
1120
1121                        CacheRegister(SCALER_H_COEFF0);
1122                        CacheRegister(SCALER_H_COEFF1);
1123                        CacheRegister(SCALER_H_COEFF2);
1124                        CacheRegister(SCALER_H_COEFF3);
1125                        CacheRegister(SCALER_H_COEFF4);
1126
1127                        CacheRegister(SCALER_BUF0_OFFSET_U);
1128                        CacheRegister(SCALER_BUF0_OFFSET_V);
1129                        CacheRegister(SCALER_BUF1_OFFSET_U);
1130                        CacheRegister(SCALER_BUF1_OFFSET_V);
1131                    }
1132                }
1133            }
1134        }
1135    }
1136
1137#ifndef AVOID_CPIO
1138
1139    if (pATIHW->crtc == ATI_CRTC_MACH64)
1140
1141#endif /* AVOID_CPIO */
1142
1143    {
1144        /* Aperture setup */
1145        outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
1146        outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
1147
1148        outr(DAC_CNTL, pATIHW->dac_cntl);
1149
1150        outr(CONFIG_CNTL, pATIHW->config_cntl);
1151        outr(BUS_CNTL, pATIHW->bus_cntl);
1152
1153        if (pATI->Chip >= ATI_CHIP_264VTB)
1154        {
1155            outr(MEM_BUF_CNTL, pATIHW->mem_buf_cntl);
1156            outr(MEM_CNTL, pATIHW->mem_cntl);
1157            outr(MPP_CONFIG, pATIHW->mpp_config);
1158            outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq);
1159            outr(TVO_CNTL, pATIHW->tvo_cntl);
1160        }
1161    }
1162}
1163
1164/*
1165 * ATIMach64SaveScreen --
1166 *
1167 * This function blanks or unblanks a Mach64 screen.
1168 */
1169void
1170ATIMach64SaveScreen
1171(
1172    ATIPtr pATI,
1173    int    Mode
1174)
1175{
1176    CARD32 crtc_gen_cntl = inr(CRTC_GEN_CNTL);
1177
1178    switch (Mode)
1179    {
1180        case SCREEN_SAVER_OFF:
1181        case SCREEN_SAVER_FORCER:
1182            outr(CRTC_GEN_CNTL, crtc_gen_cntl & ~CRTC_DISPLAY_DIS);
1183            break;
1184
1185        case SCREEN_SAVER_ON:
1186        case SCREEN_SAVER_CYCLE:
1187            outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_DISPLAY_DIS);
1188            break;
1189
1190        default:
1191            break;
1192    }
1193}
1194
1195/*
1196 * ATIMach64SetDPMSMode --
1197 *
1198 * This function sets a Mach64's VESA Display Power Management Signaling mode.
1199 */
1200void
1201ATIMach64SetDPMSMode
1202(
1203    ScrnInfoPtr pScreenInfo,
1204    ATIPtr      pATI,
1205    int         DPMSMode
1206)
1207{
1208    CARD32 crtc_gen_cntl =
1209        inr(CRTC_GEN_CNTL) & ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS);
1210
1211    switch (DPMSMode)
1212    {
1213        case DPMSModeOn:        /* HSync on, VSync on */
1214            break;
1215
1216        case DPMSModeStandby:   /* HSync off, VSync on */
1217            crtc_gen_cntl |= CRTC_HSYNC_DIS;
1218            break;
1219
1220        case DPMSModeSuspend:   /* HSync on, VSync off */
1221            crtc_gen_cntl |= CRTC_VSYNC_DIS;
1222            break;
1223
1224        case DPMSModeOff:       /* HSync off, VSync off */
1225            crtc_gen_cntl |= CRTC_HSYNC_DIS | CRTC_VSYNC_DIS;
1226            break;
1227
1228        default:                /* Muffle compiler */
1229            return;
1230    }
1231
1232#ifdef XF86DRI_DEVEL
1233
1234    /* XAA Sync requires the DRM lock if DRI enabled */
1235    ATIDRILock(pScreenInfo);
1236
1237#endif /* XF86DRI_DEVEL */
1238
1239    ATIMach64Sync(pScreenInfo);
1240
1241    outr(CRTC_GEN_CNTL, crtc_gen_cntl);
1242
1243    if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0))
1244    {
1245        CARD32 lcd_index = 0;
1246
1247        /*
1248         * ATI's BIOS simply turns the panel on and off, so do the same by
1249         * default, but keep the previous behaviour around for reference.
1250         */
1251        if (pATI->OptionDevel)
1252        {
1253            CARD32 power_management;
1254
1255            if (pATI->Chip == ATI_CHIP_264LT)
1256            {
1257                power_management = inr(POWER_MANAGEMENT);
1258            }
1259            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
1260                        (pATI->Chip == ATI_CHIP_264XL) ||
1261                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
1262            {
1263                lcd_index = inr(LCD_INDEX);
1264                power_management = ATIMach64GetLCDReg(LCD_POWER_MANAGEMENT);
1265            }
1266
1267            power_management &= ~(STANDBY_NOW | SUSPEND_NOW);
1268
1269            switch (DPMSMode)
1270            {
1271                case DPMSModeOn:
1272                    break;
1273
1274                case DPMSModeStandby:
1275                    power_management |= STANDBY_NOW;
1276                    break;
1277
1278                case DPMSModeSuspend:
1279                    power_management |= SUSPEND_NOW;
1280                    break;
1281
1282                case DPMSModeOff:
1283                    power_management |= STANDBY_NOW | SUSPEND_NOW;  /* ? */
1284                    break;
1285
1286                default:        /* Muffle compiler */
1287                    return;
1288            }
1289
1290            if (pATI->Chip == ATI_CHIP_264LT)
1291            {
1292                outr(POWER_MANAGEMENT, power_management);
1293            }
1294            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
1295                        (pATI->Chip == ATI_CHIP_264XL) ||
1296                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
1297            {
1298                ATIMach64PutLCDReg(LCD_POWER_MANAGEMENT, power_management);
1299                outr(LCD_INDEX, lcd_index);
1300            }
1301        }
1302        else
1303        {
1304            CARD32 lcd_gen_ctrl;
1305
1306            if (pATI->Chip == ATI_CHIP_264LT)
1307            {
1308                lcd_gen_ctrl = inr(LCD_GEN_CTRL);
1309            }
1310            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
1311                        (pATI->Chip == ATI_CHIP_264XL) ||
1312                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
1313            {
1314                lcd_index = inr(LCD_INDEX);
1315                lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL);
1316            }
1317
1318            if (DPMSMode == DPMSModeOn)
1319                lcd_gen_ctrl |= LCD_ON;
1320            else
1321                lcd_gen_ctrl &= ~LCD_ON;
1322
1323            if (pATI->Chip == ATI_CHIP_264LT)
1324                outr(LCD_GEN_CTRL, lcd_gen_ctrl);
1325            else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
1326                        (pATI->Chip == ATI_CHIP_264XL) ||
1327                        (pATI->Chip == ATI_CHIP_MOBILITY)) */
1328            {
1329                ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
1330                outr(LCD_INDEX, lcd_index);
1331            }
1332        }
1333    }
1334
1335#ifdef XF86DRI_DEVEL
1336
1337    ATIDRIUnlock(pScreenInfo);
1338
1339#endif /* XF86DRI_DEVEL */
1340
1341}
1342