📄 atipreinit.c
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c,v 1.74 2003/12/22 17:48:09 tsi Exp $ *//* $XdotOrg: driver/xf86-video-ati/src/atipreinit.c,v 1.9 2005/08/28 18:10:34 ajax Exp $ *//* * Copyright 1999 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. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include <stdio.h>#include "ati.h"#include "atiadapter.h"#include "atiadjust.h"#include "atiaudio.h"#include "atibus.h"#include "atichip.h"#include "aticonfig.h"#include "aticursor.h"#include "atidac.h"#include "atidsp.h"#include "atii2c.h"#include "atiident.h"#include "atiload.h"#include "atilock.h"#include "atimach64.h"#include "atimach64accel.h"#include "atimach64io.h"#include "atimode.h"#include "atipreinit.h"#include "atiprint.h"#include "atividmem.h"#include "atiwonderio.h"#include "atixv.h"#include "vbe.h"#include "xf86RAC.h"#ifndef AVOID_CPIOtypedef CARD16 Colour; /* The correct spelling should be OK :-) *//* * Bit patterns which are extremely unlikely to show up when reading from * nonexistant memory (which normally shows up as either all bits set or all * bits clear). */static const Colour Test_Pixel[] = {0x5AA5U, 0x55AAU, 0xA55AU, 0xCA53U};static const struct{ int videoRamSize; int Miscellaneous_Options_Setting; struct { short int x, y; } Coordinates[NumberOf(Test_Pixel) + 1];}Test_Case[] ={ /* * Given the engine settings used, only a 4M card will have enough memory * to back up the 1025th line of the display. Since the pixel coordinates * are zero-based, line 1024 will be the first one which is only backed on * 4M cards. * * <Mark_Weaver@brown.edu>: * In case memory is being wrapped, (0,0) and (0,1024) to make sure they * can each hold a unique value. */ {4096, MEM_SIZE_4M, {{0,0}, {0,1024}, {-1,-1}}}, /* * This card has 2M or less. On a 1M card, the first 2M of the card's * memory will have even doublewords backed by physical memory and odd * doublewords unbacked. * * Pixels 0 and 1 of a row will be in the zeroth doubleword, while pixels 2 * and 3 will be in the first. Check both pixels 2 and 3 in case this is a * pseudo-1M card (one chip pulled to turn a 2M card into a 1M card). * * <Mark_Weaver@brown.edu>: * I don't have a 1M card, so I'm taking a stab in the dark. Maybe memory * wraps every 512 lines, or maybe odd doublewords are aliases of their * even doubleword counterparts. I try everything here. */ {2048, MEM_SIZE_2M, {{0,0}, {0,512}, {2,0}, {3,0}, {-1,-1}}}, /* * This is a either a 1M card or a 512k card. Test pixel 1, since it is an * odd word in an even doubleword. * * <Mark_Weaver@brown.edu>: * This is the same idea as the test above. */ {1024, MEM_SIZE_1M, {{0,0}, {0,256}, {1,0}, {-1,-1}}}, /* * Assume it is a 512k card by default, since that is the minimum * configuration. */ {512, MEM_SIZE_512K, {{-1,-1}}}};/* * ATIMach32ReadPixel -- * * Return the colour of the specified screen location. Called from * ATIMach32videoRam function below. */static ColourATIMach32ReadPixel( const short int X, const short int Y){ Colour Pixel_Colour; /* Wait for idle engine */ ProbeWaitIdleEmpty(); /* Set up engine for pixel read */ ATIWaitQueue(7); outw(RD_MASK, (CARD16)(~0)); outw(DP_CONFIG, FG_COLOR_SRC_BLIT | DATA_WIDTH | DRAW | DATA_ORDER); outw(CUR_X, X); outw(CUR_Y, Y); outw(DEST_X_START, X); outw(DEST_X_END, X + 1); outw(DEST_Y_END, Y + 1); /* Wait for data to become ready */ ATIWaitQueue(16); WaitDataReady(); /* Read pixel colour */ Pixel_Colour = inw(PIX_TRANS); ProbeWaitIdleEmpty(); return Pixel_Colour;}/* * ATIMach32WritePixel -- * * Set the colour of the specified screen location. Called from * ATIMach32videoRam function below. */static voidATIMach32WritePixel( const short int X, const short int Y, const Colour Pixel_Colour){ /* Set up engine for pixel write */ ATIWaitQueue(9); outw(WRT_MASK, (CARD16)(~0)); outw(DP_CONFIG, FG_COLOR_SRC_FG | DRAW | READ_WRITE); outw(ALU_FG_FN, MIX_FN_PAINT); outw(FRGD_COLOR, Pixel_Colour); outw(CUR_X, X); outw(CUR_Y, Y); outw(DEST_X_START, X); outw(DEST_X_END, X + 1); outw(DEST_Y_END, Y + 1);}/* * ATIMach32videoRam -- * * Determine the amount of video memory installed on an 68800-6 based adapter. * This is done because these chips exhibit a bug that causes their * MISC_OPTIONS register to report 1M rather than the true amount of memory. * * This function is adapted from a similar function in mach32mem.c written by * Robert Wolff, David Dawes and Mark Weaver. */static intATIMach32videoRam( void){ CARD16 clock_sel, mem_bndry, misc_options, ext_ge_config; Colour saved_Pixel[NumberOf(Test_Pixel)]; unsigned int Case_Number, Pixel_Number; Bool AllPixelsOK; /* Save register values to be modified */ clock_sel = inw(CLOCK_SEL); mem_bndry = inw(MEM_BNDRY); misc_options = inw(MISC_OPTIONS) & ~MEM_SIZE_ALIAS; ext_ge_config = inw(R_EXT_GE_CONFIG); /* Wait for enough FIFO entries */ ATIWaitQueue(7); /* Enable accelerator */ outw(CLOCK_SEL, clock_sel | DISABPASSTHRU); /* Make accelerator and VGA share video memory */ outw(MEM_BNDRY, mem_bndry & ~(MEM_PAGE_BNDRY | MEM_BNDRY_ENA)); /* Prevent video memory wrap */ outw(MISC_OPTIONS, misc_options | MEM_SIZE_4M); /* * Set up the drawing engine for a pitch of 1024 at 16 bits per pixel. No * need to mess with the CRT because the results of this test are not * intended to be seen. */ outw(EXT_GE_CONFIG, PIXEL_WIDTH_16 | ORDER_16BPP_565 | MONITOR_8514 | ALIAS_ENA); outw(GE_PITCH, 1024 >> 3); outw(GE_OFFSET_HI, 0); outw(GE_OFFSET_LO, 0); for (Case_Number = 0; Case_Number < (NumberOf(Test_Case) - 1); Case_Number++) { /* Reduce redundancy as per Mark_Weaver@brown.edu */# define TestPixel Test_Case[Case_Number].Coordinates[Pixel_Number]# define ForEachTestPixel \ for (Pixel_Number = 0; TestPixel.x >= 0; Pixel_Number++) /* Save pixel colours that will be clobbered */ ForEachTestPixel saved_Pixel[Pixel_Number] = ATIMach32ReadPixel(TestPixel.x, TestPixel.y); /* Write test patterns */ ForEachTestPixel ATIMach32WritePixel(TestPixel.x, TestPixel.y, Test_Pixel[Pixel_Number]); /* Test for lost pixels */ AllPixelsOK = TRUE; ForEachTestPixel { if (ATIMach32ReadPixel(TestPixel.x, TestPixel.y) != Test_Pixel[Pixel_Number]) { AllPixelsOK = FALSE; break; } } /* Restore clobbered pixels */ ForEachTestPixel ATIMach32WritePixel(TestPixel.x, TestPixel.y, saved_Pixel[Pixel_Number]); /* End test on success */ if (AllPixelsOK) break; /* Completeness */# undef ForEachTestPixel# undef TestPixel } /* Restore what was changed and correct MISC_OPTIONS register */ ATIWaitQueue(4); outw(EXT_GE_CONFIG, ext_ge_config); misc_options |= Test_Case[Case_Number].Miscellaneous_Options_Setting; outw(MISC_OPTIONS, misc_options); outw(MEM_BNDRY, mem_bndry); outw(CLOCK_SEL, clock_sel); /* Wait for activity to die down */ ProbeWaitIdleEmpty(); /* Tell ATIPreInit the REAL story */ return Test_Case[Case_Number].videoRamSize;}#endif /* AVOID_CPIO *//* * ATIReportMemory -- * * This function reports on the amount and type of video memory found. */static voidATIReportMemory( ScrnInfoPtr pScreenInfo, ATIPtr pATI, const char *MemoryTypeName){ char Buffer[128], *Message; Message = Buffer + snprintf(Buffer, SizeOf(Buffer), "%d kB of %s detected", pATI->VideoRAM, MemoryTypeName);#ifndef AVOID_CPIO if (pATI->depth == 1) { /* 1bpp only uses one plane of four */ pScreenInfo->videoRam /= 4; Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, " (using %d kB)", pScreenInfo->videoRam); } else#endif /* AVOID_CPIO */ if (pATI->VideoRAM > pScreenInfo->videoRam) { Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message, " (using %d kB)", pScreenInfo->videoRam); } xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer);}static const int videoRamSizes[] = {0, 256, 512, 1024, 2*1024, 4*1024, 6*1024, 8*1024, 12*1024, 16*1024, 0};static const rgb defaultWeight = {0, 0, 0};static const Gamma defaultGamma = {0.0, 0.0, 0.0};/* * ATIMach64Map -- * * This function attempts to mmap() a Mach64's MMIO aperture. */static voidATIMach64Map( int iScreen, ATIPtr pATI){ (void)ATIMapApertures(iScreen, pATI); if (!pATI->pBlock[0] || (pATI->config_chip_id != inr(CONFIG_CHIP_ID))) ATIUnmapApertures(iScreen, pATI);}/* * ATIPrintNoiseIfRequested -- * * This function formats debugging information on the server's stderr when * requested by the user through the server's verbosity setting. */static voidATIPrintNoiseIfRequested( ATIPtr pATI, CARD8 *BIOS, unsigned int BIOSSize){ if (xf86GetVerbosity() <= 3) return; if (BIOSSize > 0) ATIPrintBIOS(BIOS, BIOSSize); xf86ErrorFVerb(4, "\n On server entry:\n"); ATIPrintRegisters(pATI);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -