From b67fa40a11b840208f00ef30ca4cdcb9c2e73b67 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 18 Mar 2010 15:32:27 -0400 Subject: [PATCH] drm/radeon/kms/pm: add voltage drop support for r1xx-r4xx Voltage drop is controlled by a gpio pulled high or low. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/r100.c | 47 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 9a7d16b..0ef5b2f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -66,6 +66,49 @@ MODULE_FIRMWARE(FIRMWARE_R520); * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ +void r100_set_voltage(struct radeon_device *rdev) +{ + int requested_index = rdev->pm.requested_power_state_index; + struct radeon_voltage *voltage; + u32 tmp; + + /* first power state is lowest. if there is no voltage drop, + * no need to mess with it + */ + if (!rdev->pm.power_state[0].voltage_drop_active) + return; + + if (rdev->pm.power_state[requested_index].voltage_drop_active) { + /* enable voltage drop */ + voltage = + &rdev->pm.power_state[requested_index].clock_info[0].voltage; + if (voltage->gpio.valid) { + tmp = RREG32(voltage->gpio.reg); + if (voltage->active_high) + tmp |= voltage->gpio.mask; + else + tmp &= ~(voltage->gpio.mask); + WREG32(voltage->gpio.reg, tmp); + if (voltage->delay) + udelay(voltage->delay); + } + } else { + /* disable voltage drop */ + voltage = + &rdev->pm.power_state[0].clock_info[0].voltage; + if (voltage->gpio.valid) { + tmp = RREG32(voltage->gpio.reg); + if (voltage->active_high) + tmp &= ~(voltage->gpio.mask); + else + tmp |= voltage->gpio.mask; + WREG32(voltage->gpio.reg, tmp); + if (voltage->delay) + udelay(voltage->delay); + } + } +} + void r100_get_power_state(struct radeon_device *rdev, enum radeon_pm_action action) { @@ -183,7 +226,9 @@ void r100_set_power_state(struct radeon_device *rdev) /* TODO */ /* set voltage */ - /* TODO */ + if (rdev->family <= CHIP_RS480) + r100_set_voltage(rdev); + /* TODO: r5xx+ */ /* set engine clock */ /* reclocking the engine appears to be ok as long as the engine is idle -- 1.5.6.3