Commit ee4017f4ac8163737793cc64df535cd246792887
Committed by
Dave Airlie
1 parent
d698a34da7
Exists in
master
and in
7 other branches
drm/radeon/kms: handle special cases for vddc
A voltage value of 0xff01 requires that the driver look up the max voltage for the board based using the atom SetVoltage command table. Setting the proper voltage should fix stability on some newer asics. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Showing 2 changed files with 37 additions and 0 deletions Side-by-side Diff
drivers/gpu/drm/radeon/radeon.h
... | ... | @@ -179,6 +179,7 @@ |
179 | 179 | void radeon_combios_get_power_modes(struct radeon_device *rdev); |
180 | 180 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
181 | 181 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); |
182 | +int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage); | |
182 | 183 | void rs690_pm_info(struct radeon_device *rdev); |
183 | 184 | extern int rv6xx_get_temp(struct radeon_device *rdev); |
184 | 185 | extern int rv770_get_temp(struct radeon_device *rdev); |
drivers/gpu/drm/radeon/radeon_atombios.c
... | ... | @@ -2320,6 +2320,14 @@ |
2320 | 2320 | le16_to_cpu(clock_info->r600.usVDDC); |
2321 | 2321 | } |
2322 | 2322 | |
2323 | + /* patch up vddc if necessary */ | |
2324 | + if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) { | |
2325 | + u16 vddc; | |
2326 | + | |
2327 | + if (radeon_atom_get_max_vddc(rdev, &vddc) == 0) | |
2328 | + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; | |
2329 | + } | |
2330 | + | |
2323 | 2331 | if (rdev->flags & RADEON_IS_IGP) { |
2324 | 2332 | /* skip invalid modes */ |
2325 | 2333 | if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) |
2326 | 2334 | |
... | ... | @@ -2630,7 +2638,35 @@ |
2630 | 2638 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
2631 | 2639 | } |
2632 | 2640 | |
2641 | +int radeon_atom_get_max_vddc(struct radeon_device *rdev, | |
2642 | + u16 *voltage) | |
2643 | +{ | |
2644 | + union set_voltage args; | |
2645 | + int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); | |
2646 | + u8 frev, crev; | |
2633 | 2647 | |
2648 | + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | |
2649 | + return -EINVAL; | |
2650 | + | |
2651 | + switch (crev) { | |
2652 | + case 1: | |
2653 | + return -EINVAL; | |
2654 | + case 2: | |
2655 | + args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; | |
2656 | + args.v2.ucVoltageMode = 0; | |
2657 | + args.v2.usVoltageLevel = 0; | |
2658 | + | |
2659 | + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | |
2660 | + | |
2661 | + *voltage = le16_to_cpu(args.v2.usVoltageLevel); | |
2662 | + break; | |
2663 | + default: | |
2664 | + DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | |
2665 | + return -EINVAL; | |
2666 | + } | |
2667 | + | |
2668 | + return 0; | |
2669 | +} | |
2634 | 2670 | |
2635 | 2671 | void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) |
2636 | 2672 | { |