diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2011-06-23 12:19:32 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-06-24 11:11:53 +1000 |
commit | ee4017f4ac8163737793cc64df535cd246792887 (patch) | |
tree | a400a7e836bbb3ad9987975a0367004e049b108f /drivers/gpu/drm/radeon/radeon_atombios.c | |
parent | d698a34da7c5626c3c16a6311c6290522e902e7f (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 1e725d9f767..bf2b61584cd 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2320,6 +2320,14 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, le16_to_cpu(clock_info->r600.usVDDC); } + /* patch up vddc if necessary */ + if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) { + u16 vddc; + + if (radeon_atom_get_max_vddc(rdev, &vddc) == 0) + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; + } + if (rdev->flags & RADEON_IS_IGP) { /* skip invalid modes */ if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) @@ -2630,7 +2638,35 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +int radeon_atom_get_max_vddc(struct radeon_device *rdev, + u16 *voltage) +{ + union set_voltage args; + int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); + u8 frev, crev; + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return -EINVAL; + + switch (crev) { + case 1: + return -EINVAL; + case 2: + args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; + args.v2.ucVoltageMode = 0; + args.v2.usVoltageLevel = 0; + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + + *voltage = le16_to_cpu(args.v2.usVoltageLevel); + break; + default: + DRM_ERROR("Unknown table version %d, %d\n", frev, crev); + return -EINVAL; + } + return 0; +} void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { |