From 5081ce12217d31d8d197e66ac3bc71adc650d463 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 18 Sep 2008 10:15:43 +1000 Subject: radeon: sort out atom vs combios tables for r400 cards --- linux-core/radeon_atombios.c | 38 ++++++++++++++++++++++++++- linux-core/radeon_combios.c | 19 ++++++++++++-- linux-core/radeon_encoders.c | 2 +- linux-core/radeon_legacy_encoders.c | 52 ++++++++++++++++++++++++++++--------- linux-core/radeon_mode.h | 4 ++- 5 files changed, 98 insertions(+), 17 deletions(-) (limited to 'linux-core') diff --git a/linux-core/radeon_atombios.c b/linux-core/radeon_atombios.c index 10e3a77d..4d98cba2 100644 --- a/linux-core/radeon_atombios.c +++ b/linux-core/radeon_atombios.c @@ -305,12 +305,48 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) return true; } + +void radeon_atombios_get_tmds_info(struct radeon_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + int index = GetIndexIntoMasterTable(DATA, TMDS_Info); + uint16_t data_offset; + struct _ATOM_TMDS_INFO *tmds_info; + uint8_t frev, crev; + uint16_t maxfreq; + int i; + + atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); + + 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); + + 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; + } + } +} + union lvds_info { struct _ATOM_LVDS_INFO info; struct _ATOM_LVDS_INFO_V12 info_12; }; -void radeon_get_lvds_info(struct radeon_encoder *encoder) +void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder) { struct drm_device *dev = encoder->base.dev; struct drm_radeon_private *dev_priv = dev->dev_private; diff --git a/linux-core/radeon_combios.c b/linux-core/radeon_combios.c index a4dd43b9..1bacc464 100644 --- a/linux-core/radeon_combios.c +++ b/linux-core/radeon_combios.c @@ -55,7 +55,7 @@ enum radeon_combios_table_offset COMBIOS_CONNECTOR_INFO_TABLE, COMBIOS_DYN_CLK_1_TABLE, COMBIOS_RESERVED_MEM_TABLE, - COMBIOS_EXT_TDMS_INFO_TABLE, + COMBIOS_EXT_TMDS_INFO_TABLE, COMBIOS_MEM_CLK_INFO_TABLE, COMBIOS_EXT_DAC_INFO_TABLE, COMBIOS_MISC_INFO_TABLE, @@ -217,7 +217,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_com if (check_offset) offset = check_offset; break; - case COMBIOS_EXT_TDMS_INFO_TABLE: + case COMBIOS_EXT_TMDS_INFO_TABLE: check_offset = radeon_bios16(dev_priv, dev_priv->bios_header_start + 0x58); if (check_offset) offset = check_offset; @@ -767,6 +767,21 @@ bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder) return false; } +bool radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + uint16_t ext_tmds_info; + uint8_t ver; + + ext_tmds_info = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); + if (ext_tmds_info) { + ver = radeon_bios8(dev_priv, ext_tmds_info); + DRM_INFO("External TMDS Table revision: %d\n", ver); + // TODO + } +} + static void radeon_apply_legacy_quirks(struct drm_device *dev, int bios_index) { struct drm_radeon_private *dev_priv = dev->dev_private; diff --git a/linux-core/radeon_encoders.c b/linux-core/radeon_encoders.c index 897be82a..82ffcfb0 100644 --- a/linux-core/radeon_encoders.c +++ b/linux-core/radeon_encoders.c @@ -387,7 +387,7 @@ struct drm_encoder *radeon_encoder_lvtma_add(struct drm_device *dev, int bios_in /* TODO get the LVDS info from the BIOS for panel size etc. */ /* get the lvds info from the bios */ - radeon_get_lvds_info(radeon_encoder); + radeon_atombios_get_lvds_info(radeon_encoder); /* LVDS gets default RMX full scaling */ radeon_encoder->rmx_type = RMX_FULL; diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c index b48da9b8..1a1db534 100644 --- a/linux-core/radeon_legacy_encoders.c +++ b/linux-core/radeon_legacy_encoders.c @@ -262,16 +262,20 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, true); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, true); radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON); // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, false); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, @@ -366,6 +370,7 @@ static const struct drm_encoder_funcs radeon_legacy_lvds_enc_funcs = { struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int bios_index) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder; struct drm_encoder *encoder; @@ -387,7 +392,10 @@ struct drm_encoder *radeon_encoder_legacy_lvds_add(struct drm_device *dev, int b drm_encoder_helper_add(encoder, &radeon_legacy_lvds_helper_funcs); /* get the lvds info from the bios */ - radeon_combios_get_lvds_info(radeon_encoder); + if (dev_priv->is_atom_bios) + radeon_atombios_get_lvds_info(radeon_encoder); + else + radeon_combios_get_lvds_info(radeon_encoder); /* LVDS gets default RMX full scaling */ radeon_encoder->rmx_type = RMX_FULL; @@ -462,16 +470,20 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, true); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, true); radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON); // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, false); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, @@ -608,6 +620,7 @@ static const struct drm_encoder_funcs radeon_legacy_primary_dac_enc_funcs = { struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev, int bios_index, int has_tv) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder; struct drm_encoder *encoder; @@ -628,7 +641,8 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs); /* get the primary dac bg/adj vals from bios tables */ - radeon_combios_get_primary_dac_info(radeon_encoder); + if (!dev_priv->is_atom_bios) + radeon_combios_get_primary_dac_info(radeon_encoder); return encoder; } @@ -686,16 +700,20 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, true); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, true); radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON); // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, true); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, true); } static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, @@ -799,6 +817,7 @@ static const struct drm_encoder_funcs radeon_legacy_tmds_int_enc_funcs = { struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, int bios_index) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder; struct drm_encoder *encoder; @@ -818,7 +837,10 @@ 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); - radeon_combios_get_tmds_info(radeon_encoder); + if (dev_priv->is_atom_bios) + radeon_atombios_get_tmds_info(radeon_encoder); + else + radeon_combios_get_tmds_info(radeon_encoder); return encoder; } @@ -877,16 +899,20 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, true); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, true); radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) { + struct drm_radeon_private *dev_priv = encoder->dev->dev_private; radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON); // fix me: atom/legacy r4xx - radeon_combios_output_lock(encoder, false); + if (!dev_priv->is_atom_bios) + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, @@ -961,6 +987,7 @@ static const struct drm_encoder_funcs radeon_legacy_tmds_ext_enc_funcs = { struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index) { + struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder; struct drm_encoder *encoder; @@ -980,7 +1007,8 @@ struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, i drm_encoder_helper_add(encoder, &radeon_legacy_tmds_ext_helper_funcs); - //radeon_combios_get_tmds_info(radeon_encoder); + if (!dev_priv->is_atom_bios) + radeon_combios_get_ext_tmds_info(radeon_encoder); return encoder; } diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index e8a0106e..f12a1161 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -288,9 +288,11 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, extern bool radeon_atom_get_clock_info(struct drm_device *dev); extern bool radeon_combios_get_clock_info(struct drm_device *dev); -extern void radeon_get_lvds_info(struct radeon_encoder *encoder); +extern void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); +extern void radeon_atombios_get_tmds_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_ext_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 bool radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); -- cgit v1.2.3