1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2008 Advanced Micro Devices, Inc. 3254885Sdumbbell * Copyright 2008 Red Hat Inc. 4254885Sdumbbell * Copyright 2009 Jerome Glisse. 5254885Sdumbbell * 6254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 7254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 8254885Sdumbbell * to deal in the Software without restriction, including without limitation 9254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 11254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 12254885Sdumbbell * 13254885Sdumbbell * The above copyright notice and this permission notice shall be included in 14254885Sdumbbell * all copies or substantial portions of the Software. 15254885Sdumbbell * 16254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 23254885Sdumbbell * 24254885Sdumbbell * Authors: Dave Airlie 25254885Sdumbbell * Alex Deucher 26254885Sdumbbell * Jerome Glisse 27254885Sdumbbell */ 28254885Sdumbbell 29254885Sdumbbell#include <sys/cdefs.h> 30254885Sdumbbell__FBSDID("$FreeBSD$"); 31254885Sdumbbell 32254885Sdumbbell#include <dev/drm2/drmP.h> 33254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h> 34254885Sdumbbell#include "radeon_reg.h" 35254885Sdumbbell#include "radeon.h" 36254885Sdumbbell#include "radeon_asic.h" 37254885Sdumbbell#include "atom.h" 38254885Sdumbbell 39254885Sdumbbell/* 10 khz */ 40254885Sdumbbelluint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev) 41254885Sdumbbell{ 42254885Sdumbbell struct radeon_pll *spll = &rdev->clock.spll; 43254885Sdumbbell uint32_t fb_div, ref_div, post_div, sclk; 44254885Sdumbbell 45254885Sdumbbell fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV); 46254885Sdumbbell fb_div = (fb_div >> RADEON_SPLL_FB_DIV_SHIFT) & RADEON_SPLL_FB_DIV_MASK; 47254885Sdumbbell fb_div <<= 1; 48254885Sdumbbell fb_div *= spll->reference_freq; 49254885Sdumbbell 50254885Sdumbbell ref_div = 51254885Sdumbbell RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; 52254885Sdumbbell 53254885Sdumbbell if (ref_div == 0) 54254885Sdumbbell return 0; 55254885Sdumbbell 56254885Sdumbbell sclk = fb_div / ref_div; 57254885Sdumbbell 58254885Sdumbbell post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK; 59254885Sdumbbell if (post_div == 2) 60254885Sdumbbell sclk >>= 1; 61254885Sdumbbell else if (post_div == 3) 62254885Sdumbbell sclk >>= 2; 63254885Sdumbbell else if (post_div == 4) 64254885Sdumbbell sclk >>= 3; 65254885Sdumbbell 66254885Sdumbbell return sclk; 67254885Sdumbbell} 68254885Sdumbbell 69254885Sdumbbell/* 10 khz */ 70254885Sdumbbelluint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev) 71254885Sdumbbell{ 72254885Sdumbbell struct radeon_pll *mpll = &rdev->clock.mpll; 73254885Sdumbbell uint32_t fb_div, ref_div, post_div, mclk; 74254885Sdumbbell 75254885Sdumbbell fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV); 76254885Sdumbbell fb_div = (fb_div >> RADEON_MPLL_FB_DIV_SHIFT) & RADEON_MPLL_FB_DIV_MASK; 77254885Sdumbbell fb_div <<= 1; 78254885Sdumbbell fb_div *= mpll->reference_freq; 79254885Sdumbbell 80254885Sdumbbell ref_div = 81254885Sdumbbell RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK; 82254885Sdumbbell 83254885Sdumbbell if (ref_div == 0) 84254885Sdumbbell return 0; 85254885Sdumbbell 86254885Sdumbbell mclk = fb_div / ref_div; 87254885Sdumbbell 88254885Sdumbbell post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7; 89254885Sdumbbell if (post_div == 2) 90254885Sdumbbell mclk >>= 1; 91254885Sdumbbell else if (post_div == 3) 92254885Sdumbbell mclk >>= 2; 93254885Sdumbbell else if (post_div == 4) 94254885Sdumbbell mclk >>= 3; 95254885Sdumbbell 96254885Sdumbbell return mclk; 97254885Sdumbbell} 98254885Sdumbbell 99254885Sdumbbell#ifdef CONFIG_OF 100254885Sdumbbell/* 101254885Sdumbbell * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device 102254885Sdumbbell * tree. Hopefully, ATI OF driver is kind enough to fill these 103254885Sdumbbell */ 104254885Sdumbbellstatic bool radeon_read_clocks_OF(struct drm_device *dev) 105254885Sdumbbell{ 106254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 107254885Sdumbbell struct device_node *dp = rdev->pdev->dev.of_node; 108254885Sdumbbell const u32 *val; 109254885Sdumbbell struct radeon_pll *p1pll = &rdev->clock.p1pll; 110254885Sdumbbell struct radeon_pll *p2pll = &rdev->clock.p2pll; 111254885Sdumbbell struct radeon_pll *spll = &rdev->clock.spll; 112254885Sdumbbell struct radeon_pll *mpll = &rdev->clock.mpll; 113254885Sdumbbell 114254885Sdumbbell if (dp == NULL) 115254885Sdumbbell return false; 116254885Sdumbbell val = of_get_property(dp, "ATY,RefCLK", NULL); 117254885Sdumbbell if (!val || !*val) { 118254885Sdumbbell printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n"); 119254885Sdumbbell return false; 120254885Sdumbbell } 121254885Sdumbbell p1pll->reference_freq = p2pll->reference_freq = (*val) / 10; 122254885Sdumbbell p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; 123254885Sdumbbell if (p1pll->reference_div < 2) 124254885Sdumbbell p1pll->reference_div = 12; 125254885Sdumbbell p2pll->reference_div = p1pll->reference_div; 126254885Sdumbbell 127254885Sdumbbell /* These aren't in the device-tree */ 128254885Sdumbbell if (rdev->family >= CHIP_R420) { 129254885Sdumbbell p1pll->pll_in_min = 100; 130254885Sdumbbell p1pll->pll_in_max = 1350; 131254885Sdumbbell p1pll->pll_out_min = 20000; 132254885Sdumbbell p1pll->pll_out_max = 50000; 133254885Sdumbbell p2pll->pll_in_min = 100; 134254885Sdumbbell p2pll->pll_in_max = 1350; 135254885Sdumbbell p2pll->pll_out_min = 20000; 136254885Sdumbbell p2pll->pll_out_max = 50000; 137254885Sdumbbell } else { 138254885Sdumbbell p1pll->pll_in_min = 40; 139254885Sdumbbell p1pll->pll_in_max = 500; 140254885Sdumbbell p1pll->pll_out_min = 12500; 141254885Sdumbbell p1pll->pll_out_max = 35000; 142254885Sdumbbell p2pll->pll_in_min = 40; 143254885Sdumbbell p2pll->pll_in_max = 500; 144254885Sdumbbell p2pll->pll_out_min = 12500; 145254885Sdumbbell p2pll->pll_out_max = 35000; 146254885Sdumbbell } 147254885Sdumbbell /* not sure what the max should be in all cases */ 148254885Sdumbbell rdev->clock.max_pixel_clock = 35000; 149254885Sdumbbell 150254885Sdumbbell spll->reference_freq = mpll->reference_freq = p1pll->reference_freq; 151254885Sdumbbell spll->reference_div = mpll->reference_div = 152254885Sdumbbell RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & 153254885Sdumbbell RADEON_M_SPLL_REF_DIV_MASK; 154254885Sdumbbell 155254885Sdumbbell val = of_get_property(dp, "ATY,SCLK", NULL); 156254885Sdumbbell if (val && *val) 157254885Sdumbbell rdev->clock.default_sclk = (*val) / 10; 158254885Sdumbbell else 159254885Sdumbbell rdev->clock.default_sclk = 160254885Sdumbbell radeon_legacy_get_engine_clock(rdev); 161254885Sdumbbell 162254885Sdumbbell val = of_get_property(dp, "ATY,MCLK", NULL); 163254885Sdumbbell if (val && *val) 164254885Sdumbbell rdev->clock.default_mclk = (*val) / 10; 165254885Sdumbbell else 166254885Sdumbbell rdev->clock.default_mclk = 167254885Sdumbbell radeon_legacy_get_memory_clock(rdev); 168254885Sdumbbell 169254885Sdumbbell DRM_INFO("Using device-tree clock info\n"); 170254885Sdumbbell 171254885Sdumbbell return true; 172254885Sdumbbell} 173254885Sdumbbell#else 174254885Sdumbbellstatic bool radeon_read_clocks_OF(struct drm_device *dev) 175254885Sdumbbell{ 176254885Sdumbbell return false; 177254885Sdumbbell} 178254885Sdumbbell#endif /* CONFIG_OF */ 179254885Sdumbbell 180254885Sdumbbellvoid radeon_get_clock_info(struct drm_device *dev) 181254885Sdumbbell{ 182254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 183254885Sdumbbell struct radeon_pll *p1pll = &rdev->clock.p1pll; 184254885Sdumbbell struct radeon_pll *p2pll = &rdev->clock.p2pll; 185254885Sdumbbell struct radeon_pll *dcpll = &rdev->clock.dcpll; 186254885Sdumbbell struct radeon_pll *spll = &rdev->clock.spll; 187254885Sdumbbell struct radeon_pll *mpll = &rdev->clock.mpll; 188254885Sdumbbell int ret; 189254885Sdumbbell 190254885Sdumbbell if (rdev->is_atom_bios) 191254885Sdumbbell ret = radeon_atom_get_clock_info(dev); 192254885Sdumbbell else 193254885Sdumbbell ret = radeon_combios_get_clock_info(dev); 194254885Sdumbbell if (!ret) 195254885Sdumbbell ret = radeon_read_clocks_OF(dev); 196254885Sdumbbell 197254885Sdumbbell if (ret) { 198254885Sdumbbell if (p1pll->reference_div < 2) { 199254885Sdumbbell if (!ASIC_IS_AVIVO(rdev)) { 200254885Sdumbbell u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV); 201254885Sdumbbell if (ASIC_IS_R300(rdev)) 202254885Sdumbbell p1pll->reference_div = 203254885Sdumbbell (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT; 204254885Sdumbbell else 205254885Sdumbbell p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK; 206254885Sdumbbell if (p1pll->reference_div < 2) 207254885Sdumbbell p1pll->reference_div = 12; 208254885Sdumbbell } else 209254885Sdumbbell p1pll->reference_div = 12; 210254885Sdumbbell } 211254885Sdumbbell if (p2pll->reference_div < 2) 212254885Sdumbbell p2pll->reference_div = 12; 213254885Sdumbbell if (rdev->family < CHIP_RS600) { 214254885Sdumbbell if (spll->reference_div < 2) 215254885Sdumbbell spll->reference_div = 216254885Sdumbbell RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & 217254885Sdumbbell RADEON_M_SPLL_REF_DIV_MASK; 218254885Sdumbbell } 219254885Sdumbbell if (mpll->reference_div < 2) 220254885Sdumbbell mpll->reference_div = spll->reference_div; 221254885Sdumbbell } else { 222254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) { 223254885Sdumbbell /* TODO FALLBACK */ 224254885Sdumbbell } else { 225254885Sdumbbell DRM_INFO("Using generic clock info\n"); 226254885Sdumbbell 227254885Sdumbbell /* may need to be per card */ 228254885Sdumbbell rdev->clock.max_pixel_clock = 35000; 229254885Sdumbbell 230254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) { 231254885Sdumbbell p1pll->reference_freq = 1432; 232254885Sdumbbell p2pll->reference_freq = 1432; 233254885Sdumbbell spll->reference_freq = 1432; 234254885Sdumbbell mpll->reference_freq = 1432; 235254885Sdumbbell } else { 236254885Sdumbbell p1pll->reference_freq = 2700; 237254885Sdumbbell p2pll->reference_freq = 2700; 238254885Sdumbbell spll->reference_freq = 2700; 239254885Sdumbbell mpll->reference_freq = 2700; 240254885Sdumbbell } 241254885Sdumbbell p1pll->reference_div = 242254885Sdumbbell RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff; 243254885Sdumbbell if (p1pll->reference_div < 2) 244254885Sdumbbell p1pll->reference_div = 12; 245254885Sdumbbell p2pll->reference_div = p1pll->reference_div; 246254885Sdumbbell 247254885Sdumbbell if (rdev->family >= CHIP_R420) { 248254885Sdumbbell p1pll->pll_in_min = 100; 249254885Sdumbbell p1pll->pll_in_max = 1350; 250254885Sdumbbell p1pll->pll_out_min = 20000; 251254885Sdumbbell p1pll->pll_out_max = 50000; 252254885Sdumbbell p2pll->pll_in_min = 100; 253254885Sdumbbell p2pll->pll_in_max = 1350; 254254885Sdumbbell p2pll->pll_out_min = 20000; 255254885Sdumbbell p2pll->pll_out_max = 50000; 256254885Sdumbbell } else { 257254885Sdumbbell p1pll->pll_in_min = 40; 258254885Sdumbbell p1pll->pll_in_max = 500; 259254885Sdumbbell p1pll->pll_out_min = 12500; 260254885Sdumbbell p1pll->pll_out_max = 35000; 261254885Sdumbbell p2pll->pll_in_min = 40; 262254885Sdumbbell p2pll->pll_in_max = 500; 263254885Sdumbbell p2pll->pll_out_min = 12500; 264254885Sdumbbell p2pll->pll_out_max = 35000; 265254885Sdumbbell } 266254885Sdumbbell 267254885Sdumbbell spll->reference_div = 268254885Sdumbbell RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & 269254885Sdumbbell RADEON_M_SPLL_REF_DIV_MASK; 270254885Sdumbbell mpll->reference_div = spll->reference_div; 271254885Sdumbbell rdev->clock.default_sclk = 272254885Sdumbbell radeon_legacy_get_engine_clock(rdev); 273254885Sdumbbell rdev->clock.default_mclk = 274254885Sdumbbell radeon_legacy_get_memory_clock(rdev); 275254885Sdumbbell } 276254885Sdumbbell } 277254885Sdumbbell 278254885Sdumbbell /* pixel clocks */ 279254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) { 280254885Sdumbbell p1pll->min_post_div = 2; 281254885Sdumbbell p1pll->max_post_div = 0x7f; 282254885Sdumbbell p1pll->min_frac_feedback_div = 0; 283254885Sdumbbell p1pll->max_frac_feedback_div = 9; 284254885Sdumbbell p2pll->min_post_div = 2; 285254885Sdumbbell p2pll->max_post_div = 0x7f; 286254885Sdumbbell p2pll->min_frac_feedback_div = 0; 287254885Sdumbbell p2pll->max_frac_feedback_div = 9; 288254885Sdumbbell } else { 289254885Sdumbbell p1pll->min_post_div = 1; 290254885Sdumbbell p1pll->max_post_div = 16; 291254885Sdumbbell p1pll->min_frac_feedback_div = 0; 292254885Sdumbbell p1pll->max_frac_feedback_div = 0; 293254885Sdumbbell p2pll->min_post_div = 1; 294254885Sdumbbell p2pll->max_post_div = 12; 295254885Sdumbbell p2pll->min_frac_feedback_div = 0; 296254885Sdumbbell p2pll->max_frac_feedback_div = 0; 297254885Sdumbbell } 298254885Sdumbbell 299254885Sdumbbell /* dcpll is DCE4 only */ 300254885Sdumbbell dcpll->min_post_div = 2; 301254885Sdumbbell dcpll->max_post_div = 0x7f; 302254885Sdumbbell dcpll->min_frac_feedback_div = 0; 303254885Sdumbbell dcpll->max_frac_feedback_div = 9; 304254885Sdumbbell dcpll->min_ref_div = 2; 305254885Sdumbbell dcpll->max_ref_div = 0x3ff; 306254885Sdumbbell dcpll->min_feedback_div = 4; 307254885Sdumbbell dcpll->max_feedback_div = 0xfff; 308254885Sdumbbell dcpll->best_vco = 0; 309254885Sdumbbell 310254885Sdumbbell p1pll->min_ref_div = 2; 311254885Sdumbbell p1pll->max_ref_div = 0x3ff; 312254885Sdumbbell p1pll->min_feedback_div = 4; 313254885Sdumbbell p1pll->max_feedback_div = 0x7ff; 314254885Sdumbbell p1pll->best_vco = 0; 315254885Sdumbbell 316254885Sdumbbell p2pll->min_ref_div = 2; 317254885Sdumbbell p2pll->max_ref_div = 0x3ff; 318254885Sdumbbell p2pll->min_feedback_div = 4; 319254885Sdumbbell p2pll->max_feedback_div = 0x7ff; 320254885Sdumbbell p2pll->best_vco = 0; 321254885Sdumbbell 322254885Sdumbbell /* system clock */ 323254885Sdumbbell spll->min_post_div = 1; 324254885Sdumbbell spll->max_post_div = 1; 325254885Sdumbbell spll->min_ref_div = 2; 326254885Sdumbbell spll->max_ref_div = 0xff; 327254885Sdumbbell spll->min_feedback_div = 4; 328254885Sdumbbell spll->max_feedback_div = 0xff; 329254885Sdumbbell spll->best_vco = 0; 330254885Sdumbbell 331254885Sdumbbell /* memory clock */ 332254885Sdumbbell mpll->min_post_div = 1; 333254885Sdumbbell mpll->max_post_div = 1; 334254885Sdumbbell mpll->min_ref_div = 2; 335254885Sdumbbell mpll->max_ref_div = 0xff; 336254885Sdumbbell mpll->min_feedback_div = 4; 337254885Sdumbbell mpll->max_feedback_div = 0xff; 338254885Sdumbbell mpll->best_vco = 0; 339254885Sdumbbell 340254885Sdumbbell if (!rdev->clock.default_sclk) 341254885Sdumbbell rdev->clock.default_sclk = radeon_get_engine_clock(rdev); 342254885Sdumbbell if ((!rdev->clock.default_mclk) && rdev->asic->pm.get_memory_clock) 343254885Sdumbbell rdev->clock.default_mclk = radeon_get_memory_clock(rdev); 344254885Sdumbbell 345254885Sdumbbell rdev->pm.current_sclk = rdev->clock.default_sclk; 346254885Sdumbbell rdev->pm.current_mclk = rdev->clock.default_mclk; 347254885Sdumbbell 348254885Sdumbbell} 349254885Sdumbbell 350254885Sdumbbell/* 10 khz */ 351254885Sdumbbellstatic uint32_t calc_eng_mem_clock(struct radeon_device *rdev, 352254885Sdumbbell uint32_t req_clock, 353254885Sdumbbell int *fb_div, int *post_div) 354254885Sdumbbell{ 355254885Sdumbbell struct radeon_pll *spll = &rdev->clock.spll; 356254885Sdumbbell int ref_div = spll->reference_div; 357254885Sdumbbell 358254885Sdumbbell if (!ref_div) 359254885Sdumbbell ref_div = 360254885Sdumbbell RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & 361254885Sdumbbell RADEON_M_SPLL_REF_DIV_MASK; 362254885Sdumbbell 363254885Sdumbbell if (req_clock < 15000) { 364254885Sdumbbell *post_div = 8; 365254885Sdumbbell req_clock *= 8; 366254885Sdumbbell } else if (req_clock < 30000) { 367254885Sdumbbell *post_div = 4; 368254885Sdumbbell req_clock *= 4; 369254885Sdumbbell } else if (req_clock < 60000) { 370254885Sdumbbell *post_div = 2; 371254885Sdumbbell req_clock *= 2; 372254885Sdumbbell } else 373254885Sdumbbell *post_div = 1; 374254885Sdumbbell 375254885Sdumbbell req_clock *= ref_div; 376254885Sdumbbell req_clock += spll->reference_freq; 377254885Sdumbbell req_clock /= (2 * spll->reference_freq); 378254885Sdumbbell 379254885Sdumbbell *fb_div = req_clock & 0xff; 380254885Sdumbbell 381254885Sdumbbell req_clock = (req_clock & 0xffff) << 1; 382254885Sdumbbell req_clock *= spll->reference_freq; 383254885Sdumbbell req_clock /= ref_div; 384254885Sdumbbell req_clock /= *post_div; 385254885Sdumbbell 386254885Sdumbbell return req_clock; 387254885Sdumbbell} 388254885Sdumbbell 389254885Sdumbbell/* 10 khz */ 390254885Sdumbbellvoid radeon_legacy_set_engine_clock(struct radeon_device *rdev, 391254885Sdumbbell uint32_t eng_clock) 392254885Sdumbbell{ 393254885Sdumbbell uint32_t tmp; 394254885Sdumbbell int fb_div, post_div; 395254885Sdumbbell 396254885Sdumbbell /* XXX: wait for idle */ 397254885Sdumbbell 398254885Sdumbbell eng_clock = calc_eng_mem_clock(rdev, eng_clock, &fb_div, &post_div); 399254885Sdumbbell 400254885Sdumbbell tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); 401254885Sdumbbell tmp &= ~RADEON_DONT_USE_XTALIN; 402254885Sdumbbell WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); 403254885Sdumbbell 404254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 405254885Sdumbbell tmp &= ~RADEON_SCLK_SRC_SEL_MASK; 406254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 407254885Sdumbbell 408280183Sdumbbell udelay(10); 409254885Sdumbbell 410254885Sdumbbell tmp = RREG32_PLL(RADEON_SPLL_CNTL); 411254885Sdumbbell tmp |= RADEON_SPLL_SLEEP; 412254885Sdumbbell WREG32_PLL(RADEON_SPLL_CNTL, tmp); 413254885Sdumbbell 414280183Sdumbbell udelay(2); 415254885Sdumbbell 416254885Sdumbbell tmp = RREG32_PLL(RADEON_SPLL_CNTL); 417254885Sdumbbell tmp |= RADEON_SPLL_RESET; 418254885Sdumbbell WREG32_PLL(RADEON_SPLL_CNTL, tmp); 419254885Sdumbbell 420280183Sdumbbell udelay(200); 421254885Sdumbbell 422254885Sdumbbell tmp = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV); 423254885Sdumbbell tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT); 424254885Sdumbbell tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT; 425254885Sdumbbell WREG32_PLL(RADEON_M_SPLL_REF_FB_DIV, tmp); 426254885Sdumbbell 427254885Sdumbbell /* XXX: verify on different asics */ 428254885Sdumbbell tmp = RREG32_PLL(RADEON_SPLL_CNTL); 429254885Sdumbbell tmp &= ~RADEON_SPLL_PVG_MASK; 430254885Sdumbbell if ((eng_clock * post_div) >= 90000) 431254885Sdumbbell tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT); 432254885Sdumbbell else 433254885Sdumbbell tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT); 434254885Sdumbbell WREG32_PLL(RADEON_SPLL_CNTL, tmp); 435254885Sdumbbell 436254885Sdumbbell tmp = RREG32_PLL(RADEON_SPLL_CNTL); 437254885Sdumbbell tmp &= ~RADEON_SPLL_SLEEP; 438254885Sdumbbell WREG32_PLL(RADEON_SPLL_CNTL, tmp); 439254885Sdumbbell 440280183Sdumbbell udelay(2); 441254885Sdumbbell 442254885Sdumbbell tmp = RREG32_PLL(RADEON_SPLL_CNTL); 443254885Sdumbbell tmp &= ~RADEON_SPLL_RESET; 444254885Sdumbbell WREG32_PLL(RADEON_SPLL_CNTL, tmp); 445254885Sdumbbell 446280183Sdumbbell udelay(200); 447254885Sdumbbell 448254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 449254885Sdumbbell tmp &= ~RADEON_SCLK_SRC_SEL_MASK; 450254885Sdumbbell switch (post_div) { 451254885Sdumbbell case 1: 452254885Sdumbbell default: 453254885Sdumbbell tmp |= 1; 454254885Sdumbbell break; 455254885Sdumbbell case 2: 456254885Sdumbbell tmp |= 2; 457254885Sdumbbell break; 458254885Sdumbbell case 4: 459254885Sdumbbell tmp |= 3; 460254885Sdumbbell break; 461254885Sdumbbell case 8: 462254885Sdumbbell tmp |= 4; 463254885Sdumbbell break; 464254885Sdumbbell } 465254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 466254885Sdumbbell 467280183Sdumbbell udelay(20); 468254885Sdumbbell 469254885Sdumbbell tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); 470254885Sdumbbell tmp |= RADEON_DONT_USE_XTALIN; 471254885Sdumbbell WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); 472254885Sdumbbell 473280183Sdumbbell udelay(10); 474254885Sdumbbell} 475254885Sdumbbell 476254885Sdumbbellvoid radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable) 477254885Sdumbbell{ 478254885Sdumbbell uint32_t tmp; 479254885Sdumbbell 480254885Sdumbbell if (enable) { 481254885Sdumbbell if (rdev->flags & RADEON_SINGLE_CRTC) { 482254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 483254885Sdumbbell if ((RREG32(RADEON_CONFIG_CNTL) & 484254885Sdumbbell RADEON_CFG_ATI_REV_ID_MASK) > 485254885Sdumbbell RADEON_CFG_ATI_REV_A13) { 486254885Sdumbbell tmp &= 487254885Sdumbbell ~(RADEON_SCLK_FORCE_CP | 488254885Sdumbbell RADEON_SCLK_FORCE_RB); 489254885Sdumbbell } 490254885Sdumbbell tmp &= 491254885Sdumbbell ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 | 492254885Sdumbbell RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE | 493254885Sdumbbell RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE | 494254885Sdumbbell RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM | 495254885Sdumbbell RADEON_SCLK_FORCE_TDM); 496254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 497254885Sdumbbell } else if (ASIC_IS_R300(rdev)) { 498254885Sdumbbell if ((rdev->family == CHIP_RS400) || 499254885Sdumbbell (rdev->family == CHIP_RS480)) { 500254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 501254885Sdumbbell tmp &= 502254885Sdumbbell ~(RADEON_SCLK_FORCE_DISP2 | 503254885Sdumbbell RADEON_SCLK_FORCE_CP | 504254885Sdumbbell RADEON_SCLK_FORCE_HDP | 505254885Sdumbbell RADEON_SCLK_FORCE_DISP1 | 506254885Sdumbbell RADEON_SCLK_FORCE_TOP | 507254885Sdumbbell RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP 508254885Sdumbbell | RADEON_SCLK_FORCE_IDCT | 509254885Sdumbbell RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR 510254885Sdumbbell | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX 511254885Sdumbbell | R300_SCLK_FORCE_US | 512254885Sdumbbell RADEON_SCLK_FORCE_TV_SCLK | 513254885Sdumbbell R300_SCLK_FORCE_SU | 514254885Sdumbbell RADEON_SCLK_FORCE_OV0); 515254885Sdumbbell tmp |= RADEON_DYN_STOP_LAT_MASK; 516254885Sdumbbell tmp |= 517254885Sdumbbell RADEON_SCLK_FORCE_TOP | 518254885Sdumbbell RADEON_SCLK_FORCE_VIP; 519254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 520254885Sdumbbell 521254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); 522254885Sdumbbell tmp &= ~RADEON_SCLK_MORE_FORCEON; 523254885Sdumbbell tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; 524254885Sdumbbell WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); 525254885Sdumbbell 526254885Sdumbbell tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 527254885Sdumbbell tmp |= (RADEON_PIXCLK_ALWAYS_ONb | 528254885Sdumbbell RADEON_PIXCLK_DAC_ALWAYS_ONb); 529254885Sdumbbell WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 530254885Sdumbbell 531254885Sdumbbell tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); 532254885Sdumbbell tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | 533254885Sdumbbell RADEON_PIX2CLK_DAC_ALWAYS_ONb | 534254885Sdumbbell RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 535254885Sdumbbell R300_DVOCLK_ALWAYS_ONb | 536254885Sdumbbell RADEON_PIXCLK_BLEND_ALWAYS_ONb | 537254885Sdumbbell RADEON_PIXCLK_GV_ALWAYS_ONb | 538254885Sdumbbell R300_PIXCLK_DVO_ALWAYS_ONb | 539254885Sdumbbell RADEON_PIXCLK_LVDS_ALWAYS_ONb | 540254885Sdumbbell RADEON_PIXCLK_TMDS_ALWAYS_ONb | 541254885Sdumbbell R300_PIXCLK_TRANS_ALWAYS_ONb | 542254885Sdumbbell R300_PIXCLK_TVO_ALWAYS_ONb | 543254885Sdumbbell R300_P2G2CLK_ALWAYS_ONb | 544254885Sdumbbell R300_P2G2CLK_DAC_ALWAYS_ONb); 545254885Sdumbbell WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 546254885Sdumbbell } else if (rdev->family >= CHIP_RV350) { 547254885Sdumbbell tmp = RREG32_PLL(R300_SCLK_CNTL2); 548254885Sdumbbell tmp &= ~(R300_SCLK_FORCE_TCL | 549254885Sdumbbell R300_SCLK_FORCE_GA | 550254885Sdumbbell R300_SCLK_FORCE_CBA); 551254885Sdumbbell tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT | 552254885Sdumbbell R300_SCLK_GA_MAX_DYN_STOP_LAT | 553254885Sdumbbell R300_SCLK_CBA_MAX_DYN_STOP_LAT); 554254885Sdumbbell WREG32_PLL(R300_SCLK_CNTL2, tmp); 555254885Sdumbbell 556254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 557254885Sdumbbell tmp &= 558254885Sdumbbell ~(RADEON_SCLK_FORCE_DISP2 | 559254885Sdumbbell RADEON_SCLK_FORCE_CP | 560254885Sdumbbell RADEON_SCLK_FORCE_HDP | 561254885Sdumbbell RADEON_SCLK_FORCE_DISP1 | 562254885Sdumbbell RADEON_SCLK_FORCE_TOP | 563254885Sdumbbell RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP 564254885Sdumbbell | RADEON_SCLK_FORCE_IDCT | 565254885Sdumbbell RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR 566254885Sdumbbell | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX 567254885Sdumbbell | R300_SCLK_FORCE_US | 568254885Sdumbbell RADEON_SCLK_FORCE_TV_SCLK | 569254885Sdumbbell R300_SCLK_FORCE_SU | 570254885Sdumbbell RADEON_SCLK_FORCE_OV0); 571254885Sdumbbell tmp |= RADEON_DYN_STOP_LAT_MASK; 572254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 573254885Sdumbbell 574254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); 575254885Sdumbbell tmp &= ~RADEON_SCLK_MORE_FORCEON; 576254885Sdumbbell tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT; 577254885Sdumbbell WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); 578254885Sdumbbell 579254885Sdumbbell tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 580254885Sdumbbell tmp |= (RADEON_PIXCLK_ALWAYS_ONb | 581254885Sdumbbell RADEON_PIXCLK_DAC_ALWAYS_ONb); 582254885Sdumbbell WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 583254885Sdumbbell 584254885Sdumbbell tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); 585254885Sdumbbell tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | 586254885Sdumbbell RADEON_PIX2CLK_DAC_ALWAYS_ONb | 587254885Sdumbbell RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 588254885Sdumbbell R300_DVOCLK_ALWAYS_ONb | 589254885Sdumbbell RADEON_PIXCLK_BLEND_ALWAYS_ONb | 590254885Sdumbbell RADEON_PIXCLK_GV_ALWAYS_ONb | 591254885Sdumbbell R300_PIXCLK_DVO_ALWAYS_ONb | 592254885Sdumbbell RADEON_PIXCLK_LVDS_ALWAYS_ONb | 593254885Sdumbbell RADEON_PIXCLK_TMDS_ALWAYS_ONb | 594254885Sdumbbell R300_PIXCLK_TRANS_ALWAYS_ONb | 595254885Sdumbbell R300_PIXCLK_TVO_ALWAYS_ONb | 596254885Sdumbbell R300_P2G2CLK_ALWAYS_ONb | 597254885Sdumbbell R300_P2G2CLK_DAC_ALWAYS_ONb); 598254885Sdumbbell WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 599254885Sdumbbell 600254885Sdumbbell tmp = RREG32_PLL(RADEON_MCLK_MISC); 601254885Sdumbbell tmp |= (RADEON_MC_MCLK_DYN_ENABLE | 602254885Sdumbbell RADEON_IO_MCLK_DYN_ENABLE); 603254885Sdumbbell WREG32_PLL(RADEON_MCLK_MISC, tmp); 604254885Sdumbbell 605254885Sdumbbell tmp = RREG32_PLL(RADEON_MCLK_CNTL); 606254885Sdumbbell tmp |= (RADEON_FORCEON_MCLKA | 607254885Sdumbbell RADEON_FORCEON_MCLKB); 608254885Sdumbbell 609254885Sdumbbell tmp &= ~(RADEON_FORCEON_YCLKA | 610254885Sdumbbell RADEON_FORCEON_YCLKB | 611254885Sdumbbell RADEON_FORCEON_MC); 612254885Sdumbbell 613254885Sdumbbell /* Some releases of vbios have set DISABLE_MC_MCLKA 614254885Sdumbbell and DISABLE_MC_MCLKB bits in the vbios table. Setting these 615254885Sdumbbell bits will cause H/W hang when reading video memory with dynamic clocking 616254885Sdumbbell enabled. */ 617254885Sdumbbell if ((tmp & R300_DISABLE_MC_MCLKA) && 618254885Sdumbbell (tmp & R300_DISABLE_MC_MCLKB)) { 619254885Sdumbbell /* If both bits are set, then check the active channels */ 620254885Sdumbbell tmp = RREG32_PLL(RADEON_MCLK_CNTL); 621254885Sdumbbell if (rdev->mc.vram_width == 64) { 622254885Sdumbbell if (RREG32(RADEON_MEM_CNTL) & 623254885Sdumbbell R300_MEM_USE_CD_CH_ONLY) 624254885Sdumbbell tmp &= 625254885Sdumbbell ~R300_DISABLE_MC_MCLKB; 626254885Sdumbbell else 627254885Sdumbbell tmp &= 628254885Sdumbbell ~R300_DISABLE_MC_MCLKA; 629254885Sdumbbell } else { 630254885Sdumbbell tmp &= ~(R300_DISABLE_MC_MCLKA | 631254885Sdumbbell R300_DISABLE_MC_MCLKB); 632254885Sdumbbell } 633254885Sdumbbell } 634254885Sdumbbell 635254885Sdumbbell WREG32_PLL(RADEON_MCLK_CNTL, tmp); 636254885Sdumbbell } else { 637254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 638254885Sdumbbell tmp &= ~(R300_SCLK_FORCE_VAP); 639254885Sdumbbell tmp |= RADEON_SCLK_FORCE_CP; 640254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 641280183Sdumbbell mdelay(15); 642254885Sdumbbell 643254885Sdumbbell tmp = RREG32_PLL(R300_SCLK_CNTL2); 644254885Sdumbbell tmp &= ~(R300_SCLK_FORCE_TCL | 645254885Sdumbbell R300_SCLK_FORCE_GA | 646254885Sdumbbell R300_SCLK_FORCE_CBA); 647254885Sdumbbell WREG32_PLL(R300_SCLK_CNTL2, tmp); 648254885Sdumbbell } 649254885Sdumbbell } else { 650254885Sdumbbell tmp = RREG32_PLL(RADEON_CLK_PWRMGT_CNTL); 651254885Sdumbbell 652254885Sdumbbell tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK | 653254885Sdumbbell RADEON_DISP_DYN_STOP_LAT_MASK | 654254885Sdumbbell RADEON_DYN_STOP_MODE_MASK); 655254885Sdumbbell 656254885Sdumbbell tmp |= (RADEON_ENGIN_DYNCLK_MODE | 657254885Sdumbbell (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT)); 658254885Sdumbbell WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp); 659280183Sdumbbell mdelay(15); 660254885Sdumbbell 661254885Sdumbbell tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL); 662254885Sdumbbell tmp |= RADEON_SCLK_DYN_START_CNTL; 663254885Sdumbbell WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp); 664280183Sdumbbell mdelay(15); 665254885Sdumbbell 666254885Sdumbbell /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 667254885Sdumbbell to lockup randomly, leave them as set by BIOS. 668254885Sdumbbell */ 669254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 670254885Sdumbbell /*tmp &= RADEON_SCLK_SRC_SEL_MASK; */ 671254885Sdumbbell tmp &= ~RADEON_SCLK_FORCEON_MASK; 672254885Sdumbbell 673254885Sdumbbell /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300 */ 674254885Sdumbbell if (((rdev->family == CHIP_RV250) && 675254885Sdumbbell ((RREG32(RADEON_CONFIG_CNTL) & 676254885Sdumbbell RADEON_CFG_ATI_REV_ID_MASK) < 677254885Sdumbbell RADEON_CFG_ATI_REV_A13)) 678254885Sdumbbell || ((rdev->family == CHIP_RV100) 679254885Sdumbbell && 680254885Sdumbbell ((RREG32(RADEON_CONFIG_CNTL) & 681254885Sdumbbell RADEON_CFG_ATI_REV_ID_MASK) <= 682254885Sdumbbell RADEON_CFG_ATI_REV_A13))) { 683254885Sdumbbell tmp |= RADEON_SCLK_FORCE_CP; 684254885Sdumbbell tmp |= RADEON_SCLK_FORCE_VIP; 685254885Sdumbbell } 686254885Sdumbbell 687254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 688254885Sdumbbell 689254885Sdumbbell if ((rdev->family == CHIP_RV200) || 690254885Sdumbbell (rdev->family == CHIP_RV250) || 691254885Sdumbbell (rdev->family == CHIP_RV280)) { 692254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); 693254885Sdumbbell tmp &= ~RADEON_SCLK_MORE_FORCEON; 694254885Sdumbbell 695254885Sdumbbell /* RV200::A11 A12 RV250::A11 A12 */ 696254885Sdumbbell if (((rdev->family == CHIP_RV200) || 697254885Sdumbbell (rdev->family == CHIP_RV250)) && 698254885Sdumbbell ((RREG32(RADEON_CONFIG_CNTL) & 699254885Sdumbbell RADEON_CFG_ATI_REV_ID_MASK) < 700254885Sdumbbell RADEON_CFG_ATI_REV_A13)) { 701254885Sdumbbell tmp |= RADEON_SCLK_MORE_FORCEON; 702254885Sdumbbell } 703254885Sdumbbell WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); 704280183Sdumbbell mdelay(15); 705254885Sdumbbell } 706254885Sdumbbell 707254885Sdumbbell /* RV200::A11 A12, RV250::A11 A12 */ 708254885Sdumbbell if (((rdev->family == CHIP_RV200) || 709254885Sdumbbell (rdev->family == CHIP_RV250)) && 710254885Sdumbbell ((RREG32(RADEON_CONFIG_CNTL) & 711254885Sdumbbell RADEON_CFG_ATI_REV_ID_MASK) < 712254885Sdumbbell RADEON_CFG_ATI_REV_A13)) { 713254885Sdumbbell tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL); 714254885Sdumbbell tmp |= RADEON_TCL_BYPASS_DISABLE; 715254885Sdumbbell WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); 716254885Sdumbbell } 717280183Sdumbbell mdelay(15); 718254885Sdumbbell 719254885Sdumbbell /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */ 720254885Sdumbbell tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); 721254885Sdumbbell tmp |= (RADEON_PIX2CLK_ALWAYS_ONb | 722254885Sdumbbell RADEON_PIX2CLK_DAC_ALWAYS_ONb | 723254885Sdumbbell RADEON_PIXCLK_BLEND_ALWAYS_ONb | 724254885Sdumbbell RADEON_PIXCLK_GV_ALWAYS_ONb | 725254885Sdumbbell RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | 726254885Sdumbbell RADEON_PIXCLK_LVDS_ALWAYS_ONb | 727254885Sdumbbell RADEON_PIXCLK_TMDS_ALWAYS_ONb); 728254885Sdumbbell 729254885Sdumbbell WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 730280183Sdumbbell mdelay(15); 731254885Sdumbbell 732254885Sdumbbell tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 733254885Sdumbbell tmp |= (RADEON_PIXCLK_ALWAYS_ONb | 734254885Sdumbbell RADEON_PIXCLK_DAC_ALWAYS_ONb); 735254885Sdumbbell 736254885Sdumbbell WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 737280183Sdumbbell mdelay(15); 738254885Sdumbbell } 739254885Sdumbbell } else { 740254885Sdumbbell /* Turn everything OFF (ForceON to everything) */ 741254885Sdumbbell if (rdev->flags & RADEON_SINGLE_CRTC) { 742254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 743254885Sdumbbell tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP | 744254885Sdumbbell RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP 745254885Sdumbbell | RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE | 746254885Sdumbbell RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP | 747254885Sdumbbell RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB | 748254885Sdumbbell RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM | 749254885Sdumbbell RADEON_SCLK_FORCE_RB); 750254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 751254885Sdumbbell } else if ((rdev->family == CHIP_RS400) || 752254885Sdumbbell (rdev->family == CHIP_RS480)) { 753254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 754254885Sdumbbell tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | 755254885Sdumbbell RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 756254885Sdumbbell | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | 757254885Sdumbbell R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | 758254885Sdumbbell RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | 759254885Sdumbbell R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | 760254885Sdumbbell R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | 761254885Sdumbbell R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); 762254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 763254885Sdumbbell 764254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); 765254885Sdumbbell tmp |= RADEON_SCLK_MORE_FORCEON; 766254885Sdumbbell WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); 767254885Sdumbbell 768254885Sdumbbell tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 769254885Sdumbbell tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | 770254885Sdumbbell RADEON_PIXCLK_DAC_ALWAYS_ONb | 771254885Sdumbbell R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); 772254885Sdumbbell WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 773254885Sdumbbell 774254885Sdumbbell tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); 775254885Sdumbbell tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | 776254885Sdumbbell RADEON_PIX2CLK_DAC_ALWAYS_ONb | 777254885Sdumbbell RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 778254885Sdumbbell R300_DVOCLK_ALWAYS_ONb | 779254885Sdumbbell RADEON_PIXCLK_BLEND_ALWAYS_ONb | 780254885Sdumbbell RADEON_PIXCLK_GV_ALWAYS_ONb | 781254885Sdumbbell R300_PIXCLK_DVO_ALWAYS_ONb | 782254885Sdumbbell RADEON_PIXCLK_LVDS_ALWAYS_ONb | 783254885Sdumbbell RADEON_PIXCLK_TMDS_ALWAYS_ONb | 784254885Sdumbbell R300_PIXCLK_TRANS_ALWAYS_ONb | 785254885Sdumbbell R300_PIXCLK_TVO_ALWAYS_ONb | 786254885Sdumbbell R300_P2G2CLK_ALWAYS_ONb | 787254885Sdumbbell R300_P2G2CLK_DAC_ALWAYS_ONb | 788254885Sdumbbell R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 789254885Sdumbbell WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 790254885Sdumbbell } else if (rdev->family >= CHIP_RV350) { 791254885Sdumbbell /* for RV350/M10, no delays are required. */ 792254885Sdumbbell tmp = RREG32_PLL(R300_SCLK_CNTL2); 793254885Sdumbbell tmp |= (R300_SCLK_FORCE_TCL | 794254885Sdumbbell R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA); 795254885Sdumbbell WREG32_PLL(R300_SCLK_CNTL2, tmp); 796254885Sdumbbell 797254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 798254885Sdumbbell tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP | 799254885Sdumbbell RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 800254885Sdumbbell | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 | 801254885Sdumbbell R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT | 802254885Sdumbbell RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR | 803254885Sdumbbell R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX | 804254885Sdumbbell R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK | 805254885Sdumbbell R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0); 806254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 807254885Sdumbbell 808254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); 809254885Sdumbbell tmp |= RADEON_SCLK_MORE_FORCEON; 810254885Sdumbbell WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); 811254885Sdumbbell 812254885Sdumbbell tmp = RREG32_PLL(RADEON_MCLK_CNTL); 813254885Sdumbbell tmp |= (RADEON_FORCEON_MCLKA | 814254885Sdumbbell RADEON_FORCEON_MCLKB | 815254885Sdumbbell RADEON_FORCEON_YCLKA | 816254885Sdumbbell RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC); 817254885Sdumbbell WREG32_PLL(RADEON_MCLK_CNTL, tmp); 818254885Sdumbbell 819254885Sdumbbell tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 820254885Sdumbbell tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | 821254885Sdumbbell RADEON_PIXCLK_DAC_ALWAYS_ONb | 822254885Sdumbbell R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); 823254885Sdumbbell WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 824254885Sdumbbell 825254885Sdumbbell tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); 826254885Sdumbbell tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | 827254885Sdumbbell RADEON_PIX2CLK_DAC_ALWAYS_ONb | 828254885Sdumbbell RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb | 829254885Sdumbbell R300_DVOCLK_ALWAYS_ONb | 830254885Sdumbbell RADEON_PIXCLK_BLEND_ALWAYS_ONb | 831254885Sdumbbell RADEON_PIXCLK_GV_ALWAYS_ONb | 832254885Sdumbbell R300_PIXCLK_DVO_ALWAYS_ONb | 833254885Sdumbbell RADEON_PIXCLK_LVDS_ALWAYS_ONb | 834254885Sdumbbell RADEON_PIXCLK_TMDS_ALWAYS_ONb | 835254885Sdumbbell R300_PIXCLK_TRANS_ALWAYS_ONb | 836254885Sdumbbell R300_PIXCLK_TVO_ALWAYS_ONb | 837254885Sdumbbell R300_P2G2CLK_ALWAYS_ONb | 838254885Sdumbbell R300_P2G2CLK_DAC_ALWAYS_ONb | 839254885Sdumbbell R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 840254885Sdumbbell WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 841254885Sdumbbell } else { 842254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_CNTL); 843254885Sdumbbell tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2); 844254885Sdumbbell tmp |= RADEON_SCLK_FORCE_SE; 845254885Sdumbbell 846254885Sdumbbell if (rdev->flags & RADEON_SINGLE_CRTC) { 847254885Sdumbbell tmp |= (RADEON_SCLK_FORCE_RB | 848254885Sdumbbell RADEON_SCLK_FORCE_TDM | 849254885Sdumbbell RADEON_SCLK_FORCE_TAM | 850254885Sdumbbell RADEON_SCLK_FORCE_PB | 851254885Sdumbbell RADEON_SCLK_FORCE_RE | 852254885Sdumbbell RADEON_SCLK_FORCE_VIP | 853254885Sdumbbell RADEON_SCLK_FORCE_IDCT | 854254885Sdumbbell RADEON_SCLK_FORCE_TOP | 855254885Sdumbbell RADEON_SCLK_FORCE_DISP1 | 856254885Sdumbbell RADEON_SCLK_FORCE_DISP2 | 857254885Sdumbbell RADEON_SCLK_FORCE_HDP); 858254885Sdumbbell } else if ((rdev->family == CHIP_R300) || 859254885Sdumbbell (rdev->family == CHIP_R350)) { 860254885Sdumbbell tmp |= (RADEON_SCLK_FORCE_HDP | 861254885Sdumbbell RADEON_SCLK_FORCE_DISP1 | 862254885Sdumbbell RADEON_SCLK_FORCE_DISP2 | 863254885Sdumbbell RADEON_SCLK_FORCE_TOP | 864254885Sdumbbell RADEON_SCLK_FORCE_IDCT | 865254885Sdumbbell RADEON_SCLK_FORCE_VIP); 866254885Sdumbbell } 867254885Sdumbbell WREG32_PLL(RADEON_SCLK_CNTL, tmp); 868254885Sdumbbell 869280183Sdumbbell mdelay(16); 870254885Sdumbbell 871254885Sdumbbell if ((rdev->family == CHIP_R300) || 872254885Sdumbbell (rdev->family == CHIP_R350)) { 873254885Sdumbbell tmp = RREG32_PLL(R300_SCLK_CNTL2); 874254885Sdumbbell tmp |= (R300_SCLK_FORCE_TCL | 875254885Sdumbbell R300_SCLK_FORCE_GA | 876254885Sdumbbell R300_SCLK_FORCE_CBA); 877254885Sdumbbell WREG32_PLL(R300_SCLK_CNTL2, tmp); 878280183Sdumbbell mdelay(16); 879254885Sdumbbell } 880254885Sdumbbell 881254885Sdumbbell if (rdev->flags & RADEON_IS_IGP) { 882254885Sdumbbell tmp = RREG32_PLL(RADEON_MCLK_CNTL); 883254885Sdumbbell tmp &= ~(RADEON_FORCEON_MCLKA | 884254885Sdumbbell RADEON_FORCEON_YCLKA); 885254885Sdumbbell WREG32_PLL(RADEON_MCLK_CNTL, tmp); 886280183Sdumbbell mdelay(16); 887254885Sdumbbell } 888254885Sdumbbell 889254885Sdumbbell if ((rdev->family == CHIP_RV200) || 890254885Sdumbbell (rdev->family == CHIP_RV250) || 891254885Sdumbbell (rdev->family == CHIP_RV280)) { 892254885Sdumbbell tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL); 893254885Sdumbbell tmp |= RADEON_SCLK_MORE_FORCEON; 894254885Sdumbbell WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp); 895280183Sdumbbell mdelay(16); 896254885Sdumbbell } 897254885Sdumbbell 898254885Sdumbbell tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL); 899254885Sdumbbell tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb | 900254885Sdumbbell RADEON_PIX2CLK_DAC_ALWAYS_ONb | 901254885Sdumbbell RADEON_PIXCLK_BLEND_ALWAYS_ONb | 902254885Sdumbbell RADEON_PIXCLK_GV_ALWAYS_ONb | 903254885Sdumbbell RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb | 904254885Sdumbbell RADEON_PIXCLK_LVDS_ALWAYS_ONb | 905254885Sdumbbell RADEON_PIXCLK_TMDS_ALWAYS_ONb); 906254885Sdumbbell 907254885Sdumbbell WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 908280183Sdumbbell mdelay(16); 909254885Sdumbbell 910254885Sdumbbell tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL); 911254885Sdumbbell tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb | 912254885Sdumbbell RADEON_PIXCLK_DAC_ALWAYS_ONb); 913254885Sdumbbell WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp); 914254885Sdumbbell } 915254885Sdumbbell } 916254885Sdumbbell} 917254885Sdumbbell 918