/* * Copyright 2007 Luc Verhaegen * Copyright 2007 Matthias Hopf * Copyright 2007 Egbert Eich * Copyright 2007 Advanced Micro Devices, Inc. * * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if HAVE_XF86_ANSIC_H # include "xf86_ansic.h" #else # include #endif #include "xf86.h" #include "rhd.h" #include "rhd_regs.h" Bool RHDMCIdle(RHDPtr rhdPtr, CARD32 count); Bool RHDMCIdle(RHDPtr rhdPtr, CARD32 count); struct rhdMC { CARD32 FbLocation; CARD32 HdpFbBase; CARD32 MiscLatencyTimer; Bool Stored; void (*SaveMC)(RHDPtr rhdPtr); void (*RestoreMC)(RHDPtr rhdPtr); void (*SetupMC)(RHDPtr rhdPtr); Bool (*MCIdle)(RHDPtr rhdPtr); CARD32 (*GetFBLocation)(RHDPtr rhdPtr, CARD32 *size); void (*TuneMCAccessForDisplay)(RHDPtr rhdPtr, int crtc, DisplayModePtr Mode, DisplayModePtr ScaledToMode); Bool RV515Variant; }; /* * Save MC_VM state. */ static void rs600SaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); MC->FbLocation = RHDReadMC(rhdPtr, RS60_NB_FB_LOCATION); MC->HdpFbBase = RHDRegRead(rhdPtr, HDP_FB_LOCATION); } /* * */ static void rs690SaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); MC->FbLocation = RHDReadMC(rhdPtr, RS69_MCCFG_FB_LOCATION); MC->HdpFbBase = RHDRegRead(rhdPtr, HDP_FB_LOCATION); MC->MiscLatencyTimer = RHDReadMC(rhdPtr, RS69_MC_INIT_MISC_LAT_TIMER); } /* * */ static void r6xxSaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); MC->FbLocation = RHDRegRead(rhdPtr, R6XX_MC_VM_FB_LOCATION); MC->HdpFbBase = RHDRegRead(rhdPtr, R6XX_HDP_NONSURFACE_BASE); } /* * */ #ifdef NOTYET static void rs780SaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); MC->FbLocation = RHDReadMC(rhdPtr, RS78_MC_FB_LOCATION); /* RS780 uses the same register as R6xx */ MC->HdpFbBase = RHDRegRead(rhdPtr, R6XX_HDP_NONSURFACE_BASE); } #endif /* * */ static void r7xxSaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); MC->FbLocation = RHDRegRead(rhdPtr, R7XX_MC_VM_FB_LOCATION); MC->HdpFbBase = RHDRegRead(rhdPtr, R6XX_HDP_NONSURFACE_BASE); } /* * */ static void r5xxRestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (MC->RV515Variant) { RHDWriteMC(rhdPtr, MC_IND_ALL | RV515_MC_FB_LOCATION, MC->FbLocation); RHDWriteMC(rhdPtr, MC_IND_ALL | RV515_MC_MISC_LAT_TIMER, MC->MiscLatencyTimer); } else RHDWriteMC(rhdPtr, MC_IND_ALL | R5XX_MC_FB_LOCATION, MC->FbLocation); RHDRegWrite(rhdPtr, HDP_FB_LOCATION, MC->HdpFbBase); } /* * */ static void rs600RestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); RHDWriteMC(rhdPtr, RS60_NB_FB_LOCATION, MC->FbLocation); RHDRegWrite(rhdPtr, HDP_FB_LOCATION, MC->HdpFbBase); } /* * */ static void rs690RestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); RHDWriteMC(rhdPtr, RS69_MCCFG_FB_LOCATION, MC->FbLocation); RHDRegWrite(rhdPtr, HDP_FB_LOCATION, MC->HdpFbBase); RHDWriteMC(rhdPtr, RS69_MC_INIT_MISC_LAT_TIMER, MC->MiscLatencyTimer); } /* * */ static void r6xxRestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); RHDRegWrite(rhdPtr, R6XX_MC_VM_FB_LOCATION, MC->FbLocation); RHDRegWrite(rhdPtr, R6XX_HDP_NONSURFACE_BASE, MC->HdpFbBase); } /* * */ #ifdef NOTYET static void rs780RestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); RHDWriteMC(rhdPtr, RS78_MC_FB_LOCATION, MC->FbLocation); /* RS780 uses the same register as R6xx */ RHDRegWrite(rhdPtr, R6XX_HDP_NONSURFACE_BASE, MC->HdpFbBase); } #endif /* * */ static void r7xxRestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); RHDRegWrite(rhdPtr, R7XX_MC_VM_FB_LOCATION, MC->FbLocation); RHDRegWrite(rhdPtr, R6XX_HDP_NONSURFACE_BASE, MC->HdpFbBase); } /* * Setup the MC */ /* * */ static void r5xxSetupMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; CARD32 fb_location, fb_location_tmp; CARD16 fb_size; unsigned int reg; RHDFUNC(rhdPtr); if (MC->RV515Variant) reg = RV515_MC_FB_LOCATION | MC_IND_ALL; else reg = R5XX_MC_FB_LOCATION | MC_IND_ALL; fb_location = RHDReadMC(rhdPtr, reg); fb_size = (fb_location >> 16) - (fb_location & 0xFFFF); fb_location_tmp = rhdPtr->FbIntAddress >> 16; fb_location_tmp |= (fb_location_tmp + fb_size) << 16; RHDDebug(rhdPtr->scrnIndex, "%s: fb_location: 0x%08X " "[fb_size: 0x%04X] -> fb_location: 0x%08X\n", __func__, (unsigned int)fb_location, fb_size,(unsigned int)fb_location_tmp); RHDWriteMC(rhdPtr, reg, fb_location_tmp); RHDRegWrite(rhdPtr, HDP_FB_LOCATION, fb_location_tmp & 0xFFFF); } /* * */ static void rs600SetupMC(RHDPtr rhdPtr) { CARD32 fb_location, fb_location_tmp; CARD16 fb_size; RHDFUNC(rhdPtr); fb_location = RHDReadMC(rhdPtr, RS60_NB_FB_LOCATION); fb_size = (fb_location >> 16) - (fb_location & 0xFFFF); fb_location_tmp = rhdPtr->FbIntAddress >> 16; fb_location_tmp |= (fb_location_tmp + fb_size) << 16; RHDDebug(rhdPtr->scrnIndex, "%s: fb_location: 0x%08X " "[fb_size: 0x%04X] -> fb_location: 0x%08X\n", __func__, (unsigned int)fb_location, fb_size,(unsigned int)fb_location_tmp); RHDWriteMC(rhdPtr, RS60_NB_FB_LOCATION, fb_location_tmp); RHDRegWrite(rhdPtr, HDP_FB_LOCATION, fb_location_tmp & 0xFFFF); /* same ;) */ } /* * */ static void rs690SetupMC(RHDPtr rhdPtr) { CARD32 fb_location, fb_location_tmp; CARD16 fb_size; RHDFUNC(rhdPtr); fb_location = RHDReadMC(rhdPtr, RS69_MCCFG_FB_LOCATION); fb_size = (fb_location >> 16) - (fb_location & 0xFFFF); fb_location_tmp = rhdPtr->FbIntAddress >> 16; fb_location_tmp |= (fb_location_tmp + fb_size) << 16; RHDDebug(rhdPtr->scrnIndex, "%s: fb_location: 0x%08X " "[fb_size: 0x%04X] -> fb_location: 0x%08X\n", __func__, (unsigned int)fb_location, fb_size,(unsigned int)fb_location_tmp); RHDWriteMC(rhdPtr, RS69_MCCFG_FB_LOCATION, fb_location_tmp); RHDRegWrite(rhdPtr, HDP_FB_LOCATION, fb_location_tmp & 0xFFFF); } /* * */ static void r6xxSetupMC(RHDPtr rhdPtr) { CARD32 fb_location, fb_location_tmp, hdp_fbbase_tmp; CARD16 fb_size; RHDFUNC(rhdPtr); fb_location = RHDRegRead(rhdPtr, R6XX_MC_VM_FB_LOCATION); fb_size = (fb_location >> 16) - (fb_location & 0xFFFF); fb_location_tmp = rhdPtr->FbIntAddress >> 24; fb_location_tmp |= (fb_location_tmp + fb_size) << 16; hdp_fbbase_tmp = (rhdPtr->FbIntAddress >> 8) & 0xff0000; RHDDebug(rhdPtr->scrnIndex, "%s: fb_location: 0x%08X " "fb_offset: 0x%08X [fb_size: 0x%04X] -> fb_location: 0x%08X " "fb_offset: 0x%08X\n", __func__, (unsigned int)fb_location, RHDRegRead(rhdPtr,R6XX_HDP_NONSURFACE_BASE), fb_size, (unsigned int)fb_location_tmp, (unsigned int)hdp_fbbase_tmp); RHDRegWrite(rhdPtr, R6XX_MC_VM_FB_LOCATION, fb_location_tmp); RHDRegWrite(rhdPtr, R6XX_HDP_NONSURFACE_BASE, hdp_fbbase_tmp); } /* * */ #ifdef NOTYET static void rs780SetupMC(RHDPtr rhdPtr) { CARD32 fb_location, fb_location_tmp, hdp_fbbase_tmp; CARD16 fb_size; RHDFUNC(rhdPtr); fb_location = RHDReadMC(rhdPtr, RS78_MC_FB_LOCATION); fb_size = (fb_location >> 16) - (fb_location & 0xFFFF); fb_location_tmp = rhdPtr->FbIntAddress >> 16; fb_location_tmp |= (fb_location_tmp + fb_size) << 16; hdp_fbbase_tmp = (rhdPtr->FbIntAddress >> 8) & 0xff0000; RHDDebug(rhdPtr->scrnIndex, "%s: fb_location: 0x%08X " "[fb_size: 0x%04X] -> fb_location: 0x%08X\n", __func__, (unsigned int)fb_location, fb_size,(unsigned int)fb_location_tmp); RHDWriteMC(rhdPtr, RS78_MC_FB_LOCATION, fb_location_tmp); /* RS780 uses the same register as R6xx */ RHDRegWrite(rhdPtr, R6XX_HDP_NONSURFACE_BASE, hdp_fbbase_tmp); } #endif /* * */ static void r7xxSetupMC(RHDPtr rhdPtr) { CARD32 fb_location, fb_location_tmp, hdp_fbbase_tmp; CARD16 fb_size; RHDFUNC(rhdPtr); fb_location = RHDRegRead(rhdPtr, R7XX_MC_VM_FB_LOCATION); fb_size = (fb_location >> 16) - (fb_location & 0xFFFF); fb_location_tmp = rhdPtr->FbIntAddress >> 24; fb_location_tmp |= (fb_location_tmp + fb_size) << 16; hdp_fbbase_tmp = (rhdPtr->FbIntAddress >> 8) & 0xff0000; RHDDebug(rhdPtr->scrnIndex, "%s: fb_location: 0x%08X " "fb_offset: 0x%08X [fb_size: 0x%04X] -> fb_location: 0x%08X " "fb_offset: 0x%08X\n", __func__, (unsigned int)fb_location, RHDRegRead(rhdPtr,R6XX_HDP_NONSURFACE_BASE), fb_size, (unsigned int)fb_location_tmp, (unsigned int)hdp_fbbase_tmp); RHDRegWrite(rhdPtr, R7XX_MC_VM_FB_LOCATION, fb_location_tmp); RHDRegWrite(rhdPtr, R6XX_HDP_NONSURFACE_BASE, hdp_fbbase_tmp); } /* * */ void RHDMCSetup(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (!MC) return; /* * make sure the hw is in a state such that we can update * the MC - ie no subsystem is currently accessing memory. */ ASSERT((RHDRegRead(rhdPtr, D1VGA_CONTROL) & D1VGA_MODE_ENABLE) != D1VGA_MODE_ENABLE); ASSERT((RHDRegRead(rhdPtr, D2VGA_CONTROL) & D2VGA_MODE_ENABLE) != D2VGA_MODE_ENABLE); ASSERT((RHDRegRead(rhdPtr, D1CRTC_CONTROL) & 0x1) != 0x1); ASSERT((RHDRegRead(rhdPtr, D2CRTC_CONTROL) & 0x1) != 0x1); ASSERT(RHDMCIdle(rhdPtr, 1)); MC->SetupMC(rhdPtr); } /* * Get FB location and size. */ static CARD32 r5xxGetFBLocation(RHDPtr rhdPtr, CARD32 *size) { struct rhdMC *MC = rhdPtr->MC; CARD32 val; CARD32 reg; if (MC->RV515Variant) reg = RV515_MC_FB_LOCATION | MC_IND_ALL; else reg = R5XX_MC_FB_LOCATION | MC_IND_ALL; val = RHDReadMC(rhdPtr, reg); if (size) *size = ((val >> 16) - (val & 0xFFFF)) << 16; return (val & 0xFFFF) << 16; } /* * */ static CARD32 rs600GetFBLocation(RHDPtr rhdPtr, CARD32 *size) { CARD32 val = RHDReadMC(rhdPtr, RS60_NB_FB_LOCATION); if (size) *size = ((val >> 16) - (val & 0xFFFF)) << 16; return (val & 0xFFFF) << 16; } /* * */ static CARD32 rs690GetFBLocation(RHDPtr rhdPtr, CARD32 *size) { CARD32 val = RHDReadMC(rhdPtr, RS69_MCCFG_FB_LOCATION); if (size) *size = ((val >> 16) - (val & 0xFFFF)) << 16; return (val & 0xFFFF) << 16; } /* * */ static CARD32 r6xxGetFBLocation(RHDPtr rhdPtr, CARD32 *size) { CARD32 val = RHDRegRead(rhdPtr, R6XX_MC_VM_FB_LOCATION); if (size) *size = ((val >> 16) - (val & 0xFFFF)) << 24; return (val & 0xFFFF) << 24; } /* * */ #ifdef NOTYET static CARD32 rs780GetFBLocation(RHDPtr rhdPtr, CARD32 *size) { CARD32 val = RHDReadMC(rhdPtr, RS78_MC_FB_LOCATION); if (size) *size = ((val >> 16) - (val & 0xFFFF)) << 16; return (val & 0xFFFF) << 16; } #endif /* * */ static CARD32 r7xxGetFBLocation(RHDPtr rhdPtr, CARD32 *size) { CARD32 val = RHDRegRead(rhdPtr, R7XX_MC_VM_FB_LOCATION); if (size) *size = ((val >> 16) - (val & 0xFFFF)) << 24; return (val & 0xFFFF) << 24; } /* * */ CARD32 RHDGetFBLocation(RHDPtr rhdPtr, CARD32 *size) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (!MC) { if (size) *size = 0; return 0; } return MC->GetFBLocation(rhdPtr, size); } /* * */ static Bool rv515MCIdle(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (RHDReadMC(rhdPtr, MC_IND_ALL | RV515_MC_STATUS) & RV515_MC_IDLE) return TRUE; return FALSE; } /* * */ static Bool r5xxMCIdle(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (RHDReadMC(rhdPtr, MC_IND_ALL | R5XX_MC_STATUS) & R5XX_MC_IDLE) return TRUE; return FALSE; } /* * */ static Bool rs600MCIdle(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (RHDReadMC(rhdPtr, RS60_MC_SYSTEM_STATUS) & RS6X_MC_SEQUENCER_IDLE) return TRUE; return FALSE; } /* * */ static Bool rs690MCIdle(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (RHDReadMC(rhdPtr, RS69_MC_SYSTEM_STATUS) & RS6X_MC_SEQUENCER_IDLE) return TRUE; return FALSE; } /* * */ static Bool r6xxMCIdle(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (!(RHDRegRead(rhdPtr, SRBM_STATUS) & 0x3f00)) return TRUE; return FALSE; } /* * */ #ifdef NOTYET static Bool rs780MCIdle(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (RHDReadMC(rhdPtr, RS78_MC_SYSTEM_STATUS) & RS78_MC_SEQUENCER_IDLE) return TRUE; return FALSE; } #endif /* * */ Bool RHDMCIdle(RHDPtr rhdPtr, CARD32 count) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (!MC) return TRUE; do { if (MC->MCIdle(rhdPtr)) return TRUE; usleep(10); } while (count--); RHDDebug(rhdPtr->scrnIndex, "%s: MC not idle\n",__func__); return FALSE; } /* * */ void RHDSaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (!MC) return; MC->SaveMC(rhdPtr); MC->Stored = TRUE; } /* * Restore MC VM state. */ void RHDRestoreMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (!MC) return; if (!MC->Stored) { xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "%s: trying to restore uninitialized values.\n",__func__); return; } /* * make sure the hw is in a state such that we can update * the MC - ie no subsystem is currently accessing memory. */ ASSERT((RHDRegRead(rhdPtr, D1VGA_CONTROL) & D1VGA_MODE_ENABLE) != D1VGA_MODE_ENABLE); ASSERT((RHDRegRead(rhdPtr, D2VGA_CONTROL) & D2VGA_MODE_ENABLE) != D2VGA_MODE_ENABLE); ASSERT((RHDRegRead(rhdPtr, D1CRTC_CONTROL) & 0x1) != 0x1); ASSERT((RHDRegRead(rhdPtr, D2CRTC_CONTROL) & 0x1) != 0x1); ASSERT(RHDMCIdle(rhdPtr, 1)); MC->RestoreMC(rhdPtr); } /* * */ static void r5xxSaveMC(RHDPtr rhdPtr) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (MC->RV515Variant) { MC->FbLocation = RHDReadMC(rhdPtr, MC_IND_ALL | RV515_MC_FB_LOCATION); MC->MiscLatencyTimer = RHDReadMC(rhdPtr, MC_IND_ALL | RV515_MC_MISC_LAT_TIMER); } else MC->FbLocation = RHDReadMC(rhdPtr, MC_IND_ALL | R5XX_MC_FB_LOCATION); MC->HdpFbBase = RHDRegRead(rhdPtr, HDP_FB_LOCATION); } /* * */ static void rv515TuneMCAccessForDisplay(RHDPtr rhdPtr, int crtc, DisplayModePtr Mode, DisplayModePtr ScaledToMode) { CARD32 value, setting = 0x1; RHDFUNC(rhdPtr); value = RHDReadMC(rhdPtr, RV515_MC_MISC_LAT_TIMER); value |= (setting << (crtc ? MC_DISP1R_INIT_LAT_SHIFT : MC_DISP0R_INIT_LAT_SHIFT)); RHDWriteMC(rhdPtr, RV515_MC_MISC_LAT_TIMER, value); } /* * */ static void rs690TuneMCAccessForDisplay(RHDPtr rhdPtr, int crtc, DisplayModePtr Mode, DisplayModePtr ScaledToMode) { CARD32 value, setting = 0x1; RHDFUNC(rhdPtr); value = RHDReadMC(rhdPtr, RS69_MC_INIT_MISC_LAT_TIMER); value |= setting << (crtc ? MC_DISP1R_INIT_LAT_SHIFT : MC_DISP0R_INIT_LAT_SHIFT); RHDWriteMC(rhdPtr, RS69_MC_INIT_MISC_LAT_TIMER, value); } /* * */ void RHDTuneMCAccessForDisplay(RHDPtr rhdPtr, int crtc, DisplayModePtr Mode, DisplayModePtr ScaledToMode) { struct rhdMC *MC = rhdPtr->MC; RHDFUNC(rhdPtr); if (MC->TuneMCAccessForDisplay) MC->TuneMCAccessForDisplay(rhdPtr, crtc, Mode, ScaledToMode); } /* * */ void RHDMCInit(RHDPtr rhdPtr) { struct rhdMC *MC; RHDFUNC(rhdPtr); /* These devices have an internal address reference, which some other * address registers in there also use. This can be different from the * address in the BAR. * * We read out the address here from some known location. This address * is as good a guess as any, we just need to pick one, but then make * sure that it is made consistent in MCSetup and the various MC * accessing subsystems. */ if (rhdPtr->ChipSet < RHD_R600) rhdPtr->FbIntAddress = RHDRegRead(rhdPtr, HDP_FB_LOCATION) << 16; else rhdPtr->FbIntAddress = RHDRegRead(rhdPtr, R6XX_CONFIG_FB_BASE); RHDDebug(rhdPtr->scrnIndex, "MC FB Address: 0x%08X.\n", rhdPtr->FbIntAddress); MC = xnfcalloc(1, sizeof(struct rhdMC)); MC->Stored = FALSE; if (rhdPtr->ChipSet < RHD_RS600) { MC->SaveMC = r5xxSaveMC; MC->RestoreMC = r5xxRestoreMC; MC->SetupMC = r5xxSetupMC; MC->GetFBLocation = r5xxGetFBLocation; if (rhdPtr->ChipSet == RHD_RV515 || rhdPtr->ChipSet == RHD_RV505 || rhdPtr->ChipSet == RHD_RV516 || rhdPtr->ChipSet == RHD_RV550 || rhdPtr->ChipSet == RHD_M52 || rhdPtr->ChipSet == RHD_M54 || rhdPtr->ChipSet == RHD_M62 || rhdPtr->ChipSet == RHD_M64 || rhdPtr->ChipSet == RHD_M71) { MC->RV515Variant = TRUE; MC->MCIdle = rv515MCIdle; MC->TuneMCAccessForDisplay = rv515TuneMCAccessForDisplay; } else { MC->RV515Variant = FALSE; MC->MCIdle = r5xxMCIdle; } } else if (rhdPtr->ChipSet == RHD_RS600) { MC->SaveMC = rs600SaveMC; MC->RestoreMC = rs600RestoreMC; MC->SetupMC = rs600SetupMC; MC->MCIdle = rs600MCIdle; MC->GetFBLocation = rs600GetFBLocation; } else if (rhdPtr->ChipSet < RHD_R600) { MC->SaveMC = rs690SaveMC; MC->RestoreMC = rs690RestoreMC; MC->SetupMC = rs690SetupMC; MC->MCIdle = rs690MCIdle; MC->GetFBLocation = rs690GetFBLocation; MC->TuneMCAccessForDisplay = rs690TuneMCAccessForDisplay; } else if (rhdPtr->ChipSet <= RHD_RS780) { MC->SaveMC = r6xxSaveMC; MC->RestoreMC = r6xxRestoreMC; MC->SetupMC = r6xxSetupMC; MC->MCIdle = r6xxMCIdle; MC->GetFBLocation = r6xxGetFBLocation; } #if 0 else if (rhdPtr->ChipSet == RHD_RS780) { MC->SaveMC = rs780SaveMC; MC->RestoreMC = rs780RestoreMC; MC->SetupMC = rs780SetupMC; MC->MCIdle = rs780MCIdle; MC->GetFBLocation = rs780GetFBLocation; } #endif else if (rhdPtr->ChipSet >= RHD_RV770) { MC->SaveMC = r7xxSaveMC; MC->RestoreMC = r7xxRestoreMC; MC->SetupMC = r7xxSetupMC; MC->MCIdle = r6xxMCIdle; MC->GetFBLocation = r7xxGetFBLocation; } else { xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "I don't know anything about MC on this chipset\n"); xfree(MC); return; } rhdPtr->MC = MC; } /* * Free structure. */ void RHDMCDestroy(RHDPtr rhdPtr) { RHDFUNC(rhdPtr); if (!rhdPtr->MC) return; xfree(rhdPtr->MC); rhdPtr->MC = NULL; } /* * */ Bool RHD_MC_IGP_SideportMemoryPresent(RHDPtr rhdPtr) { Bool Present = FALSE; RHDFUNC(rhdPtr); switch (rhdPtr->ChipSet) { case RHD_RS690: case RHD_RS740: Present = (RHDReadMC(rhdPtr, RS69_MC_MISC_UMA_CNTL) & RS69_SIDE_PORT_PRESENT_R) != 0; break; case RHD_RS780: Present = (RHDReadMC(rhdPtr, RS78_MC_MISC_UMA_CNTL) & RS78_SIDE_PORT_PRESENT_R) != 0; break; default: break; } xf86DrvMsg(rhdPtr->scrnIndex, X_INFO, "IPG sideport memory %s present.\n", Present ? "" : "not"); return Present; }