/* * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of Marc Aurele La France not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Marc Aurele La France makes no representations * about the suitability of this software for any purpose. It is provided * "as-is" without express or implied warranty. * * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * DRI support by: * Manuel Teira * Leif Delgass */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "ati.h" #include "atibus.h" #include "atichip.h" #include "atidac.h" #include "atimach64.h" #include "atimach64accel.h" #include "atimach64io.h" #include "atirgb514.h" #ifdef HAVE_XEXTPROTO_71 #include #else #ifndef DPMS_SERVER # define DPMS_SERVER #endif #include #endif /* * ATIMach64PreInit -- * * This function fills in the Mach64 portion of an ATIHWRec that is common to * all video modes generated by the driver. */ void ATIMach64PreInit ( ScrnInfoPtr pScreenInfo, ATIPtr pATI, ATIHWPtr pATIHW ) { if ((pATI->LockData.crtc_gen_cntl & CRTC_CSYNC_EN) && !pATI->OptionCSync) { xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE, "Using composite sync to match input timing.\n"); pATI->OptionCSync = TRUE; } pATIHW->bus_cntl = inr(BUS_CNTL); if (pATI->Chip < ATI_CHIP_264VT4) pATIHW->bus_cntl = (pATIHW->bus_cntl & ~BUS_HOST_ERR_INT_EN) | BUS_HOST_ERR_INT; if (pATI->Chip < ATI_CHIP_264VTB) { pATIHW->bus_cntl &= ~(BUS_FIFO_ERR_INT_EN | BUS_ROM_DIS); pATIHW->bus_cntl |= SetBits(15, BUS_FIFO_WS) | BUS_FIFO_ERR_INT; } else if (pATI->MMIOInLinear) { pATIHW->bus_cntl &= ~BUS_APER_REG_DIS; } else { pATIHW->bus_cntl |= BUS_APER_REG_DIS; } if (pATI->Chip >= ATI_CHIP_264VT) pATIHW->bus_cntl |= BUS_EXT_REG_EN; /* Enable Block 1 */ #ifdef AVOID_CPIO pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) | SetBits(1, MEM_VGA_WPS1); pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) | SetBits(1, MEM_VGA_RPS1); #else /* AVOID_CPIO */ pATIHW->mem_vga_wp_sel = SetBits(0, MEM_VGA_WPS0) | SetBits(pATIHW->nPlane, MEM_VGA_WPS1); pATIHW->mem_vga_rp_sel = SetBits(0, MEM_VGA_RPS0) | SetBits(pATIHW->nPlane, MEM_VGA_RPS1); #endif /* AVOID_CPIO */ pATIHW->dac_cntl = inr(DAC_CNTL) & ~(DAC1_CLK_SEL | DAC_PALETTE_ACCESS_CNTL | DAC_8BIT_EN); if (pATI->Chip >= ATI_CHIP_264CT) pATIHW->dac_cntl &= ~DAC_FEA_CON_EN; if (pATI->rgbBits == 8) pATIHW->dac_cntl |= DAC_8BIT_EN; pATIHW->gen_test_cntl = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN; if (pATI->DAC == ATI_DAC_IBMRGB514) pATIHW->gen_test_cntl |= GEN_OVR_OUTPUT_EN; pATIHW->config_cntl = inr(CONFIG_CNTL); #ifndef AVOID_CPIO if (pATI->VGAAdapter) { pATIHW->config_cntl |= CFG_MEM_VGA_AP_EN; } else #endif /* AVOID_CPIO */ { pATIHW->config_cntl &= ~CFG_MEM_VGA_AP_EN; } if ((pATI->Chip < ATI_CHIP_264CT)) { /* Replace linear aperture size and address */ pATIHW->config_cntl &= ~(CFG_MEM_AP_LOC | CFG_MEM_AP_SIZE); pATIHW->config_cntl |= SetBits(pATI->LinearBase >> 22, CFG_MEM_AP_LOC); if ((pATI->Chip < ATI_CHIP_264CT) && (pATI->VideoRAM < 4096)) pATIHW->config_cntl |= SetBits(1, CFG_MEM_AP_SIZE); else pATIHW->config_cntl |= SetBits(2, CFG_MEM_AP_SIZE); } if (pATI->Chip >= ATI_CHIP_264VTB) { pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE; pATIHW->mem_cntl = (pATI->LockData.mem_cntl & ~(CTL_MEM_LOWER_APER_ENDIAN | CTL_MEM_UPPER_APER_ENDIAN)) | SetBits(CTL_MEM_APER_BYTE_ENDIAN, CTL_MEM_LOWER_APER_ENDIAN); switch (pATI->bitsPerPixel) { default: pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_BYTE_ENDIAN, CTL_MEM_UPPER_APER_ENDIAN); break; case 16: pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_WORD_ENDIAN, CTL_MEM_UPPER_APER_ENDIAN); break; case 32: pATIHW->mem_cntl |= SetBits(CTL_MEM_APER_LONG_ENDIAN, CTL_MEM_UPPER_APER_ENDIAN); break; } pATIHW->mpp_config = inr(MPP_CONFIG); pATIHW->mpp_config &= ~(MPP_PRESCALE | MPP_NSTATES | MPP_FORMAT | MPP_WAIT_STATE | MPP_INSERT_WAIT | MPP_TRISTATE_ADDR | MPP_AUTO_INC_EN | MPP_CHKREQ_EN | MPP_BUFFER_SIZE | MPP_BUFFER_MODE | MPP_BUSY); pATIHW->mpp_config |= (MPP_NSTATES_8 | MPP_FORMAT_DA8 | SetBits(4, MPP_WAIT_STATE) | MPP_CHKRDY_EN | MPP_READ_EARLY | MPP_RW_MODE | MPP_EN); pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ); pATIHW->mpp_strobe_seq &= ~(MPP_STB0_SEQ | MPP_STB1_SEQ); pATIHW->mpp_strobe_seq |= SetBits(0x0087U, MPP_STB0_SEQ) | SetBits(0x0083U, MPP_STB1_SEQ); pATIHW->tvo_cntl = 0; } /* Draw engine setup */ if (pATI->Block0Base) { CARD32 bus_cntl = inr(BUS_CNTL); CARD32 config_cntl = inr(CONFIG_CNTL); /* Ensure apertures are enabled */ outr(BUS_CNTL, pATIHW->bus_cntl); outr(CONFIG_CNTL, pATIHW->config_cntl); /* * When possible, max out command FIFO size. */ if (pATI->Chip >= ATI_CHIP_264VT4) #ifdef XF86DRI_DEVEL /* Changing the FIFO depth seems to interfere with DMA, so use * default of 128 entries (0x01) */ pATIHW->gui_cntl = (inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE) | 0x01; #else /* XF86DRI_DEVEL */ pATIHW->gui_cntl = inm(GUI_CNTL) & ~CMDFIFO_SIZE_MODE; #endif /* XF86DRI_DEVEL */ /* Initialise destination registers */ pATIHW->dst_off_pitch = SetBits((pATI->displayWidth * pATI->XModifier) >> 3, DST_PITCH); pATIHW->dst_cntl = DST_X_DIR | DST_Y_DIR | DST_LAST_PEL; /* Initialise source registers */ pATIHW->src_off_pitch = pATIHW->dst_off_pitch; pATIHW->src_width1 = pATIHW->src_height1 = pATIHW->src_width2 = pATIHW->src_height2 = 1; pATIHW->src_cntl = SRC_LINE_X_DIR; /* Initialise scissor, allowing for offscreen areas */ #ifdef USE_XAA if (!pATI->useEXA) { int width, height, total; pATIHW->sc_right = (pATI->displayWidth * pATI->XModifier) - 1; width = pATI->displayWidth * pATI->bitsPerPixel; total = pScreenInfo->videoRam * (1024 * 8); height = (total + width - 1) / width; if (height > ATIMach64MaxY + 1) height = ATIMach64MaxY + 1; pATIHW->sc_bottom = height - 1; } #endif /* USE_XAA */ #ifdef USE_EXA if (pATI->useEXA) { pATIHW->sc_right = ATIMach64MaxX; pATIHW->sc_bottom = ATIMach64MaxY; } #endif /* USE_EXA */ pATI->sc_left_right = SetWord(pATI->NewHW.sc_right, 1) | SetWord(pATI->NewHW.sc_left, 0); pATI->sc_top_bottom = SetWord(pATI->NewHW.sc_bottom, 1) | SetWord(pATI->NewHW.sc_top, 0); /* Initialise data path */ pATIHW->dp_frgd_clr = (CARD32)(-1); pATIHW->dp_write_mask = (CARD32)(-1); switch (pATI->depth) { case 8: pATIHW->dp_chain_mask = DP_CHAIN_8BPP; pATIHW->dp_pix_width = SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); break; case 15: pATIHW->dp_chain_mask = DP_CHAIN_15BPP_1555; pATIHW->dp_pix_width = SetBits(PIX_WIDTH_15BPP, DP_DST_PIX_WIDTH) | SetBits(PIX_WIDTH_15BPP, DP_SRC_PIX_WIDTH) | SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); break; case 16: pATIHW->dp_chain_mask = DP_CHAIN_16BPP_565; pATIHW->dp_pix_width = SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) | SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) | SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); break; case 24: if (pATI->bitsPerPixel == 24) { pATIHW->dp_chain_mask = DP_CHAIN_24BPP_888; pATIHW->dp_pix_width = SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); } else { pATIHW->dp_chain_mask = DP_CHAIN_32BPP_8888; pATIHW->dp_pix_width = SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) | SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) | SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); } break; default: break; } #if X_BYTE_ORDER == X_LITTLE_ENDIAN pATIHW->dp_pix_width |= DP_BYTE_PIX_ORDER; #endif /* X_BYTE_ORDER */ pATIHW->dp_mix = SetBits(MIX_SRC, DP_FRGD_MIX) | SetBits(MIX_DST, DP_BKGD_MIX); pATIHW->dp_src = DP_MONO_SRC_ALLONES | SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC); /* Initialise colour compare */ pATIHW->clr_cmp_msk = (1 << pATI->depth) - 1; if (pATI->Block1Base) { pATIHW->overlay_y_x_start = SetBits(0, OVERLAY_Y_START) | SetBits(0, OVERLAY_X_START) | OVERLAY_LOCK_START; pATIHW->overlay_y_x_end = SetBits(0, OVERLAY_Y_END) | SetBits(0, OVERLAY_X_END) | OVERLAY_LOCK_END; pATIHW->overlay_graphics_key_clr = (3 << ((2 * pATI->depth) / 3)) | (2 << ((1 * pATI->depth) / 3)) | (1 << ((0 * pATI->depth) / 3)); pATIHW->overlay_graphics_key_msk = (1 << pATI->depth) - 1; pATIHW->overlay_key_cntl = SetBits(OVERLAY_MIX_FALSE, OVERLAY_VIDEO_FN) | SetBits(OVERLAY_MIX_EQUAL, OVERLAY_GRAPHICS_FN); pATIHW->overlay_scale_cntl = SCALE_EN; pATIHW->video_format = VIDEO_IN_VYUY422 | SCALER_IN_VYUY422; if (pATI->Chip >= ATI_CHIP_264GTPRO) { /* These values are documented voodoo */ pATIHW->scaler_h_coeff0 = SetByte(0x20U, 1); pATIHW->scaler_h_coeff1 = SetByte(0x0DU, 0) | SetByte(0x20U, 1) | SetByte(0x06U, 2) | SetByte(0x0DU, 3); pATIHW->scaler_h_coeff2 = SetByte(0x0DU, 0) | SetByte(0x1CU, 1) | SetByte(0x0AU, 2) | SetByte(0x0DU, 3); pATIHW->scaler_h_coeff3 = SetByte(0x0CU, 0) | SetByte(0x1AU, 1) | SetByte(0x0EU, 2) | SetByte(0x0CU, 3); pATIHW->scaler_h_coeff4 = SetByte(0x0CU, 0) | SetByte(0x14U, 1) | SetByte(0x14U, 2) | SetByte(0x0CU, 3); } } /* Restore aperture enablement */ outr(BUS_CNTL, bus_cntl); outr(CONFIG_CNTL, config_cntl); } } /* * ATIMach64Save -- * * This function is called to save the Mach64 portion of the current video * state. */ void ATIMach64Save ( ATIPtr pATI, ATIHWPtr pATIHW ) { pATIHW->crtc_h_total_disp = inr(CRTC_H_TOTAL_DISP); pATIHW->crtc_h_sync_strt_wid = inr(CRTC_H_SYNC_STRT_WID); pATIHW->crtc_v_total_disp = inr(CRTC_V_TOTAL_DISP); pATIHW->crtc_v_sync_strt_wid = inr(CRTC_V_SYNC_STRT_WID); pATIHW->crtc_off_pitch = inr(CRTC_OFF_PITCH); pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL); pATIHW->ovr_clr = inr(OVR_CLR); pATIHW->ovr_wid_left_right = inr(OVR_WID_LEFT_RIGHT); pATIHW->ovr_wid_top_bottom = inr(OVR_WID_TOP_BOTTOM); pATIHW->cur_clr0 = inr(CUR_CLR0); pATIHW->cur_clr1 = inr(CUR_CLR1); pATIHW->cur_offset = inr(CUR_OFFSET); pATIHW->cur_horz_vert_posn = inr(CUR_HORZ_VERT_POSN); pATIHW->cur_horz_vert_off = inr(CUR_HORZ_VERT_OFF); pATIHW->clock_cntl = inr(CLOCK_CNTL); pATIHW->bus_cntl = inr(BUS_CNTL); pATIHW->mem_vga_wp_sel = inr(MEM_VGA_WP_SEL); pATIHW->mem_vga_rp_sel = inr(MEM_VGA_RP_SEL); pATIHW->dac_cntl = inr(DAC_CNTL); pATIHW->config_cntl = inr(CONFIG_CNTL); pATIHW->gen_test_cntl = inr(GEN_TEST_CNTL) & ~GEN_CUR_EN; if (pATI->Chip >= ATI_CHIP_264VTB) { pATIHW->mem_buf_cntl = inr(MEM_BUF_CNTL) | INVALIDATE_RB_CACHE; pATIHW->mem_cntl = inr(MEM_CNTL); pATIHW->mpp_config = inr(MPP_CONFIG); pATIHW->mpp_strobe_seq = inr(MPP_STROBE_SEQ); pATIHW->tvo_cntl = inr(TVO_CNTL); } /* Save draw engine state */ if (pATI->Block0Base && (pATIHW == &pATI->OldHW)) { /* Ensure apertures are enabled */ outr(BUS_CNTL, pATI->NewHW.bus_cntl); outr(CONFIG_CNTL, pATI->NewHW.config_cntl); ATIMach64WaitForIdle(pATI); /* Save FIFO size */ if (pATI->Chip >= ATI_CHIP_264VT4) pATIHW->gui_cntl = inm(GUI_CNTL); /* Save destination registers */ pATIHW->dst_off_pitch = inm(DST_OFF_PITCH); pATIHW->dst_x = inm(DST_X); pATIHW->dst_y = inm(DST_Y); pATIHW->dst_height = inm(DST_HEIGHT); pATIHW->dst_bres_err = inm(DST_BRES_ERR); pATIHW->dst_bres_inc = inm(DST_BRES_INC); pATIHW->dst_bres_dec = inm(DST_BRES_DEC); pATIHW->dst_cntl = inm(DST_CNTL); /* Save source registers */ pATIHW->src_off_pitch = inm(SRC_OFF_PITCH); pATIHW->src_x = inm(SRC_X); pATIHW->src_y = inm(SRC_Y); pATIHW->src_width1 = inm(SRC_WIDTH1); pATIHW->src_height1 = inm(SRC_HEIGHT1); pATIHW->src_x_start = inm(SRC_X_START); pATIHW->src_y_start = inm(SRC_Y_START); pATIHW->src_width2 = inm(SRC_WIDTH2); pATIHW->src_height2 = inm(SRC_HEIGHT2); pATIHW->src_cntl = inm(SRC_CNTL); if (pATI->Chip >= ATI_CHIP_264GTPRO) { CARD32 offset = TEX_LEVEL(inm(TEX_SIZE_PITCH)); /* Save 3D control & texture registers */ pATIHW->tex_offset = inm(TEX_0_OFF + offset); pATIHW->scale_3d_cntl = inm(SCALE_3D_CNTL); } /* Save host data register */ pATIHW->host_cntl = inm(HOST_CNTL); /* Save pattern registers */ pATIHW->pat_reg0 = inm(PAT_REG0); pATIHW->pat_reg1 = inm(PAT_REG1); pATIHW->pat_cntl = inm(PAT_CNTL); /* Save scissor registers */ pATIHW->sc_left = pATI->sc_left = inm(SC_LEFT); pATIHW->sc_right = pATI->sc_right = inm(SC_RIGHT); pATIHW->sc_top = pATI->sc_top = inm(SC_TOP); pATIHW->sc_bottom = pATI->sc_bottom = inm(SC_BOTTOM); /* Save data path registers */ pATIHW->dp_bkgd_clr = inm(DP_BKGD_CLR); pATIHW->dp_frgd_clr = inm(DP_FRGD_CLR); pATIHW->dp_write_mask = inm(DP_WRITE_MASK); pATIHW->dp_chain_mask = inm(DP_CHAIN_MASK); pATIHW->dp_pix_width = inm(DP_PIX_WIDTH); pATIHW->dp_mix = inm(DP_MIX); pATIHW->dp_src = inm(DP_SRC); /* Save colour compare registers */ pATIHW->clr_cmp_clr = inm(CLR_CMP_CLR); pATIHW->clr_cmp_msk = inm(CLR_CMP_MSK); pATIHW->clr_cmp_cntl = inm(CLR_CMP_CNTL); /* Save context */ pATIHW->context_mask = inm(CONTEXT_MASK); if (pATI->Chip >= ATI_CHIP_264GTPRO) { /* Save texture setup registers */ pATIHW->tex_size_pitch = inm(TEX_SIZE_PITCH); pATIHW->tex_cntl = inm(TEX_CNTL); } if (pATI->Block1Base) { /* Save overlay & scaler registers */ pATIHW->overlay_y_x_start = inm(OVERLAY_Y_X_START); pATIHW->overlay_y_x_end = inm(OVERLAY_Y_X_END); pATIHW->overlay_graphics_key_clr = inm(OVERLAY_GRAPHICS_KEY_CLR); pATIHW->overlay_graphics_key_msk = inm(OVERLAY_GRAPHICS_KEY_MSK); pATIHW->overlay_key_cntl = inm(OVERLAY_KEY_CNTL); pATIHW->overlay_scale_inc = inm(OVERLAY_SCALE_INC); pATIHW->overlay_scale_cntl = inm(OVERLAY_SCALE_CNTL); pATIHW->scaler_height_width = inm(SCALER_HEIGHT_WIDTH); pATIHW->scaler_test = inm(SCALER_TEST); pATIHW->video_format = inm(VIDEO_FORMAT); if (pATI->Chip < ATI_CHIP_264VTB) { pATIHW->buf0_offset = inm(BUF0_OFFSET); pATIHW->buf0_pitch = inm(BUF0_PITCH); pATIHW->buf1_offset = inm(BUF1_OFFSET); pATIHW->buf1_pitch = inm(BUF1_PITCH); } else { pATIHW->scaler_buf0_offset = inm(SCALER_BUF0_OFFSET); pATIHW->scaler_buf1_offset = inm(SCALER_BUF1_OFFSET); pATIHW->scaler_buf_pitch = inm(SCALER_BUF_PITCH); pATIHW->overlay_exclusive_horz = inm(OVERLAY_EXCLUSIVE_HORZ); pATIHW->overlay_exclusive_vert = inm(OVERLAY_EXCLUSIVE_VERT); if (pATI->Chip >= ATI_CHIP_264GTPRO) { pATIHW->scaler_colour_cntl = inm(SCALER_COLOUR_CNTL); pATIHW->scaler_h_coeff0 = inm(SCALER_H_COEFF0); pATIHW->scaler_h_coeff1 = inm(SCALER_H_COEFF1); pATIHW->scaler_h_coeff2 = inm(SCALER_H_COEFF2); pATIHW->scaler_h_coeff3 = inm(SCALER_H_COEFF3); pATIHW->scaler_h_coeff4 = inm(SCALER_H_COEFF4); pATIHW->scaler_buf0_offset_u = inm(SCALER_BUF0_OFFSET_U); pATIHW->scaler_buf0_offset_v = inm(SCALER_BUF0_OFFSET_V); pATIHW->scaler_buf1_offset_u = inm(SCALER_BUF1_OFFSET_U); pATIHW->scaler_buf1_offset_v = inm(SCALER_BUF1_OFFSET_V); } } } /* Restore aperture enablement */ outr(BUS_CNTL, pATIHW->bus_cntl); outr(CONFIG_CNTL, pATIHW->config_cntl); } } /* * ATIMach64ModeAdjust -- * * This function is called to adjust horizontal and vertical timings. */ static void ATIMach64ModeAdjust ( ATIPtr pATI, ATIHWPtr pATIHW, DisplayModePtr pMode ) { int VDisplay; /* Clobber mode timings */ if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)) { if (!pMode->CrtcHAdjusted && !pMode->CrtcVAdjusted && (!pATI->OptionLCDSync || (pMode->type & M_T_BUILTIN))) { int VScan; pMode->Clock = pATI->LCDClock; pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2); pMode->VScan = 0; /* * Use doublescanning or multiscanning to get around vertical blending * limitations. */ VScan = pATI->LCDVertical / pMode->VDisplay; if (VScan > 1) { VScan = 2; pMode->Flags |= V_DBLSCAN; } pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart; pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth; pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth; pMode->VSyncStart = pMode->VDisplay + ATIDivide(pATI->LCDVSyncStart, VScan, 0, 0); pMode->VSyncEnd = pMode->VSyncStart + ATIDivide(pATI->LCDVSyncWidth, VScan, 0, 1); pMode->VTotal = pMode->VDisplay + ATIDivide(pATI->LCDVBlankWidth, VScan, 0, 0); } } /* If not already done adjust horizontal timings */ if (!pMode->CrtcHAdjusted) { pMode->CrtcHAdjusted = TRUE; /* XXX Deal with Blank Start/End and overscan later */ pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1; pMode->CrtcHSyncStart = (pMode->HSyncStart >> 3) - 1; pMode->CrtcHSyncEnd = (pMode->HSyncEnd >> 3) - 1; pMode->CrtcHTotal = (pMode->HTotal >> 3) - 1; /* Make adjustments if sync pulse width is out-of-bounds */ if ((pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart) > (int)MaxBits(CRTC_H_SYNC_WID)) { pMode->CrtcHSyncEnd = pMode->CrtcHSyncStart + MaxBits(CRTC_H_SYNC_WID); } else if (pMode->CrtcHSyncStart == pMode->CrtcHSyncEnd) { if (pMode->CrtcHDisplay < pMode->CrtcHSyncStart) pMode->CrtcHSyncStart--; else if (pMode->CrtcHSyncEnd < pMode->CrtcHTotal) pMode->CrtcHSyncEnd++; } } /* * Always re-do vertical adjustments. */ pMode->CrtcVDisplay = pMode->VDisplay; pMode->CrtcVSyncStart = pMode->VSyncStart; pMode->CrtcVSyncEnd = pMode->VSyncEnd; pMode->CrtcVTotal = pMode->VTotal; if ((pATI->Chip >= ATI_CHIP_264CT) && ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1))) { pMode->CrtcVDisplay <<= 1; pMode->CrtcVSyncStart <<= 1; pMode->CrtcVSyncEnd <<= 1; pMode->CrtcVTotal <<= 1; } /* * Might as well default to the same as VGA with respect to sync * polarities. */ if ((!(pMode->Flags & (V_PHSYNC | V_NHSYNC))) || (!(pMode->Flags & (V_PVSYNC | V_NVSYNC)))) { pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC); if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)) VDisplay = pATI->LCDVertical; else VDisplay = pMode->CrtcVDisplay; #ifdef TV_OUT if (pATI->tvActive) VDisplay = pMode->CrtcVDisplay; #endif if (VDisplay < 400) pMode->Flags |= V_PHSYNC | V_NVSYNC; else if (VDisplay < 480) pMode->Flags |= V_NHSYNC | V_PVSYNC; else if (VDisplay < 768) pMode->Flags |= V_NHSYNC | V_NVSYNC; else pMode->Flags |= V_PHSYNC | V_PVSYNC; } pMode->CrtcVDisplay--; pMode->CrtcVSyncStart--; pMode->CrtcVSyncEnd--; pMode->CrtcVTotal--; /* Make sure sync pulse is not too wide */ if ((pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart) > (int)MaxBits(CRTC_V_SYNC_WID)) pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + MaxBits(CRTC_V_SYNC_WID); pMode->CrtcVAdjusted = TRUE; /* Redundant */ } /* * ATIMach64Calculate -- * * This function is called to fill in the Mach64 portion of an ATIHWRec. */ void ATIMach64Calculate ( ATIPtr pATI, ATIHWPtr pATIHW, DisplayModePtr pMode ) { ATIMach64ModeAdjust(pATI, pATIHW, pMode); /* Build register contents */ pATIHW->crtc_h_total_disp = SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) | SetBits(pMode->CrtcHDisplay, CRTC_H_DISP); pATIHW->crtc_h_sync_strt_wid = SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) | SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) | /* ? */ SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U), CRTC_H_SYNC_STRT_HI) | SetBits(pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart, CRTC_H_SYNC_WID); if (pMode->Flags & V_NHSYNC) pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL; pATIHW->crtc_v_total_disp = SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) | SetBits(pMode->CrtcVDisplay, CRTC_V_DISP); pATIHW->crtc_v_sync_strt_wid = SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) | SetBits(pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart, CRTC_V_SYNC_WID); if (pMode->Flags & V_NVSYNC) pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL; pATIHW->crtc_off_pitch = SetBits(pATI->displayWidth >> 3, CRTC_PITCH); pATIHW->crtc_gen_cntl = inr(CRTC_GEN_CNTL) & ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN | CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS | CRTC_VGA_XOVERSCAN | CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER | CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE | CRTC_LOCK_REGS | /* Already off, but ... */ CRTC_SYNC_TRISTATE | CRTC_DISP_REQ_EN | CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST); pATIHW->crtc_gen_cntl |= CRTC_EXT_DISP_EN | CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN; switch (pATI->depth) { case 8: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_8BPP, CRTC_PIX_WIDTH); break; case 15: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_15BPP, CRTC_PIX_WIDTH); break; case 16: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_16BPP, CRTC_PIX_WIDTH); break; case 24: if (pATI->bitsPerPixel == 24) { pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_24BPP, CRTC_PIX_WIDTH); break; } if (pATI->bitsPerPixel != 32) break; /* Fall through */ case 32: pATIHW->crtc_gen_cntl |= SetBits(PIX_WIDTH_32BPP, CRTC_PIX_WIDTH); break; default: break; } if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1)) pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN; if (pMode->Flags & V_INTERLACE) pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN; if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC))) pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN; /* For now, set display FIFO low water mark as high as possible */ if (pATI->Chip < ATI_CHIP_264VTB) pATIHW->crtc_gen_cntl |= CRTC_FIFO_LWM; } /* * ATIMach64Set -- * * This function is called to load a Mach64's accelerator CRTC and draw engine. */ void ATIMach64Set ( ATIPtr pATI, ATIHWPtr pATIHW ) { #ifndef AVOID_CPIO if (pATIHW->crtc == ATI_CRTC_MACH64) #endif /* AVOID_CPIO */ { if ((pATIHW->FeedbackDivider > 0)) ATIClockSet(pATI, pATIHW); /* Programme clock */ if (pATI->DAC == ATI_DAC_IBMRGB514) ATIRGB514Set(pATI, pATIHW); /* Load Mach64 CRTC registers */ outr(CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp); outr(CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid); outr(CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp); outr(CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid); outr(CRTC_OFF_PITCH, pATIHW->crtc_off_pitch); /* Load overscan registers */ outr(OVR_CLR, pATIHW->ovr_clr); outr(OVR_WID_LEFT_RIGHT, pATIHW->ovr_wid_left_right); outr(OVR_WID_TOP_BOTTOM, pATIHW->ovr_wid_top_bottom); /* Load hardware cursor registers */ outr(CUR_CLR0, pATIHW->cur_clr0); outr(CUR_CLR1, pATIHW->cur_clr1); outr(CUR_OFFSET, pATIHW->cur_offset); outr(CUR_HORZ_VERT_POSN, pATIHW->cur_horz_vert_posn); outr(CUR_HORZ_VERT_OFF, pATIHW->cur_horz_vert_off); /* Set pixel clock */ outr(CLOCK_CNTL, pATIHW->clock_cntl | CLOCK_STROBE); outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN); outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl); outr(GEN_TEST_CNTL, pATIHW->gen_test_cntl | GEN_GUI_EN); /* Finalise CRTC setup and turn on the screen */ outr(CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl); } /* Load draw engine */ if (pATI->Block0Base) { /* Clobber MMIO cache */ (void)memset(pATI->MMIOCached, 0, SizeOf(pATI->MMIOCached)); /* Ensure apertures are enabled */ outr(BUS_CNTL, pATI->NewHW.bus_cntl); outr(CONFIG_CNTL, pATI->NewHW.config_cntl); pATI->EngineIsBusy = TRUE; /* Force engine poll */ ATIMach64WaitForIdle(pATI); /* Load FIFO size */ if (pATI->Chip >= ATI_CHIP_264VT4) { outm(GUI_CNTL, pATIHW->gui_cntl); pATI->nAvailableFIFOEntries = 0; ATIMach64PollEngineStatus(pATI); } /* Set FIFO depth */ pATI->nFIFOEntries = pATI->nAvailableFIFOEntries; /* Load destination registers */ ATIMach64WaitForFIFO(pATI, 7); outf(DST_OFF_PITCH, pATIHW->dst_off_pitch); outf(DST_Y_X, SetWord(pATIHW->dst_x, 1) | SetWord(pATIHW->dst_y, 0)); outf(DST_HEIGHT, pATIHW->dst_height); outf(DST_BRES_ERR, pATIHW->dst_bres_err); outf(DST_BRES_INC, pATIHW->dst_bres_inc); outf(DST_BRES_DEC, pATIHW->dst_bres_dec); outf(DST_CNTL, pATIHW->dst_cntl); if (pATI->Chip >= ATI_CHIP_264GTPRO) { /* Load ROP unit registers */ ATIMach64WaitForFIFO(pATI, 2); outf(Z_CNTL, 0); outf(ALPHA_TST_CNTL, 0); } /* Load source registers */ ATIMach64WaitForFIFO(pATI, 6); outf(SRC_OFF_PITCH, pATIHW->src_off_pitch); outf(SRC_Y_X, SetWord(pATIHW->src_x, 1) | SetWord(pATIHW->src_y, 0)); outf(SRC_HEIGHT1_WIDTH1, SetWord(pATIHW->src_width1, 1) | SetWord(pATIHW->src_height1, 0)); outf(SRC_Y_X_START, SetWord(pATIHW->src_x_start, 1) | SetWord(pATIHW->src_y_start, 0)); outf(SRC_HEIGHT2_WIDTH2, SetWord(pATIHW->src_width2, 1) | SetWord(pATIHW->src_height2, 0)); outf(SRC_CNTL, pATIHW->src_cntl); if (pATI->Chip >= ATI_CHIP_264GTPRO) { CARD32 offset = TEX_LEVEL(pATIHW->tex_size_pitch); /* Load 3D control & texture registers */ ATIMach64WaitForFIFO(pATI, 2); outf(TEX_0_OFF + offset, pATIHW->tex_offset); outf(SCALE_3D_CNTL, pATIHW->scale_3d_cntl); } /* Load host data register */ ATIMach64WaitForFIFO(pATI, 1); outf(HOST_CNTL, pATIHW->host_cntl); /* Set host transfer window address and size clamp */ pATI->pHOST_DATA = ATIHostDataAddr(HOST_DATA_0); pATI->nHostFIFOEntries = pATI->nFIFOEntries >> 1; if (pATI->nHostFIFOEntries > 16) pATI->nHostFIFOEntries = 16; /* Load pattern registers */ ATIMach64WaitForFIFO(pATI, 3); outf(PAT_REG0, pATIHW->pat_reg0); outf(PAT_REG1, pATIHW->pat_reg1); outf(PAT_CNTL, pATIHW->pat_cntl); /* Load scissor registers */ ATIMach64WaitForFIFO(pATI, 2); outf(SC_LEFT_RIGHT, SetWord(pATIHW->sc_right, 1) | SetWord(pATIHW->sc_left, 0)); outf(SC_TOP_BOTTOM, SetWord(pATIHW->sc_bottom, 1) | SetWord(pATIHW->sc_top, 0)); pATI->sc_left = pATIHW->sc_left; pATI->sc_right = pATIHW->sc_right; pATI->sc_top = pATIHW->sc_top; pATI->sc_bottom = pATIHW->sc_bottom; /* Load data path registers */ ATIMach64WaitForFIFO(pATI, 7); outf(DP_BKGD_CLR, pATIHW->dp_bkgd_clr); outf(DP_FRGD_CLR, pATIHW->dp_frgd_clr); outf(DP_WRITE_MASK, pATIHW->dp_write_mask); outf(DP_CHAIN_MASK, pATIHW->dp_chain_mask); outf(DP_PIX_WIDTH, pATIHW->dp_pix_width); outf(DP_MIX, pATIHW->dp_mix); outf(DP_SRC, pATIHW->dp_src); /* Load colour compare registers */ ATIMach64WaitForFIFO(pATI, 3); outf(CLR_CMP_CLR, pATIHW->clr_cmp_clr); outf(CLR_CMP_MSK, pATIHW->clr_cmp_msk); outf(CLR_CMP_CNTL, pATIHW->clr_cmp_cntl); /* Load context mask */ ATIMach64WaitForFIFO(pATI, 1); outf(CONTEXT_MASK, pATIHW->context_mask); if (pATI->Chip >= ATI_CHIP_264GTPRO) { /* Load texture setup registers */ ATIMach64WaitForFIFO(pATI, 2); outf(TEX_SIZE_PITCH, pATIHW->tex_size_pitch); outf(TEX_CNTL, pATIHW->tex_cntl); } if (pATI->Block1Base) { /* Load overlay & scaler registers */ ATIMach64WaitForFIFO(pATI, 10); outf(OVERLAY_Y_X_START, pATIHW->overlay_y_x_start); outf(OVERLAY_Y_X_END, pATIHW->overlay_y_x_end); outf(OVERLAY_GRAPHICS_KEY_CLR, pATIHW->overlay_graphics_key_clr); outf(OVERLAY_GRAPHICS_KEY_MSK, pATIHW->overlay_graphics_key_msk); outf(OVERLAY_KEY_CNTL, pATIHW->overlay_key_cntl); outf(OVERLAY_SCALE_INC, pATIHW->overlay_scale_inc); outf(OVERLAY_SCALE_CNTL, pATIHW->overlay_scale_cntl); outf(SCALER_HEIGHT_WIDTH, pATIHW->scaler_height_width); outf(SCALER_TEST, pATIHW->scaler_test); outf(VIDEO_FORMAT, pATIHW->video_format); if (pATI->Chip < ATI_CHIP_264VTB) { ATIMach64WaitForFIFO(pATI, 4); outf(BUF0_OFFSET, pATIHW->buf0_offset); outf(BUF0_PITCH, pATIHW->buf0_pitch); outf(BUF1_OFFSET, pATIHW->buf1_offset); outf(BUF1_PITCH, pATIHW->buf1_pitch); } else { ATIMach64WaitForFIFO(pATI, 5); outf(SCALER_BUF0_OFFSET, pATIHW->scaler_buf0_offset); outf(SCALER_BUF1_OFFSET, pATIHW->scaler_buf1_offset); outf(SCALER_BUF_PITCH, pATIHW->scaler_buf_pitch); outf(OVERLAY_EXCLUSIVE_HORZ, pATIHW->overlay_exclusive_horz); outf(OVERLAY_EXCLUSIVE_VERT, pATIHW->overlay_exclusive_vert); if (pATI->Chip >= ATI_CHIP_264GTPRO) { ATIMach64WaitForFIFO(pATI, 10); outf(SCALER_COLOUR_CNTL, pATIHW->scaler_colour_cntl); outf(SCALER_H_COEFF0, pATIHW->scaler_h_coeff0); outf(SCALER_H_COEFF1, pATIHW->scaler_h_coeff1); outf(SCALER_H_COEFF2, pATIHW->scaler_h_coeff2); outf(SCALER_H_COEFF3, pATIHW->scaler_h_coeff3); outf(SCALER_H_COEFF4, pATIHW->scaler_h_coeff4); outf(SCALER_BUF0_OFFSET_U, pATIHW->scaler_buf0_offset_u); outf(SCALER_BUF0_OFFSET_V, pATIHW->scaler_buf0_offset_v); outf(SCALER_BUF1_OFFSET_U, pATIHW->scaler_buf1_offset_u); outf(SCALER_BUF1_OFFSET_V, pATIHW->scaler_buf1_offset_v); } } } ATIMach64WaitForIdle(pATI); if (pATI->OptionMMIOCache) { /* * Enable write caching for selected MMIO registers. This can only * be done for those registers whose value does not change without * driver intervention. */ CacheRegister(SRC_CNTL); if (pATI->Chip >= ATI_CHIP_264GTPRO) { CacheRegister(SCALE_3D_CNTL); } CacheRegister(HOST_CNTL); CacheRegister(PAT_REG0); CacheRegister(PAT_REG1); CacheRegister(PAT_CNTL); CacheRegister(SC_LEFT_RIGHT); CacheRegister(SC_TOP_BOTTOM); CacheRegister(DP_BKGD_CLR); CacheRegister(DP_FRGD_CLR); CacheRegister(DP_PIX_WIDTH); CacheRegister(DP_MIX); CacheRegister(CLR_CMP_CLR); CacheRegister(CLR_CMP_MSK); CacheRegister(CLR_CMP_CNTL); if (pATI->Chip >= ATI_CHIP_264GTPRO) { CacheRegister(TEX_SIZE_PITCH); } if (pATI->Block1Base) { CacheRegister(OVERLAY_Y_X_START); CacheRegister(OVERLAY_Y_X_END); CacheRegister(OVERLAY_GRAPHICS_KEY_CLR); CacheRegister(OVERLAY_GRAPHICS_KEY_MSK); CacheRegister(OVERLAY_KEY_CNTL); CacheRegister(OVERLAY_SCALE_INC); CacheRegister(OVERLAY_SCALE_CNTL); CacheRegister(SCALER_HEIGHT_WIDTH); CacheRegister(SCALER_TEST); CacheRegister(VIDEO_FORMAT); if (pATI->Chip < ATI_CHIP_264VTB) { CacheRegister(BUF0_OFFSET); CacheRegister(BUF0_PITCH); CacheRegister(BUF1_OFFSET); CacheRegister(BUF1_PITCH); } else { CacheRegister(SCALER_BUF0_OFFSET); CacheRegister(SCALER_BUF1_OFFSET); CacheRegister(SCALER_BUF_PITCH); CacheRegister(OVERLAY_EXCLUSIVE_HORZ); CacheRegister(OVERLAY_EXCLUSIVE_VERT); if (pATI->Chip >= ATI_CHIP_264GTPRO) { CacheRegister(SCALER_COLOUR_CNTL); CacheRegister(SCALER_H_COEFF0); CacheRegister(SCALER_H_COEFF1); CacheRegister(SCALER_H_COEFF2); CacheRegister(SCALER_H_COEFF3); CacheRegister(SCALER_H_COEFF4); CacheRegister(SCALER_BUF0_OFFSET_U); CacheRegister(SCALER_BUF0_OFFSET_V); CacheRegister(SCALER_BUF1_OFFSET_U); CacheRegister(SCALER_BUF1_OFFSET_V); } } } } } #ifndef AVOID_CPIO if (pATIHW->crtc == ATI_CRTC_MACH64) #endif /* AVOID_CPIO */ { /* Aperture setup */ outr(MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel); outr(MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel); outr(DAC_CNTL, pATIHW->dac_cntl); outr(CONFIG_CNTL, pATIHW->config_cntl); outr(BUS_CNTL, pATIHW->bus_cntl); if (pATI->Chip >= ATI_CHIP_264VTB) { outr(MEM_BUF_CNTL, pATIHW->mem_buf_cntl); outr(MEM_CNTL, pATIHW->mem_cntl); outr(MPP_CONFIG, pATIHW->mpp_config); outr(MPP_STROBE_SEQ, pATIHW->mpp_strobe_seq); outr(TVO_CNTL, pATIHW->tvo_cntl); } } } /* * ATIMach64SaveScreen -- * * This function blanks or unblanks a Mach64 screen. */ void ATIMach64SaveScreen ( ATIPtr pATI, int Mode ) { CARD32 crtc_gen_cntl = inr(CRTC_GEN_CNTL); switch (Mode) { case SCREEN_SAVER_OFF: case SCREEN_SAVER_FORCER: outr(CRTC_GEN_CNTL, crtc_gen_cntl & ~CRTC_DISPLAY_DIS); break; case SCREEN_SAVER_ON: case SCREEN_SAVER_CYCLE: outr(CRTC_GEN_CNTL, crtc_gen_cntl | CRTC_DISPLAY_DIS); break; default: break; } } /* * ATIMach64SetDPMSMode -- * * This function sets a Mach64's VESA Display Power Management Signaling mode. */ void ATIMach64SetDPMSMode ( ScrnInfoPtr pScreenInfo, ATIPtr pATI, int DPMSMode ) { CARD32 crtc_gen_cntl = inr(CRTC_GEN_CNTL) & ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS); switch (DPMSMode) { case DPMSModeOn: /* HSync on, VSync on */ break; case DPMSModeStandby: /* HSync off, VSync on */ crtc_gen_cntl |= CRTC_HSYNC_DIS; break; case DPMSModeSuspend: /* HSync on, VSync off */ crtc_gen_cntl |= CRTC_VSYNC_DIS; break; case DPMSModeOff: /* HSync off, VSync off */ crtc_gen_cntl |= CRTC_HSYNC_DIS | CRTC_VSYNC_DIS; break; default: /* Muffle compiler */ return; } #ifdef XF86DRI_DEVEL /* XAA Sync requires the DRM lock if DRI enabled */ ATIDRILock(pScreenInfo); #endif /* XF86DRI_DEVEL */ ATIMach64Sync(pScreenInfo); outr(CRTC_GEN_CNTL, crtc_gen_cntl); if (pATI->OptionPanelDisplay && (pATI->LCDPanelID >= 0)) { CARD32 lcd_index = 0; /* * ATI's BIOS simply turns the panel on and off, so do the same by * default, but keep the previous behaviour around for reference. */ if (pATI->OptionDevel) { CARD32 power_management; if (pATI->Chip == ATI_CHIP_264LT) { power_management = inr(POWER_MANAGEMENT); } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { lcd_index = inr(LCD_INDEX); power_management = ATIMach64GetLCDReg(LCD_POWER_MANAGEMENT); } power_management &= ~(STANDBY_NOW | SUSPEND_NOW); switch (DPMSMode) { case DPMSModeOn: break; case DPMSModeStandby: power_management |= STANDBY_NOW; break; case DPMSModeSuspend: power_management |= SUSPEND_NOW; break; case DPMSModeOff: power_management |= STANDBY_NOW | SUSPEND_NOW; /* ? */ break; default: /* Muffle compiler */ return; } if (pATI->Chip == ATI_CHIP_264LT) { outr(POWER_MANAGEMENT, power_management); } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { ATIMach64PutLCDReg(LCD_POWER_MANAGEMENT, power_management); outr(LCD_INDEX, lcd_index); } } else { CARD32 lcd_gen_ctrl; if (pATI->Chip == ATI_CHIP_264LT) { lcd_gen_ctrl = inr(LCD_GEN_CTRL); } else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { lcd_index = inr(LCD_INDEX); lcd_gen_ctrl = ATIMach64GetLCDReg(LCD_GEN_CNTL); } if (DPMSMode == DPMSModeOn) lcd_gen_ctrl |= LCD_ON; else lcd_gen_ctrl &= ~LCD_ON; if (pATI->Chip == ATI_CHIP_264LT) outr(LCD_GEN_CTRL, lcd_gen_ctrl); else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) || (pATI->Chip == ATI_CHIP_264XL) || (pATI->Chip == ATI_CHIP_MOBILITY)) */ { ATIMach64PutLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl); outr(LCD_INDEX, lcd_index); } } } #ifdef XF86DRI_DEVEL ATIDRIUnlock(pScreenInfo); #endif /* XF86DRI_DEVEL */ }