Radeon: restructure PLL data

- store pixel clocks, core clock, and memory clocks separately
- grab all pll limits from bios tables
main
Alex Deucher 2008-09-18 15:11:48 -04:00
parent 6d0de5a899
commit e1e782af5d
7 changed files with 231 additions and 92 deletions

View File

@ -163,13 +163,19 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode,
PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
uint32_t sclock = mode->clock;
uint32_t ref_div = 0, fb_div = 0, post_div = 0;
struct radeon_pll *pll;
memset(&spc_param, 0, sizeof(SET_PIXEL_CLOCK_PS_ALLOCATION));
pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
radeon_compute_pll(&dev_priv->mode_info.pll, mode->clock,
&sclock, &fb_div, &ref_div, &post_div, pll_flags);
if (radeon_crtc->crtc_id == 0)
pll = &dev_priv->mode_info.p1pll;
else
pll = &dev_priv->mode_info.p2pll;
radeon_compute_pll(pll, mode->clock, &sclock,
&fb_div, &ref_div, &post_div, pll_flags);
if (radeon_is_avivo(dev_priv)) {
uint32_t ss_cntl;
@ -338,6 +344,8 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc,
if (radeon_is_avivo(dev_priv))
atombios_crtc_set_base(crtc, x, y);
else
radeon_crtc_set_base(crtc, x, y);
atombios_crtc_set_pll(crtc, adjusted_mode, pll_flags);

View File

@ -37,7 +37,7 @@ union atom_supported_devices {
struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1;
};
static inline struct radeon_i2c_bus_rec radeon_lookup_gpio_for_ddc(struct drm_device *dev, uint8_t id)
static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *dev, uint8_t id)
{
struct drm_radeon_private *dev_priv = dev->dev_private;
struct atom_context *ctx = dev_priv->mode_info.atom_context;
@ -160,13 +160,13 @@ bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device
(dev_priv->chip_family == CHIP_RS740)) {
if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX))
mode_info->bios_connector[i].ddc_i2c =
radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
radeon_lookup_gpio(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1);
else
mode_info->bios_connector[i].ddc_i2c =
radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
radeon_lookup_gpio(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
} else
mode_info->bios_connector[i].ddc_i2c =
radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
radeon_lookup_gpio(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
if (i == ATOM_DEVICE_DFP1_INDEX)
mode_info->bios_connector[i].tmds_type = TMDS_INT;
@ -277,32 +277,79 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
union firmware_info *firmware_info;
uint8_t frev, crev;
struct radeon_pll *pll = &mode_info->pll;
struct radeon_pll *p1pll = &mode_info->p1pll;
struct radeon_pll *p2pll = &mode_info->p2pll;
struct radeon_pll *spll = &mode_info->spll;
struct radeon_pll *mpll = &mode_info->mpll;
uint16_t data_offset;
atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset);
firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset);
pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
pll->reference_div = 0;
if (firmware_info) {
/* pixel clocks */
p1pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
p1pll->reference_div = 0;
pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
p1pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output);
p1pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output);
if (pll->pll_out_min == 0) {
if (radeon_is_avivo(dev_priv))
pll->pll_out_min = 64800;
else
pll->pll_out_min = 20000;
if (p1pll->pll_out_min == 0) {
if (radeon_is_avivo(dev_priv))
p1pll->pll_out_min = 64800;
else
p1pll->pll_out_min = 20000;
}
p1pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
p1pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
*p2pll = *p1pll;
/* system clock */
spll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
spll->reference_div = 0;
spll->pll_out_min = le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output);
spll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output);
/* ??? */
if (spll->pll_out_min == 0) {
if (radeon_is_avivo(dev_priv))
spll->pll_out_min = 64800;
else
spll->pll_out_min = 20000;
}
spll->pll_in_min = le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input);
spll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);
/* memory clock */
mpll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock);
mpll->reference_div = 0;
mpll->pll_out_min = le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output);
mpll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output);
/* ??? */
if (mpll->pll_out_min == 0) {
if (radeon_is_avivo(dev_priv))
mpll->pll_out_min = 64800;
else
mpll->pll_out_min = 20000;
}
mpll->pll_in_min = le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input);
mpll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input);
mode_info->sclk = le32_to_cpu(firmware_info->info.ulDefaultEngineClock);
mode_info->mclk = le32_to_cpu(firmware_info->info.ulDefaultMemoryClock);
return true;
}
pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input);
pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input);
pll->xclk = le16_to_cpu(firmware_info->info.usMaxPixelClock);
return true;
return false;
}
@ -322,21 +369,23 @@ void radeon_atombios_get_tmds_info(struct radeon_encoder *encoder)
tmds_info = (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + data_offset);
maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
for (i = 0; i < 4; i++) {
encoder->tmds_pll[i].freq = le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency);
encoder->tmds_pll[i].value = tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f;
encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VCO_Gain & 0x3f << 6);
encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_DutyCycle & 0xf << 12);
encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VoltageSwing & 0xf << 16);
if (tmds_info) {
maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
for (i = 0; i < 4; i++) {
encoder->tmds_pll[i].freq = le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency);
encoder->tmds_pll[i].value = tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f;
encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VCO_Gain & 0x3f << 6);
encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_DutyCycle & 0xf << 12);
encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VoltageSwing & 0xf << 16);
DRM_DEBUG("TMDS PLL From BIOS %u %x\n",
encoder->tmds_pll[i].freq,
encoder->tmds_pll[i].value);
DRM_DEBUG("TMDS PLL From BIOS %u %x\n",
encoder->tmds_pll[i].freq,
encoder->tmds_pll[i].value);
if (maxfreq == encoder->tmds_pll[i].freq) {
encoder->tmds_pll[i].freq = 0xffffffff;
break;
if (maxfreq == encoder->tmds_pll[i].freq) {
encoder->tmds_pll[i].freq = 0xffffffff;
break;
}
}
}
}
@ -360,17 +409,19 @@ void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder)
lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset);
encoder->dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
encoder->panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
encoder->panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
encoder->hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
if (lvds_info) {
encoder->dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10;
encoder->panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive);
encoder->panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive);
encoder->hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time);
encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset);
encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth);
encoder->vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
encoder->voverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
encoder->vsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs);
encoder->vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time);
encoder->voverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset);
encoder->vsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth);
encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs);
}
}
void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable)

