From a084e6ee6e64a76f1a9665d527203cdab7d6048f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Mar 2010 01:04:01 -0400 Subject: drm/radeon/kms/atom: make sure tables are valid (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check that atom cmd and data tables are valid before using them. (v2) - fix some whitespace errors noticed by Rafał Miłecki - check a few more cases Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/rs690.c | 74 +++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 30 deletions(-) (limited to 'drivers/gpu/drm/radeon/rs690.c') diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index e356935b0283..f758d5cc1160 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -58,42 +58,57 @@ static void rs690_gpu_init(struct radeon_device *rdev) } } +union igp_info { + struct _ATOM_INTEGRATED_SYSTEM_INFO info; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_v2; +}; + void rs690_pm_info(struct radeon_device *rdev) { int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); - struct _ATOM_INTEGRATED_SYSTEM_INFO *info; - struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2; - void *ptr; + union igp_info *info; uint16_t data_offset; uint8_t frev, crev; fixed20_12 tmp; - atom_parse_data_header(rdev->mode_info.atom_context, index, NULL, - &frev, &crev, &data_offset); - ptr = rdev->mode_info.atom_context->bios + data_offset; - info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr; - info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr; - /* Get various system informations from bios */ - switch (crev) { - case 1: - tmp.full = rfixed_const(100); - rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock); - rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); - rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock)); - rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock)); - rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth); - break; - case 2: - tmp.full = rfixed_const(100); - rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock); - rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); - rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock); - rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); - rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq); - rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp); - rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth)); - break; - default: + if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL, + &frev, &crev, &data_offset)) { + info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset); + + /* Get various system informations from bios */ + switch (crev) { + case 1: + tmp.full = rfixed_const(100); + rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info.ulBootUpMemoryClock); + rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); + rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->info.usK8MemoryClock)); + rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->info.usFSBClock)); + rdev->pm.igp_ht_link_width.full = rfixed_const(info->info.ucHTLinkWidth); + break; + case 2: + tmp.full = rfixed_const(100); + rdev->pm.igp_sideport_mclk.full = rfixed_const(info->info_v2.ulBootUpSidePortClock); + rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp); + rdev->pm.igp_system_mclk.full = rfixed_const(info->info_v2.ulBootUpUMAClock); + rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = rfixed_const(info->info_v2.ulHTLinkFreq); + rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp); + rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info->info_v2.usMinHTLinkWidth)); + break; + default: + tmp.full = rfixed_const(100); + /* We assume the slower possible clock ie worst case */ + /* DDR 333Mhz */ + rdev->pm.igp_sideport_mclk.full = rfixed_const(333); + /* FIXME: system clock ? */ + rdev->pm.igp_system_mclk.full = rfixed_const(100); + rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp); + rdev->pm.igp_ht_link_clk.full = rfixed_const(200); + rdev->pm.igp_ht_link_width.full = rfixed_const(8); + DRM_ERROR("No integrated system info for your GPU, using safe default\n"); + break; + } + } else { tmp.full = rfixed_const(100); /* We assume the slower possible clock ie worst case */ /* DDR 333Mhz */ @@ -104,7 +119,6 @@ void rs690_pm_info(struct radeon_device *rdev) rdev->pm.igp_ht_link_clk.full = rfixed_const(200); rdev->pm.igp_ht_link_width.full = rfixed_const(8); DRM_ERROR("No integrated system info for your GPU, using safe default\n"); - break; } /* Compute various bandwidth */ /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */ -- cgit v1.2.3