1ad43ddacSmrg/* 2ad43ddacSmrg * Copyright 2009 Advanced Micro Devices, Inc. 3ad43ddacSmrg * 4ad43ddacSmrg * All Rights Reserved. 5ad43ddacSmrg * 6ad43ddacSmrg * Permission is hereby granted, free of charge, to any person obtaining 7ad43ddacSmrg * a copy of this software and associated documentation files (the 8ad43ddacSmrg * "Software"), to deal in the Software without restriction, including 9ad43ddacSmrg * without limitation on the rights to use, copy, modify, merge, 10ad43ddacSmrg * publish, distribute, sublicense, and/or sell copies of the Software, 11ad43ddacSmrg * and to permit persons to whom the Software is furnished to do so, 12ad43ddacSmrg * subject to the following conditions: 13ad43ddacSmrg * 14ad43ddacSmrg * The above copyright notice and this permission notice (including the 15ad43ddacSmrg * next paragraph) shall be included in all copies or substantial 16ad43ddacSmrg * portions of the Software. 17ad43ddacSmrg * 18ad43ddacSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19ad43ddacSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20ad43ddacSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21ad43ddacSmrg * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR 22ad43ddacSmrg * AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23ad43ddacSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24ad43ddacSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25ad43ddacSmrg * DEALINGS IN THE SOFTWARE. 26ad43ddacSmrg * 27ad43ddacSmrg * Author: Alex Deucher <alexander.deucher@amd.com> 28ad43ddacSmrg * 29ad43ddacSmrg */ 30ad43ddacSmrg 31ad43ddacSmrg#ifdef HAVE_CONFIG_H 32ad43ddacSmrg#include "config.h" 33ad43ddacSmrg#endif 34ad43ddacSmrg 35ad43ddacSmrg /* Driver data structures */ 36ad43ddacSmrg#include "radeon.h" 37ad43ddacSmrg#include "radeon_reg.h" 38ad43ddacSmrg#include "radeon_macros.h" 39ad43ddacSmrg#include "radeon_atombios.h" 40ad43ddacSmrg 41ad43ddacSmrg#include "ati_pciids_gen.h" 42ad43ddacSmrg 43ad43ddacSmrg/* 10 khz */ 44ad43ddacSmrgstatic uint32_t calc_eng_mem_clock(ScrnInfoPtr pScrn, 45ad43ddacSmrg uint32_t req_clock, 46ad43ddacSmrg int ref_div, 47ad43ddacSmrg int *fb_div, 48ad43ddacSmrg int *post_div) 49ad43ddacSmrg{ 50ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 51ad43ddacSmrg RADEONPLLPtr pll = &info->pll; 52ad43ddacSmrg 53ad43ddacSmrg if (req_clock < 15000) { 54ad43ddacSmrg *post_div = 8; 55ad43ddacSmrg req_clock *= 8; 56ad43ddacSmrg } else if (req_clock < 30000) { 57ad43ddacSmrg *post_div = 4; 58ad43ddacSmrg req_clock *= 4; 59ad43ddacSmrg } else if (req_clock < 60000) { 60ad43ddacSmrg *post_div = 2; 61ad43ddacSmrg req_clock *= 2; 62ad43ddacSmrg } else 63ad43ddacSmrg *post_div = 1; 64ad43ddacSmrg 65ad43ddacSmrg req_clock *= ref_div; 66ad43ddacSmrg req_clock += pll->reference_freq; 67ad43ddacSmrg req_clock /= (2 * pll->reference_freq); 68ad43ddacSmrg 69ad43ddacSmrg *fb_div = req_clock & 0xff; 70ad43ddacSmrg 71ad43ddacSmrg req_clock = (req_clock & 0xffff) << 1; 72ad43ddacSmrg req_clock *= pll->reference_freq; 73ad43ddacSmrg req_clock /= ref_div; 74ad43ddacSmrg req_clock /= *post_div; 75ad43ddacSmrg 76ad43ddacSmrg return req_clock; 77ad43ddacSmrg 78ad43ddacSmrg} 79ad43ddacSmrg 80ad43ddacSmrgstatic void 81ad43ddacSmrgRADEONSetEngineClock(ScrnInfoPtr pScrn, uint32_t eng_clock) 82ad43ddacSmrg{ 83ad43ddacSmrg uint32_t tmp; 84ad43ddacSmrg int ref_div, fb_div, post_div; 85ad43ddacSmrg 86ad43ddacSmrg RADEONWaitForIdleMMIO(pScrn); 87ad43ddacSmrg 88ad43ddacSmrg tmp = INPLL(pScrn, RADEON_M_SPLL_REF_FB_DIV); 89ad43ddacSmrg ref_div = tmp & RADEON_M_SPLL_REF_DIV_MASK; 90ad43ddacSmrg 91ad43ddacSmrg eng_clock = calc_eng_mem_clock(pScrn, eng_clock, ref_div, &fb_div, &post_div); 92ad43ddacSmrg 93ad43ddacSmrg tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL); 94ad43ddacSmrg tmp &= ~RADEON_DONT_USE_XTALIN; 95ad43ddacSmrg OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp); 96ad43ddacSmrg 97ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 98ad43ddacSmrg tmp &= ~RADEON_SCLK_SRC_SEL_MASK; 99ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 100ad43ddacSmrg 101ad43ddacSmrg usleep(10); 102ad43ddacSmrg 103ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SPLL_CNTL); 104ad43ddacSmrg tmp |= RADEON_SPLL_SLEEP; 105ad43ddacSmrg OUTPLL(pScrn, RADEON_SPLL_CNTL, tmp); 106ad43ddacSmrg 107ad43ddacSmrg usleep(2); 108ad43ddacSmrg 109ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SPLL_CNTL); 110ad43ddacSmrg tmp |= RADEON_SPLL_RESET; 111ad43ddacSmrg OUTPLL(pScrn, RADEON_SPLL_CNTL, tmp); 112ad43ddacSmrg 113ad43ddacSmrg usleep(200); 114ad43ddacSmrg 115ad43ddacSmrg tmp = INPLL(pScrn, RADEON_M_SPLL_REF_FB_DIV); 116ad43ddacSmrg tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT); 117ad43ddacSmrg tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT; 118ad43ddacSmrg OUTPLL(pScrn, RADEON_M_SPLL_REF_FB_DIV, tmp); 119ad43ddacSmrg 120ad43ddacSmrg /* XXX: verify on different asics */ 121ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SPLL_CNTL); 122ad43ddacSmrg tmp &= ~RADEON_SPLL_PVG_MASK; 123ad43ddacSmrg if ((eng_clock * post_div) >= 90000) 124ad43ddacSmrg tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT); 125ad43ddacSmrg else 126ad43ddacSmrg tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT); 127ad43ddacSmrg OUTPLL(pScrn, RADEON_SPLL_CNTL, tmp); 128ad43ddacSmrg 129ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SPLL_CNTL); 130ad43ddacSmrg tmp &= ~RADEON_SPLL_SLEEP; 131ad43ddacSmrg OUTPLL(pScrn, RADEON_SPLL_CNTL, tmp); 132ad43ddacSmrg 133ad43ddacSmrg usleep(2); 134ad43ddacSmrg 135ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SPLL_CNTL); 136ad43ddacSmrg tmp &= ~RADEON_SPLL_RESET; 137ad43ddacSmrg OUTPLL(pScrn, RADEON_SPLL_CNTL, tmp); 138ad43ddacSmrg 139ad43ddacSmrg usleep(200); 140ad43ddacSmrg 141ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 142ad43ddacSmrg tmp &= ~RADEON_SCLK_SRC_SEL_MASK; 143ad43ddacSmrg switch (post_div) { 144ad43ddacSmrg case 1: 145ad43ddacSmrg default: 146ad43ddacSmrg tmp |= 1; 147ad43ddacSmrg break; 148ad43ddacSmrg case 2: 149ad43ddacSmrg tmp |= 2; 150ad43ddacSmrg break; 151ad43ddacSmrg case 4: 152ad43ddacSmrg tmp |= 3; 153ad43ddacSmrg break; 154ad43ddacSmrg case 8: 155ad43ddacSmrg tmp |= 4; 156ad43ddacSmrg break; 157ad43ddacSmrg } 158ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 159ad43ddacSmrg 160ad43ddacSmrg usleep(20); 161ad43ddacSmrg 162ad43ddacSmrg tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL); 163ad43ddacSmrg tmp |= RADEON_DONT_USE_XTALIN; 164ad43ddacSmrg OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp); 165ad43ddacSmrg 166ad43ddacSmrg usleep(10); 167ad43ddacSmrg 168ad43ddacSmrg} 169ad43ddacSmrg 170ad43ddacSmrgstatic void LegacySetClockGating(ScrnInfoPtr pScrn, Bool enable) 171ad43ddacSmrg{ 172ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 173ad43ddacSmrg RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 174ad43ddacSmrg unsigned char *RADEONMMIO = info->MMIO; 175ad43ddacSmrg uint32_t tmp; 176ad43ddacSmrg 177ad43ddacSmrg if (enable) { 178ad43ddacSmrg if (!pRADEONEnt->HasCRTC2) { 179ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 180ad43ddacSmrg if ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) > 181ad43ddacSmrg RADEON_CFG_ATI_REV_A13) { 182ad43ddacSmrg tmp &= ~(RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_RB); 183ad43ddacSmrg } 184ad43ddacSmrg tmp &= ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | 185ad43ddacSmrg RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | 186ad43ddacSmrg RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | 187ad43ddacSmrg RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | 188ad43ddacSmrg RADEON_SCLK_FORCE_TDM); 189ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 190ad43ddacSmrg } else if (IS_R300_VARIANT) { 191ad43ddacSmrg if ((info->ChipFamily == CHIP_FAMILY_RS400) || 192ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RS480)) { 193ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 194ad43ddacSmrg tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | 195ad43ddacSmrg RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | 196ad43ddacSmrg RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | 197ad43ddacSmrg R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | 198ad43ddacSmrg RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | 199ad43ddacSmrg R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | 200ad43ddacSmrg R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | 201ad43ddacSmrg R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); 202ad43ddacSmrg tmp |= RADEON_DYN_STOP_LAT_MASK; 203ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_VIP; 204ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 205ad43ddacSmrg 206ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); 207ad43ddacSmrg tmp &= ~RADEON_SCLK_MORE_FORCEON; 208ad43ddacSmrg tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; 209ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp); 210ad43ddacSmrg 211ad43ddacSmrg tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); 212ad43ddacSmrg tmp |= (RADEON_PIXCLK_ALWAYS_ONb | 213ad43ddacSmrg RADEON_PIXCLK_DAC_ALWAYS_ONb); 214ad43ddacSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp); 215ad43ddacSmrg 216ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); 217ad43ddacSmrg tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | 218ad43ddacSmrg RADEON_PIX2CLK_DAC_ALWAYS_ONb | 219ad43ddacSmrg RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 220ad43ddacSmrg R300_DVOCLK_ALWAYS_ONb | 221ad43ddacSmrg RADEON_PIXCLK_BLEND_ALWAYS_ONb | 222ad43ddacSmrg RADEON_PIXCLK_GV_ALWAYS_ONb | 223ad43ddacSmrg R300_PIXCLK_DVO_ALWAYS_ONb | 224ad43ddacSmrg RADEON_PIXCLK_LVDS_ALWAYS_ONb | 225ad43ddacSmrg RADEON_PIXCLK_TMDS_ALWAYS_ONb | 226ad43ddacSmrg R300_PIXCLK_TRANS_ALWAYS_ONb | 227ad43ddacSmrg R300_PIXCLK_TVO_ALWAYS_ONb | 228ad43ddacSmrg R300_P2G2CLK_ALWAYS_ONb | 229ad43ddacSmrg R300_P2G2CLK_DAC_ALWAYS_ONb); 230ad43ddacSmrg OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp); 231ad43ddacSmrg } else if (info->ChipFamily >= CHIP_FAMILY_RV350) { 232ad43ddacSmrg tmp = INPLL(pScrn, R300_SCLK_CNTL2); 233ad43ddacSmrg tmp &= ~(R300_SCLK_FORCE_TCL | 234ad43ddacSmrg R300_SCLK_FORCE_GA | 235ad43ddacSmrg R300_SCLK_FORCE_CBA); 236ad43ddacSmrg tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | 237ad43ddacSmrg R300_SCLK_GA_MAX_DYN_STOP_LAT | 238ad43ddacSmrg R300_SCLK_CBA_MAX_DYN_STOP_LAT); 239ad43ddacSmrg OUTPLL(pScrn, R300_SCLK_CNTL2, tmp); 240ad43ddacSmrg 241ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 242ad43ddacSmrg tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | 243ad43ddacSmrg RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | 244ad43ddacSmrg RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | 245ad43ddacSmrg R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | 246ad43ddacSmrg RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | 247ad43ddacSmrg R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | 248ad43ddacSmrg R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | 249ad43ddacSmrg R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); 250ad43ddacSmrg tmp |= RADEON_DYN_STOP_LAT_MASK; 251ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 252ad43ddacSmrg 253ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); 254ad43ddacSmrg tmp &= ~RADEON_SCLK_MORE_FORCEON; 255ad43ddacSmrg tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; 256ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp); 257ad43ddacSmrg 258ad43ddacSmrg tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); 259ad43ddacSmrg tmp |= (RADEON_PIXCLK_ALWAYS_ONb | 260ad43ddacSmrg RADEON_PIXCLK_DAC_ALWAYS_ONb); 261ad43ddacSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp); 262ad43ddacSmrg 263ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); 264ad43ddacSmrg tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | 265ad43ddacSmrg RADEON_PIX2CLK_DAC_ALWAYS_ONb | 266ad43ddacSmrg RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 267ad43ddacSmrg R300_DVOCLK_ALWAYS_ONb | 268ad43ddacSmrg RADEON_PIXCLK_BLEND_ALWAYS_ONb | 269ad43ddacSmrg RADEON_PIXCLK_GV_ALWAYS_ONb | 270ad43ddacSmrg R300_PIXCLK_DVO_ALWAYS_ONb | 271ad43ddacSmrg RADEON_PIXCLK_LVDS_ALWAYS_ONb | 272ad43ddacSmrg RADEON_PIXCLK_TMDS_ALWAYS_ONb | 273ad43ddacSmrg R300_PIXCLK_TRANS_ALWAYS_ONb | 274ad43ddacSmrg R300_PIXCLK_TVO_ALWAYS_ONb | 275ad43ddacSmrg R300_P2G2CLK_ALWAYS_ONb | 276ad43ddacSmrg R300_P2G2CLK_DAC_ALWAYS_ONb); 277ad43ddacSmrg OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp); 278ad43ddacSmrg 279ad43ddacSmrg tmp = INPLL(pScrn, RADEON_MCLK_MISC); 280ad43ddacSmrg tmp |= (RADEON_MC_MCLK_DYN_ENABLE | 281ad43ddacSmrg RADEON_IO_MCLK_DYN_ENABLE); 282ad43ddacSmrg OUTPLL(pScrn, RADEON_MCLK_MISC, tmp); 283ad43ddacSmrg 284ad43ddacSmrg tmp = INPLL(pScrn, RADEON_MCLK_CNTL); 285ad43ddacSmrg tmp |= (RADEON_FORCEON_MCLKA | 286ad43ddacSmrg RADEON_FORCEON_MCLKB); 287ad43ddacSmrg 288ad43ddacSmrg tmp &= ~(RADEON_FORCEON_YCLKA | 289ad43ddacSmrg RADEON_FORCEON_YCLKB | 290ad43ddacSmrg RADEON_FORCEON_MC); 291ad43ddacSmrg 292ad43ddacSmrg /* Some releases of vbios have set DISABLE_MC_MCLKA 293ad43ddacSmrg and DISABLE_MC_MCLKB bits in the vbios table. Setting these 294ad43ddacSmrg bits will cause H/W hang when reading video memory with dynamic clocking 295ad43ddacSmrg enabled. */ 296ad43ddacSmrg if ((tmp & R300_DISABLE_MC_MCLKA) && 297ad43ddacSmrg (tmp & R300_DISABLE_MC_MCLKB)) { 298ad43ddacSmrg /* If both bits are set, then check the active channels */ 299ad43ddacSmrg tmp = INPLL(pScrn, RADEON_MCLK_CNTL); 300ad43ddacSmrg if (info->RamWidth == 64) { 301ad43ddacSmrg if (INREG(RADEON_MEM_CNTL) & R300_MEM_USE_CD_CH_ONLY) 302ad43ddacSmrg tmp &= ~R300_DISABLE_MC_MCLKB; 303ad43ddacSmrg else 304ad43ddacSmrg tmp &= ~R300_DISABLE_MC_MCLKA; 305ad43ddacSmrg } else { 306ad43ddacSmrg tmp &= ~(R300_DISABLE_MC_MCLKA | 307ad43ddacSmrg R300_DISABLE_MC_MCLKB); 308ad43ddacSmrg } 309ad43ddacSmrg } 310ad43ddacSmrg 311ad43ddacSmrg OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp); 312ad43ddacSmrg } else { 313ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 314ad43ddacSmrg tmp &= ~(R300_SCLK_FORCE_VAP); 315ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_CP; 316ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 317ad43ddacSmrg usleep(15000); 318ad43ddacSmrg 319ad43ddacSmrg tmp = INPLL(pScrn, R300_SCLK_CNTL2); 320ad43ddacSmrg tmp &= ~(R300_SCLK_FORCE_TCL | 321ad43ddacSmrg R300_SCLK_FORCE_GA | 322ad43ddacSmrg R300_SCLK_FORCE_CBA); 323ad43ddacSmrg OUTPLL(pScrn, R300_SCLK_CNTL2, tmp); 324ad43ddacSmrg } 325ad43ddacSmrg } else { 326ad43ddacSmrg tmp = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL); 327ad43ddacSmrg 328ad43ddacSmrg tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | 329ad43ddacSmrg RADEON_DISP_DYN_STOP_LAT_MASK | 330ad43ddacSmrg RADEON_DYN_STOP_MODE_MASK); 331ad43ddacSmrg 332ad43ddacSmrg tmp |= (RADEON_ENGIN_DYNCLK_MODE | 333ad43ddacSmrg (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); 334ad43ddacSmrg OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL, tmp); 335ad43ddacSmrg usleep(15000); 336ad43ddacSmrg 337ad43ddacSmrg tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL); 338ad43ddacSmrg tmp |= RADEON_SCLK_DYN_START_CNTL; 339ad43ddacSmrg OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp); 340ad43ddacSmrg usleep(15000); 341ad43ddacSmrg 342ad43ddacSmrg /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 343ad43ddacSmrg to lockup randomly, leave them as set by BIOS. 344ad43ddacSmrg */ 345ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 346ad43ddacSmrg /*tmp &= RADEON_SCLK_SRC_SEL_MASK;*/ 347ad43ddacSmrg tmp &= ~RADEON_SCLK_FORCEON_MASK; 348ad43ddacSmrg 349ad43ddacSmrg /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300*/ 350ad43ddacSmrg if (((info->ChipFamily == CHIP_FAMILY_RV250) && 351ad43ddacSmrg ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < 352ad43ddacSmrg RADEON_CFG_ATI_REV_A13)) || 353ad43ddacSmrg ((info->ChipFamily == CHIP_FAMILY_RV100) && 354ad43ddacSmrg ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) <= 355ad43ddacSmrg RADEON_CFG_ATI_REV_A13))) { 356ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_CP; 357ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_VIP; 358ad43ddacSmrg } 359ad43ddacSmrg 360ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 361ad43ddacSmrg 362ad43ddacSmrg if ((info->ChipFamily == CHIP_FAMILY_RV200) || 363ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV250) || 364ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV280)) { 365ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); 366ad43ddacSmrg tmp &= ~RADEON_SCLK_MORE_FORCEON; 367ad43ddacSmrg 368ad43ddacSmrg /* RV200::A11 A12 RV250::A11 A12 */ 369ad43ddacSmrg if (((info->ChipFamily == CHIP_FAMILY_RV200) || 370ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV250)) && 371ad43ddacSmrg ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < 372ad43ddacSmrg RADEON_CFG_ATI_REV_A13)) { 373ad43ddacSmrg tmp |= RADEON_SCLK_MORE_FORCEON; 374ad43ddacSmrg } 375ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp); 376ad43ddacSmrg usleep(15000); 377ad43ddacSmrg } 378ad43ddacSmrg 379ad43ddacSmrg /* RV200::A11 A12, RV250::A11 A12 */ 380ad43ddacSmrg if (((info->ChipFamily == CHIP_FAMILY_RV200) || 381ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV250)) && 382ad43ddacSmrg ((INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) < 383ad43ddacSmrg RADEON_CFG_ATI_REV_A13)) { 384ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PLL_PWRMGT_CNTL); 385ad43ddacSmrg tmp |= RADEON_TCL_BYPASS_DISABLE; 386ad43ddacSmrg OUTPLL(pScrn, RADEON_PLL_PWRMGT_CNTL, tmp); 387ad43ddacSmrg } 388ad43ddacSmrg usleep(15000); 389ad43ddacSmrg 390ad43ddacSmrg /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK)*/ 391ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); 392ad43ddacSmrg tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | 393ad43ddacSmrg RADEON_PIX2CLK_DAC_ALWAYS_ONb | 394ad43ddacSmrg RADEON_PIXCLK_BLEND_ALWAYS_ONb | 395ad43ddacSmrg RADEON_PIXCLK_GV_ALWAYS_ONb | 396ad43ddacSmrg RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | 397ad43ddacSmrg RADEON_PIXCLK_LVDS_ALWAYS_ONb | 398ad43ddacSmrg RADEON_PIXCLK_TMDS_ALWAYS_ONb); 399ad43ddacSmrg 400ad43ddacSmrg OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp); 401ad43ddacSmrg usleep(15000); 402ad43ddacSmrg 403ad43ddacSmrg tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); 404ad43ddacSmrg tmp |= (RADEON_PIXCLK_ALWAYS_ONb | 405ad43ddacSmrg RADEON_PIXCLK_DAC_ALWAYS_ONb); 406ad43ddacSmrg 407ad43ddacSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp); 408ad43ddacSmrg usleep(15000); 409ad43ddacSmrg } 410ad43ddacSmrg } else { 411ad43ddacSmrg /* Turn everything OFF (ForceON to everything)*/ 412ad43ddacSmrg if ( !pRADEONEnt->HasCRTC2 ) { 413ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 414ad43ddacSmrg tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | 415ad43ddacSmrg RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP | 416ad43ddacSmrg RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | 417ad43ddacSmrg RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | 418ad43ddacSmrg RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | 419ad43ddacSmrg RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | 420ad43ddacSmrg RADEON_SCLK_FORCE_RB); 421ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 422ad43ddacSmrg } else if ((info->ChipFamily == CHIP_FAMILY_RS400) || 423ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RS480)) { 424ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 425ad43ddacSmrg tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | 426ad43ddacSmrg RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | 427ad43ddacSmrg RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | 428ad43ddacSmrg R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | 429ad43ddacSmrg RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | 430ad43ddacSmrg R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | 431ad43ddacSmrg R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | 432ad43ddacSmrg R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); 433ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 434ad43ddacSmrg 435ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); 436ad43ddacSmrg tmp |= RADEON_SCLK_MORE_FORCEON; 437ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp); 438ad43ddacSmrg 439ad43ddacSmrg tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); 440ad43ddacSmrg tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | 441ad43ddacSmrg RADEON_PIXCLK_DAC_ALWAYS_ONb | 442ad43ddacSmrg R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); 443ad43ddacSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp); 444ad43ddacSmrg 445ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); 446ad43ddacSmrg tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | 447ad43ddacSmrg RADEON_PIX2CLK_DAC_ALWAYS_ONb | 448ad43ddacSmrg RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 449ad43ddacSmrg R300_DVOCLK_ALWAYS_ONb | 450ad43ddacSmrg RADEON_PIXCLK_BLEND_ALWAYS_ONb | 451ad43ddacSmrg RADEON_PIXCLK_GV_ALWAYS_ONb | 452ad43ddacSmrg R300_PIXCLK_DVO_ALWAYS_ONb | 453ad43ddacSmrg RADEON_PIXCLK_LVDS_ALWAYS_ONb | 454ad43ddacSmrg RADEON_PIXCLK_TMDS_ALWAYS_ONb | 455ad43ddacSmrg R300_PIXCLK_TRANS_ALWAYS_ONb | 456ad43ddacSmrg R300_PIXCLK_TVO_ALWAYS_ONb | 457ad43ddacSmrg R300_P2G2CLK_ALWAYS_ONb | 458ad43ddacSmrg R300_P2G2CLK_DAC_ALWAYS_ONb | 459ad43ddacSmrg R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 460ad43ddacSmrg OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp); 461ad43ddacSmrg } else if (info->ChipFamily >= CHIP_FAMILY_RV350) { 462ad43ddacSmrg /* for RV350/M10, no delays are required. */ 463ad43ddacSmrg tmp = INPLL(pScrn, R300_SCLK_CNTL2); 464ad43ddacSmrg tmp |= (R300_SCLK_FORCE_TCL | 465ad43ddacSmrg R300_SCLK_FORCE_GA | 466ad43ddacSmrg R300_SCLK_FORCE_CBA); 467ad43ddacSmrg OUTPLL(pScrn, R300_SCLK_CNTL2, tmp); 468ad43ddacSmrg 469ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 470ad43ddacSmrg tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | 471ad43ddacSmrg RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | 472ad43ddacSmrg RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | 473ad43ddacSmrg R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | 474ad43ddacSmrg RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | 475ad43ddacSmrg R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | 476ad43ddacSmrg R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | 477ad43ddacSmrg R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); 478ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 479ad43ddacSmrg 480ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); 481ad43ddacSmrg tmp |= RADEON_SCLK_MORE_FORCEON; 482ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp); 483ad43ddacSmrg 484ad43ddacSmrg tmp = INPLL(pScrn, RADEON_MCLK_CNTL); 485ad43ddacSmrg tmp |= (RADEON_FORCEON_MCLKA | 486ad43ddacSmrg RADEON_FORCEON_MCLKB | 487ad43ddacSmrg RADEON_FORCEON_YCLKA | 488ad43ddacSmrg RADEON_FORCEON_YCLKB | 489ad43ddacSmrg RADEON_FORCEON_MC); 490ad43ddacSmrg OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp); 491ad43ddacSmrg 492ad43ddacSmrg tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); 493ad43ddacSmrg tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | 494ad43ddacSmrg RADEON_PIXCLK_DAC_ALWAYS_ONb | 495ad43ddacSmrg R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); 496ad43ddacSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp); 497ad43ddacSmrg 498ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); 499ad43ddacSmrg tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | 500ad43ddacSmrg RADEON_PIX2CLK_DAC_ALWAYS_ONb | 501ad43ddacSmrg RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 502ad43ddacSmrg R300_DVOCLK_ALWAYS_ONb | 503ad43ddacSmrg RADEON_PIXCLK_BLEND_ALWAYS_ONb | 504ad43ddacSmrg RADEON_PIXCLK_GV_ALWAYS_ONb | 505ad43ddacSmrg R300_PIXCLK_DVO_ALWAYS_ONb | 506ad43ddacSmrg RADEON_PIXCLK_LVDS_ALWAYS_ONb | 507ad43ddacSmrg RADEON_PIXCLK_TMDS_ALWAYS_ONb | 508ad43ddacSmrg R300_PIXCLK_TRANS_ALWAYS_ONb | 509ad43ddacSmrg R300_PIXCLK_TVO_ALWAYS_ONb | 510ad43ddacSmrg R300_P2G2CLK_ALWAYS_ONb | 511ad43ddacSmrg R300_P2G2CLK_DAC_ALWAYS_ONb | 512ad43ddacSmrg R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 513ad43ddacSmrg OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp); 514ad43ddacSmrg } else { 515ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 516ad43ddacSmrg tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); 517ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_SE; 518ad43ddacSmrg 519ad43ddacSmrg if ( !pRADEONEnt->HasCRTC2 ) { 520ad43ddacSmrg tmp |= ( RADEON_SCLK_FORCE_RB | 521ad43ddacSmrg RADEON_SCLK_FORCE_TDM | 522ad43ddacSmrg RADEON_SCLK_FORCE_TAM | 523ad43ddacSmrg RADEON_SCLK_FORCE_PB | 524ad43ddacSmrg RADEON_SCLK_FORCE_RE | 525ad43ddacSmrg RADEON_SCLK_FORCE_VIP | 526ad43ddacSmrg RADEON_SCLK_FORCE_IDCT | 527ad43ddacSmrg RADEON_SCLK_FORCE_TOP | 528ad43ddacSmrg RADEON_SCLK_FORCE_DISP1 | 529ad43ddacSmrg RADEON_SCLK_FORCE_DISP2 | 530ad43ddacSmrg RADEON_SCLK_FORCE_HDP ); 531ad43ddacSmrg } else if ((info->ChipFamily == CHIP_FAMILY_R300) || 532ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_R350)) { 533ad43ddacSmrg tmp |= ( RADEON_SCLK_FORCE_HDP | 534ad43ddacSmrg RADEON_SCLK_FORCE_DISP1 | 535ad43ddacSmrg RADEON_SCLK_FORCE_DISP2 | 536ad43ddacSmrg RADEON_SCLK_FORCE_TOP | 537ad43ddacSmrg RADEON_SCLK_FORCE_IDCT | 538ad43ddacSmrg RADEON_SCLK_FORCE_VIP); 539ad43ddacSmrg } 540ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 541ad43ddacSmrg 542ad43ddacSmrg usleep(16000); 543ad43ddacSmrg 544ad43ddacSmrg if ((info->ChipFamily == CHIP_FAMILY_R300) || 545ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_R350)) { 546ad43ddacSmrg tmp = INPLL(pScrn, R300_SCLK_CNTL2); 547ad43ddacSmrg tmp |= ( R300_SCLK_FORCE_TCL | 548ad43ddacSmrg R300_SCLK_FORCE_GA | 549ad43ddacSmrg R300_SCLK_FORCE_CBA); 550ad43ddacSmrg OUTPLL(pScrn, R300_SCLK_CNTL2, tmp); 551ad43ddacSmrg usleep(16000); 552ad43ddacSmrg } 553ad43ddacSmrg 554ad43ddacSmrg if (info->IsIGP) { 555ad43ddacSmrg tmp = INPLL(pScrn, RADEON_MCLK_CNTL); 556ad43ddacSmrg tmp &= ~(RADEON_FORCEON_MCLKA | 557ad43ddacSmrg RADEON_FORCEON_YCLKA); 558ad43ddacSmrg OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp); 559ad43ddacSmrg usleep(16000); 560ad43ddacSmrg } 561ad43ddacSmrg 562ad43ddacSmrg if ((info->ChipFamily == CHIP_FAMILY_RV200) || 563ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV250) || 564ad43ddacSmrg (info->ChipFamily == CHIP_FAMILY_RV280)) { 565ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL); 566ad43ddacSmrg tmp |= RADEON_SCLK_MORE_FORCEON; 567ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp); 568ad43ddacSmrg usleep(16000); 569ad43ddacSmrg } 570ad43ddacSmrg 571ad43ddacSmrg tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL); 572ad43ddacSmrg tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | 573ad43ddacSmrg RADEON_PIX2CLK_DAC_ALWAYS_ONb | 574ad43ddacSmrg RADEON_PIXCLK_BLEND_ALWAYS_ONb | 575ad43ddacSmrg RADEON_PIXCLK_GV_ALWAYS_ONb | 576ad43ddacSmrg RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | 577ad43ddacSmrg RADEON_PIXCLK_LVDS_ALWAYS_ONb | 578ad43ddacSmrg RADEON_PIXCLK_TMDS_ALWAYS_ONb); 579ad43ddacSmrg 580ad43ddacSmrg OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp); 581ad43ddacSmrg usleep(16000); 582ad43ddacSmrg 583ad43ddacSmrg tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL); 584ad43ddacSmrg tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | 585ad43ddacSmrg RADEON_PIXCLK_DAC_ALWAYS_ONb); 586ad43ddacSmrg OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp); 587ad43ddacSmrg } 588ad43ddacSmrg } 589ad43ddacSmrg} 590ad43ddacSmrg 591ad43ddacSmrgstatic void RADEONPMQuirks(ScrnInfoPtr pScrn) 592ad43ddacSmrg{ 593ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 594ad43ddacSmrg uint32_t tmp; 595ad43ddacSmrg 596ad43ddacSmrg RADEONWaitForIdleMMIO(pScrn); 597ad43ddacSmrg 598ad43ddacSmrg if (info->ChipFamily < CHIP_FAMILY_RV515) { 599ad43ddacSmrg tmp = INPLL(pScrn, RADEON_SCLK_CNTL); 600ad43ddacSmrg if (IS_R300_VARIANT || IS_RV100_VARIANT) 601ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_VIP; 602ad43ddacSmrg if ((info->ChipFamily == CHIP_FAMILY_RV250) || (info->ChipFamily == CHIP_FAMILY_RV280)) 603ad43ddacSmrg tmp |= RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_DISP2; 604ad43ddacSmrg if ((info->ChipFamily == CHIP_FAMILY_RV350) || (info->ChipFamily == CHIP_FAMILY_RV380)) 605ad43ddacSmrg tmp |= R300_SCLK_FORCE_VAP; 606ad43ddacSmrg if (info->ChipFamily == CHIP_FAMILY_R420) 607ad43ddacSmrg tmp |= R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX; 608ad43ddacSmrg OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp); 609ad43ddacSmrg } else if (info->ChipFamily < CHIP_FAMILY_R600) { 610ad43ddacSmrg tmp = INPLL(pScrn, AVIVO_CP_DYN_CNTL); 611ad43ddacSmrg tmp |= AVIVO_CP_FORCEON; 612ad43ddacSmrg OUTPLL(pScrn, AVIVO_CP_DYN_CNTL, tmp); 613ad43ddacSmrg 614ad43ddacSmrg tmp = INPLL(pScrn, AVIVO_E2_DYN_CNTL); 615ad43ddacSmrg tmp |= AVIVO_E2_FORCEON; 616ad43ddacSmrg OUTPLL(pScrn, AVIVO_E2_DYN_CNTL, tmp); 617ad43ddacSmrg 618ad43ddacSmrg tmp = INPLL(pScrn, AVIVO_IDCT_DYN_CNTL); 619ad43ddacSmrg tmp |= AVIVO_IDCT_FORCEON; 620ad43ddacSmrg OUTPLL(pScrn, AVIVO_IDCT_DYN_CNTL, tmp); 621ad43ddacSmrg } 622ad43ddacSmrg} 623ad43ddacSmrg 624ad43ddacSmrgstatic void 625ad43ddacSmrgRADEONSetPCIELanes(ScrnInfoPtr pScrn, int lanes) 626ad43ddacSmrg{ 627ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 628ad43ddacSmrg unsigned char *RADEONMMIO = info->MMIO; 629ad43ddacSmrg uint32_t link_width_cntl, mask, target_reg; 630ad43ddacSmrg 631ad43ddacSmrg if (info->IsIGP) 632ad43ddacSmrg return; 633ad43ddacSmrg 634ad43ddacSmrg /* don't change lanes on multi-gpu cards for now */ 635ad43ddacSmrg if ((info->Chipset == PCI_CHIP_RV770_9441) || 636ad43ddacSmrg (info->Chipset == PCI_CHIP_RV770_9443) || 637ad43ddacSmrg (info->Chipset == PCI_CHIP_RV770_944B) || 638ad43ddacSmrg (info->Chipset == PCI_CHIP_RV670_9506) || 639ad43ddacSmrg (info->Chipset == PCI_CHIP_RV670_9509) || 640ad43ddacSmrg (info->Chipset == PCI_CHIP_RV670_950F)) 641ad43ddacSmrg return; 642ad43ddacSmrg 643ad43ddacSmrg RADEONWaitForIdleMMIO(pScrn); 644ad43ddacSmrg 645ad43ddacSmrg switch (lanes) { 646ad43ddacSmrg case 0: 647ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X0; 648ad43ddacSmrg break; 649ad43ddacSmrg case 1: 650ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X1; 651ad43ddacSmrg break; 652ad43ddacSmrg case 2: 653ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X2; 654ad43ddacSmrg break; 655ad43ddacSmrg case 4: 656ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X4; 657ad43ddacSmrg break; 658ad43ddacSmrg case 8: 659ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X8; 660ad43ddacSmrg break; 661ad43ddacSmrg case 12: 662ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X12; 663ad43ddacSmrg break; 664ad43ddacSmrg case 16: 665ad43ddacSmrg default: 666ad43ddacSmrg mask = RADEON_PCIE_LC_LINK_WIDTH_X16; 667ad43ddacSmrg break; 668ad43ddacSmrg } 669ad43ddacSmrg 670ad43ddacSmrg if (info->ChipFamily >= CHIP_FAMILY_R600) { 671ad43ddacSmrg link_width_cntl = INPCIE_P(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL); 672ad43ddacSmrg 673ad43ddacSmrg if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == 674ad43ddacSmrg (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) 675ad43ddacSmrg return; 676ad43ddacSmrg 677ad43ddacSmrg link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | 678ad43ddacSmrg RADEON_PCIE_LC_RECONFIG_NOW | 679ad43ddacSmrg R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE | 680ad43ddacSmrg R600_PCIE_LC_SHORT_RECONFIG_EN | 681ad43ddacSmrg R600_PCIE_LC_RENEGOTIATE_EN); 682ad43ddacSmrg link_width_cntl |= mask; 683ad43ddacSmrg 684ad43ddacSmrg#if 0 685ad43ddacSmrg /* some northbridges can renegotiate the link rather than requiring 686ad43ddacSmrg * a complete re-config. 687ad43ddacSmrg * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.) 688ad43ddacSmrg */ 689ad43ddacSmrg if (northbridge can renegotiate) 690ad43ddacSmrg link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN; 691ad43ddacSmrg else 692ad43ddacSmrg#endif 693ad43ddacSmrg link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE; 694ad43ddacSmrg 695ad43ddacSmrg OUTPCIE_P(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); 696ad43ddacSmrg OUTPCIE_P(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl | RADEON_PCIE_LC_RECONFIG_NOW); 697ad43ddacSmrg 698ad43ddacSmrg if (info->ChipFamily >= CHIP_FAMILY_RV770) 699ad43ddacSmrg target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX; 700ad43ddacSmrg else 701ad43ddacSmrg target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX; 702ad43ddacSmrg 703ad43ddacSmrg /* wait for lane set to complete */ 704ad43ddacSmrg link_width_cntl = INREG(target_reg); 705ad43ddacSmrg while (link_width_cntl == 0xffffffff) 706ad43ddacSmrg link_width_cntl = INREG(target_reg); 707ad43ddacSmrg 708ad43ddacSmrg } else { 709ad43ddacSmrg link_width_cntl = INPCIE(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL); 710ad43ddacSmrg 711ad43ddacSmrg if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == 712ad43ddacSmrg (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) 713ad43ddacSmrg return; 714ad43ddacSmrg 715ad43ddacSmrg link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | 716ad43ddacSmrg RADEON_PCIE_LC_RECONFIG_NOW | 717ad43ddacSmrg RADEON_PCIE_LC_RECONFIG_LATER | 718ad43ddacSmrg RADEON_PCIE_LC_SHORT_RECONFIG_EN); 719ad43ddacSmrg link_width_cntl |= mask; 720ad43ddacSmrg OUTPCIE(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); 721ad43ddacSmrg OUTPCIE(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl | RADEON_PCIE_LC_RECONFIG_NOW); 722ad43ddacSmrg 723ad43ddacSmrg /* wait for lane set to complete */ 724ad43ddacSmrg link_width_cntl = INPCIE(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL); 725ad43ddacSmrg while (link_width_cntl == 0xffffffff) 726ad43ddacSmrg link_width_cntl = INPCIE(pScrn, RADEON_PCIE_LC_LINK_WIDTH_CNTL); 727ad43ddacSmrg 728ad43ddacSmrg } 729ad43ddacSmrg 730ad43ddacSmrg} 731ad43ddacSmrg 732ad43ddacSmrgstatic void 733ad43ddacSmrgRADEONSetClockGating(ScrnInfoPtr pScrn, Bool enable) 734ad43ddacSmrg{ 735ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 736ad43ddacSmrg 737ad43ddacSmrg RADEONWaitForIdleMMIO(pScrn); 738ad43ddacSmrg 739ad43ddacSmrg if (info->ChipFamily >= CHIP_FAMILY_R600) 740ad43ddacSmrg atombios_static_pwrmgt_setup(pScrn, enable); 741ad43ddacSmrg else { 742ad43ddacSmrg if (info->IsAtomBios) { 743ad43ddacSmrg atombios_static_pwrmgt_setup(pScrn, enable); 744ad43ddacSmrg atombios_clk_gating_setup(pScrn, enable); 745ad43ddacSmrg } else if (info->IsMobility) 746ad43ddacSmrg LegacySetClockGating(pScrn, enable); 747ad43ddacSmrg } 748ad43ddacSmrg 749ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Gating %sabled\n", 750ad43ddacSmrg enable ? "En" : "Dis"); 751ad43ddacSmrg} 752ad43ddacSmrg 753ad43ddacSmrgstatic void RADEONSetStaticPowerMode(ScrnInfoPtr pScrn, RADEONPMType type) 754ad43ddacSmrg{ 755ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 756ad43ddacSmrg int i; 757ad43ddacSmrg 758ad43ddacSmrg for (i = 0; i < info->pm.num_modes; i++) { 759ad43ddacSmrg if (info->pm.mode[i].type == type) 760ad43ddacSmrg break; 761ad43ddacSmrg } 762ad43ddacSmrg 763ad43ddacSmrg if (i == info->pm.num_modes) 764ad43ddacSmrg return; 765ad43ddacSmrg 766ad43ddacSmrg if (i == info->pm.current_mode) 767ad43ddacSmrg return; 768ad43ddacSmrg 769ad43ddacSmrg RADEONWaitForIdleMMIO(pScrn); 770ad43ddacSmrg 771ad43ddacSmrg if (info->IsAtomBios) 772ad43ddacSmrg atombios_set_engine_clock(pScrn, info->pm.mode[i].sclk); 773ad43ddacSmrg else 774ad43ddacSmrg RADEONSetEngineClock(pScrn, info->pm.mode[i].sclk); 775ad43ddacSmrg 776ad43ddacSmrg if (info->cardType == CARD_PCIE) 777ad43ddacSmrg RADEONSetPCIELanes(pScrn, info->pm.mode[i].pcie_lanes); 778ad43ddacSmrg 779ad43ddacSmrg info->pm.current_mode = i; 780ad43ddacSmrg 781ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Power Mode Switch\n"); 782ad43ddacSmrg} 783ad43ddacSmrg 784ad43ddacSmrg 785ad43ddacSmrgvoid RADEONPMInit(ScrnInfoPtr pScrn) 786ad43ddacSmrg{ 787ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 788ad43ddacSmrg 789ad43ddacSmrg if (xf86ReturnOptValBool(info->Options, OPTION_CLOCK_GATING, FALSE)) { 790ad43ddacSmrg info->pm.clock_gating_enabled = TRUE; 791ad43ddacSmrg RADEONSetClockGating(pScrn, info->pm.clock_gating_enabled); 792ad43ddacSmrg } else 793ad43ddacSmrg info->pm.clock_gating_enabled = FALSE; 794ad43ddacSmrg 795ad43ddacSmrg info->pm.mode[0].type = POWER_DEFAULT; 796ad43ddacSmrg info->pm.mode[0].sclk = (uint32_t)info->sclk * 100; /* 10 khz */ 797ad43ddacSmrg info->pm.mode[0].mclk = (uint32_t)info->mclk * 100; /* 10 khz */ 798ad43ddacSmrg info->pm.mode[0].pcie_lanes = 16; /* XXX: read back current lane config */ 799ad43ddacSmrg info->pm.current_mode = 0; 800ad43ddacSmrg info->pm.num_modes = 1; 801ad43ddacSmrg 802ad43ddacSmrg if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_PM, FALSE)) { 803ad43ddacSmrg info->pm.dynamic_mode_enabled = TRUE; 804ad43ddacSmrg info->pm.mode[1].type = POWER_LOW; 805ad43ddacSmrg info->pm.mode[1].sclk = info->pm.mode[0].sclk / 4; 806ad43ddacSmrg info->pm.mode[1].mclk = info->pm.mode[0].mclk / 4; 807ad43ddacSmrg info->pm.mode[1].pcie_lanes = 1; 808ad43ddacSmrg 809ad43ddacSmrg info->pm.mode[2].type = POWER_HIGH; 810ad43ddacSmrg info->pm.mode[2].sclk = info->pm.mode[0].sclk; 811ad43ddacSmrg info->pm.mode[2].mclk = info->pm.mode[0].mclk; 812ad43ddacSmrg info->pm.mode[2].pcie_lanes = 16; 813ad43ddacSmrg 814ad43ddacSmrg info->pm.num_modes += 2; 815ad43ddacSmrg 816ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Power Management Enabled\n"); 817ad43ddacSmrg } else { 818ad43ddacSmrg info->pm.dynamic_mode_enabled = FALSE; 819ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Power Management Disabled\n"); 820ad43ddacSmrg } 821ad43ddacSmrg 822ad43ddacSmrg if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_LOW_POWER, FALSE)) { 823ad43ddacSmrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Force Low Power Mode Enabled\n"); 824ad43ddacSmrg info->pm.force_low_power_enabled = TRUE; 825ad43ddacSmrg if (info->pm.dynamic_mode_enabled) { 826ad43ddacSmrg info->pm.mode[2].type = POWER_HIGH; 827ad43ddacSmrg info->pm.mode[2].sclk = info->pm.mode[0].sclk / 2; 828ad43ddacSmrg info->pm.mode[2].mclk = info->pm.mode[0].mclk / 2; 829ad43ddacSmrg info->pm.mode[2].pcie_lanes = 4; 830ad43ddacSmrg } else { 831ad43ddacSmrg info->pm.mode[1].type = POWER_HIGH; 832ad43ddacSmrg info->pm.mode[1].sclk = info->pm.mode[0].sclk / 2; 833ad43ddacSmrg info->pm.mode[1].mclk = info->pm.mode[0].mclk / 2; 834ad43ddacSmrg info->pm.mode[1].pcie_lanes = 4; 835ad43ddacSmrg info->pm.num_modes += 1; 836ad43ddacSmrg } 837ad43ddacSmrg RADEONSetStaticPowerMode(pScrn, POWER_HIGH); 838ad43ddacSmrg } else 839ad43ddacSmrg info->pm.force_low_power_enabled = FALSE; 840ad43ddacSmrg 841ad43ddacSmrg RADEONPMQuirks(pScrn); 842ad43ddacSmrg} 843ad43ddacSmrg 844ad43ddacSmrgvoid RADEONPMEnterVT(ScrnInfoPtr pScrn) 845ad43ddacSmrg{ 846ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 847ad43ddacSmrg 848ad43ddacSmrg if (info->pm.clock_gating_enabled) 849ad43ddacSmrg RADEONSetClockGating(pScrn, info->pm.clock_gating_enabled); 850ad43ddacSmrg RADEONPMQuirks(pScrn); 851ad43ddacSmrg if (info->pm.force_low_power_enabled || info->pm.dynamic_mode_enabled) 852ad43ddacSmrg RADEONSetStaticPowerMode(pScrn, POWER_HIGH); 853ad43ddacSmrg} 854ad43ddacSmrg 855ad43ddacSmrgvoid RADEONPMLeaveVT(ScrnInfoPtr pScrn) 856ad43ddacSmrg{ 857ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 858ad43ddacSmrg 859ad43ddacSmrg if (info->pm.clock_gating_enabled) 860ad43ddacSmrg RADEONSetClockGating(pScrn, FALSE); 861ad43ddacSmrg if (info->pm.force_low_power_enabled || info->pm.dynamic_mode_enabled) 862ad43ddacSmrg RADEONSetStaticPowerMode(pScrn, POWER_DEFAULT); 863ad43ddacSmrg} 864ad43ddacSmrg 865ad43ddacSmrgvoid RADEONPMFini(ScrnInfoPtr pScrn) 866ad43ddacSmrg{ 867ad43ddacSmrg RADEONInfoPtr info = RADEONPTR(pScrn); 868ad43ddacSmrg 869ad43ddacSmrg if (info->pm.clock_gating_enabled) 870ad43ddacSmrg RADEONSetClockGating(pScrn, FALSE); 871ad43ddacSmrg if (info->pm.force_low_power_enabled || info->pm.dynamic_mode_enabled) 872ad43ddacSmrg RADEONSetStaticPowerMode(pScrn, POWER_DEFAULT); 873ad43ddacSmrg} 874ad43ddacSmrg 875ad43ddacSmrgvoid RADEONPMBlockHandler(ScrnInfoPtr pScrn) 876ad43ddacSmrg{ 877ad43ddacSmrg RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 878ad43ddacSmrg 879ad43ddacSmrg if ((!pRADEONEnt->Controller[0]->enabled) && 880ad43ddacSmrg (!pRADEONEnt->Controller[1]->enabled)) 881ad43ddacSmrg RADEONSetStaticPowerMode(pScrn, POWER_LOW); 882ad43ddacSmrg else 883ad43ddacSmrg RADEONSetStaticPowerMode(pScrn, POWER_HIGH); 884ad43ddacSmrg 885ad43ddacSmrg} 886ad43ddacSmrg 887