Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon/dpm: fix atom vram table parsing

Parsing the table in incorrectly led to problems with
certain asics with mclk switching.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+10 -16
+10 -16
drivers/gpu/drm/radeon/radeon_atombios.c
··· 3513 3513 u8 frev, crev, i; 3514 3514 u16 data_offset, size; 3515 3515 union vram_info *vram_info; 3516 - u8 *p; 3517 3516 3518 3517 memset(mem_info, 0, sizeof(struct atom_memory_info)); 3519 3518 ··· 3528 3529 if (module_index < vram_info->v1_3.ucNumOfVRAMModule) { 3529 3530 ATOM_VRAM_MODULE_V3 *vram_module = 3530 3531 (ATOM_VRAM_MODULE_V3 *)vram_info->v1_3.aVramInfo; 3531 - p = (u8 *)vram_info->v1_3.aVramInfo; 3532 3532 3533 3533 for (i = 0; i < module_index; i++) { 3534 - vram_module = (ATOM_VRAM_MODULE_V3 *)p; 3535 3534 if (le16_to_cpu(vram_module->usSize) == 0) 3536 3535 return -EINVAL; 3537 - p += le16_to_cpu(vram_module->usSize); 3536 + vram_module = (ATOM_VRAM_MODULE_V3 *) 3537 + ((u8 *)vram_module + le16_to_cpu(vram_module->usSize)); 3538 3538 } 3539 3539 mem_info->mem_vendor = vram_module->asMemory.ucMemoryVenderID & 0xf; 3540 3540 mem_info->mem_type = vram_module->asMemory.ucMemoryType & 0xf0; ··· 3545 3547 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) { 3546 3548 ATOM_VRAM_MODULE_V4 *vram_module = 3547 3549 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo; 3548 - p = (u8 *)vram_info->v1_4.aVramInfo; 3549 3550 3550 3551 for (i = 0; i < module_index; i++) { 3551 - vram_module = (ATOM_VRAM_MODULE_V4 *)p; 3552 3552 if (le16_to_cpu(vram_module->usModuleSize) == 0) 3553 3553 return -EINVAL; 3554 - p += le16_to_cpu(vram_module->usModuleSize); 3554 + vram_module = (ATOM_VRAM_MODULE_V4 *) 3555 + ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize)); 3555 3556 } 3556 3557 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf; 3557 3558 mem_info->mem_type = vram_module->ucMemoryType & 0xf0; ··· 3569 3572 if (module_index < vram_info->v2_1.ucNumOfVRAMModule) { 3570 3573 ATOM_VRAM_MODULE_V7 *vram_module = 3571 3574 (ATOM_VRAM_MODULE_V7 *)vram_info->v2_1.aVramInfo; 3572 - p = (u8 *)vram_info->v2_1.aVramInfo; 3573 3575 3574 3576 for (i = 0; i < module_index; i++) { 3575 - vram_module = (ATOM_VRAM_MODULE_V7 *)p; 3576 3577 if (le16_to_cpu(vram_module->usModuleSize) == 0) 3577 3578 return -EINVAL; 3578 - p += le16_to_cpu(vram_module->usModuleSize); 3579 + vram_module = (ATOM_VRAM_MODULE_V7 *) 3580 + ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize)); 3579 3581 } 3580 3582 mem_info->mem_vendor = vram_module->ucMemoryVenderID & 0xf; 3581 3583 mem_info->mem_type = vram_module->ucMemoryType & 0xf0; ··· 3624 3628 if (module_index < vram_info->v1_4.ucNumOfVRAMModule) { 3625 3629 ATOM_VRAM_MODULE_V4 *vram_module = 3626 3630 (ATOM_VRAM_MODULE_V4 *)vram_info->v1_4.aVramInfo; 3627 - ATOM_MEMORY_TIMING_FORMAT *format; 3628 - p = (u8 *)vram_info->v1_4.aVramInfo; 3629 3631 3630 3632 for (i = 0; i < module_index; i++) { 3631 - vram_module = (ATOM_VRAM_MODULE_V4 *)p; 3632 3633 if (le16_to_cpu(vram_module->usModuleSize) == 0) 3633 3634 return -EINVAL; 3634 - p += le16_to_cpu(vram_module->usModuleSize); 3635 + vram_module = (ATOM_VRAM_MODULE_V4 *) 3636 + ((u8 *)vram_module + le16_to_cpu(vram_module->usModuleSize)); 3635 3637 } 3636 3638 mclk_range_table->num_entries = (u8) 3637 3639 ((le16_to_cpu(vram_module->usModuleSize) - offsetof(ATOM_VRAM_MODULE_V4, asMemTiming)) / 3638 3640 mem_timing_size); 3639 - p = (u8 *)vram_module->asMemTiming; 3641 + p = (u8 *)&vram_module->asMemTiming[0]; 3640 3642 for (i = 0; i < mclk_range_table->num_entries; i++) { 3641 - format = (ATOM_MEMORY_TIMING_FORMAT *)p; 3643 + ATOM_MEMORY_TIMING_FORMAT *format = (ATOM_MEMORY_TIMING_FORMAT *)p; 3642 3644 mclk_range_table->mclk[i] = le32_to_cpu(format->ulClkRange); 3643 3645 p += mem_timing_size; 3644 3646 }