The default power state does not always match the default clocks and voltage for a particular card. The information in the firmware info table is correct and should be used in preference to the info the default power state.
Signed-off-by: Alex Deucher alexdeucher@gmail.com --- drivers/gpu/drm/radeon/radeon_atombios.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index f858be0..ebfe8fd 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1746,9 +1746,22 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].misc2 = 0; } } else { + int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); + uint8_t fw_frev, fw_crev; + uint16_t fw_data_offset, vddc = 0; + union firmware_info *firmware_info; + ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; + + if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, + &fw_frev, &fw_crev, &fw_data_offset)) { + firmware_info = + (union firmware_info *)(mode_info->atom_context->bios + + fw_data_offset); + vddc = firmware_info->info_14.usBootUpVDDCVoltage; + } + /* add the i2c bus for thermal/fan chip */ /* no support for internal controller yet */ - ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; if (controller->ucType > 0) { if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) || (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) || @@ -1895,6 +1908,16 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.default_power_state_index = state_index; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; + /* patch the table values with the default slck/mclk from firmware info */ + for (j = 0; j < mode_index; j++) { + rdev->pm.power_state[state_index].clock_info[j].mclk = + rdev->clock.default_mclk; + rdev->pm.power_state[state_index].clock_info[j].sclk = + rdev->clock.default_sclk; + if (vddc) + rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = + vddc; + } } state_index++; }
- wait for vbl for both profile and dynpm - unify profile and dynpm code paths more - call pm_misc before of after clocks to make sure voltage is changed in the proper order.
Signed-off-by: Alex Deucher alexdeucher@gmail.com --- drivers/gpu/drm/radeon/radeon_pm.c | 75 ++++++++++++++++------------------- 1 files changed, 34 insertions(+), 41 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index c88edae..a51326c 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -151,6 +151,7 @@ static void radeon_sync_with_vblank(struct radeon_device *rdev) static void radeon_set_power_state(struct radeon_device *rdev) { u32 sclk, mclk; + bool misc_after = false;
if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) @@ -167,55 +168,47 @@ static void radeon_set_power_state(struct radeon_device *rdev) if (mclk > rdev->clock.default_mclk) mclk = rdev->clock.default_mclk;
- /* voltage, pcie lanes, etc.*/ - radeon_pm_misc(rdev); + /* upvolt before raising clocks, downvolt after lowering clocks */ + if (sclk < rdev->pm.current_sclk) + misc_after = true;
- if (rdev->pm.pm_method == PM_METHOD_DYNPM) { - radeon_sync_with_vblank(rdev); + radeon_sync_with_vblank(rdev);
+ if (rdev->pm.pm_method == PM_METHOD_DYNPM) { if (!radeon_pm_in_vbl(rdev)) return; + }
- radeon_pm_prepare(rdev); - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); - } + radeon_pm_prepare(rdev);
- /* set memory clock */ - if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_pm_debug_check_in_vbl(rdev, false); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_debug_check_in_vbl(rdev, true); - rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); - } - radeon_pm_finish(rdev); - } else { - /* set engine clock */ - if (sclk != rdev->pm.current_sclk) { - radeon_sync_with_vblank(rdev); - radeon_pm_prepare(rdev); - radeon_set_engine_clock(rdev, sclk); - radeon_pm_finish(rdev); - rdev->pm.current_sclk = sclk; - DRM_DEBUG("Setting: e: %d\n", sclk); - } - /* set memory clock */ - if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { - radeon_sync_with_vblank(rdev); - radeon_pm_prepare(rdev); - radeon_set_memory_clock(rdev, mclk); - radeon_pm_finish(rdev); - rdev->pm.current_mclk = mclk; - DRM_DEBUG("Setting: m: %d\n", mclk); - } + if (!misc_after) + /* voltage, pcie lanes, etc.*/ + radeon_pm_misc(rdev); + + /* set engine clock */ + if (sclk != rdev->pm.current_sclk) { + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_engine_clock(rdev, sclk); + radeon_pm_debug_check_in_vbl(rdev, true); + rdev->pm.current_sclk = sclk; + DRM_DEBUG("Setting: e: %d\n", sclk); + } + + /* set memory clock */ + if (rdev->asic->set_memory_clock && (mclk != rdev->pm.current_mclk)) { + radeon_pm_debug_check_in_vbl(rdev, false); + radeon_set_memory_clock(rdev, mclk); + radeon_pm_debug_check_in_vbl(rdev, true); + rdev->pm.current_mclk = mclk; + DRM_DEBUG("Setting: m: %d\n", mclk); }
+ if (misc_after) + /* voltage, pcie lanes, etc.*/ + radeon_pm_misc(rdev); + + radeon_pm_finish(rdev); + rdev->pm.current_power_state_index = rdev->pm.requested_power_state_index; rdev->pm.current_clock_mode_index = rdev->pm.requested_clock_mode_index; } else
- Enable GPIO voltage for non pm modes as well so resetting the default voltage works.
Signed-off-by: Alex Deucher alexdeucher@gmail.com --- drivers/gpu/drm/radeon/radeon_atombios.c | 9 ++++++--- drivers/gpu/drm/radeon/radeon_combios.c | 7 ++++++- 2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index ebfe8fd..da42306 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1529,7 +1529,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) rdev->pm.power_state[state_index].pcie_lanes = power_info->info.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = @@ -1596,7 +1597,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = @@ -1670,7 +1672,8 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) { + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_GPIO; rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 7b5e10d..102c744 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2454,7 +2454,12 @@ default_mode: rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + if ((state_index > 0) && + (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO)) + rdev->pm.power_state[state_index].clock_info[0].voltage = + rdev->pm.power_state[0].clock_info[0].voltage; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; rdev->pm.power_state[state_index].pcie_lanes = 16; rdev->pm.power_state[state_index].flags = 0; rdev->pm.default_power_state_index = state_index;
- This enables voltage adjustment on r6xx+ and certain r5xx asics. - Voltage drop support is already available for most r1xx-r5xx asics.
Signed-off-by: Alex Deucher alexdeucher@gmail.com --- drivers/gpu/drm/radeon/r600.c | 6 +++++ drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_atombios.c | 36 ++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/rs600.c | 3 +- 4 files changed, 45 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index dac2534..d84d7cf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
void r600_pm_misc(struct radeon_device *rdev) { + int requested_index = rdev->pm.requested_power_state_index; + struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; + struct radeon_voltage *voltage = &ps->clock_info[0].voltage; + + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) + radeon_atom_set_voltage(rdev, voltage->voltage);
}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 78b59a7..a2561c0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -176,6 +176,7 @@ void radeon_pm_suspend(struct radeon_device *rdev); void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); +void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
/* * Fences. diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index da42306..be5f755 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2015,6 +2015,42 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); }
+union set_voltage { + struct _SET_VOLTAGE_PS_ALLOCATION alloc; + struct _SET_VOLTAGE_PARAMETERS v1; + struct _SET_VOLTAGE_PARAMETERS_V2 v2; +}; + +void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) +{ + union set_voltage args; + int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); + u8 frev, crev, volt_index = level; + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return; + + switch (crev) { + case 1: + args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; + args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; + args.v1.ucVoltageIndex = volt_index; + break; + case 2: + args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; + args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; + args.v2.usVoltageLevel = level; + break; + default: + DRM_ERROR("Unknown table version %d, %d\n", frev, crev); + return; + } + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +} + + + void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 79887ca..7bb4c3e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -74,7 +74,8 @@ void rs600_pm_misc(struct radeon_device *rdev) if (voltage->delay) udelay(voltage->delay); } - } + } else if (voltage->type == VOLTAGE_VDDC) + radeon_atom_set_voltage(rdev, voltage->vddc_id);
dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
- This enables voltage adjustment on r6xx+ and certain r5xx asics. - Voltage drop support is already available for most r1xx-r5xx asics.
V2: endian fix for voltage table.
Signed-off-by: Alex Deucher alexdeucher@gmail.com --- drivers/gpu/drm/radeon/r600.c | 6 +++++ drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_atombios.c | 36 ++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/rs600.c | 3 +- 4 files changed, 45 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index dac2534..d84d7cf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
void r600_pm_misc(struct radeon_device *rdev) { + int requested_index = rdev->pm.requested_power_state_index; + struct radeon_power_state *ps = &rdev->pm.power_state[requested_index]; + struct radeon_voltage *voltage = &ps->clock_info[0].voltage; + + if ((voltage->type == VOLTAGE_SW) && voltage->voltage) + radeon_atom_set_voltage(rdev, voltage->voltage);
}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 78b59a7..a2561c0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -176,6 +176,7 @@ void radeon_pm_suspend(struct radeon_device *rdev); void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); +void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level);
/* * Fences. diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index da42306..107ada0 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2015,6 +2015,42 @@ void radeon_atom_set_memory_clock(struct radeon_device *rdev, atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); }
+union set_voltage { + struct _SET_VOLTAGE_PS_ALLOCATION alloc; + struct _SET_VOLTAGE_PARAMETERS v1; + struct _SET_VOLTAGE_PARAMETERS_V2 v2; +}; + +void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) +{ + union set_voltage args; + int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); + u8 frev, crev, volt_index = level; + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return; + + switch (crev) { + case 1: + args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; + args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; + args.v1.ucVoltageIndex = volt_index; + break; + case 2: + args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; + args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; + args.v2.usVoltageLevel = cpu_to_le16(level); + break; + default: + DRM_ERROR("Unknown table version %d, %d\n", frev, crev); + return; + } + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); +} + + + void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { struct radeon_device *rdev = dev->dev_private; diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 79887ca..7bb4c3e 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -74,7 +74,8 @@ void rs600_pm_misc(struct radeon_device *rdev) if (voltage->delay) udelay(voltage->delay); } - } + } else if (voltage->type == VOLTAGE_VDDC) + radeon_atom_set_voltage(rdev, voltage->vddc_id);
dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
2010/5/28 Alex Deucher alexdeucher@gmail.com:
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index dac2534..d84d7cf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
void r600_pm_misc(struct radeon_device *rdev) {
- int requested_index = rdev->pm.requested_power_state_index;
- struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
- struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
- if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
- radeon_atom_set_voltage(rdev, voltage->voltage);
}
In case of my RV620 I can see (using AtomDis): 0004: UCHAR ucVoltageType = 0x01 (1) so it looks that my GPU uses VOLTAGE_GPIO (it's 0x01).
You seem to do not use SetVoltage AtomBIOS command for VOLTAGE_GPIO. However in case of my BIOS there is SetVoltage command table.
Could you comment on this, please?
2010/6/3 Rafał Miłecki zajec5@gmail.com:
2010/5/28 Alex Deucher alexdeucher@gmail.com:
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index dac2534..d84d7cf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
void r600_pm_misc(struct radeon_device *rdev) {
- int requested_index = rdev->pm.requested_power_state_index;
- struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
- struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
- if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
- radeon_atom_set_voltage(rdev, voltage->voltage);
}
In case of my RV620 I can see (using AtomDis): 0004: UCHAR ucVoltageType = 0x01 (1) so it looks that my GPU uses VOLTAGE_GPIO (it's 0x01).
You seem to do not use SetVoltage AtomBIOS command for VOLTAGE_GPIO. However in case of my BIOS there is SetVoltage command table.
Could you comment on this, please?
The VOLTAGE_GPIO, VOLTAGE_SW, etc. enums in the driver are a little confusing I guess. They refer to the interface used to program the voltage. We could have called them VOLTAGE_TYPE1, VOLTAGE_TYPE2, etc., but I wanted to provide a bit more info about the type.
VOLTAGE_GPIO refers to the cases where the power table specifies the GPIO reg and a mask for voltage control. VOLTAGE_VDDC refers to the cases where the power table specifies an index into the VDDC voltage table. VOLTAGE_SW refers to the cases where the power table specifies the actual voltage value which SW (software) has to program.
Your system (actually all r6xx+ vbioses) specifies a voltage value, so they are the VOLTAGE_SW type. The actual implementation on the board may be gpio or i2c, etc.; depends on the board. The SetVoltage command table uses the VoltageObject data table to look up the the relevant info based on the voltage value specified.
I hope that clarifies things.
Alex
2010/6/3 Alex Deucher alexdeucher@gmail.com:
2010/6/3 Rafał Miłecki zajec5@gmail.com:
2010/5/28 Alex Deucher alexdeucher@gmail.com:
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index dac2534..d84d7cf 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -475,6 +475,12 @@ void r600_pm_init_profile(struct radeon_device *rdev)
void r600_pm_misc(struct radeon_device *rdev) {
- int requested_index = rdev->pm.requested_power_state_index;
- struct radeon_power_state *ps = &rdev->pm.power_state[requested_index];
- struct radeon_voltage *voltage = &ps->clock_info[0].voltage;
- if ((voltage->type == VOLTAGE_SW) && voltage->voltage)
- radeon_atom_set_voltage(rdev, voltage->voltage);
}
In case of my RV620 I can see (using AtomDis): 0004: UCHAR ucVoltageType = 0x01 (1) so it looks that my GPU uses VOLTAGE_GPIO (it's 0x01).
You seem to do not use SetVoltage AtomBIOS command for VOLTAGE_GPIO. However in case of my BIOS there is SetVoltage command table.
Could you comment on this, please?
The VOLTAGE_GPIO, VOLTAGE_SW, etc. enums in the driver are a little confusing I guess. They refer to the interface used to program the
Just to clarify, they refer to the interface used to *store* the voltage in the power tables.
Alex
voltage. We could have called them VOLTAGE_TYPE1, VOLTAGE_TYPE2, etc., but I wanted to provide a bit more info about the type.
VOLTAGE_GPIO refers to the cases where the power table specifies the GPIO reg and a mask for voltage control. VOLTAGE_VDDC refers to the cases where the power table specifies an index into the VDDC voltage table. VOLTAGE_SW refers to the cases where the power table specifies the actual voltage value which SW (software) has to program.
Your system (actually all r6xx+ vbioses) specifies a voltage value, so they are the VOLTAGE_SW type. The actual implementation on the board may be gpio or i2c, etc.; depends on the board. The SetVoltage command table uses the VoltageObject data table to look up the the relevant info based on the voltage value specified.
I hope that clarifies things.
Alex
2010/5/27 Alex Deucher alexdeucher@gmail.com:
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 7b5e10d..102c744 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2454,7 +2454,12 @@ default_mode: rdev->pm.power_state[state_index].clock_info[0].mclk = rdev->clock.default_mclk; rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0];
- rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
- if ((state_index > 0) &&
- (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO))
- rdev->pm.power_state[state_index].clock_info[0].voltage =
- rdev->pm.power_state[0].clock_info[0].voltage;
- else
- rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE;
Condition typo. Assignment -> comparison.
Noticed by Rafał Miłecki.
Signed-off-by: Alex Deucher alexdeucher@gmail.com --- drivers/gpu/drm/radeon/radeon_combios.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 102c744..f6f907e 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2455,7 +2455,7 @@ default_mode: rdev->pm.power_state[state_index].clock_info[0].sclk = rdev->clock.default_sclk; rdev->pm.power_state[state_index].default_clock_mode = &rdev->pm.power_state[state_index].clock_info[0]; if ((state_index > 0) && - (rdev->pm.power_state[0].clock_info[0].voltage.type = VOLTAGE_GPIO)) + (rdev->pm.power_state[0].clock_info[0].voltage.type == VOLTAGE_GPIO)) rdev->pm.power_state[state_index].clock_info[0].voltage = rdev->pm.power_state[0].clock_info[0].voltage; else
dri-devel@lists.freedesktop.org