diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-06-26 00:11:19 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-06-27 19:14:59 -0400 |
commit | 66229b200598a3b66b839d1759ff3f5b17ac5639 (patch) | |
tree | 5bfb3d7ba630171afe67c9aeae007a1db03d22d3 /drivers/gpu/drm/radeon/r600.c | |
parent | 4a6369e9935e392402d4ccb67f5cddac953e8d3c (diff) |
drm/radeon/kms: add dpm support for rv7xx (v4)
This adds dpm support for rv7xx asics. This includes:
- clockgating
- dynamic engine clock scaling
- dynamic memory clock scaling
- dynamic voltage scaling
- dynamic pcie gen1/gen2 switching
Set radeon.dpm=1 to enable.
v2: reduce stack usage
v3: fix 64 bit div
v4: fix state enable
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ce5aa1febb80..a27d746386ae 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -57,10 +57,14 @@ MODULE_FIRMWARE("radeon/RS780_pfp.bin"); | |||
57 | MODULE_FIRMWARE("radeon/RS780_me.bin"); | 57 | MODULE_FIRMWARE("radeon/RS780_me.bin"); |
58 | MODULE_FIRMWARE("radeon/RV770_pfp.bin"); | 58 | MODULE_FIRMWARE("radeon/RV770_pfp.bin"); |
59 | MODULE_FIRMWARE("radeon/RV770_me.bin"); | 59 | MODULE_FIRMWARE("radeon/RV770_me.bin"); |
60 | MODULE_FIRMWARE("radeon/RV770_smc.bin"); | ||
60 | MODULE_FIRMWARE("radeon/RV730_pfp.bin"); | 61 | MODULE_FIRMWARE("radeon/RV730_pfp.bin"); |
61 | MODULE_FIRMWARE("radeon/RV730_me.bin"); | 62 | MODULE_FIRMWARE("radeon/RV730_me.bin"); |
63 | MODULE_FIRMWARE("radeon/RV730_smc.bin"); | ||
64 | MODULE_FIRMWARE("radeon/RV740_smc.bin"); | ||
62 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); | 65 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); |
63 | MODULE_FIRMWARE("radeon/RV710_me.bin"); | 66 | MODULE_FIRMWARE("radeon/RV710_me.bin"); |
67 | MODULE_FIRMWARE("radeon/RV710_smc.bin"); | ||
64 | MODULE_FIRMWARE("radeon/R600_rlc.bin"); | 68 | MODULE_FIRMWARE("radeon/R600_rlc.bin"); |
65 | MODULE_FIRMWARE("radeon/R700_rlc.bin"); | 69 | MODULE_FIRMWARE("radeon/R700_rlc.bin"); |
66 | MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); | 70 | MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); |
@@ -2139,7 +2143,8 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2139 | struct platform_device *pdev; | 2143 | struct platform_device *pdev; |
2140 | const char *chip_name; | 2144 | const char *chip_name; |
2141 | const char *rlc_chip_name; | 2145 | const char *rlc_chip_name; |
2142 | size_t pfp_req_size, me_req_size, rlc_req_size; | 2146 | const char *smc_chip_name = "RV770"; |
2147 | size_t pfp_req_size, me_req_size, rlc_req_size, smc_req_size = 0; | ||
2143 | char fw_name[30]; | 2148 | char fw_name[30]; |
2144 | int err; | 2149 | int err; |
2145 | 2150 | ||
@@ -2185,15 +2190,26 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2185 | case CHIP_RV770: | 2190 | case CHIP_RV770: |
2186 | chip_name = "RV770"; | 2191 | chip_name = "RV770"; |
2187 | rlc_chip_name = "R700"; | 2192 | rlc_chip_name = "R700"; |
2193 | smc_chip_name = "RV770"; | ||
2194 | smc_req_size = ALIGN(RV770_SMC_UCODE_SIZE, 4); | ||
2188 | break; | 2195 | break; |
2189 | case CHIP_RV730: | 2196 | case CHIP_RV730: |
2190 | case CHIP_RV740: | ||
2191 | chip_name = "RV730"; | 2197 | chip_name = "RV730"; |
2192 | rlc_chip_name = "R700"; | 2198 | rlc_chip_name = "R700"; |
2199 | smc_chip_name = "RV730"; | ||
2200 | smc_req_size = ALIGN(RV730_SMC_UCODE_SIZE, 4); | ||
2193 | break; | 2201 | break; |
2194 | case CHIP_RV710: | 2202 | case CHIP_RV710: |
2195 | chip_name = "RV710"; | 2203 | chip_name = "RV710"; |
2196 | rlc_chip_name = "R700"; | 2204 | rlc_chip_name = "R700"; |
2205 | smc_chip_name = "RV710"; | ||
2206 | smc_req_size = ALIGN(RV710_SMC_UCODE_SIZE, 4); | ||
2207 | break; | ||
2208 | case CHIP_RV740: | ||
2209 | chip_name = "RV730"; | ||
2210 | rlc_chip_name = "R700"; | ||
2211 | smc_chip_name = "RV740"; | ||
2212 | smc_req_size = ALIGN(RV740_SMC_UCODE_SIZE, 4); | ||
2197 | break; | 2213 | break; |
2198 | case CHIP_CEDAR: | 2214 | case CHIP_CEDAR: |
2199 | chip_name = "CEDAR"; | 2215 | chip_name = "CEDAR"; |
@@ -2277,6 +2293,19 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2277 | err = -EINVAL; | 2293 | err = -EINVAL; |
2278 | } | 2294 | } |
2279 | 2295 | ||
2296 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | ||
2297 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); | ||
2298 | err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev); | ||
2299 | if (err) | ||
2300 | goto out; | ||
2301 | if (rdev->smc_fw->size != smc_req_size) { | ||
2302 | printk(KERN_ERR | ||
2303 | "smc: Bogus length %zu in firmware \"%s\"\n", | ||
2304 | rdev->smc_fw->size, fw_name); | ||
2305 | err = -EINVAL; | ||
2306 | } | ||
2307 | } | ||
2308 | |||
2280 | out: | 2309 | out: |
2281 | platform_device_unregister(pdev); | 2310 | platform_device_unregister(pdev); |
2282 | 2311 | ||
@@ -2291,6 +2320,8 @@ out: | |||
2291 | rdev->me_fw = NULL; | 2320 | rdev->me_fw = NULL; |
2292 | release_firmware(rdev->rlc_fw); | 2321 | release_firmware(rdev->rlc_fw); |
2293 | rdev->rlc_fw = NULL; | 2322 | rdev->rlc_fw = NULL; |
2323 | release_firmware(rdev->smc_fw); | ||
2324 | rdev->smc_fw = NULL; | ||
2294 | } | 2325 | } |
2295 | return err; | 2326 | return err; |
2296 | } | 2327 | } |
@@ -4039,10 +4070,13 @@ int r600_irq_set(struct radeon_device *rdev) | |||
4039 | if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) { | 4070 | if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) { |
4040 | thermal_int = RREG32(CG_THERMAL_INT) & | 4071 | thermal_int = RREG32(CG_THERMAL_INT) & |
4041 | ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); | 4072 | ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); |
4042 | if (rdev->irq.dpm_thermal) { | 4073 | } else if (rdev->family >= CHIP_RV770) { |
4043 | DRM_DEBUG("dpm thermal\n"); | 4074 | thermal_int = RREG32(RV770_CG_THERMAL_INT) & |
4044 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; | 4075 | ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); |
4045 | } | 4076 | } |
4077 | if (rdev->irq.dpm_thermal) { | ||
4078 | DRM_DEBUG("dpm thermal\n"); | ||
4079 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; | ||
4046 | } | 4080 | } |
4047 | 4081 | ||
4048 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { | 4082 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
@@ -4128,6 +4162,8 @@ int r600_irq_set(struct radeon_device *rdev) | |||
4128 | } | 4162 | } |
4129 | if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) { | 4163 | if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) { |
4130 | WREG32(CG_THERMAL_INT, thermal_int); | 4164 | WREG32(CG_THERMAL_INT, thermal_int); |
4165 | } else if (rdev->family >= CHIP_RV770) { | ||
4166 | WREG32(RV770_CG_THERMAL_INT, thermal_int); | ||
4131 | } | 4167 | } |
4132 | 4168 | ||
4133 | return 0; | 4169 | return 0; |