Fill in and make use of more com bios tables on legacy chips
parent
9b79d356c1
commit
f38fff5416
|
@ -428,7 +428,7 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
|
||||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||||
uint16_t pll_info;
|
uint16_t pll_info;
|
||||||
struct radeon_pll *pll = &mode_info->pll;
|
struct radeon_pll *pll = &mode_info->pll;
|
||||||
int rev;
|
int8_t rev;
|
||||||
|
|
||||||
pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
|
pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
|
||||||
if (pll_info) {
|
if (pll_info) {
|
||||||
|
@ -450,17 +450,153 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
|
||||||
pll->xclk = radeon_bios16(dev_priv, pll_info + 0x08);
|
pll->xclk = radeon_bios16(dev_priv, pll_info + 0x08);
|
||||||
|
|
||||||
// sclk/mclk use fixed point
|
// 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;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = encoder->base.dev;
|
||||||
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
|
uint16_t dac_info;
|
||||||
|
uint8_t rev, bg, dac;
|
||||||
|
|
||||||
|
/* first check TV table */
|
||||||
|
dac_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
|
||||||
|
if (dac_info) {
|
||||||
|
rev = radeon_bios8(dev_priv, dac_info + 0x3);
|
||||||
|
if (rev > 4) {
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0xc) & 0xf;
|
||||||
|
dac = radeon_bios8(dev_priv, dac_info + 0xd) & 0xf;
|
||||||
|
encoder->ps2_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0xe) & 0xf;
|
||||||
|
dac = radeon_bios8(dev_priv, dac_info + 0xf) & 0xf;
|
||||||
|
encoder->pal_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0x10) & 0xf;
|
||||||
|
dac = radeon_bios8(dev_priv, dac_info + 0x11) & 0xf;
|
||||||
|
encoder->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (rev > 1) {
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0xc) & 0xf;
|
||||||
|
dac = (radeon_bios8(dev_priv, dac_info + 0xc) >> 4) & 0xf;
|
||||||
|
encoder->ps2_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0xd) & 0xf;
|
||||||
|
dac = (radeon_bios8(dev_priv, dac_info + 0xd) >> 4) & 0xf;
|
||||||
|
encoder->pal_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0xe) & 0xf;
|
||||||
|
dac = (radeon_bios8(dev_priv, dac_info + 0xe) >> 4) & 0xf;
|
||||||
|
encoder->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* then check CRT table */
|
||||||
|
dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE);
|
||||||
|
if (dac_info) {
|
||||||
|
rev = radeon_bios8(dev_priv, dac_info) & 0x3;
|
||||||
|
if (rev < 2) {
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0x3) & 0xf;
|
||||||
|
dac = (radeon_bios8(dev_priv, dac_info + 0x3) >> 4) & 0xf;
|
||||||
|
encoder->ps2_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
encoder->pal_tvdac_adj = encoder->ps2_tvdac_adj;
|
||||||
|
encoder->ntsc_tvdac_adj = encoder->ps2_tvdac_adj;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
bg = radeon_bios8(dev_priv, dac_info + 0x4) & 0xf;
|
||||||
|
dac = radeon_bios8(dev_priv, dac_info + 0x5) & 0xf;
|
||||||
|
encoder->ps2_tvdac_adj = (bg << 16) | (dac << 20);
|
||||||
|
encoder->pal_tvdac_adj = encoder->ps2_tvdac_adj;
|
||||||
|
encoder->ntsc_tvdac_adj = encoder->ps2_tvdac_adj;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool radeon_combios_get_tv_info(struct radeon_encoder *encoder)
|
||||||
|
{
|
||||||
|
struct drm_device *dev = encoder->base.dev;
|
||||||
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
|
uint16_t tv_info;
|
||||||
|
|
||||||
|
tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
|
||||||
|
if (tv_info) {
|
||||||
|
if (radeon_bios8(dev_priv, tv_info + 6) == 'T') {
|
||||||
|
switch (radeon_bios8(dev_priv, tv_info + 7) & 0xf) {
|
||||||
|
case 1:
|
||||||
|
encoder->tv_std = TV_STD_NTSC;
|
||||||
|
DRM_INFO("Default TV standard: NTSC\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
encoder->tv_std = TV_STD_PAL;
|
||||||
|
DRM_INFO("Default TV standard: PAL\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
encoder->tv_std = TV_STD_PAL_M;
|
||||||
|
DRM_INFO("Default TV standard: PAL-M\n");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
encoder->tv_std = TV_STD_PAL_60;
|
||||||
|
DRM_INFO("Default TV standard: PAL-60\n");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
encoder->tv_std = TV_STD_NTSC_J;
|
||||||
|
DRM_INFO("Default TV standard: NTSC-J\n");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
encoder->tv_std = TV_STD_SCART_PAL;
|
||||||
|
DRM_INFO("Default TV standard: SCART-PAL\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
encoder->tv_std = TV_STD_NTSC;
|
||||||
|
DRM_INFO("Unknown TV standard; defaulting to NTSC\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ((radeon_bios8(dev_priv, tv_info + 9) >> 2) & 0x3) {
|
||||||
|
case 0:
|
||||||
|
DRM_INFO("29.498928713 MHz TV ref clk\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
DRM_INFO("28.636360000 MHz TV ref clk\n");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
DRM_INFO("14.318180000 MHz TV ref clk\n");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
DRM_INFO("27.000000000 MHz TV ref clk\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder)
|
bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = encoder->base.dev;
|
struct drm_device *dev = encoder->base.dev;
|
||||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
uint16_t lcd_info;
|
uint16_t lcd_info;
|
||||||
|
uint32_t panel_setup;
|
||||||
char stmp[30];
|
char stmp[30];
|
||||||
int tmp, i;
|
int tmp, i;
|
||||||
|
|
||||||
|
@ -478,9 +614,57 @@ bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder)
|
||||||
|
|
||||||
DRM_INFO("Panel Size %dx%d\n", encoder->panel_xres, encoder->panel_yres);
|
DRM_INFO("Panel Size %dx%d\n", encoder->panel_xres, encoder->panel_yres);
|
||||||
|
|
||||||
encoder->panel_pwr_delay = radeon_bios16(dev_priv, lcd_info + 44);
|
encoder->panel_vcc_delay = radeon_bios16(dev_priv, lcd_info + 44);
|
||||||
if (encoder->panel_pwr_delay > 2000 || encoder->panel_pwr_delay < 0)
|
if (encoder->panel_vcc_delay > 2000 || encoder->panel_vcc_delay < 0)
|
||||||
encoder->panel_pwr_delay = 2000;
|
encoder->panel_vcc_delay = 2000;
|
||||||
|
|
||||||
|
encoder->panel_pwr_delay = radeon_bios16(dev_priv, lcd_info + 0x24);
|
||||||
|
encoder->panel_digon_delay = radeon_bios16(dev_priv, lcd_info + 0x38) & 0xf;
|
||||||
|
encoder->panel_blon_delay = (radeon_bios16(dev_priv, lcd_info + 0x38) >> 4) & 0xf;
|
||||||
|
|
||||||
|
encoder->panel_ref_divider = radeon_bios16(dev_priv, lcd_info + 46);
|
||||||
|
encoder->panel_post_divider = radeon_bios8(dev_priv, lcd_info + 48);
|
||||||
|
encoder->panel_fb_divider = radeon_bios16(dev_priv, lcd_info + 49);
|
||||||
|
if ((encoder->panel_ref_divider != 0) &&
|
||||||
|
(encoder->panel_fb_divider > 3))
|
||||||
|
encoder->use_bios_dividers = true;
|
||||||
|
|
||||||
|
panel_setup = radeon_bios32(dev_priv, lcd_info + 0x39);
|
||||||
|
encoder->lvds_gen_cntl = 0;
|
||||||
|
if (panel_setup & 0x1)
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_PANEL_FORMAT;
|
||||||
|
|
||||||
|
if ((panel_setup >> 4) & 0x1)
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_PANEL_TYPE;
|
||||||
|
|
||||||
|
switch ((panel_setup >> 8) & 0x8) {
|
||||||
|
case 0:
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_NO_FM;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_2_GREY;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_4_GREY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((panel_setup >> 16) & 0x1)
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_FP_POL_LOW;
|
||||||
|
|
||||||
|
if ((panel_setup >> 17) & 0x1)
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_LP_POL_LOW;
|
||||||
|
|
||||||
|
if ((panel_setup >> 18) & 0x1)
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_DTM_POL_LOW;
|
||||||
|
|
||||||
|
if ((panel_setup >> 23) & 0x1)
|
||||||
|
encoder->lvds_gen_cntl |= RADEON_LVDS_BL_CLK_SEL;
|
||||||
|
|
||||||
|
encoder->lvds_gen_cntl |= (panel_setup & 0xf0000000);
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
tmp = radeon_bios16(dev_priv, lcd_info + 64 + i * 2);
|
tmp = radeon_bios16(dev_priv, lcd_info + 64 + i * 2);
|
||||||
|
|
|
@ -356,13 +356,9 @@ static bool radeon_set_crtc1_timing(struct drm_crtc *crtc, struct drm_display_mo
|
||||||
uint32_t tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL);
|
uint32_t tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL);
|
||||||
uint32_t dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2);
|
uint32_t dac2_cntl = RADEON_READ(RADEON_DAC_CNTL2);
|
||||||
uint32_t crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL);
|
uint32_t crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL);
|
||||||
// state->dac2_cntl = info->StatedReg->dac2_cntl;
|
|
||||||
// state->tv_dac_cntl = info->StatedReg->tv_dac_cntl;
|
|
||||||
// state->crtc2_gen_cntl = info->StatedReg->crtc2_gen_cntl;
|
|
||||||
// state->disp_hw_debug = info->StatedReg->disp_hw_debug;
|
|
||||||
|
|
||||||
// state->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
|
dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
|
||||||
// state->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
|
dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
|
||||||
|
|
||||||
/* For CRT on DAC2, don't turn it on if BIOS didn't
|
/* For CRT on DAC2, don't turn it on if BIOS didn't
|
||||||
enable it, even it's detected.
|
enable it, even it's detected.
|
||||||
|
@ -395,19 +391,22 @@ static bool radeon_set_crtc1_timing(struct drm_crtc *crtc, struct drm_display_mo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode, int flags)
|
static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
|
struct drm_encoder *encoder;
|
||||||
uint32_t feedback_div = 0;
|
uint32_t feedback_div = 0;
|
||||||
uint32_t reference_div = 0;
|
uint32_t reference_div = 0;
|
||||||
uint32_t post_divider = 0;
|
uint32_t post_divider = 0;
|
||||||
uint32_t freq = 0;
|
uint32_t freq = 0;
|
||||||
uint8_t pll_gain;
|
uint8_t pll_gain;
|
||||||
|
int pll_flags = RADEON_PLL_LEGACY | RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||||
|
bool use_bios_divs = false;
|
||||||
/* PLL registers */
|
/* PLL registers */
|
||||||
uint32_t ppll_ref_div;
|
uint32_t ppll_ref_div = 0;
|
||||||
uint32_t ppll_div_3;
|
uint32_t ppll_div_3 = 0;
|
||||||
uint32_t htotal_cntl;
|
uint32_t htotal_cntl = 0;
|
||||||
uint32_t vclk_ecp_cntl;
|
uint32_t vclk_ecp_cntl;
|
||||||
|
|
||||||
struct radeon_pll *pll = &dev_priv->mode_info.pll;
|
struct radeon_pll *pll = &dev_priv->mode_info.pll;
|
||||||
|
@ -432,17 +431,29 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0 // TODO
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
|
if (encoder->crtc == crtc) {
|
||||||
ppll_ref_div = info->RefDivider;
|
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
|
||||||
ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
|
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||||
|
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
|
||||||
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
|
|
||||||
|
if (radeon_encoder->use_bios_dividers) {
|
||||||
|
ppll_ref_div = radeon_encoder->panel_ref_divider;
|
||||||
|
ppll_div_3 = (radeon_encoder->panel_fb_divider |
|
||||||
|
(radeon_encoder->panel_post_divider << 16));
|
||||||
htotal_cntl = 0;
|
htotal_cntl = 0;
|
||||||
return;
|
use_bios_divs = true;
|
||||||
|
} else
|
||||||
|
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
radeon_compute_pll(pll, mode->clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
|
|
||||||
|
if (!use_bios_divs) {
|
||||||
|
radeon_compute_pll(pll, mode->clock, &freq, &feedback_div, &reference_div, &post_divider, pll_flags);
|
||||||
|
|
||||||
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
|
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
|
||||||
if (post_div->divider == post_divider)
|
if (post_div->divider == post_divider)
|
||||||
|
@ -460,7 +471,6 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
|
||||||
post_divider);
|
post_divider);
|
||||||
|
|
||||||
ppll_ref_div = reference_div;
|
ppll_ref_div = reference_div;
|
||||||
|
|
||||||
#if defined(__powerpc__) && (0) /* TODO */
|
#if defined(__powerpc__) && (0) /* TODO */
|
||||||
/* apparently programming this otherwise causes a hang??? */
|
/* apparently programming this otherwise causes a hang??? */
|
||||||
if (info->MacModel == RADEON_MAC_IBOOK)
|
if (info->MacModel == RADEON_MAC_IBOOK)
|
||||||
|
@ -468,9 +478,10 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
ppll_div_3 = (feedback_div | (post_div->bitvalue << 16));
|
ppll_div_3 = (feedback_div | (post_div->bitvalue << 16));
|
||||||
|
|
||||||
htotal_cntl = mode->htotal & 0x7;
|
htotal_cntl = mode->htotal & 0x7;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
vclk_ecp_cntl = (RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL) &
|
vclk_ecp_cntl = (RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL) &
|
||||||
~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
|
~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
|
||||||
|
|
||||||
|
@ -783,19 +794,22 @@ static bool radeon_set_crtc2_timing(struct drm_crtc *crtc, struct drm_display_mo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode, int flags)
|
static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
|
struct drm_encoder *encoder;
|
||||||
uint32_t feedback_div = 0;
|
uint32_t feedback_div = 0;
|
||||||
uint32_t reference_div = 0;
|
uint32_t reference_div = 0;
|
||||||
uint32_t post_divider = 0;
|
uint32_t post_divider = 0;
|
||||||
uint32_t freq = 0;
|
uint32_t freq = 0;
|
||||||
uint8_t pll_gain;
|
uint8_t pll_gain;
|
||||||
|
int pll_flags = RADEON_PLL_LEGACY | RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||||
|
bool use_bios_divs = false;
|
||||||
/* PLL2 registers */
|
/* PLL2 registers */
|
||||||
uint32_t p2pll_ref_div;
|
uint32_t p2pll_ref_div = 0;
|
||||||
uint32_t p2pll_div_0;
|
uint32_t p2pll_div_0 = 0;
|
||||||
uint32_t htotal_cntl2;
|
uint32_t htotal_cntl2 = 0;
|
||||||
uint32_t pixclks_cntl;
|
uint32_t pixclks_cntl;
|
||||||
|
|
||||||
struct radeon_pll *pll = &dev_priv->mode_info.pll;
|
struct radeon_pll *pll = &dev_priv->mode_info.pll;
|
||||||
|
@ -819,16 +833,29 @@ static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
|
if (encoder->crtc == crtc) {
|
||||||
p2pll_ref_div = info->RefDivider;
|
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
|
||||||
p2pll_div_0 = info->FeedbackDivider | (info->PostDivider << 16);
|
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
||||||
htotal_cntl2 = 0;
|
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
|
||||||
return;
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
radeon_compute_pll(pll, mode->clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
|
if (radeon_encoder->use_bios_dividers) {
|
||||||
|
p2pll_ref_div = radeon_encoder->panel_ref_divider;
|
||||||
|
p2pll_div_0 = (radeon_encoder->panel_fb_divider |
|
||||||
|
(radeon_encoder->panel_post_divider << 16));
|
||||||
|
htotal_cntl2 = 0;
|
||||||
|
use_bios_divs = true;
|
||||||
|
} else
|
||||||
|
pll_flags |= RADEON_PLL_USE_REF_DIV;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
|
if (!use_bios_divs) {
|
||||||
|
radeon_compute_pll(pll, mode->clock, &freq, &feedback_div, &reference_div, &post_divider, pll_flags);
|
||||||
|
|
||||||
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
|
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
|
||||||
if (post_div->divider == post_divider)
|
if (post_div->divider == post_divider)
|
||||||
|
@ -846,11 +873,11 @@ static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode
|
||||||
post_divider);
|
post_divider);
|
||||||
|
|
||||||
p2pll_ref_div = reference_div;
|
p2pll_ref_div = reference_div;
|
||||||
|
|
||||||
p2pll_div_0 = (feedback_div | (post_div->bitvalue << 16));
|
p2pll_div_0 = (feedback_div | (post_div->bitvalue << 16));
|
||||||
|
|
||||||
htotal_cntl2 = mode->htotal & 0x7;
|
htotal_cntl2 = mode->htotal & 0x7;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pixclks_cntl = ((RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL) &
|
pixclks_cntl = ((RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL) &
|
||||||
~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
|
~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
|
||||||
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
|
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
|
||||||
|
@ -946,22 +973,9 @@ static void radeon_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
int x, int y)
|
int x, int y)
|
||||||
{
|
{
|
||||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||||
struct drm_device *dev = crtc->dev;
|
|
||||||
struct drm_encoder *encoder;
|
|
||||||
int pll_flags = RADEON_PLL_LEGACY | RADEON_PLL_PREFER_LOW_REF_DIV;
|
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
|
|
||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
|
||||||
|
|
||||||
if (encoder->crtc == crtc) {
|
|
||||||
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
|
|
||||||
pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
|
|
||||||
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS)
|
|
||||||
pll_flags |= RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO TV */
|
/* TODO TV */
|
||||||
|
|
||||||
radeon_crtc_set_base(crtc, x, y);
|
radeon_crtc_set_base(crtc, x, y);
|
||||||
|
@ -969,11 +983,11 @@ static void radeon_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
switch(radeon_crtc->crtc_id) {
|
switch(radeon_crtc->crtc_id) {
|
||||||
case 0:
|
case 0:
|
||||||
radeon_set_crtc1_timing(crtc, adjusted_mode);
|
radeon_set_crtc1_timing(crtc, adjusted_mode);
|
||||||
radeon_set_pll1(crtc, adjusted_mode, pll_flags);
|
radeon_set_pll1(crtc, adjusted_mode);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
radeon_set_crtc2_timing(crtc, adjusted_mode);
|
radeon_set_crtc2_timing(crtc, adjusted_mode);
|
||||||
radeon_set_pll2(crtc, adjusted_mode, pll_flags);
|
radeon_set_pll2(crtc, adjusted_mode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,10 +213,20 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
|
||||||
lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL);
|
lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL);
|
||||||
lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
|
lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
|
||||||
RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
|
RADEON_WRITE(RADEON_LVDS_PLL_CNTL, lvds_pll_cntl);
|
||||||
|
|
||||||
|
/* enable lvds, turn on voltage */
|
||||||
lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
|
lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
|
||||||
lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
|
lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
|
||||||
|
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
|
||||||
|
udelay(radeon_encoder->panel_digon_delay * 1000);
|
||||||
|
|
||||||
|
/* enable data */
|
||||||
lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
|
lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
|
||||||
udelay(radeon_encoder->panel_pwr_delay * 1000);
|
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
|
||||||
|
udelay(radeon_encoder->panel_blon_delay * 1000);
|
||||||
|
|
||||||
|
/* enable backlight */
|
||||||
|
lvds_gen_cntl |= RADEON_LVDS_BLON;
|
||||||
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
|
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
|
||||||
break;
|
break;
|
||||||
case DRM_MODE_DPMS_STANDBY:
|
case DRM_MODE_DPMS_STANDBY:
|
||||||
|
@ -226,7 +236,7 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode)
|
||||||
RADEON_WRITE_PLL_P(dev_priv, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
|
RADEON_WRITE_PLL_P(dev_priv, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
|
||||||
lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
|
lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
|
||||||
lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
|
lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
|
||||||
lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
|
lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON);
|
||||||
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
|
RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
|
||||||
RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl);
|
RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl);
|
||||||
break;
|
break;
|
||||||
|
@ -260,6 +270,9 @@ static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder,
|
||||||
|
|
||||||
lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL);
|
lvds_pll_cntl = RADEON_READ(RADEON_LVDS_PLL_CNTL);
|
||||||
lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
|
lvds_pll_cntl &= ~RADEON_LVDS_PLL_EN;
|
||||||
|
if (radeon_encoder->lvds_gen_cntl)
|
||||||
|
lvds_gen_cntl = radeon_encoder->lvds_gen_cntl;
|
||||||
|
else
|
||||||
lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
|
lvds_gen_cntl = RADEON_READ(RADEON_LVDS_GEN_CNTL);
|
||||||
lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
|
lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
|
||||||
lvds_gen_cntl &= ~(RADEON_LVDS_ON |
|
lvds_gen_cntl &= ~(RADEON_LVDS_ON |
|
||||||
|
@ -339,7 +352,6 @@ struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int b
|
||||||
|
|
||||||
drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs);
|
drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs);
|
||||||
|
|
||||||
/* TODO get the LVDS info from the BIOS for panel size etc. */
|
|
||||||
/* get the lvds info from the bios */
|
/* get the lvds info from the bios */
|
||||||
radeon_combios_get_lvds_info(radeon_encoder);
|
radeon_combios_get_lvds_info(radeon_encoder);
|
||||||
|
|
||||||
|
@ -659,6 +671,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, i
|
||||||
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
|
drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
|
||||||
|
|
||||||
radeon_combios_get_tmds_info(radeon_encoder);
|
radeon_combios_get_tmds_info(radeon_encoder);
|
||||||
|
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,6 +906,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
|
||||||
struct drm_device *dev = encoder->dev;
|
struct drm_device *dev = encoder->dev;
|
||||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
||||||
|
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||||
uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0;
|
uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0;
|
||||||
uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0;
|
uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0;
|
||||||
|
|
||||||
|
@ -924,8 +938,8 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
|
||||||
// FIXME TV
|
// FIXME TV
|
||||||
tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
|
tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
|
||||||
RADEON_TV_DAC_NHOLD |
|
RADEON_TV_DAC_NHOLD |
|
||||||
RADEON_TV_DAC_STD_PS2 /*|
|
RADEON_TV_DAC_STD_PS2 |
|
||||||
radeon_encoder->ps2_tvdac_adj*/); // fixme, get from bios
|
radeon_encoder->ps2_tvdac_adj);
|
||||||
|
|
||||||
RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl);
|
||||||
}
|
}
|
||||||
|
@ -1015,8 +1029,9 @@ struct drm_encoder *radeon_encoder_legacy_tv_dac_add(struct drm_device *dev, int
|
||||||
|
|
||||||
drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs);
|
drm_encoder_helper_add(encoder, &radeon_legacy_tv_dac_helper_funcs);
|
||||||
|
|
||||||
/* TODO get the tv dac vals from bios tables */
|
/* get the tv dac vals from bios tables */
|
||||||
//radeon_combios_get_lvds_info(radeon_encoder);
|
radeon_combios_get_tv_info(radeon_encoder);
|
||||||
|
radeon_combios_get_tv_dac_info(radeon_encoder);
|
||||||
|
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,6 +87,17 @@ enum radeon_rmx_type {
|
||||||
RMX_CENTER,
|
RMX_CENTER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum radeon_tv_std {
|
||||||
|
TV_STD_NTSC,
|
||||||
|
TV_STD_PAL,
|
||||||
|
TV_STD_PAL_M,
|
||||||
|
TV_STD_PAL_60,
|
||||||
|
TV_STD_NTSC_J,
|
||||||
|
TV_STD_SCART_PAL,
|
||||||
|
TV_STD_SECAM,
|
||||||
|
TV_STD_PAL_CN,
|
||||||
|
};
|
||||||
|
|
||||||
struct radeon_i2c_bus_rec {
|
struct radeon_i2c_bus_rec {
|
||||||
bool valid;
|
bool valid;
|
||||||
uint32_t mask_clk_reg;
|
uint32_t mask_clk_reg;
|
||||||
|
@ -337,13 +348,33 @@ struct radeon_encoder {
|
||||||
enum radeon_tmds_type tmds;
|
enum radeon_tmds_type tmds;
|
||||||
} type;
|
} type;
|
||||||
int atom_device; /* atom devices */
|
int atom_device; /* atom devices */
|
||||||
|
|
||||||
|
/* preferred mode */
|
||||||
uint32_t panel_xres, panel_yres;
|
uint32_t panel_xres, panel_yres;
|
||||||
uint32_t hoverplus, hsync_width;
|
uint32_t hoverplus, hsync_width;
|
||||||
uint32_t hblank;
|
uint32_t hblank;
|
||||||
uint32_t voverplus, vsync_width;
|
uint32_t voverplus, vsync_width;
|
||||||
uint32_t vblank;
|
uint32_t vblank;
|
||||||
uint32_t panel_pwr_delay;
|
|
||||||
uint32_t dotclock;
|
uint32_t dotclock;
|
||||||
|
|
||||||
|
/* legacy lvds */
|
||||||
|
uint16_t panel_vcc_delay;
|
||||||
|
uint16_t panel_pwr_delay;
|
||||||
|
uint16_t panel_digon_delay;
|
||||||
|
uint16_t panel_blon_delay;
|
||||||
|
uint32_t panel_ref_divider;
|
||||||
|
uint32_t panel_post_divider;
|
||||||
|
uint32_t panel_fb_divider;
|
||||||
|
bool use_bios_dividers;
|
||||||
|
uint32_t lvds_gen_cntl;
|
||||||
|
|
||||||
|
/* legacy tv dac */
|
||||||
|
uint32_t ps2_tvdac_adj;
|
||||||
|
uint32_t ntsc_tvdac_adj;
|
||||||
|
uint32_t pal_tvdac_adj;
|
||||||
|
enum radeon_tv_std tv_std;
|
||||||
|
|
||||||
|
/* legacy int tmds */
|
||||||
struct radeon_tmds_pll tmds_pll[4];
|
struct radeon_tmds_pll tmds_pll[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -351,7 +382,6 @@ struct radeon_connector {
|
||||||
struct drm_connector base;
|
struct drm_connector base;
|
||||||
struct radeon_i2c_chan *ddc_bus;
|
struct radeon_i2c_chan *ddc_bus;
|
||||||
int use_digital;
|
int use_digital;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radeon_framebuffer {
|
struct radeon_framebuffer {
|
||||||
|
@ -407,6 +437,8 @@ extern bool radeon_combios_get_clock_info(struct drm_device *dev);
|
||||||
extern void radeon_get_lvds_info(struct radeon_encoder *encoder);
|
extern void radeon_get_lvds_info(struct radeon_encoder *encoder);
|
||||||
extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
|
extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
|
||||||
extern bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
|
extern bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
|
||||||
|
extern bool radeon_combios_get_tv_info(struct radeon_encoder *encoder);
|
||||||
|
extern bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);
|
||||||
extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
|
||||||
u16 blue, int regno);
|
u16 blue, int regno);
|
||||||
struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev,
|
struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev,
|
||||||
|
|
|
@ -1027,14 +1027,23 @@
|
||||||
# define RADEON_LVDS_DISPLAY_DIS (1 << 1)
|
# define RADEON_LVDS_DISPLAY_DIS (1 << 1)
|
||||||
# define RADEON_LVDS_PANEL_TYPE (1 << 2)
|
# define RADEON_LVDS_PANEL_TYPE (1 << 2)
|
||||||
# define RADEON_LVDS_PANEL_FORMAT (1 << 3)
|
# define RADEON_LVDS_PANEL_FORMAT (1 << 3)
|
||||||
|
# define RADEON_LVDS_NO_FM (0 << 4)
|
||||||
|
# define RADEON_LVDS_2_GREY (1 << 4)
|
||||||
|
# define RADEON_LVDS_4_GREY (2 << 4)
|
||||||
# define RADEON_LVDS_RST_FM (1 << 6)
|
# define RADEON_LVDS_RST_FM (1 << 6)
|
||||||
# define RADEON_LVDS_EN (1 << 7)
|
# define RADEON_LVDS_EN (1 << 7)
|
||||||
# define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8
|
# define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8
|
||||||
# define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8)
|
# define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8)
|
||||||
# define RADEON_LVDS_BL_MOD_EN (1 << 16)
|
# define RADEON_LVDS_BL_MOD_EN (1 << 16)
|
||||||
|
# define RADEON_LVDS_BL_CLK_SEL (1 << 17)
|
||||||
# define RADEON_LVDS_DIGON (1 << 18)
|
# define RADEON_LVDS_DIGON (1 << 18)
|
||||||
# define RADEON_LVDS_BLON (1 << 19)
|
# define RADEON_LVDS_BLON (1 << 19)
|
||||||
|
# define RADEON_LVDS_FP_POL_LOW (1 << 20)
|
||||||
|
# define RADEON_LVDS_LP_POL_LOW (1 << 21)
|
||||||
|
# define RADEON_LVDS_DTM_POL_LOW (1 << 22)
|
||||||
# define RADEON_LVDS_SEL_CRTC2 (1 << 23)
|
# define RADEON_LVDS_SEL_CRTC2 (1 << 23)
|
||||||
|
# define RADEON_LVDS_FPDI_EN (1 << 27)
|
||||||
|
# define RADEON_LVDS_HSYNC_DELAY_SHIFT 28
|
||||||
#define RADEON_LVDS_PLL_CNTL 0x02d4
|
#define RADEON_LVDS_PLL_CNTL 0x02d4
|
||||||
# define RADEON_HSYNC_DELAY_SHIFT 28
|
# define RADEON_HSYNC_DELAY_SHIFT 28
|
||||||
# define RADEON_HSYNC_DELAY_MASK (0xf << 28)
|
# define RADEON_HSYNC_DELAY_MASK (0xf << 28)
|
||||||
|
|
Loading…
Reference in New Issue