diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2012-03-20 17:18:08 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-03-21 06:55:51 +0000 |
commit | e83753bb61f6d2184daf3c59707094d8994ec85e (patch) | |
tree | f3a4ccbb3829417778150e0bcc4d3ecbd70027d4 /drivers/gpu/drm/radeon/radeon_atombios.c | |
parent | 2d415869f163a8b6dd5f0fde0a2467d2b6488e90 (diff) |
drm/radeon/kms/atom: add support for SI SetVoltage table
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 | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 7e2ba258089..afb127c02b6 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -56,6 +56,10 @@ extern void radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device); +/* local */ +static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, + u16 voltage_id, u16 *voltage); + union atom_supported_devices { struct _ATOM_SUPPORTED_DEVICES_INFO info; struct _ATOM_SUPPORTED_DEVICES_INFO_2 info_2; @@ -2283,6 +2287,7 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, union pplib_clock_info *clock_info) { u32 sclk, mclk; + u16 vddc; if (rdev->flags & RADEON_IS_IGP) { if (rdev->family >= CHIP_PALM) { @@ -2321,11 +2326,18 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, } /* 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) + switch (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage) { + case ATOM_VIRTUAL_VOLTAGE_ID0: + case ATOM_VIRTUAL_VOLTAGE_ID1: + case ATOM_VIRTUAL_VOLTAGE_ID2: + case ATOM_VIRTUAL_VOLTAGE_ID3: + if (radeon_atom_get_max_vddc(rdev, VOLTAGE_TYPE_VDDC, + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage, + &vddc) == 0) rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; + break; + default: + break; } if (rdev->flags & RADEON_IS_IGP) { @@ -2640,6 +2652,7 @@ union set_voltage { struct _SET_VOLTAGE_PS_ALLOCATION alloc; struct _SET_VOLTAGE_PARAMETERS v1; struct _SET_VOLTAGE_PARAMETERS_V2 v2; + struct _SET_VOLTAGE_PARAMETERS_V1_3 v3; }; void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type) @@ -2666,6 +2679,11 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; args.v2.usVoltageLevel = cpu_to_le16(voltage_level); break; + case 3: + args.v3.ucVoltageType = voltage_type; + args.v3.ucVoltageMode = ATOM_SET_VOLTAGE; + args.v3.usVoltageLevel = cpu_to_le16(voltage_level); + break; default: DRM_ERROR("Unknown table version %d, %d\n", frev, crev); return; @@ -2674,8 +2692,8 @@ 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) +static int radeon_atom_get_max_vddc(struct radeon_device *rdev, u8 voltage_type, + u16 voltage_id, u16 *voltage) { union set_voltage args; int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); @@ -2696,6 +2714,15 @@ int radeon_atom_get_max_vddc(struct radeon_device *rdev, *voltage = le16_to_cpu(args.v2.usVoltageLevel); break; + case 3: + args.v3.ucVoltageType = voltage_type; + args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL; + args.v3.usVoltageLevel = cpu_to_le16(voltage_id); + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + + *voltage = le16_to_cpu(args.v3.usVoltageLevel); + break; default: DRM_ERROR("Unknown table version %d, %d\n", frev, crev); return -EINVAL; |