View File

@ -73,7 +73,7 @@ enum radeon_combios_table_offset
COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */
COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */
COMBIOS_RAM_RESET_TABLE, /* offset from mem config */
COMBIOS_POWERPLAY_TABLE, /* offset from mobile info */
COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */
COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */
COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */
COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */
@ -325,7 +325,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_com
offset = check_offset;
}
break;
case COMBIOS_POWERPLAY_TABLE: /* offset from mobile info */
case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */
check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE);
if (check_offset) {
check_offset = radeon_bios16(dev_priv, check_offset + 0x11);
@ -427,33 +427,72 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
struct drm_radeon_private *dev_priv = dev->dev_private;
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
uint16_t pll_info;
struct radeon_pll *pll = &mode_info->pll;
struct radeon_pll *p1pll = &mode_info->p1pll;
struct radeon_pll *p2pll = &mode_info->p2pll;
struct radeon_pll *spll = &mode_info->spll;
struct radeon_pll *mpll = &mode_info->mpll;
int8_t rev;
uint16_t sclk, mclk;
pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
if (pll_info) {
rev = radeon_bios8(dev_priv, pll_info);
pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe);
pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10);
pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12);
pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16);
/* pixel clocks */
p1pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe);
p1pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10);
p1pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12);
p1pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16);
if (rev > 9) {
pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36);
pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a);
p1pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36);
p1pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a);
} else {
pll->pll_in_min = 40;
pll->pll_in_max = 500;
p1pll->pll_in_min = 40;
p1pll->pll_in_max = 500;
}
*p2pll = *p1pll;
/* system clock */
spll->reference_freq = radeon_bios16(dev_priv, pll_info + 0x1a);
spll->reference_div = radeon_bios16(dev_priv, pll_info + 0x1c);
spll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x1e);
spll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x22);
if (rev > 10) {
spll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x48);
spll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x4c);
} else {
/* ??? */
spll->pll_in_min = 40;
spll->pll_in_max = 500;
}
pll->xclk = radeon_bios16(dev_priv, pll_info + 0x08);
/* memory clock */
mpll->reference_freq = radeon_bios16(dev_priv, pll_info + 0x26);
mpll->reference_div = radeon_bios16(dev_priv, pll_info + 0x28);
mpll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x2a);
mpll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x2e);
// sclk/mclk use fixed point
//sclk = radeon_bios16(pll_info + 8) / 100.0;
//mclk = radeon_bios16(pll_info + 10) / 100.0;
//if (sclk == 0) sclk = 200;
//if (mclk == 0) mclk = 200;
if (rev > 10) {
mpll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x5a);
mpll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x5e);
} else {
/* ??? */
mpll->pll_in_min = 40;
mpll->pll_in_max = 500;
}
/* default sclk/mclk */
sclk = radeon_bios16(dev_priv, pll_info + 0x8);
mclk = radeon_bios16(dev_priv, pll_info + 0xa);
if (sclk == 0)
sclk = 200;
if (mclk == 0)
mclk = 200;
mode_info->sclk = sclk;
mode_info->mclk = mclk;
return true;
}

