Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/radeon/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 26 kB image not shown  

Quelle  radeon_clocks.c   Sprache: C

 
/*
 * Copyright 2008 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 * Copyright 2009 Jerome Glisse.
 *
 * 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.
 *
 * Authors: Dave Airlie
 *          Alex Deucher
 *          Jerome Glisse
 */


#include <linux/pci.h>

#include <drm/drm_device.h>
#include <drm/radeon_drm.h>

#include "atom.h"
#include "radeon.h"
#include "radeon_asic.h"
#include "radeon_reg.h"

/* 10 khz */
uint32_t radeon_legacy_get_engine_clock(struct radeon_device *rdev)
{
 struct radeon_pll *spll = &rdev->clock.spll;
 uint32_t fb_div, ref_div, post_div, sclk;

 fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
 fb_div = (fb_div >> RADEON_SPLL_FB_DIV_SHIFT) & RADEON_SPLL_FB_DIV_MASK;
 fb_div <<= 1;
 fb_div *= spll->reference_freq;

 ref_div =
     RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;

 if (ref_div == 0)
  return 0;

 sclk = fb_div / ref_div;

 post_div = RREG32_PLL(RADEON_SCLK_CNTL) & RADEON_SCLK_SRC_SEL_MASK;
 if (post_div == 2)
  sclk >>= 1;
 else if (post_div == 3)
  sclk >>= 2;
 else if (post_div == 4)
  sclk >>= 3;

 return sclk;
}

/* 10 khz */
uint32_t radeon_legacy_get_memory_clock(struct radeon_device *rdev)
{
 struct radeon_pll *mpll = &rdev->clock.mpll;
 uint32_t fb_div, ref_div, post_div, mclk;

 fb_div = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
 fb_div = (fb_div >> RADEON_MPLL_FB_DIV_SHIFT) & RADEON_MPLL_FB_DIV_MASK;
 fb_div <<= 1;
 fb_div *= mpll->reference_freq;

 ref_div =
     RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & RADEON_M_SPLL_REF_DIV_MASK;

 if (ref_div == 0)
  return 0;

 mclk = fb_div / ref_div;

 post_div = RREG32_PLL(RADEON_MCLK_CNTL) & 0x7;
 if (post_div == 2)
  mclk >>= 1;
 else if (post_div == 3)
  mclk >>= 2;
 else if (post_div == 4)
  mclk >>= 3;

 return mclk;
}

#ifdef CONFIG_OF
/*
 * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device
 * tree. Hopefully, ATI OF driver is kind enough to fill these
 */

static bool radeon_read_clocks_OF(struct drm_device *dev)
{
 struct radeon_device *rdev = dev->dev_private;
 struct device_node *dp = rdev->pdev->dev.of_node;
 const u32 *val;
 struct radeon_pll *p1pll = &rdev->clock.p1pll;
 struct radeon_pll *p2pll = &rdev->clock.p2pll;
 struct radeon_pll *spll = &rdev->clock.spll;
 struct radeon_pll *mpll = &rdev->clock.mpll;

 if (dp == NULL)
  return false;
 val = of_get_property(dp, "ATY,RefCLK", NULL);
 if (!val || !*val) {
  pr_warn("radeonfb: No ATY,RefCLK property !\n");
  return false;
 }
 p1pll->reference_freq = p2pll->reference_freq = (*val) / 10;
 p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
 if (p1pll->reference_div < 2)
  p1pll->reference_div = 12;
 p2pll->reference_div = p1pll->reference_div;

 /* These aren't in the device-tree */
 if (rdev->family >= CHIP_R420) {
  p1pll->pll_in_min = 100;
  p1pll->pll_in_max = 1350;
  p1pll->pll_out_min = 20000;
  p1pll->pll_out_max = 50000;
  p2pll->pll_in_min = 100;
  p2pll->pll_in_max = 1350;
  p2pll->pll_out_min = 20000;
  p2pll->pll_out_max = 50000;
 } else {
  p1pll->pll_in_min = 40;
  p1pll->pll_in_max = 500;
  p1pll->pll_out_min = 12500;
  p1pll->pll_out_max = 35000;
  p2pll->pll_in_min = 40;
  p2pll->pll_in_max = 500;
  p2pll->pll_out_min = 12500;
  p2pll->pll_out_max = 35000;
 }
 /* not sure what the max should be in all cases */
 rdev->clock.max_pixel_clock = 35000;

 spll->reference_freq = mpll->reference_freq = p1pll->reference_freq;
 spll->reference_div = mpll->reference_div =
  RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
       RADEON_M_SPLL_REF_DIV_MASK;

 val = of_get_property(dp, "ATY,SCLK", NULL);
 if (val && *val)
  rdev->clock.default_sclk = (*val) / 10;
 else
  rdev->clock.default_sclk =
   radeon_legacy_get_engine_clock(rdev);

 val = of_get_property(dp, "ATY,MCLK", NULL);
 if (val && *val)
  rdev->clock.default_mclk = (*val) / 10;
 else
  rdev->clock.default_mclk =
   radeon_legacy_get_memory_clock(rdev);

 DRM_INFO("Using device-tree clock info\n");

 return true;
}
#else
static bool radeon_read_clocks_OF(struct drm_device *dev)
{
 return false;
}
#endif /* CONFIG_OF */

void radeon_get_clock_info(struct drm_device *dev)
{
 struct radeon_device *rdev = dev->dev_private;
 struct radeon_pll *p1pll = &rdev->clock.p1pll;
 struct radeon_pll *p2pll = &rdev->clock.p2pll;
 struct radeon_pll *dcpll = &rdev->clock.dcpll;
 struct radeon_pll *spll = &rdev->clock.spll;
 struct radeon_pll *mpll = &rdev->clock.mpll;
 int ret;

 if (rdev->is_atom_bios)
  ret = radeon_atom_get_clock_info(dev);
 else
  ret = radeon_combios_get_clock_info(dev);
 if (!ret)
  ret = radeon_read_clocks_OF(dev);

 if (ret) {
  if (p1pll->reference_div < 2) {
   if (!ASIC_IS_AVIVO(rdev)) {
    u32 tmp = RREG32_PLL(RADEON_PPLL_REF_DIV);
    if (ASIC_IS_R300(rdev))
     p1pll->reference_div =
      (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
    else
     p1pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
    if (p1pll->reference_div < 2)
     p1pll->reference_div = 12;
   } else
    p1pll->reference_div = 12;
  }
  if (p2pll->reference_div < 2)
   p2pll->reference_div = 12;
  if (rdev->family < CHIP_RS600) {
   if (spll->reference_div < 2)
    spll->reference_div =
     RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
     RADEON_M_SPLL_REF_DIV_MASK;
  }
  if (mpll->reference_div < 2)
   mpll->reference_div = spll->reference_div;
 } else {
  if (ASIC_IS_AVIVO(rdev)) {
   /* TODO FALLBACK */
  } else {
   DRM_INFO("Using generic clock info\n");

   /* may need to be per card */
   rdev->clock.max_pixel_clock = 35000;

   if (rdev->flags & RADEON_IS_IGP) {
    p1pll->reference_freq = 1432;
    p2pll->reference_freq = 1432;
    spll->reference_freq = 1432;
    mpll->reference_freq = 1432;
   } else {
    p1pll->reference_freq = 2700;
    p2pll->reference_freq = 2700;
    spll->reference_freq = 2700;
    mpll->reference_freq = 2700;
   }
   p1pll->reference_div =
       RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
   if (p1pll->reference_div < 2)
    p1pll->reference_div = 12;
   p2pll->reference_div = p1pll->reference_div;

   if (rdev->family >= CHIP_R420) {
    p1pll->pll_in_min = 100;
    p1pll->pll_in_max = 1350;
    p1pll->pll_out_min = 20000;
    p1pll->pll_out_max = 50000;
    p2pll->pll_in_min = 100;
    p2pll->pll_in_max = 1350;
    p2pll->pll_out_min = 20000;
    p2pll->pll_out_max = 50000;
   } else {
    p1pll->pll_in_min = 40;
    p1pll->pll_in_max = 500;
    p1pll->pll_out_min = 12500;
    p1pll->pll_out_max = 35000;
    p2pll->pll_in_min = 40;
    p2pll->pll_in_max = 500;
    p2pll->pll_out_min = 12500;
    p2pll->pll_out_max = 35000;
   }

   spll->reference_div =
       RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
       RADEON_M_SPLL_REF_DIV_MASK;
   mpll->reference_div = spll->reference_div;
   rdev->clock.default_sclk =
       radeon_legacy_get_engine_clock(rdev);
   rdev->clock.default_mclk =
       radeon_legacy_get_memory_clock(rdev);
  }
 }

 /* pixel clocks */
 if (ASIC_IS_AVIVO(rdev)) {
  p1pll->min_post_div = 2;
  p1pll->max_post_div = 0x7f;
  p1pll->min_frac_feedback_div = 0;
  p1pll->max_frac_feedback_div = 9;
  p2pll->min_post_div = 2;
  p2pll->max_post_div = 0x7f;
  p2pll->min_frac_feedback_div = 0;
  p2pll->max_frac_feedback_div = 9;
 } else {
  p1pll->min_post_div = 1;
  p1pll->max_post_div = 16;
  p1pll->min_frac_feedback_div = 0;
  p1pll->max_frac_feedback_div = 0;
  p2pll->min_post_div = 1;
  p2pll->max_post_div = 12;
  p2pll->min_frac_feedback_div = 0;
  p2pll->max_frac_feedback_div = 0;
 }

 /* dcpll is DCE4 only */
 dcpll->min_post_div = 2;
 dcpll->max_post_div = 0x7f;
 dcpll->min_frac_feedback_div = 0;
 dcpll->max_frac_feedback_div = 9;
 dcpll->min_ref_div = 2;
 dcpll->max_ref_div = 0x3ff;
 dcpll->min_feedback_div = 4;
 dcpll->max_feedback_div = 0xfff;
 dcpll->best_vco = 0;

 p1pll->min_ref_div = 2;
 p1pll->max_ref_div = 0x3ff;
 p1pll->min_feedback_div = 4;
 p1pll->max_feedback_div = 0x7ff;
 p1pll->best_vco = 0;

 p2pll->min_ref_div = 2;
 p2pll->max_ref_div = 0x3ff;
 p2pll->min_feedback_div = 4;
 p2pll->max_feedback_div = 0x7ff;
 p2pll->best_vco = 0;

 /* system clock */
 spll->min_post_div = 1;
 spll->max_post_div = 1;
 spll->min_ref_div = 2;
 spll->max_ref_div = 0xff;
 spll->min_feedback_div = 4;
 spll->max_feedback_div = 0xff;
 spll->best_vco = 0;

 /* memory clock */
 mpll->min_post_div = 1;
 mpll->max_post_div = 1;
 mpll->min_ref_div = 2;
 mpll->max_ref_div = 0xff;
 mpll->min_feedback_div = 4;
 mpll->max_feedback_div = 0xff;
 mpll->best_vco = 0;

 if (!rdev->clock.default_sclk)
  rdev->clock.default_sclk = radeon_get_engine_clock(rdev);
 if ((!rdev->clock.default_mclk) && rdev->asic->pm.get_memory_clock)
  rdev->clock.default_mclk = radeon_get_memory_clock(rdev);

 rdev->pm.current_sclk = rdev->clock.default_sclk;
 rdev->pm.current_mclk = rdev->clock.default_mclk;

}

/* 10 khz */
static uint32_t calc_eng_mem_clock(struct radeon_device *rdev,
       uint32_t req_clock,
       int *fb_div, int *post_div)
{
 struct radeon_pll *spll = &rdev->clock.spll;
 int ref_div = spll->reference_div;

 if (!ref_div)
  ref_div =
      RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) &
      RADEON_M_SPLL_REF_DIV_MASK;

 if (req_clock < 15000) {
  *post_div = 8;
  req_clock *= 8;
 } else if (req_clock < 30000) {
  *post_div = 4;
  req_clock *= 4;
 } else if (req_clock < 60000) {
  *post_div = 2;
  req_clock *= 2;
 } else
  *post_div = 1;

 req_clock *= ref_div;
 req_clock += spll->reference_freq;
 req_clock /= (2 * spll->reference_freq);

 *fb_div = req_clock & 0xff;

 req_clock = (req_clock & 0xffff) << 1;
 req_clock *= spll->reference_freq;
 req_clock /= ref_div;
 req_clock /= *post_div;

 return req_clock;
}

/* 10 khz */
void radeon_legacy_set_engine_clock(struct radeon_device *rdev,
        uint32_t eng_clock)
{
 uint32_t tmp;
 int fb_div, post_div;

 /* XXX: wait for idle */

 eng_clock = calc_eng_mem_clock(rdev, eng_clock, &fb_div, &post_div);

 tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
 tmp &= ~RADEON_DONT_USE_XTALIN;
 WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);

 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
 tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
 WREG32_PLL(RADEON_SCLK_CNTL, tmp);

 udelay(10);

 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
 tmp |= RADEON_SPLL_SLEEP;
 WREG32_PLL(RADEON_SPLL_CNTL, tmp);

 udelay(2);

 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
 tmp |= RADEON_SPLL_RESET;
 WREG32_PLL(RADEON_SPLL_CNTL, tmp);

 udelay(200);

 tmp = RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV);
 tmp &= ~(RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT);
 tmp |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT;
 WREG32_PLL(RADEON_M_SPLL_REF_FB_DIV, tmp);

 /* XXX: verify on different asics */
 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
 tmp &= ~RADEON_SPLL_PVG_MASK;
 if ((eng_clock * post_div) >= 90000)
  tmp |= (0x7 << RADEON_SPLL_PVG_SHIFT);
 else
  tmp |= (0x4 << RADEON_SPLL_PVG_SHIFT);
 WREG32_PLL(RADEON_SPLL_CNTL, tmp);

 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
 tmp &= ~RADEON_SPLL_SLEEP;
 WREG32_PLL(RADEON_SPLL_CNTL, tmp);

 udelay(2);

 tmp = RREG32_PLL(RADEON_SPLL_CNTL);
 tmp &= ~RADEON_SPLL_RESET;
 WREG32_PLL(RADEON_SPLL_CNTL, tmp);

 udelay(200);

 tmp = RREG32_PLL(RADEON_SCLK_CNTL);
 tmp &= ~RADEON_SCLK_SRC_SEL_MASK;
 switch (post_div) {
 case 1:
 default:
  tmp |= 1;
  break;
 case 2:
  tmp |= 2;
  break;
 case 4:
  tmp |= 3;
  break;
 case 8:
  tmp |= 4;
  break;
 }
 WREG32_PLL(RADEON_SCLK_CNTL, tmp);

 udelay(20);

 tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
 tmp |= RADEON_DONT_USE_XTALIN;
 WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);

 udelay(10);
}

void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
{
 uint32_t tmp;

 if (enable) {
  if (rdev->flags & RADEON_SINGLE_CRTC) {
   tmp = RREG32_PLL(RADEON_SCLK_CNTL);
   if ((RREG32(RADEON_CONFIG_CNTL) &
        RADEON_CFG_ATI_REV_ID_MASK) >
       RADEON_CFG_ATI_REV_A13) {
    tmp &=
        ~(RADEON_SCLK_FORCE_CP |
          RADEON_SCLK_FORCE_RB);
   }
   tmp &=
       ~(RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1 |
         RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_SE |
         RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
         RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
         RADEON_SCLK_FORCE_TDM);
   WREG32_PLL(RADEON_SCLK_CNTL, tmp);
  } else if (ASIC_IS_R300(rdev)) {
   if ((rdev->family == CHIP_RS400) ||
       (rdev->family == CHIP_RS480)) {
    tmp = RREG32_PLL(RADEON_SCLK_CNTL);
    tmp &=
        ~(RADEON_SCLK_FORCE_DISP2 |
          RADEON_SCLK_FORCE_CP |
          RADEON_SCLK_FORCE_HDP |
          RADEON_SCLK_FORCE_DISP1 |
          RADEON_SCLK_FORCE_TOP |
          RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
          | RADEON_SCLK_FORCE_IDCT |
          RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
          | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
          | R300_SCLK_FORCE_US |
          RADEON_SCLK_FORCE_TV_SCLK |
          R300_SCLK_FORCE_SU |
          RADEON_SCLK_FORCE_OV0);
    tmp |= RADEON_DYN_STOP_LAT_MASK;
    tmp |=
        RADEON_SCLK_FORCE_TOP |
        RADEON_SCLK_FORCE_VIP;
    WREG32_PLL(RADEON_SCLK_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
    tmp &= ~RADEON_SCLK_MORE_FORCEON;
    tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
    WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
    tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
     RADEON_PIXCLK_DAC_ALWAYS_ONb);
    WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
    tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
     RADEON_PIX2CLK_DAC_ALWAYS_ONb |
     RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
     R300_DVOCLK_ALWAYS_ONb |
     RADEON_PIXCLK_BLEND_ALWAYS_ONb |
     RADEON_PIXCLK_GV_ALWAYS_ONb |
     R300_PIXCLK_DVO_ALWAYS_ONb |
     RADEON_PIXCLK_LVDS_ALWAYS_ONb |
     RADEON_PIXCLK_TMDS_ALWAYS_ONb |
     R300_PIXCLK_TRANS_ALWAYS_ONb |
     R300_PIXCLK_TVO_ALWAYS_ONb |
     R300_P2G2CLK_ALWAYS_ONb |
     R300_P2G2CLK_DAC_ALWAYS_ONb);
    WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
   } else if (rdev->family >= CHIP_RV350) {
    tmp = RREG32_PLL(R300_SCLK_CNTL2);
    tmp &= ~(R300_SCLK_FORCE_TCL |
      R300_SCLK_FORCE_GA |
      R300_SCLK_FORCE_CBA);
    tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
     R300_SCLK_GA_MAX_DYN_STOP_LAT |
     R300_SCLK_CBA_MAX_DYN_STOP_LAT);
    WREG32_PLL(R300_SCLK_CNTL2, tmp);

    tmp = RREG32_PLL(RADEON_SCLK_CNTL);
    tmp &=
        ~(RADEON_SCLK_FORCE_DISP2 |
          RADEON_SCLK_FORCE_CP |
          RADEON_SCLK_FORCE_HDP |
          RADEON_SCLK_FORCE_DISP1 |
          RADEON_SCLK_FORCE_TOP |
          RADEON_SCLK_FORCE_E2 | R300_SCLK_FORCE_VAP
          | RADEON_SCLK_FORCE_IDCT |
          RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR
          | R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX
          | R300_SCLK_FORCE_US |
          RADEON_SCLK_FORCE_TV_SCLK |
          R300_SCLK_FORCE_SU |
          RADEON_SCLK_FORCE_OV0);
    tmp |= RADEON_DYN_STOP_LAT_MASK;
    WREG32_PLL(RADEON_SCLK_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
    tmp &= ~RADEON_SCLK_MORE_FORCEON;
    tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
    WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
    tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
     RADEON_PIXCLK_DAC_ALWAYS_ONb);
    WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
    tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
     RADEON_PIX2CLK_DAC_ALWAYS_ONb |
     RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
     R300_DVOCLK_ALWAYS_ONb |
     RADEON_PIXCLK_BLEND_ALWAYS_ONb |
     RADEON_PIXCLK_GV_ALWAYS_ONb |
     R300_PIXCLK_DVO_ALWAYS_ONb |
     RADEON_PIXCLK_LVDS_ALWAYS_ONb |
     RADEON_PIXCLK_TMDS_ALWAYS_ONb |
     R300_PIXCLK_TRANS_ALWAYS_ONb |
     R300_PIXCLK_TVO_ALWAYS_ONb |
     R300_P2G2CLK_ALWAYS_ONb |
     R300_P2G2CLK_DAC_ALWAYS_ONb);
    WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);

    tmp = RREG32_PLL(RADEON_MCLK_MISC);
    tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
     RADEON_IO_MCLK_DYN_ENABLE);
    WREG32_PLL(RADEON_MCLK_MISC, tmp);

    tmp = RREG32_PLL(RADEON_MCLK_CNTL);
    tmp |= (RADEON_FORCEON_MCLKA |
     RADEON_FORCEON_MCLKB);

    tmp &= ~(RADEON_FORCEON_YCLKA |
      RADEON_FORCEON_YCLKB |
      RADEON_FORCEON_MC);

    /* Some releases of vbios have set DISABLE_MC_MCLKA
   and DISABLE_MC_MCLKB bits in the vbios table.  Setting these
   bits will cause H/W hang when reading video memory with dynamic clocking
   enabled. */

    if ((tmp & R300_DISABLE_MC_MCLKA) &&
        (tmp & R300_DISABLE_MC_MCLKB)) {
     /* If both bits are set, then check the active channels */
     tmp = RREG32_PLL(RADEON_MCLK_CNTL);
     if (rdev->mc.vram_width == 64) {
      if (RREG32(RADEON_MEM_CNTL) &
          R300_MEM_USE_CD_CH_ONLY)
       tmp &=
           ~R300_DISABLE_MC_MCLKB;
      else
       tmp &=
           ~R300_DISABLE_MC_MCLKA;
     } else {
      tmp &= ~(R300_DISABLE_MC_MCLKA |
        R300_DISABLE_MC_MCLKB);
     }
    }

    WREG32_PLL(RADEON_MCLK_CNTL, tmp);
   } else {
    tmp = RREG32_PLL(RADEON_SCLK_CNTL);
    tmp &= ~(R300_SCLK_FORCE_VAP);
    tmp |= RADEON_SCLK_FORCE_CP;
    WREG32_PLL(RADEON_SCLK_CNTL, tmp);
    mdelay(15);

    tmp = RREG32_PLL(R300_SCLK_CNTL2);
    tmp &= ~(R300_SCLK_FORCE_TCL |
      R300_SCLK_FORCE_GA |
      R300_SCLK_FORCE_CBA);
    WREG32_PLL(R300_SCLK_CNTL2, tmp);
   }
  } else {
   tmp = RREG32_PLL(RADEON_CLK_PWRMGT_CNTL);

   tmp &= ~(RADEON_ACTIVE_HILO_LAT_MASK |
     RADEON_DISP_DYN_STOP_LAT_MASK |
     RADEON_DYN_STOP_MODE_MASK);

   tmp |= (RADEON_ENGIN_DYNCLK_MODE |
    (0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
   WREG32_PLL(RADEON_CLK_PWRMGT_CNTL, tmp);
   mdelay(15);

   tmp = RREG32_PLL(RADEON_CLK_PIN_CNTL);
   tmp |= RADEON_SCLK_DYN_START_CNTL;
   WREG32_PLL(RADEON_CLK_PIN_CNTL, tmp);
   mdelay(15);

   /* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
   to lockup randomly, leave them as set by BIOS.
 */

   tmp = RREG32_PLL(RADEON_SCLK_CNTL);
   /*tmp &= RADEON_SCLK_SRC_SEL_MASK; */
   tmp &= ~RADEON_SCLK_FORCEON_MASK;

   /*RAGE_6::A11 A12 A12N1 A13, RV250::A11 A12, R300 */
   if (((rdev->family == CHIP_RV250) &&
        ((RREG32(RADEON_CONFIG_CNTL) &
          RADEON_CFG_ATI_REV_ID_MASK) <
         RADEON_CFG_ATI_REV_A13))
       || ((rdev->family == CHIP_RV100)
    &&
    ((RREG32(RADEON_CONFIG_CNTL) &
      RADEON_CFG_ATI_REV_ID_MASK) <=
     RADEON_CFG_ATI_REV_A13))) {
    tmp |= RADEON_SCLK_FORCE_CP;
    tmp |= RADEON_SCLK_FORCE_VIP;
   }

   WREG32_PLL(RADEON_SCLK_CNTL, tmp);

   if ((rdev->family == CHIP_RV200) ||
       (rdev->family == CHIP_RV250) ||
       (rdev->family == CHIP_RV280)) {
    tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
    tmp &= ~RADEON_SCLK_MORE_FORCEON;

    /* RV200::A11 A12 RV250::A11 A12 */
    if (((rdev->family == CHIP_RV200) ||
         (rdev->family == CHIP_RV250)) &&
        ((RREG32(RADEON_CONFIG_CNTL) &
          RADEON_CFG_ATI_REV_ID_MASK) <
         RADEON_CFG_ATI_REV_A13)) {
     tmp |= RADEON_SCLK_MORE_FORCEON;
    }
    WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
    mdelay(15);
   }

   /* RV200::A11 A12, RV250::A11 A12 */
   if (((rdev->family == CHIP_RV200) ||
        (rdev->family == CHIP_RV250)) &&
       ((RREG32(RADEON_CONFIG_CNTL) &
         RADEON_CFG_ATI_REV_ID_MASK) <
        RADEON_CFG_ATI_REV_A13)) {
    tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
    tmp |= RADEON_TCL_BYPASS_DISABLE;
    WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
   }
   mdelay(15);

   /*enable dynamic mode for display clocks (PIXCLK and PIX2CLK) */
   tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
   tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
    RADEON_PIX2CLK_DAC_ALWAYS_ONb |
    RADEON_PIXCLK_BLEND_ALWAYS_ONb |
    RADEON_PIXCLK_GV_ALWAYS_ONb |
    RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
    RADEON_PIXCLK_LVDS_ALWAYS_ONb |
    RADEON_PIXCLK_TMDS_ALWAYS_ONb);

   WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
   mdelay(15);

   tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
   tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
    RADEON_PIXCLK_DAC_ALWAYS_ONb);

   WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
   mdelay(15);
  }
 } else {
  /* Turn everything OFF (ForceON to everything) */
  if (rdev->flags & RADEON_SINGLE_CRTC) {
   tmp = RREG32_PLL(RADEON_SCLK_CNTL);
   tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_HDP |
    RADEON_SCLK_FORCE_DISP1 | RADEON_SCLK_FORCE_TOP
    | RADEON_SCLK_FORCE_E2 | RADEON_SCLK_FORCE_SE |
    RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_VIP |
    RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
    RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
    RADEON_SCLK_FORCE_RB);
   WREG32_PLL(RADEON_SCLK_CNTL, tmp);
  } else if ((rdev->family == CHIP_RS400) ||
      (rdev->family == CHIP_RS480)) {
   tmp = RREG32_PLL(RADEON_SCLK_CNTL);
   tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
    RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
    | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
    R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
    RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
    R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
    R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
    R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
   WREG32_PLL(RADEON_SCLK_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
   tmp |= RADEON_SCLK_MORE_FORCEON;
   WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
   tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
     RADEON_PIXCLK_DAC_ALWAYS_ONb |
     R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
   WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
   tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
     RADEON_PIX2CLK_DAC_ALWAYS_ONb |
     RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
     R300_DVOCLK_ALWAYS_ONb |
     RADEON_PIXCLK_BLEND_ALWAYS_ONb |
     RADEON_PIXCLK_GV_ALWAYS_ONb |
     R300_PIXCLK_DVO_ALWAYS_ONb |
     RADEON_PIXCLK_LVDS_ALWAYS_ONb |
     RADEON_PIXCLK_TMDS_ALWAYS_ONb |
     R300_PIXCLK_TRANS_ALWAYS_ONb |
     R300_PIXCLK_TVO_ALWAYS_ONb |
     R300_P2G2CLK_ALWAYS_ONb |
     R300_P2G2CLK_DAC_ALWAYS_ONb |
     R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
   WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
  } else if (rdev->family >= CHIP_RV350) {
   /* for RV350/M10, no delays are required. */
   tmp = RREG32_PLL(R300_SCLK_CNTL2);
   tmp |= (R300_SCLK_FORCE_TCL |
    R300_SCLK_FORCE_GA | R300_SCLK_FORCE_CBA);
   WREG32_PLL(R300_SCLK_CNTL2, tmp);

   tmp = RREG32_PLL(RADEON_SCLK_CNTL);
   tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
    RADEON_SCLK_FORCE_HDP | RADEON_SCLK_FORCE_DISP1
    | RADEON_SCLK_FORCE_TOP | RADEON_SCLK_FORCE_E2 |
    R300_SCLK_FORCE_VAP | RADEON_SCLK_FORCE_IDCT |
    RADEON_SCLK_FORCE_VIP | R300_SCLK_FORCE_SR |
    R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
    R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
    R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
   WREG32_PLL(RADEON_SCLK_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
   tmp |= RADEON_SCLK_MORE_FORCEON;
   WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_MCLK_CNTL);
   tmp |= (RADEON_FORCEON_MCLKA |
    RADEON_FORCEON_MCLKB |
    RADEON_FORCEON_YCLKA |
    RADEON_FORCEON_YCLKB | RADEON_FORCEON_MC);
   WREG32_PLL(RADEON_MCLK_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
   tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
     RADEON_PIXCLK_DAC_ALWAYS_ONb |
     R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
   WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);

   tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
   tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
     RADEON_PIX2CLK_DAC_ALWAYS_ONb |
     RADEON_DISP_TVOUT_PIXCLK_TV_ALWAYS_ONb |
     R300_DVOCLK_ALWAYS_ONb |
     RADEON_PIXCLK_BLEND_ALWAYS_ONb |
     RADEON_PIXCLK_GV_ALWAYS_ONb |
     R300_PIXCLK_DVO_ALWAYS_ONb |
     RADEON_PIXCLK_LVDS_ALWAYS_ONb |
     RADEON_PIXCLK_TMDS_ALWAYS_ONb |
     R300_PIXCLK_TRANS_ALWAYS_ONb |
     R300_PIXCLK_TVO_ALWAYS_ONb |
     R300_P2G2CLK_ALWAYS_ONb |
     R300_P2G2CLK_DAC_ALWAYS_ONb |
     R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
   WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
  } else {
   tmp = RREG32_PLL(RADEON_SCLK_CNTL);
   tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
   tmp |= RADEON_SCLK_FORCE_SE;

   if (rdev->flags & RADEON_SINGLE_CRTC) {
    tmp |= (RADEON_SCLK_FORCE_RB |
     RADEON_SCLK_FORCE_TDM |
     RADEON_SCLK_FORCE_TAM |
     RADEON_SCLK_FORCE_PB |
     RADEON_SCLK_FORCE_RE |
     RADEON_SCLK_FORCE_VIP |
     RADEON_SCLK_FORCE_IDCT |
     RADEON_SCLK_FORCE_TOP |
     RADEON_SCLK_FORCE_DISP1 |
     RADEON_SCLK_FORCE_DISP2 |
     RADEON_SCLK_FORCE_HDP);
   } else if ((rdev->family == CHIP_R300) ||
       (rdev->family == CHIP_R350)) {
    tmp |= (RADEON_SCLK_FORCE_HDP |
     RADEON_SCLK_FORCE_DISP1 |
     RADEON_SCLK_FORCE_DISP2 |
     RADEON_SCLK_FORCE_TOP |
     RADEON_SCLK_FORCE_IDCT |
     RADEON_SCLK_FORCE_VIP);
   }
   WREG32_PLL(RADEON_SCLK_CNTL, tmp);

   mdelay(16);

   if ((rdev->family == CHIP_R300) ||
       (rdev->family == CHIP_R350)) {
    tmp = RREG32_PLL(R300_SCLK_CNTL2);
    tmp |= (R300_SCLK_FORCE_TCL |
     R300_SCLK_FORCE_GA |
     R300_SCLK_FORCE_CBA);
    WREG32_PLL(R300_SCLK_CNTL2, tmp);
    mdelay(16);
   }

   if (rdev->flags & RADEON_IS_IGP) {
    tmp = RREG32_PLL(RADEON_MCLK_CNTL);
    tmp &= ~(RADEON_FORCEON_MCLKA |
      RADEON_FORCEON_YCLKA);
    WREG32_PLL(RADEON_MCLK_CNTL, tmp);
    mdelay(16);
   }

   if ((rdev->family == CHIP_RV200) ||
       (rdev->family == CHIP_RV250) ||
       (rdev->family == CHIP_RV280)) {
    tmp = RREG32_PLL(RADEON_SCLK_MORE_CNTL);
    tmp |= RADEON_SCLK_MORE_FORCEON;
    WREG32_PLL(RADEON_SCLK_MORE_CNTL, tmp);
    mdelay(16);
   }

   tmp = RREG32_PLL(RADEON_PIXCLKS_CNTL);
   tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
     RADEON_PIX2CLK_DAC_ALWAYS_ONb |
     RADEON_PIXCLK_BLEND_ALWAYS_ONb |
     RADEON_PIXCLK_GV_ALWAYS_ONb |
     RADEON_PIXCLK_DIG_TMDS_ALWAYS_ONb |
     RADEON_PIXCLK_LVDS_ALWAYS_ONb |
     RADEON_PIXCLK_TMDS_ALWAYS_ONb);

   WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
   mdelay(16);

   tmp = RREG32_PLL(RADEON_VCLK_ECP_CNTL);
   tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
     RADEON_PIXCLK_DAC_ALWAYS_ONb);
   WREG32_PLL(RADEON_VCLK_ECP_CNTL, tmp);
  }
 }
}


Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.