Convert COM BIOS to table offset lookup function
parent
5af426a2b2
commit
ae89ced7de
|
@ -30,6 +30,57 @@
|
||||||
|
|
||||||
/* old legacy ATI BIOS routines */
|
/* old legacy ATI BIOS routines */
|
||||||
|
|
||||||
|
/* COMBIOS table offsets */
|
||||||
|
enum radeon_combios_table_offset
|
||||||
|
{
|
||||||
|
/* absolute offset tables */
|
||||||
|
COMBIOS_ASIC_INIT_1_TABLE,
|
||||||
|
COMBIOS_BIOS_SUPPORT_TABLE,
|
||||||
|
COMBIOS_DAC_PROGRAMMING_TABLE,
|
||||||
|
COMBIOS_MAX_COLOR_DEPTH_TABLE,
|
||||||
|
COMBIOS_CRTC_INFO_TABLE,
|
||||||
|
COMBIOS_PLL_INFO_TABLE,
|
||||||
|
COMBIOS_TV_INFO_TABLE,
|
||||||
|
COMBIOS_DFP_INFO_TABLE,
|
||||||
|
COMBIOS_HW_CONFIG_INFO_TABLE,
|
||||||
|
COMBIOS_MULTIMEDIA_INFO_TABLE,
|
||||||
|
COMBIOS_TV_STD_PATCH_TABLE,
|
||||||
|
COMBIOS_LCD_INFO_TABLE,
|
||||||
|
COMBIOS_MOBILE_INFO_TABLE,
|
||||||
|
COMBIOS_PLL_INIT_TABLE,
|
||||||
|
COMBIOS_MEM_CONFIG_TABLE,
|
||||||
|
COMBIOS_SAVE_MASK_TABLE,
|
||||||
|
COMBIOS_HARDCODED_EDID_TABLE,
|
||||||
|
COMBIOS_ASIC_INIT_2_TABLE,
|
||||||
|
COMBIOS_CONNECTOR_INFO_TABLE,
|
||||||
|
COMBIOS_DYN_CLK_1_TABLE,
|
||||||
|
COMBIOS_RESERVED_MEM_TABLE,
|
||||||
|
COMBIOS_EXT_TDMS_INFO_TABLE,
|
||||||
|
COMBIOS_MEM_CLK_INFO_TABLE,
|
||||||
|
COMBIOS_EXT_DAC_INFO_TABLE,
|
||||||
|
COMBIOS_MISC_INFO_TABLE,
|
||||||
|
COMBIOS_CRT_INFO_TABLE,
|
||||||
|
COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE,
|
||||||
|
COMBIOS_COMPONENT_VIDEO_INFO_TABLE,
|
||||||
|
COMBIOS_FAN_SPEED_INFO_TABLE,
|
||||||
|
COMBIOS_OVERDRIVE_INFO_TABLE,
|
||||||
|
COMBIOS_OEM_INFO_TABLE,
|
||||||
|
COMBIOS_DYN_CLK_2_TABLE,
|
||||||
|
COMBIOS_POWER_CONNECTOR_INFO_TABLE,
|
||||||
|
COMBIOS_I2C_INFO_TABLE,
|
||||||
|
/* relative offset tables */
|
||||||
|
COMBIOS_ASIC_INIT_3_TABLE, /* offset from misc info */
|
||||||
|
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_GPIO_INFO_TABLE, /* offset from mobile info */
|
||||||
|
COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */
|
||||||
|
COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */
|
||||||
|
COMBIOS_TMDS_POWER_ON_TABLE, /* offset from tmds power */
|
||||||
|
COMBIOS_TMDS_POWER_OFF_TABLE, /* offset from tmds power */
|
||||||
|
};
|
||||||
|
|
||||||
enum radeon_combios_ddc
|
enum radeon_combios_ddc
|
||||||
{
|
{
|
||||||
DDC_NONE_DETECTED,
|
DDC_NONE_DETECTED,
|
||||||
|
@ -53,6 +104,283 @@ enum radeon_combios_connector
|
||||||
CONNECTOR_UNSUPPORTED_LEGACY
|
CONNECTOR_UNSUPPORTED_LEGACY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_combios_table_offset table)
|
||||||
|
{
|
||||||
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
|
int rev;
|
||||||
|
uint16_t offset = 0, check_offset;
|
||||||
|
|
||||||
|
switch (table) {
|
||||||
|
/* absolute offset tables */
|
||||||
|
case COMBIOS_ASIC_INIT_1_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0xc);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_BIOS_SUPPORT_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x14);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_DAC_PROGRAMMING_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2a);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_MAX_COLOR_DEPTH_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2c);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_CRTC_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x2e);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_PLL_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x30);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_TV_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x32);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_DFP_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x34);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_HW_CONFIG_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x36);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_MULTIMEDIA_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x38);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_TV_STD_PATCH_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x3e);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_LCD_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_MOBILE_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x42);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_PLL_INIT_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x46);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_MEM_CONFIG_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x48);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_SAVE_MASK_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4a);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_HARDCODED_EDID_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4c);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_ASIC_INIT_2_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x4e);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_CONNECTOR_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x50);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_DYN_CLK_1_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x52);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_RESERVED_MEM_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x54);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_EXT_TDMS_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x58);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_MEM_CLK_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5a);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_EXT_DAC_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5c);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_MISC_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x5e);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_CRT_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x60);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x62);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_COMPONENT_VIDEO_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x64);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_FAN_SPEED_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x66);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_OVERDRIVE_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x68);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_OEM_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6a);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_DYN_CLK_2_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6c);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_POWER_CONNECTOR_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x6e);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
case COMBIOS_I2C_INFO_TABLE:
|
||||||
|
check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x70);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
break;
|
||||||
|
/* relative offset tables */
|
||||||
|
case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */
|
||||||
|
check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
|
||||||
|
if (check_offset) {
|
||||||
|
rev = radeon_bios8(dev_priv, check_offset);
|
||||||
|
if (rev > 0) {
|
||||||
|
check_offset = radeon_bios16(dev_priv, check_offset + 0x3);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_ASIC_INIT_4_TABLE: /* offset from misc info */
|
||||||
|
check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
|
||||||
|
if (check_offset) {
|
||||||
|
rev = radeon_bios8(dev_priv, check_offset);
|
||||||
|
if (rev > 0) {
|
||||||
|
check_offset = radeon_bios16(dev_priv, check_offset + 0x5);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_ASIC_INIT_5_TABLE: /* offset from misc info */
|
||||||
|
check_offset = combios_get_table_offset(dev, COMBIOS_MISC_INFO_TABLE);
|
||||||
|
if (check_offset) {
|
||||||
|
rev = radeon_bios8(dev_priv, check_offset);
|
||||||
|
if (rev == 2) {
|
||||||
|
check_offset = radeon_bios16(dev_priv, check_offset + 0x9);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_RAM_RESET_TABLE: /* offset from mem config */
|
||||||
|
check_offset = combios_get_table_offset(dev, COMBIOS_MEM_CONFIG_TABLE);
|
||||||
|
if (check_offset) {
|
||||||
|
while (radeon_bios8(dev_priv, check_offset++));
|
||||||
|
check_offset += 2;
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_POWERPLAY_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);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_GPIO_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 + 0x13);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_LCD_DDC_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 + 0x15);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_TMDS_POWER_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 + 0x17);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_TMDS_POWER_ON_TABLE: /* offset from tmds power */
|
||||||
|
check_offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
|
||||||
|
if (check_offset) {
|
||||||
|
check_offset = radeon_bios16(dev_priv, check_offset + 0x2);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMBIOS_TMDS_POWER_OFF_TABLE: /* offset from tmds power */
|
||||||
|
check_offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_TABLE);
|
||||||
|
if (check_offset) {
|
||||||
|
check_offset = radeon_bios16(dev_priv, check_offset + 0x4);
|
||||||
|
if (check_offset)
|
||||||
|
offset = check_offset;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
|
struct radeon_i2c_bus_rec combios_setup_i2c_bus(int ddc_line)
|
||||||
{
|
{
|
||||||
struct radeon_i2c_bus_rec i2c;
|
struct radeon_i2c_bus_rec i2c;
|
||||||
|
@ -98,125 +426,130 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||||
uint16_t pll_info_block;
|
uint16_t pll_info;
|
||||||
struct radeon_pll *pll = &mode_info->pll;
|
struct radeon_pll *pll = &mode_info->pll;
|
||||||
int rev;
|
int rev;
|
||||||
|
|
||||||
pll_info_block = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x30);
|
pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE);
|
||||||
rev = radeon_bios8(dev_priv, pll_info_block);
|
if (pll_info) {
|
||||||
|
rev = radeon_bios8(dev_priv, pll_info);
|
||||||
|
|
||||||
pll->reference_freq = radeon_bios16(dev_priv, pll_info_block + 0xe);
|
pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe);
|
||||||
pll->reference_div = radeon_bios16(dev_priv, pll_info_block + 0x10);
|
pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10);
|
||||||
pll->pll_out_min = radeon_bios32(dev_priv, pll_info_block + 0x12);
|
pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12);
|
||||||
pll->pll_out_max = radeon_bios32(dev_priv, pll_info_block + 0x16);
|
pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16);
|
||||||
|
|
||||||
if (rev > 9) {
|
if (rev > 9) {
|
||||||
pll->pll_in_min = radeon_bios32(dev_priv, pll_info_block + 0x36);
|
pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36);
|
||||||
pll->pll_in_max = radeon_bios32(dev_priv, pll_info_block + 0x3a);
|
pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a);
|
||||||
} else {
|
} else {
|
||||||
pll->pll_in_min = 40;
|
pll->pll_in_min = 40;
|
||||||
pll->pll_in_max = 500;
|
pll->pll_in_max = 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
pll->xclk = radeon_bios16(dev_priv, pll_info_block + 0x08);
|
pll->xclk = radeon_bios16(dev_priv, pll_info + 0x08);
|
||||||
|
|
||||||
// sclk/mclk use fixed point
|
// sclk/mclk use fixed point
|
||||||
|
|
||||||
return true;
|
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 tmp;
|
uint16_t lcd_info;
|
||||||
char stmp[30];
|
char stmp[30];
|
||||||
int tmp0;
|
int tmp, i;
|
||||||
int i;
|
|
||||||
|
|
||||||
tmp = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40);
|
lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
|
||||||
if (!tmp) {
|
|
||||||
DRM_INFO("No panel info found in BIOS\n");
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (lcd_info) {
|
||||||
for (i = 0; i < 24; i++)
|
for (i = 0; i < 24; i++)
|
||||||
stmp[i] = radeon_bios8(dev_priv, tmp + i + 1);
|
stmp[i] = radeon_bios8(dev_priv, lcd_info + i + 1);
|
||||||
stmp[24] = 0;
|
stmp[24] = 0;
|
||||||
|
|
||||||
DRM_INFO("Panel ID String: %s\n", stmp);
|
DRM_INFO("Panel ID String: %s\n", stmp);
|
||||||
|
|
||||||
encoder->panel_xres = radeon_bios16(dev_priv, tmp + 25);
|
encoder->panel_xres = radeon_bios16(dev_priv, lcd_info + 25);
|
||||||
encoder->panel_yres = radeon_bios16(dev_priv, tmp + 27);
|
encoder->panel_yres = radeon_bios16(dev_priv, lcd_info + 27);
|
||||||
|
|
||||||
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, tmp + 44);
|
encoder->panel_pwr_delay = radeon_bios16(dev_priv, lcd_info + 44);
|
||||||
if (encoder->panel_pwr_delay > 2000 || encoder->panel_pwr_delay < 0)
|
if (encoder->panel_pwr_delay > 2000 || encoder->panel_pwr_delay < 0)
|
||||||
encoder->panel_pwr_delay = 2000;
|
encoder->panel_pwr_delay = 2000;
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
tmp0 = radeon_bios16(dev_priv, tmp + 64 + i * 2);
|
tmp = radeon_bios16(dev_priv, lcd_info + 64 + i * 2);
|
||||||
if (tmp0 == 0) break;
|
if (tmp == 0) break;
|
||||||
|
|
||||||
if ((radeon_bios16(dev_priv, tmp0) == encoder->panel_xres) &&
|
if ((radeon_bios16(dev_priv, tmp) == encoder->panel_xres) &&
|
||||||
(radeon_bios16(dev_priv, tmp0 + 2) == encoder->panel_yres)) {
|
(radeon_bios16(dev_priv, tmp + 2) == encoder->panel_yres)) {
|
||||||
encoder->hblank = (radeon_bios16(dev_priv, tmp0 + 17) -
|
encoder->hblank = (radeon_bios16(dev_priv, tmp + 17) -
|
||||||
radeon_bios16(dev_priv, tmp0 + 19)) * 8;
|
radeon_bios16(dev_priv, tmp + 19)) * 8;
|
||||||
encoder->hoverplus = (radeon_bios16(dev_priv, tmp0 + 21) -
|
encoder->hoverplus = (radeon_bios16(dev_priv, tmp + 21) -
|
||||||
radeon_bios16(dev_priv, tmp0 + 19) - 1) * 8;
|
radeon_bios16(dev_priv, tmp + 19) - 1) * 8;
|
||||||
encoder->hsync_width = radeon_bios8(dev_priv, tmp0 + 23) * 8;
|
encoder->hsync_width = radeon_bios8(dev_priv, tmp + 23) * 8;
|
||||||
|
|
||||||
encoder->vblank = (radeon_bios16(dev_priv, tmp0 + 24) -
|
encoder->vblank = (radeon_bios16(dev_priv, tmp + 24) -
|
||||||
radeon_bios16(dev_priv, tmp0 + 26));
|
radeon_bios16(dev_priv, tmp + 26));
|
||||||
encoder->voverplus = ((radeon_bios16(dev_priv, tmp0 + 28) & 0x7fff) -
|
encoder->voverplus = ((radeon_bios16(dev_priv, tmp + 28) & 0x7fff) -
|
||||||
radeon_bios16(dev_priv, tmp0 + 26));
|
radeon_bios16(dev_priv, tmp + 26));
|
||||||
encoder->vsync_width = ((radeon_bios16(dev_priv, tmp0 + 28) & 0xf800) >> 11);
|
encoder->vsync_width = ((radeon_bios16(dev_priv, tmp + 28) & 0xf800) >> 11);
|
||||||
encoder->dotclock = radeon_bios16(dev_priv, tmp0 + 9) * 10;
|
encoder->dotclock = radeon_bios16(dev_priv, tmp + 9) * 10;
|
||||||
encoder->flags = 0;
|
encoder->flags = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
DRM_INFO("No panel info found in BIOS\n");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
|
bool radeon_combios_get_tmds_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 tmp;
|
uint16_t tmds_info;
|
||||||
int i, n;
|
int i, n;
|
||||||
uint8_t ver;
|
uint8_t ver;
|
||||||
|
|
||||||
tmp = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x34);
|
tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
|
||||||
if (!tmp) {
|
|
||||||
DRM_INFO("No TMDS info found in BIOS\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ver = radeon_bios8(dev_priv, tmp);
|
if (tmds_info) {
|
||||||
|
ver = radeon_bios8(dev_priv, tmds_info);
|
||||||
DRM_INFO("DFP table revision: %d\n", ver);
|
DRM_INFO("DFP table revision: %d\n", ver);
|
||||||
if (ver == 3) {
|
if (ver == 3) {
|
||||||
n = radeon_bios8(dev_priv, tmp + 5) + 1;
|
n = radeon_bios8(dev_priv, tmds_info + 5) + 1;
|
||||||
if (n > 4) n = 4;
|
if (n > 4)
|
||||||
|
n = 4;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
encoder->tmds_pll[i].value = radeon_bios32(dev_priv, tmp+i*10+0x08);
|
encoder->tmds_pll[i].value = radeon_bios32(dev_priv, tmds_info + i * 10 + 0x08);
|
||||||
encoder->tmds_pll[i].freq = radeon_bios16(dev_priv, tmp+i*10+0x10);
|
encoder->tmds_pll[i].freq = radeon_bios16(dev_priv, tmds_info + i * 10 + 0x10);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (ver == 4) {
|
} else if (ver == 4) {
|
||||||
int stride = 0;
|
int stride = 0;
|
||||||
n = radeon_bios8(dev_priv, tmp + 5) + 1;
|
n = radeon_bios8(dev_priv, tmds_info + 5) + 1;
|
||||||
if (n > 4) n = 4;
|
if (n > 4)
|
||||||
|
n = 4;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
encoder->tmds_pll[i].value = radeon_bios32(dev_priv, tmp+stride+0x08);
|
encoder->tmds_pll[i].value = radeon_bios32(dev_priv, tmds_info + stride + 0x08);
|
||||||
encoder->tmds_pll[i].freq = radeon_bios16(dev_priv, tmp+stride+0x10);
|
encoder->tmds_pll[i].freq = radeon_bios16(dev_priv, tmds_info + stride + 0x10);
|
||||||
if (i == 0) stride += 10;
|
if (i == 0)
|
||||||
else stride += 6;
|
stride += 10;
|
||||||
|
else
|
||||||
|
stride += 6;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DRM_INFO("No TMDS info found in BIOS\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,17 +595,17 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_radeon_private *dev_priv = dev->dev_private;
|
struct drm_radeon_private *dev_priv = dev->dev_private;
|
||||||
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
struct radeon_mode_info *mode_info = &dev_priv->mode_info;
|
||||||
uint32_t offset, entry;
|
uint32_t conn_info, entry;
|
||||||
uint16_t tmp0, tmp1, tmp;
|
uint16_t tmp;
|
||||||
enum radeon_combios_ddc ddctype;
|
enum radeon_combios_ddc ddc_type;
|
||||||
enum radeon_combios_connector connector_type;
|
enum radeon_combios_connector connector_type;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DRM_DEBUG("\n");
|
DRM_DEBUG("\n");
|
||||||
offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x50);
|
conn_info = combios_get_table_offset(dev, COMBIOS_CONNECTOR_INFO_TABLE);
|
||||||
if (offset) {
|
if (conn_info) {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
entry = offset + 2 + i * 2;
|
entry = conn_info + 2 + i * 2;
|
||||||
|
|
||||||
if (!radeon_bios16(dev_priv, entry))
|
if (!radeon_bios16(dev_priv, entry))
|
||||||
break;
|
break;
|
||||||
|
@ -311,8 +644,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||||
|
|
||||||
mode_info->bios_connector[i].ddc_i2c.valid = false;
|
mode_info->bios_connector[i].ddc_i2c.valid = false;
|
||||||
|
|
||||||
ddctype = (tmp >> 8) & 0xf;
|
ddc_type = (tmp >> 8) & 0xf;
|
||||||
switch (ddctype) {
|
switch (ddc_type) {
|
||||||
case DDC_MONID:
|
case DDC_MONID:
|
||||||
mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
mode_info->bios_connector[i].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||||
break;
|
break;
|
||||||
|
@ -347,9 +680,8 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||||
radeon_apply_legacy_quirks(dev, i);
|
radeon_apply_legacy_quirks(dev, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DRM_INFO("no connector table found in BIOS\n");
|
uint16_t tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
|
||||||
offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x34);
|
if (tmds_info) {
|
||||||
if (offset) {
|
|
||||||
DRM_DEBUG("Found DFP table, assuming DVI connector\n");
|
DRM_DEBUG("Found DFP table, assuming DVI connector\n");
|
||||||
|
|
||||||
mode_info->bios_connector[0].valid = true;
|
mode_info->bios_connector[0].valid = true;
|
||||||
|
@ -358,44 +690,107 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
|
||||||
mode_info->bios_connector[0].tmds_type = TMDS_INT;
|
mode_info->bios_connector[0].tmds_type = TMDS_INT;
|
||||||
mode_info->bios_connector[0].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
mode_info->bios_connector[0].ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
||||||
} else {
|
} else {
|
||||||
DRM_DEBUG("No table found\n");
|
DRM_DEBUG("No connector info found\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_priv->flags & RADEON_IS_MOBILITY) {
|
if (dev_priv->flags & RADEON_IS_MOBILITY ||
|
||||||
offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x40);
|
dev_priv->chip_family == CHIP_RS400 ||
|
||||||
if (offset) {
|
dev_priv->chip_family == CHIP_RS480) {
|
||||||
|
uint16_t lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE);
|
||||||
|
if (lcd_info) {
|
||||||
|
uint16_t lcd_ddc_info = lcd_ddc_info = combios_get_table_offset(dev, COMBIOS_LCD_DDC_INFO_TABLE);
|
||||||
|
|
||||||
mode_info->bios_connector[4].valid = true;
|
mode_info->bios_connector[4].valid = true;
|
||||||
mode_info->bios_connector[4].connector_type = CONNECTOR_LVDS;
|
mode_info->bios_connector[4].connector_type = CONNECTOR_LVDS;
|
||||||
mode_info->bios_connector[4].dac_type = DAC_NONE;
|
mode_info->bios_connector[4].dac_type = DAC_NONE;
|
||||||
mode_info->bios_connector[4].tmds_type = TMDS_NONE;
|
mode_info->bios_connector[4].tmds_type = TMDS_NONE;
|
||||||
mode_info->bios_connector[4].ddc_i2c.valid = false;
|
mode_info->bios_connector[4].ddc_i2c.valid = false;
|
||||||
|
|
||||||
tmp = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x42);
|
if (lcd_ddc_info) {
|
||||||
if (tmp) {
|
ddc_type = radeon_bios8(dev_priv, lcd_ddc_info + 2);
|
||||||
tmp0 = radeon_bios16(dev_priv, tmp + 0x15);
|
switch(ddc_type) {
|
||||||
if (tmp0) {
|
|
||||||
tmp1 = radeon_bios8(dev_priv, tmp0 + 2) & 0x07;
|
|
||||||
if (tmp1) {
|
|
||||||
ddctype = tmp1;
|
|
||||||
|
|
||||||
switch(ddctype) {
|
|
||||||
case DDC_MONID:
|
case DDC_MONID:
|
||||||
|
mode_info->bios_connector[4].ddc_i2c =
|
||||||
|
combios_setup_i2c_bus(RADEON_GPIO_MONID);
|
||||||
|
break;
|
||||||
case DDC_DVI:
|
case DDC_DVI:
|
||||||
|
mode_info->bios_connector[4].ddc_i2c =
|
||||||
|
combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
|
||||||
|
break;
|
||||||
|
case DDC_VGA:
|
||||||
|
mode_info->bios_connector[4].ddc_i2c =
|
||||||
|
combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
|
||||||
|
break;
|
||||||
case DDC_CRT2:
|
case DDC_CRT2:
|
||||||
|
mode_info->bios_connector[4].ddc_i2c =
|
||||||
|
combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
|
||||||
|
break;
|
||||||
case DDC_LCD:
|
case DDC_LCD:
|
||||||
|
mode_info->bios_connector[4].ddc_i2c =
|
||||||
|
combios_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.mask_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.mask_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.a_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.a_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.put_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.put_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.get_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.get_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
break;
|
||||||
case DDC_GPIO:
|
case DDC_GPIO:
|
||||||
|
mode_info->bios_connector[4].ddc_i2c =
|
||||||
|
combios_setup_i2c_bus(RADEON_MDGPIO_EN_REG);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.mask_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.mask_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.a_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.a_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.put_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.put_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.get_clk_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 3);
|
||||||
|
mode_info->bios_connector[4].ddc_i2c.get_data_mask =
|
||||||
|
radeon_bios32(dev_priv, lcd_ddc_info + 7);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DRM_DEBUG("LCD DDC Info Table found!\n");
|
DRM_DEBUG("LCD DDC Info Table found!\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
mode_info->bios_connector[4].ddc_i2c.valid = false;
|
mode_info->bios_connector[4].ddc_i2c.valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check TV table */
|
||||||
|
if (dev_priv->chip_family != CHIP_R100 &&
|
||||||
|
dev_priv->chip_family != CHIP_R200) {
|
||||||
|
uint32_t tv_info = combios_get_table_offset(dev, COMBIOS_TV_INFO_TABLE);
|
||||||
|
if (tv_info) {
|
||||||
|
if (radeon_bios8(dev_priv, tv_info + 6) == 'T') {
|
||||||
|
mode_info->bios_connector[5].valid = true;
|
||||||
|
mode_info->bios_connector[5].connector_type = CONNECTOR_DIN;
|
||||||
|
mode_info->bios_connector[5].dac_type = DAC_TVDAC;
|
||||||
|
mode_info->bios_connector[5].tmds_type = TMDS_NONE;
|
||||||
|
mode_info->bios_connector[5].ddc_i2c.valid = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DRM_DEBUG("BIOS Connector table\n");
|
DRM_DEBUG("BIOS Connector table\n");
|
||||||
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
|
||||||
|
|
Loading…
Reference in New Issue