View File

@ -396,7 +396,10 @@ void radeon_compute_pll(struct radeon_pll *pll,
(post_div == 7) ||
(post_div == 9) ||
(post_div == 10) ||
(post_div == 11))
(post_div == 11) ||
(post_div == 13) ||
(post_div == 14) ||
(post_div == 15))
continue;
}
@ -475,7 +478,10 @@ void radeon_compute_pll(struct radeon_pll *pll,
void radeon_get_clock_info(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
struct radeon_pll *pll = &dev_priv->mode_info.pll;
struct radeon_pll *p1pll = &dev_priv->mode_info.p1pll;
struct radeon_pll *p2pll = &dev_priv->mode_info.p2pll;
struct radeon_pll *spll = &dev_priv->mode_info.spll;
struct radeon_pll *mpll = &dev_priv->mode_info.mpll;
int ret;
if (dev_priv->is_atom_bios)
@ -484,25 +490,56 @@ void radeon_get_clock_info(struct drm_device *dev)
ret = radeon_combios_get_clock_info(dev);
if (ret) {
if (pll->reference_div < 2) pll->reference_div = 12;
if (p1pll->reference_div < 2)
p1pll->reference_div = 12;
if (p2pll->reference_div < 2)
p2pll->reference_div = 12;
} else {
// TODO FALLBACK
}
/* pixel clocks */
if (radeon_is_avivo(dev_priv)) {
pll->min_post_div = 2;
pll->max_post_div = 0x7f;
p1pll->min_post_div = 2;
p1pll->max_post_div = 0x7f;
p2pll->min_post_div = 2;
p2pll->max_post_div = 0x7f;
} else {
pll->min_post_div = 1;
pll->max_post_div = 12; // 16 on crtc 0??
p1pll->min_post_div = 1;
p1pll->max_post_div = 16;
p2pll->min_post_div = 1;
p2pll->max_post_div = 12;
}
pll->min_ref_div = 2;
pll->max_ref_div = 0x3ff;
pll->min_feedback_div = 4;
pll->max_feedback_div = 0x7ff;
pll->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;
}

View File

@ -409,7 +409,7 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
uint32_t htotal_cntl = 0;
uint32_t vclk_ecp_cntl;
struct radeon_pll *pll = &dev_priv->mode_info.pll;
struct radeon_pll *pll = &dev_priv->mode_info.p1pll;
struct {
int divider;
@ -485,7 +485,7 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
vclk_ecp_cntl = (RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL) &
~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.pll.reference_freq,
pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.p1pll.reference_freq,
ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
@ -812,7 +812,7 @@ static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode
uint32_t htotal_cntl2 = 0;
uint32_t pixclks_cntl;
struct radeon_pll *pll = &dev_priv->mode_info.pll;
struct radeon_pll *pll = &dev_priv->mode_info.p2pll;
struct {
int divider;
@ -882,7 +882,7 @@ static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode
~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.pll.reference_freq,
pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.p2pll.reference_freq,
p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);

View File

@ -161,10 +161,22 @@ struct radeon_pll {
uint32_t best_vco;
};
struct radeon_i2c_chan {
struct drm_device *dev;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo;
struct radeon_i2c_bus_rec rec;
};
struct radeon_mode_info {
struct atom_context *atom_context;
struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR];
struct radeon_pll pll;
struct radeon_pll p1pll;
struct radeon_pll p2pll;
struct radeon_pll spll;
struct radeon_pll mpll;
uint32_t mclk;
uint32_t sclk;
};
struct radeon_crtc {
@ -178,14 +190,6 @@ struct radeon_crtc {
struct drm_mode_set mode_set;
};
struct radeon_i2c_chan {
struct drm_device *dev;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo;
struct radeon_i2c_bus_rec rec;
};
#define RADEON_USE_RMX 1
struct radeon_encoder {
@ -278,6 +282,8 @@ extern void atombios_crtc_mode_set(struct drm_crtc *crtc,
int x, int y);
extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode);
extern void radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y);
extern int radeon_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_file *file_priv,
uint32_t handle,

View File

@ -2506,8 +2506,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
else
dev_priv->flags |= RADEON_IS_PCI;
DRM_DEBUG("%s card detected\n",
((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
@ -2527,7 +2525,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
if (dev_priv->chip_family == CHIP_R300 &&
(RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11)
dev_priv->pll_errata |= CHIP_ERRATA_R300_CG;
if (dev_priv->chip_family == CHIP_RV200 ||
dev_priv->chip_family == CHIP_RS200)
dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS;