aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/Makefile3
-rw-r--r--drivers/gpu/drm/radeon/ppsmc.h78
-rw-r--r--drivers/gpu/drm/radeon/r600.c48
-rw-r--r--drivers/gpu/drm/radeon/r600d.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ucode.h21
-rw-r--r--drivers/gpu/drm/radeon/rv730_dpm.c508
-rw-r--r--drivers/gpu/drm/radeon/rv730d.h165
-rw-r--r--drivers/gpu/drm/radeon/rv740_dpm.c417
-rw-r--r--drivers/gpu/drm/radeon/rv740d.h117
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c2337
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.h273
-rw-r--r--drivers/gpu/drm/radeon/rv770_smc.c404
-rw-r--r--drivers/gpu/drm/radeon/rv770_smc.h208
-rw-r--r--drivers/gpu/drm/radeon/rv770d.h279
18 files changed, 4876 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 3aa20dc686fc..c97753d3d970 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -77,7 +77,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
77 evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ 77 evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
78 atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ 78 atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
79 si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \ 79 si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
80 r600_dpm.o rs780_dpm.o rv6xx_dpm.o 80 r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
81 rv770_smc.o
81 82
82radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 83radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
83radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 84radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h
new file mode 100644
index 000000000000..c85b96eac75f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/ppsmc.h
@@ -0,0 +1,78 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef PP_SMC_H
24#define PP_SMC_H
25
26#pragma pack(push, 1)
27
28#define PPSMC_SWSTATE_FLAG_DC 0x01
29
30#define PPSMC_THERMAL_PROTECT_TYPE_INTERNAL 0x00
31#define PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL 0x01
32#define PPSMC_THERMAL_PROTECT_TYPE_NONE 0xff
33
34#define PPSMC_SYSTEMFLAG_GPIO_DC 0x01
35#define PPSMC_SYSTEMFLAG_STEPVDDC 0x02
36#define PPSMC_SYSTEMFLAG_GDDR5 0x04
37#define PPSMC_SYSTEMFLAG_DISABLE_BABYSTEP 0x08
38#define PPSMC_SYSTEMFLAG_REGULATOR_HOT 0x10
39
40#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_MASK 0x07
41#define PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK 0x08
42#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTODPMLOWSTATE 0x00
43#define PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE 0x01
44
45#define PPSMC_DISPLAY_WATERMARK_LOW 0
46#define PPSMC_DISPLAY_WATERMARK_HIGH 1
47
48#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01
49
50#define PPSMC_Result_OK ((uint8_t)0x01)
51#define PPSMC_Result_Failed ((uint8_t)0xFF)
52
53typedef uint8_t PPSMC_Result;
54
55#define PPSMC_MSG_Halt ((uint8_t)0x10)
56#define PPSMC_MSG_Resume ((uint8_t)0x11)
57#define PPSMC_MSG_ZeroLevelsDisabled ((uint8_t)0x13)
58#define PPSMC_MSG_OneLevelsDisabled ((uint8_t)0x14)
59#define PPSMC_MSG_TwoLevelsDisabled ((uint8_t)0x15)
60#define PPSMC_MSG_EnableThermalInterrupt ((uint8_t)0x16)
61#define PPSMC_MSG_SwitchToSwState ((uint8_t)0x20)
62#define PPSMC_MSG_SwitchToInitialState ((uint8_t)0x40)
63#define PPSMC_MSG_NoForcedLevel ((uint8_t)0x41)
64#define PPSMC_MSG_SwitchToMinimumPower ((uint8_t)0x51)
65#define PPSMC_MSG_ResumeFromMinimumPower ((uint8_t)0x52)
66#define PPSMC_MSG_NoDisplay ((uint8_t)0x5D)
67#define PPSMC_MSG_HasDisplay ((uint8_t)0x5E)
68#define PPSMC_MSG_EnableULV ((uint8_t)0x62)
69#define PPSMC_MSG_DisableULV ((uint8_t)0x63)
70#define PPSMC_MSG_EnterULV ((uint8_t)0x64)
71#define PPSMC_MSG_ExitULV ((uint8_t)0x65)
72#define PPSMC_MSG_ResetToDefaults ((uint8_t)0x84)
73
74typedef uint8_t PPSMC_Msg;
75
76#pragma pack(pop)
77
78#endif
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");
57MODULE_FIRMWARE("radeon/RS780_me.bin"); 57MODULE_FIRMWARE("radeon/RS780_me.bin");
58MODULE_FIRMWARE("radeon/RV770_pfp.bin"); 58MODULE_FIRMWARE("radeon/RV770_pfp.bin");
59MODULE_FIRMWARE("radeon/RV770_me.bin"); 59MODULE_FIRMWARE("radeon/RV770_me.bin");
60MODULE_FIRMWARE("radeon/RV770_smc.bin");
60MODULE_FIRMWARE("radeon/RV730_pfp.bin"); 61MODULE_FIRMWARE("radeon/RV730_pfp.bin");
61MODULE_FIRMWARE("radeon/RV730_me.bin"); 62MODULE_FIRMWARE("radeon/RV730_me.bin");
63MODULE_FIRMWARE("radeon/RV730_smc.bin");
64MODULE_FIRMWARE("radeon/RV740_smc.bin");
62MODULE_FIRMWARE("radeon/RV710_pfp.bin"); 65MODULE_FIRMWARE("radeon/RV710_pfp.bin");
63MODULE_FIRMWARE("radeon/RV710_me.bin"); 66MODULE_FIRMWARE("radeon/RV710_me.bin");
67MODULE_FIRMWARE("radeon/RV710_smc.bin");
64MODULE_FIRMWARE("radeon/R600_rlc.bin"); 68MODULE_FIRMWARE("radeon/R600_rlc.bin");
65MODULE_FIRMWARE("radeon/R700_rlc.bin"); 69MODULE_FIRMWARE("radeon/R700_rlc.bin");
66MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); 70MODULE_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
2280out: 2309out:
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;
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 3bca4db4c46f..f1b3084d8f51 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -320,6 +320,8 @@
320#define THERM_INT_MASK_HIGH (1 << 24) 320#define THERM_INT_MASK_HIGH (1 << 24)
321#define THERM_INT_MASK_LOW (1 << 25) 321#define THERM_INT_MASK_LOW (1 << 25)
322 322
323#define RV770_CG_THERMAL_INT 0x734
324
323#define HDP_HOST_PATH_CNTL 0x2C00 325#define HDP_HOST_PATH_CNTL 0x2C00
324#define HDP_NONSURFACE_BASE 0x2C04 326#define HDP_NONSURFACE_BASE 0x2C04
325#define HDP_NONSURFACE_INFO 0x2C08 327#define HDP_NONSURFACE_INFO 0x2C08
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f9069055b069..7221ff43fdc8 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1913,6 +1913,7 @@ struct radeon_device {
1913 const struct firmware *uvd_fw; /* UVD firmware */ 1913 const struct firmware *uvd_fw; /* UVD firmware */
1914 const struct firmware *mec_fw; /* CIK MEC firmware */ 1914 const struct firmware *mec_fw; /* CIK MEC firmware */
1915 const struct firmware *sdma_fw; /* CIK SDMA firmware */ 1915 const struct firmware *sdma_fw; /* CIK SDMA firmware */
1916 const struct firmware *smc_fw; /* SMC firmware */
1916 struct r600_blit r600_blit; 1917 struct r600_blit r600_blit;
1917 struct r600_vram_scratch vram_scratch; 1918 struct r600_vram_scratch vram_scratch;
1918 int msi_enabled; /* msi enabled */ 1919 int msi_enabled; /* msi enabled */
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 45fb196c2cb9..2c18a796d351 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1374,6 +1374,18 @@ static struct radeon_asic rv770_asic = {
1374 .set_uvd_clocks = &rv770_set_uvd_clocks, 1374 .set_uvd_clocks = &rv770_set_uvd_clocks,
1375 .get_temperature = &rv770_get_temp, 1375 .get_temperature = &rv770_get_temp,
1376 }, 1376 },
1377 .dpm = {
1378 .init = &rv770_dpm_init,
1379 .setup_asic = &rv770_dpm_setup_asic,
1380 .enable = &rv770_dpm_enable,
1381 .disable = &rv770_dpm_disable,
1382 .set_power_state = &rv770_dpm_set_power_state,
1383 .display_configuration_changed = &rv770_dpm_display_configuration_changed,
1384 .fini = &rv770_dpm_fini,
1385 .get_sclk = &rv770_dpm_get_sclk,
1386 .get_mclk = &rv770_dpm_get_mclk,
1387 .print_power_state = &rv770_dpm_print_power_state,
1388 },
1377 .pflip = { 1389 .pflip = {
1378 .pre_page_flip = &rs600_pre_page_flip, 1390 .pre_page_flip = &rs600_pre_page_flip,
1379 .page_flip = &rv770_page_flip, 1391 .page_flip = &rv770_page_flip,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 36f66faa1d15..ad668a533848 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -460,6 +460,18 @@ u32 rv770_get_xclk(struct radeon_device *rdev);
460int rv770_uvd_resume(struct radeon_device *rdev); 460int rv770_uvd_resume(struct radeon_device *rdev);
461int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); 461int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk);
462int rv770_get_temp(struct radeon_device *rdev); 462int rv770_get_temp(struct radeon_device *rdev);
463/* rv7xx pm */
464int rv770_dpm_init(struct radeon_device *rdev);
465int rv770_dpm_enable(struct radeon_device *rdev);
466void rv770_dpm_disable(struct radeon_device *rdev);
467int rv770_dpm_set_power_state(struct radeon_device *rdev);
468void rv770_dpm_setup_asic(struct radeon_device *rdev);
469void rv770_dpm_display_configuration_changed(struct radeon_device *rdev);
470void rv770_dpm_fini(struct radeon_device *rdev);
471u32 rv770_dpm_get_sclk(struct radeon_device *rdev, bool low);
472u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low);
473void rv770_dpm_print_power_state(struct radeon_device *rdev,
474 struct radeon_ps *ps);
463 475
464/* 476/*
465 * evergreen 477 * evergreen
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 17f28974745e..09eef285f27b 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1037,6 +1037,10 @@ int radeon_pm_init(struct radeon_device *rdev)
1037 case CHIP_RV670: 1037 case CHIP_RV670:
1038 case CHIP_RS780: 1038 case CHIP_RS780:
1039 case CHIP_RS880: 1039 case CHIP_RS880:
1040 case CHIP_RV770:
1041 case CHIP_RV730:
1042 case CHIP_RV710:
1043 case CHIP_RV740:
1040 if (radeon_dpm == 1) 1044 if (radeon_dpm == 1)
1041 rdev->pm.pm_method = PM_METHOD_DPM; 1045 rdev->pm.pm_method = PM_METHOD_DPM;
1042 else 1046 else
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h
index d2642b01578a..19105455330d 100644
--- a/drivers/gpu/drm/radeon/radeon_ucode.h
+++ b/drivers/gpu/drm/radeon/radeon_ucode.h
@@ -44,4 +44,25 @@
44#define BTC_MC_UCODE_SIZE 6024 44#define BTC_MC_UCODE_SIZE 6024
45#define CAYMAN_MC_UCODE_SIZE 6037 45#define CAYMAN_MC_UCODE_SIZE 6037
46 46
47/* SMC */
48#define RV770_SMC_UCODE_START 0x0100
49#define RV770_SMC_UCODE_SIZE 0x410d
50#define RV770_SMC_INT_VECTOR_START 0xffc0
51#define RV770_SMC_INT_VECTOR_SIZE 0x0040
52
53#define RV730_SMC_UCODE_START 0x0100
54#define RV730_SMC_UCODE_SIZE 0x412c
55#define RV730_SMC_INT_VECTOR_START 0xffc0
56#define RV730_SMC_INT_VECTOR_SIZE 0x0040
57
58#define RV710_SMC_UCODE_START 0x0100
59#define RV710_SMC_UCODE_SIZE 0x3f1f
60#define RV710_SMC_INT_VECTOR_START 0xffc0
61#define RV710_SMC_INT_VECTOR_SIZE 0x0040
62
63#define RV740_SMC_UCODE_START 0x0100
64#define RV740_SMC_UCODE_SIZE 0x41c5
65#define RV740_SMC_INT_VECTOR_START 0xffc0
66#define RV740_SMC_INT_VECTOR_SIZE 0x0040
67
47#endif 68#endif
diff --git a/drivers/gpu/drm/radeon/rv730_dpm.c b/drivers/gpu/drm/radeon/rv730_dpm.c
new file mode 100644
index 000000000000..3f5e1cf138ba
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv730_dpm.c
@@ -0,0 +1,508 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Alex Deucher
23 */
24
25#include "drmP.h"
26#include "radeon.h"
27#include "rv730d.h"
28#include "r600_dpm.h"
29#include "rv770_dpm.h"
30#include "atom.h"
31
32#define MC_CG_ARB_FREQ_F0 0x0a
33#define MC_CG_ARB_FREQ_F1 0x0b
34#define MC_CG_ARB_FREQ_F2 0x0c
35#define MC_CG_ARB_FREQ_F3 0x0d
36
37struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
38struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
39
40int rv730_populate_sclk_value(struct radeon_device *rdev,
41 u32 engine_clock,
42 RV770_SMC_SCLK_VALUE *sclk)
43{
44 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
45 struct atom_clock_dividers dividers;
46 u32 spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl;
47 u32 spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2;
48 u32 spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3;
49 u32 cg_spll_spread_spectrum = pi->clk_regs.rv730.cg_spll_spread_spectrum;
50 u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv730.cg_spll_spread_spectrum_2;
51 u64 tmp;
52 u32 reference_clock = rdev->clock.spll.reference_freq;
53 u32 reference_divider, post_divider;
54 u32 fbdiv;
55 int ret;
56
57 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
58 engine_clock, false, &dividers);
59 if (ret)
60 return ret;
61
62 reference_divider = 1 + dividers.ref_div;
63
64 if (dividers.enable_post_div)
65 post_divider = ((dividers.post_div >> 4) & 0xf) +
66 (dividers.post_div & 0xf) + 2;
67 else
68 post_divider = 1;
69
70 tmp = (u64) engine_clock * reference_divider * post_divider * 16384;
71 do_div(tmp, reference_clock);
72 fbdiv = (u32) tmp;
73
74 /* set up registers */
75 if (dividers.enable_post_div)
76 spll_func_cntl |= SPLL_DIVEN;
77 else
78 spll_func_cntl &= ~SPLL_DIVEN;
79 spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK);
80 spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
81 spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf);
82 spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf);
83
84 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
85 spll_func_cntl_2 |= SCLK_MUX_SEL(2);
86
87 spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
88 spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
89 spll_func_cntl_3 |= SPLL_DITHEN;
90
91 if (pi->sclk_ss) {
92 struct radeon_atom_ss ss;
93 u32 vco_freq = engine_clock * post_divider;
94
95 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
96 ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
97 u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
98 u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
99
100 cg_spll_spread_spectrum &= ~CLK_S_MASK;
101 cg_spll_spread_spectrum |= CLK_S(clk_s);
102 cg_spll_spread_spectrum |= SSEN;
103
104 cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
105 cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
106 }
107 }
108
109 sclk->sclk_value = cpu_to_be32(engine_clock);
110 sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
111 sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
112 sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
113 sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
114 sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
115
116 return 0;
117}
118
119int rv730_populate_mclk_value(struct radeon_device *rdev,
120 u32 engine_clock, u32 memory_clock,
121 LPRV7XX_SMC_MCLK_VALUE mclk)
122{
123 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
124 u32 mclk_pwrmgt_cntl = pi->clk_regs.rv730.mclk_pwrmgt_cntl;
125 u32 dll_cntl = pi->clk_regs.rv730.dll_cntl;
126 u32 mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl;
127 u32 mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2;
128 u32 mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3;
129 u32 mpll_ss = pi->clk_regs.rv730.mpll_ss;
130 u32 mpll_ss2 = pi->clk_regs.rv730.mpll_ss2;
131 struct atom_clock_dividers dividers;
132 u32 post_divider, reference_divider;
133 int ret;
134
135 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
136 memory_clock, false, &dividers);
137 if (ret)
138 return ret;
139
140 reference_divider = dividers.ref_div + 1;
141
142 if (dividers.enable_post_div)
143 post_divider = ((dividers.post_div >> 4) & 0xf) +
144 (dividers.post_div & 0xf) + 2;
145 else
146 post_divider = 1;
147
148 /* setup the registers */
149 if (dividers.enable_post_div)
150 mpll_func_cntl |= MPLL_DIVEN;
151 else
152 mpll_func_cntl &= ~MPLL_DIVEN;
153
154 mpll_func_cntl &= ~(MPLL_REF_DIV_MASK | MPLL_HILEN_MASK | MPLL_LOLEN_MASK);
155 mpll_func_cntl |= MPLL_REF_DIV(dividers.ref_div);
156 mpll_func_cntl |= MPLL_HILEN((dividers.post_div >> 4) & 0xf);
157 mpll_func_cntl |= MPLL_LOLEN(dividers.post_div & 0xf);
158
159 mpll_func_cntl_3 &= ~MPLL_FB_DIV_MASK;
160 mpll_func_cntl_3 |= MPLL_FB_DIV(dividers.fb_div);
161 if (dividers.enable_dithen)
162 mpll_func_cntl_3 |= MPLL_DITHEN;
163 else
164 mpll_func_cntl_3 &= ~MPLL_DITHEN;
165
166 if (pi->mclk_ss) {
167 struct radeon_atom_ss ss;
168 u32 vco_freq = memory_clock * post_divider;
169
170 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
171 ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
172 u32 reference_clock = rdev->clock.mpll.reference_freq;
173 u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
174 u32 clk_v = ss.percentage * dividers.fb_div / (clk_s * 10000);
175
176 mpll_ss &= ~CLK_S_MASK;
177 mpll_ss |= CLK_S(clk_s);
178 mpll_ss |= SSEN;
179
180 mpll_ss2 &= ~CLK_V_MASK;
181 mpll_ss |= CLK_V(clk_v);
182 }
183 }
184
185
186 mclk->mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
187 mclk->mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl);
188 mclk->mclk730.mclk_value = cpu_to_be32(memory_clock);
189 mclk->mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
190 mclk->mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2);
191 mclk->mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3);
192 mclk->mclk730.vMPLL_SS = cpu_to_be32(mpll_ss);
193 mclk->mclk730.vMPLL_SS2 = cpu_to_be32(mpll_ss2);
194
195 return 0;
196}
197
198void rv730_read_clock_registers(struct radeon_device *rdev)
199{
200 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
201
202 pi->clk_regs.rv730.cg_spll_func_cntl =
203 RREG32(CG_SPLL_FUNC_CNTL);
204 pi->clk_regs.rv730.cg_spll_func_cntl_2 =
205 RREG32(CG_SPLL_FUNC_CNTL_2);
206 pi->clk_regs.rv730.cg_spll_func_cntl_3 =
207 RREG32(CG_SPLL_FUNC_CNTL_3);
208 pi->clk_regs.rv730.cg_spll_spread_spectrum =
209 RREG32(CG_SPLL_SPREAD_SPECTRUM);
210 pi->clk_regs.rv730.cg_spll_spread_spectrum_2 =
211 RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
212
213 pi->clk_regs.rv730.mclk_pwrmgt_cntl =
214 RREG32(TCI_MCLK_PWRMGT_CNTL);
215 pi->clk_regs.rv730.dll_cntl =
216 RREG32(TCI_DLL_CNTL);
217 pi->clk_regs.rv730.mpll_func_cntl =
218 RREG32(CG_MPLL_FUNC_CNTL);
219 pi->clk_regs.rv730.mpll_func_cntl2 =
220 RREG32(CG_MPLL_FUNC_CNTL_2);
221 pi->clk_regs.rv730.mpll_func_cntl3 =
222 RREG32(CG_MPLL_FUNC_CNTL_3);
223 pi->clk_regs.rv730.mpll_ss =
224 RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM);
225 pi->clk_regs.rv730.mpll_ss2 =
226 RREG32(CG_TCI_MPLL_SPREAD_SPECTRUM_2);
227}
228
229int rv730_populate_smc_acpi_state(struct radeon_device *rdev,
230 RV770_SMC_STATETABLE *table)
231{
232 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
233 u32 mpll_func_cntl = 0;
234 u32 mpll_func_cntl_2 = 0 ;
235 u32 mpll_func_cntl_3 = 0;
236 u32 mclk_pwrmgt_cntl;
237 u32 dll_cntl;
238 u32 spll_func_cntl;
239 u32 spll_func_cntl_2;
240 u32 spll_func_cntl_3;
241
242 table->ACPIState = table->initialState;
243 table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
244
245 if (pi->acpi_vddc) {
246 rv770_populate_vddc_value(rdev, pi->acpi_vddc,
247 &table->ACPIState.levels[0].vddc);
248 table->ACPIState.levels[0].gen2PCIE = pi->pcie_gen2 ?
249 pi->acpi_pcie_gen2 : 0;
250 table->ACPIState.levels[0].gen2XSP =
251 pi->acpi_pcie_gen2;
252 } else {
253 rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
254 &table->ACPIState.levels[0].vddc);
255 table->ACPIState.levels[0].gen2PCIE = 0;
256 }
257
258 mpll_func_cntl = pi->clk_regs.rv730.mpll_func_cntl;
259 mpll_func_cntl_2 = pi->clk_regs.rv730.mpll_func_cntl2;
260 mpll_func_cntl_3 = pi->clk_regs.rv730.mpll_func_cntl3;
261
262 mpll_func_cntl |= MPLL_RESET | MPLL_BYPASS_EN;
263 mpll_func_cntl &= ~MPLL_SLEEP;
264
265 mpll_func_cntl_2 &= ~MCLK_MUX_SEL_MASK;
266 mpll_func_cntl_2 |= MCLK_MUX_SEL(1);
267
268 mclk_pwrmgt_cntl = (MRDCKA_RESET |
269 MRDCKB_RESET |
270 MRDCKC_RESET |
271 MRDCKD_RESET |
272 MRDCKE_RESET |
273 MRDCKF_RESET |
274 MRDCKG_RESET |
275 MRDCKH_RESET |
276 MRDCKA_SLEEP |
277 MRDCKB_SLEEP |
278 MRDCKC_SLEEP |
279 MRDCKD_SLEEP |
280 MRDCKE_SLEEP |
281 MRDCKF_SLEEP |
282 MRDCKG_SLEEP |
283 MRDCKH_SLEEP);
284
285 dll_cntl = 0xff000000;
286
287 spll_func_cntl = pi->clk_regs.rv730.cg_spll_func_cntl;
288 spll_func_cntl_2 = pi->clk_regs.rv730.cg_spll_func_cntl_2;
289 spll_func_cntl_3 = pi->clk_regs.rv730.cg_spll_func_cntl_3;
290
291 spll_func_cntl |= SPLL_RESET | SPLL_BYPASS_EN;
292 spll_func_cntl &= ~SPLL_SLEEP;
293
294 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
295 spll_func_cntl_2 |= SCLK_MUX_SEL(4);
296
297 table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
298 table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 = cpu_to_be32(mpll_func_cntl_2);
299 table->ACPIState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 = cpu_to_be32(mpll_func_cntl_3);
300 table->ACPIState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
301 table->ACPIState.levels[0].mclk.mclk730.vDLL_CNTL = cpu_to_be32(dll_cntl);
302
303 table->ACPIState.levels[0].mclk.mclk730.mclk_value = 0;
304
305 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
306 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
307 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
308
309 table->ACPIState.levels[0].sclk.sclk_value = 0;
310
311 rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
312
313 table->ACPIState.levels[1] = table->ACPIState.levels[0];
314 table->ACPIState.levels[2] = table->ACPIState.levels[0];
315
316 return 0;
317}
318
319int rv730_populate_smc_initial_state(struct radeon_device *rdev,
320 struct radeon_ps *radeon_state,
321 RV770_SMC_STATETABLE *table)
322{
323 struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state);
324 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
325 u32 a_t;
326
327 table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL =
328 cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl);
329 table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL2 =
330 cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl2);
331 table->initialState.levels[0].mclk.mclk730.vMPLL_FUNC_CNTL3 =
332 cpu_to_be32(pi->clk_regs.rv730.mpll_func_cntl3);
333 table->initialState.levels[0].mclk.mclk730.vMCLK_PWRMGT_CNTL =
334 cpu_to_be32(pi->clk_regs.rv730.mclk_pwrmgt_cntl);
335 table->initialState.levels[0].mclk.mclk730.vDLL_CNTL =
336 cpu_to_be32(pi->clk_regs.rv730.dll_cntl);
337 table->initialState.levels[0].mclk.mclk730.vMPLL_SS =
338 cpu_to_be32(pi->clk_regs.rv730.mpll_ss);
339 table->initialState.levels[0].mclk.mclk730.vMPLL_SS2 =
340 cpu_to_be32(pi->clk_regs.rv730.mpll_ss2);
341
342 table->initialState.levels[0].mclk.mclk730.mclk_value =
343 cpu_to_be32(initial_state->low.mclk);
344
345 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
346 cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl);
347 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
348 cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_2);
349 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
350 cpu_to_be32(pi->clk_regs.rv730.cg_spll_func_cntl_3);
351 table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
352 cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum);
353 table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
354 cpu_to_be32(pi->clk_regs.rv730.cg_spll_spread_spectrum_2);
355
356 table->initialState.levels[0].sclk.sclk_value =
357 cpu_to_be32(initial_state->low.sclk);
358
359 table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
360
361 table->initialState.levels[0].seqValue =
362 rv770_get_seq_value(rdev, &initial_state->low);
363
364 rv770_populate_vddc_value(rdev,
365 initial_state->low.vddc,
366 &table->initialState.levels[0].vddc);
367 rv770_populate_initial_mvdd_value(rdev,
368 &table->initialState.levels[0].mvdd);
369
370 a_t = CG_R(0xffff) | CG_L(0);
371
372 table->initialState.levels[0].aT = cpu_to_be32(a_t);
373
374 table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
375
376 if (pi->boot_in_gen2)
377 table->initialState.levels[0].gen2PCIE = 1;
378 else
379 table->initialState.levels[0].gen2PCIE = 0;
380 if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
381 table->initialState.levels[0].gen2XSP = 1;
382 else
383 table->initialState.levels[0].gen2XSP = 0;
384
385 table->initialState.levels[1] = table->initialState.levels[0];
386 table->initialState.levels[2] = table->initialState.levels[0];
387
388 table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
389
390 return 0;
391}
392
393void rv730_program_memory_timing_parameters(struct radeon_device *rdev,
394 struct radeon_ps *radeon_state)
395{
396 struct rv7xx_ps *state = rv770_get_ps(radeon_state);
397 u32 arb_refresh_rate = 0;
398 u32 dram_timing = 0;
399 u32 dram_timing2 = 0;
400 u32 old_dram_timing = 0;
401 u32 old_dram_timing2 = 0;
402
403 arb_refresh_rate = RREG32(MC_ARB_RFSH_RATE) &
404 ~(POWERMODE1_MASK | POWERMODE2_MASK | POWERMODE3_MASK);
405 arb_refresh_rate |=
406 (POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) |
407 POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) |
408 POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk)));
409 WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate);
410
411 /* save the boot dram timings */
412 old_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
413 old_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
414
415 radeon_atom_set_engine_dram_timings(rdev,
416 state->high.sclk,
417 state->high.mclk);
418
419 dram_timing = RREG32(MC_ARB_DRAM_TIMING);
420 dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
421
422 WREG32(MC_ARB_DRAM_TIMING_3, dram_timing);
423 WREG32(MC_ARB_DRAM_TIMING2_3, dram_timing2);
424
425 radeon_atom_set_engine_dram_timings(rdev,
426 state->medium.sclk,
427 state->medium.mclk);
428
429 dram_timing = RREG32(MC_ARB_DRAM_TIMING);
430 dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
431
432 WREG32(MC_ARB_DRAM_TIMING_2, dram_timing);
433 WREG32(MC_ARB_DRAM_TIMING2_2, dram_timing2);
434
435 radeon_atom_set_engine_dram_timings(rdev,
436 state->low.sclk,
437 state->low.mclk);
438
439 dram_timing = RREG32(MC_ARB_DRAM_TIMING);
440 dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
441
442 WREG32(MC_ARB_DRAM_TIMING_1, dram_timing);
443 WREG32(MC_ARB_DRAM_TIMING2_1, dram_timing2);
444
445 /* restore the boot dram timings */
446 WREG32(MC_ARB_DRAM_TIMING, old_dram_timing);
447 WREG32(MC_ARB_DRAM_TIMING2, old_dram_timing2);
448
449}
450
451void rv730_start_dpm(struct radeon_device *rdev)
452{
453 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
454
455 WREG32_P(TCI_MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
456
457 WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
458}
459
460void rv730_stop_dpm(struct radeon_device *rdev)
461{
462 PPSMC_Result result;
463
464 result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
465
466 if (result != PPSMC_Result_OK)
467 DRM_ERROR("Could not force DPM to low\n");
468
469 WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
470
471 WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
472
473 WREG32_P(TCI_MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
474}
475
476void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt)
477{
478 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
479 u32 i = use_dcodt ? 0 : 1;
480 u32 mc4_io_pad_cntl;
481
482 mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0);
483 mc4_io_pad_cntl &= 0xFFFFFF00;
484 mc4_io_pad_cntl |= pi->odt_value_0[i];
485 WREG32(MC4_IO_DQ_PAD_CNTL_D0_I0, mc4_io_pad_cntl);
486 WREG32(MC4_IO_DQ_PAD_CNTL_D0_I1, mc4_io_pad_cntl);
487
488 mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0);
489 mc4_io_pad_cntl &= 0xFFFFFF00;
490 mc4_io_pad_cntl |= pi->odt_value_1[i];
491 WREG32(MC4_IO_QS_PAD_CNTL_D0_I0, mc4_io_pad_cntl);
492 WREG32(MC4_IO_QS_PAD_CNTL_D0_I1, mc4_io_pad_cntl);
493}
494
495void rv730_get_odt_values(struct radeon_device *rdev)
496{
497 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
498 u32 mc4_io_pad_cntl;
499
500 pi->odt_value_0[0] = (u8)0;
501 pi->odt_value_1[0] = (u8)0x80;
502
503 mc4_io_pad_cntl = RREG32(MC4_IO_DQ_PAD_CNTL_D0_I0);
504 pi->odt_value_0[1] = (u8)(mc4_io_pad_cntl & 0xff);
505
506 mc4_io_pad_cntl = RREG32(MC4_IO_QS_PAD_CNTL_D0_I0);
507 pi->odt_value_1[1] = (u8)(mc4_io_pad_cntl & 0xff);
508}
diff --git a/drivers/gpu/drm/radeon/rv730d.h b/drivers/gpu/drm/radeon/rv730d.h
new file mode 100644
index 000000000000..f0a7954fb1cb
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv730d.h
@@ -0,0 +1,165 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef RV730_H
24#define RV730_H
25
26#define CG_SPLL_FUNC_CNTL 0x600
27#define SPLL_RESET (1 << 0)
28#define SPLL_SLEEP (1 << 1)
29#define SPLL_DIVEN (1 << 2)
30#define SPLL_BYPASS_EN (1 << 3)
31#define SPLL_REF_DIV(x) ((x) << 4)
32#define SPLL_REF_DIV_MASK (0x3f << 4)
33#define SPLL_HILEN(x) ((x) << 12)
34#define SPLL_HILEN_MASK (0xf << 12)
35#define SPLL_LOLEN(x) ((x) << 16)
36#define SPLL_LOLEN_MASK (0xf << 16)
37#define CG_SPLL_FUNC_CNTL_2 0x604
38#define SCLK_MUX_SEL(x) ((x) << 0)
39#define SCLK_MUX_SEL_MASK (0x1ff << 0)
40#define CG_SPLL_FUNC_CNTL_3 0x608
41#define SPLL_FB_DIV(x) ((x) << 0)
42#define SPLL_FB_DIV_MASK (0x3ffffff << 0)
43#define SPLL_DITHEN (1 << 28)
44
45#define CG_MPLL_FUNC_CNTL 0x624
46#define MPLL_RESET (1 << 0)
47#define MPLL_SLEEP (1 << 1)
48#define MPLL_DIVEN (1 << 2)
49#define MPLL_BYPASS_EN (1 << 3)
50#define MPLL_REF_DIV(x) ((x) << 4)
51#define MPLL_REF_DIV_MASK (0x3f << 4)
52#define MPLL_HILEN(x) ((x) << 12)
53#define MPLL_HILEN_MASK (0xf << 12)
54#define MPLL_LOLEN(x) ((x) << 16)
55#define MPLL_LOLEN_MASK (0xf << 16)
56#define CG_MPLL_FUNC_CNTL_2 0x628
57#define MCLK_MUX_SEL(x) ((x) << 0)
58#define MCLK_MUX_SEL_MASK (0x1ff << 0)
59#define CG_MPLL_FUNC_CNTL_3 0x62c
60#define MPLL_FB_DIV(x) ((x) << 0)
61#define MPLL_FB_DIV_MASK (0x3ffffff << 0)
62#define MPLL_DITHEN (1 << 28)
63
64#define CG_TCI_MPLL_SPREAD_SPECTRUM 0x634
65#define CG_TCI_MPLL_SPREAD_SPECTRUM_2 0x638
66#define GENERAL_PWRMGT 0x63c
67# define GLOBAL_PWRMGT_EN (1 << 0)
68# define STATIC_PM_EN (1 << 1)
69# define THERMAL_PROTECTION_DIS (1 << 2)
70# define THERMAL_PROTECTION_TYPE (1 << 3)
71# define ENABLE_GEN2PCIE (1 << 4)
72# define ENABLE_GEN2XSP (1 << 5)
73# define SW_SMIO_INDEX(x) ((x) << 6)
74# define SW_SMIO_INDEX_MASK (3 << 6)
75# define LOW_VOLT_D2_ACPI (1 << 8)
76# define LOW_VOLT_D3_ACPI (1 << 9)
77# define VOLT_PWRMGT_EN (1 << 10)
78# define BACKBIAS_PAD_EN (1 << 18)
79# define BACKBIAS_VALUE (1 << 19)
80# define DYN_SPREAD_SPECTRUM_EN (1 << 23)
81# define AC_DC_SW (1 << 24)
82
83#define SCLK_PWRMGT_CNTL 0x644
84# define SCLK_PWRMGT_OFF (1 << 0)
85# define SCLK_LOW_D1 (1 << 1)
86# define FIR_RESET (1 << 4)
87# define FIR_FORCE_TREND_SEL (1 << 5)
88# define FIR_TREND_MODE (1 << 6)
89# define DYN_GFX_CLK_OFF_EN (1 << 7)
90# define GFX_CLK_FORCE_ON (1 << 8)
91# define GFX_CLK_REQUEST_OFF (1 << 9)
92# define GFX_CLK_FORCE_OFF (1 << 10)
93# define GFX_CLK_OFF_ACPI_D1 (1 << 11)
94# define GFX_CLK_OFF_ACPI_D2 (1 << 12)
95# define GFX_CLK_OFF_ACPI_D3 (1 << 13)
96
97#define TCI_MCLK_PWRMGT_CNTL 0x648
98# define MPLL_PWRMGT_OFF (1 << 5)
99# define DLL_READY (1 << 6)
100# define MC_INT_CNTL (1 << 7)
101# define MRDCKA_SLEEP (1 << 8)
102# define MRDCKB_SLEEP (1 << 9)
103# define MRDCKC_SLEEP (1 << 10)
104# define MRDCKD_SLEEP (1 << 11)
105# define MRDCKE_SLEEP (1 << 12)
106# define MRDCKF_SLEEP (1 << 13)
107# define MRDCKG_SLEEP (1 << 14)
108# define MRDCKH_SLEEP (1 << 15)
109# define MRDCKA_RESET (1 << 16)
110# define MRDCKB_RESET (1 << 17)
111# define MRDCKC_RESET (1 << 18)
112# define MRDCKD_RESET (1 << 19)
113# define MRDCKE_RESET (1 << 20)
114# define MRDCKF_RESET (1 << 21)
115# define MRDCKG_RESET (1 << 22)
116# define MRDCKH_RESET (1 << 23)
117# define DLL_READY_READ (1 << 24)
118# define USE_DISPLAY_GAP (1 << 25)
119# define USE_DISPLAY_URGENT_NORMAL (1 << 26)
120# define MPLL_TURNOFF_D2 (1 << 28)
121#define TCI_DLL_CNTL 0x64c
122
123#define CG_PG_CNTL 0x858
124# define PWRGATE_ENABLE (1 << 0)
125
126#define CG_AT 0x6d4
127#define CG_R(x) ((x) << 0)
128#define CG_R_MASK (0xffff << 0)
129#define CG_L(x) ((x) << 16)
130#define CG_L_MASK (0xffff << 16)
131
132#define CG_SPLL_SPREAD_SPECTRUM 0x790
133#define SSEN (1 << 0)
134#define CLK_S(x) ((x) << 4)
135#define CLK_S_MASK (0xfff << 4)
136#define CG_SPLL_SPREAD_SPECTRUM_2 0x794
137#define CLK_V(x) ((x) << 0)
138#define CLK_V_MASK (0x3ffffff << 0)
139
140#define MC_ARB_DRAM_TIMING 0x2774
141#define MC_ARB_DRAM_TIMING2 0x2778
142
143#define MC_ARB_RFSH_RATE 0x27b0
144#define POWERMODE0(x) ((x) << 0)
145#define POWERMODE0_MASK (0xff << 0)
146#define POWERMODE1(x) ((x) << 8)
147#define POWERMODE1_MASK (0xff << 8)
148#define POWERMODE2(x) ((x) << 16)
149#define POWERMODE2_MASK (0xff << 16)
150#define POWERMODE3(x) ((x) << 24)
151#define POWERMODE3_MASK (0xff << 24)
152
153#define MC_ARB_DRAM_TIMING_1 0x27f0
154#define MC_ARB_DRAM_TIMING_2 0x27f4
155#define MC_ARB_DRAM_TIMING_3 0x27f8
156#define MC_ARB_DRAM_TIMING2_1 0x27fc
157#define MC_ARB_DRAM_TIMING2_2 0x2800
158#define MC_ARB_DRAM_TIMING2_3 0x2804
159
160#define MC4_IO_DQ_PAD_CNTL_D0_I0 0x2978
161#define MC4_IO_DQ_PAD_CNTL_D0_I1 0x297c
162#define MC4_IO_QS_PAD_CNTL_D0_I0 0x2980
163#define MC4_IO_QS_PAD_CNTL_D0_I1 0x2984
164
165#endif
diff --git a/drivers/gpu/drm/radeon/rv740_dpm.c b/drivers/gpu/drm/radeon/rv740_dpm.c
new file mode 100644
index 000000000000..f6d79a1f62c1
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv740_dpm.c
@@ -0,0 +1,417 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Alex Deucher
23 */
24
25#include "drmP.h"
26#include "radeon.h"
27#include "rv740d.h"
28#include "r600_dpm.h"
29#include "rv770_dpm.h"
30#include "atom.h"
31
32struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
33struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
34
35u32 rv740_get_decoded_reference_divider(u32 encoded_ref)
36{
37 u32 ref = 0;
38
39 switch (encoded_ref) {
40 case 0:
41 ref = 1;
42 break;
43 case 16:
44 ref = 2;
45 break;
46 case 17:
47 ref = 3;
48 break;
49 case 18:
50 ref = 2;
51 break;
52 case 19:
53 ref = 3;
54 break;
55 case 20:
56 ref = 4;
57 break;
58 case 21:
59 ref = 5;
60 break;
61 default:
62 DRM_ERROR("Invalid encoded Reference Divider\n");
63 ref = 0;
64 break;
65 }
66
67 return ref;
68}
69
70struct dll_speed_setting {
71 u16 min;
72 u16 max;
73 u32 dll_speed;
74};
75
76static struct dll_speed_setting dll_speed_table[16] =
77{
78 { 270, 320, 0x0f },
79 { 240, 270, 0x0e },
80 { 200, 240, 0x0d },
81 { 180, 200, 0x0c },
82 { 160, 180, 0x0b },
83 { 140, 160, 0x0a },
84 { 120, 140, 0x09 },
85 { 110, 120, 0x08 },
86 { 95, 110, 0x07 },
87 { 85, 95, 0x06 },
88 { 78, 85, 0x05 },
89 { 70, 78, 0x04 },
90 { 65, 70, 0x03 },
91 { 60, 65, 0x02 },
92 { 42, 60, 0x01 },
93 { 00, 42, 0x00 }
94};
95
96u32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock)
97{
98 int i;
99 u32 factor;
100 u16 data_rate;
101
102 if (is_gddr5)
103 factor = 4;
104 else
105 factor = 2;
106
107 data_rate = (u16)(memory_clock * factor / 1000);
108
109 if (data_rate < dll_speed_table[0].max) {
110 for (i = 0; i < 16; i++) {
111 if (data_rate > dll_speed_table[i].min &&
112 data_rate <= dll_speed_table[i].max)
113 return dll_speed_table[i].dll_speed;
114 }
115 }
116
117 DRM_DEBUG_KMS("Target MCLK greater than largest MCLK in DLL speed table\n");
118
119 return 0x0f;
120}
121
122int rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock,
123 RV770_SMC_SCLK_VALUE *sclk)
124{
125 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
126 struct atom_clock_dividers dividers;
127 u32 spll_func_cntl = pi->clk_regs.rv770.cg_spll_func_cntl;
128 u32 spll_func_cntl_2 = pi->clk_regs.rv770.cg_spll_func_cntl_2;
129 u32 spll_func_cntl_3 = pi->clk_regs.rv770.cg_spll_func_cntl_3;
130 u32 cg_spll_spread_spectrum = pi->clk_regs.rv770.cg_spll_spread_spectrum;
131 u32 cg_spll_spread_spectrum_2 = pi->clk_regs.rv770.cg_spll_spread_spectrum_2;
132 u64 tmp;
133 u32 reference_clock = rdev->clock.spll.reference_freq;
134 u32 reference_divider;
135 u32 fbdiv;
136 int ret;
137
138 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
139 engine_clock, false, &dividers);
140 if (ret)
141 return ret;
142
143 reference_divider = 1 + dividers.ref_div;
144
145 tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;
146 do_div(tmp, reference_clock);
147 fbdiv = (u32) tmp;
148
149 spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
150 spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
151 spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
152
153 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
154 spll_func_cntl_2 |= SCLK_MUX_SEL(2);
155
156 spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
157 spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
158 spll_func_cntl_3 |= SPLL_DITHEN;
159
160 if (pi->sclk_ss) {
161 struct radeon_atom_ss ss;
162 u32 vco_freq = engine_clock * dividers.post_div;
163
164 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
165 ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
166 u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
167 u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
168
169 cg_spll_spread_spectrum &= ~CLK_S_MASK;
170 cg_spll_spread_spectrum |= CLK_S(clk_s);
171 cg_spll_spread_spectrum |= SSEN;
172
173 cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
174 cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
175 }
176 }
177
178 sclk->sclk_value = cpu_to_be32(engine_clock);
179 sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
180 sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
181 sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
182 sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
183 sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
184
185 return 0;
186}
187
188int rv740_populate_mclk_value(struct radeon_device *rdev,
189 u32 engine_clock, u32 memory_clock,
190 RV7XX_SMC_MCLK_VALUE *mclk)
191{
192 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
193 u32 mpll_ad_func_cntl = pi->clk_regs.rv770.mpll_ad_func_cntl;
194 u32 mpll_ad_func_cntl_2 = pi->clk_regs.rv770.mpll_ad_func_cntl_2;
195 u32 mpll_dq_func_cntl = pi->clk_regs.rv770.mpll_dq_func_cntl;
196 u32 mpll_dq_func_cntl_2 = pi->clk_regs.rv770.mpll_dq_func_cntl_2;
197 u32 mclk_pwrmgt_cntl = pi->clk_regs.rv770.mclk_pwrmgt_cntl;
198 u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
199 u32 mpll_ss1 = pi->clk_regs.rv770.mpll_ss1;
200 u32 mpll_ss2 = pi->clk_regs.rv770.mpll_ss2;
201 struct atom_clock_dividers dividers;
202 u32 ibias;
203 u32 dll_speed;
204 int ret;
205
206 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
207 memory_clock, false, &dividers);
208 if (ret)
209 return ret;
210
211 ibias = rv770_map_clkf_to_ibias(rdev, dividers.whole_fb_div);
212
213 mpll_ad_func_cntl &= ~(CLKR_MASK |
214 YCLK_POST_DIV_MASK |
215 CLKF_MASK |
216 CLKFRAC_MASK |
217 IBIAS_MASK);
218 mpll_ad_func_cntl |= CLKR(dividers.ref_div);
219 mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div);
220 mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div);
221 mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div);
222 mpll_ad_func_cntl |= IBIAS(ibias);
223
224 if (dividers.vco_mode)
225 mpll_ad_func_cntl_2 |= VCO_MODE;
226 else
227 mpll_ad_func_cntl_2 &= ~VCO_MODE;
228
229 if (pi->mem_gddr5) {
230 mpll_dq_func_cntl &= ~(CLKR_MASK |
231 YCLK_POST_DIV_MASK |
232 CLKF_MASK |
233 CLKFRAC_MASK |
234 IBIAS_MASK);
235 mpll_dq_func_cntl |= CLKR(dividers.ref_div);
236 mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div);
237 mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div);
238 mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div);
239 mpll_dq_func_cntl |= IBIAS(ibias);
240
241 if (dividers.vco_mode)
242 mpll_dq_func_cntl_2 |= VCO_MODE;
243 else
244 mpll_dq_func_cntl_2 &= ~VCO_MODE;
245 }
246
247 if (pi->mclk_ss) {
248 struct radeon_atom_ss ss;
249 u32 vco_freq = memory_clock * dividers.post_div;
250
251 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
252 ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
253 u32 reference_clock = rdev->clock.mpll.reference_freq;
254 u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
255 u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
256 u32 clk_v = 0x40000 * ss.percentage *
257 (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000);
258
259 mpll_ss1 &= ~CLKV_MASK;
260 mpll_ss1 |= CLKV(clk_v);
261
262 mpll_ss2 &= ~CLKS_MASK;
263 mpll_ss2 |= CLKS(clk_s);
264 }
265 }
266
267 dll_speed = rv740_get_dll_speed(pi->mem_gddr5,
268 memory_clock);
269
270 mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
271 mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed);
272
273 mclk->mclk770.mclk_value = cpu_to_be32(memory_clock);
274 mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
275 mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
276 mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
277 mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
278 mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
279 mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
280 mclk->mclk770.vMPLL_SS = cpu_to_be32(mpll_ss1);
281 mclk->mclk770.vMPLL_SS2 = cpu_to_be32(mpll_ss2);
282
283 return 0;
284}
285
286void rv740_read_clock_registers(struct radeon_device *rdev)
287{
288 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
289
290 pi->clk_regs.rv770.cg_spll_func_cntl =
291 RREG32(CG_SPLL_FUNC_CNTL);
292 pi->clk_regs.rv770.cg_spll_func_cntl_2 =
293 RREG32(CG_SPLL_FUNC_CNTL_2);
294 pi->clk_regs.rv770.cg_spll_func_cntl_3 =
295 RREG32(CG_SPLL_FUNC_CNTL_3);
296 pi->clk_regs.rv770.cg_spll_spread_spectrum =
297 RREG32(CG_SPLL_SPREAD_SPECTRUM);
298 pi->clk_regs.rv770.cg_spll_spread_spectrum_2 =
299 RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
300
301 pi->clk_regs.rv770.mpll_ad_func_cntl =
302 RREG32(MPLL_AD_FUNC_CNTL);
303 pi->clk_regs.rv770.mpll_ad_func_cntl_2 =
304 RREG32(MPLL_AD_FUNC_CNTL_2);
305 pi->clk_regs.rv770.mpll_dq_func_cntl =
306 RREG32(MPLL_DQ_FUNC_CNTL);
307 pi->clk_regs.rv770.mpll_dq_func_cntl_2 =
308 RREG32(MPLL_DQ_FUNC_CNTL_2);
309 pi->clk_regs.rv770.mclk_pwrmgt_cntl =
310 RREG32(MCLK_PWRMGT_CNTL);
311 pi->clk_regs.rv770.dll_cntl = RREG32(DLL_CNTL);
312 pi->clk_regs.rv770.mpll_ss1 = RREG32(MPLL_SS1);
313 pi->clk_regs.rv770.mpll_ss2 = RREG32(MPLL_SS2);
314}
315
316int rv740_populate_smc_acpi_state(struct radeon_device *rdev,
317 RV770_SMC_STATETABLE *table)
318{
319 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
320 u32 mpll_ad_func_cntl = pi->clk_regs.rv770.mpll_ad_func_cntl;
321 u32 mpll_ad_func_cntl_2 = pi->clk_regs.rv770.mpll_ad_func_cntl_2;
322 u32 mpll_dq_func_cntl = pi->clk_regs.rv770.mpll_dq_func_cntl;
323 u32 mpll_dq_func_cntl_2 = pi->clk_regs.rv770.mpll_dq_func_cntl_2;
324 u32 spll_func_cntl = pi->clk_regs.rv770.cg_spll_func_cntl;
325 u32 spll_func_cntl_2 = pi->clk_regs.rv770.cg_spll_func_cntl_2;
326 u32 spll_func_cntl_3 = pi->clk_regs.rv770.cg_spll_func_cntl_3;
327 u32 mclk_pwrmgt_cntl = pi->clk_regs.rv770.mclk_pwrmgt_cntl;
328 u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
329
330 table->ACPIState = table->initialState;
331
332 table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
333
334 if (pi->acpi_vddc) {
335 rv770_populate_vddc_value(rdev, pi->acpi_vddc,
336 &table->ACPIState.levels[0].vddc);
337 table->ACPIState.levels[0].gen2PCIE =
338 pi->pcie_gen2 ?
339 pi->acpi_pcie_gen2 : 0;
340 table->ACPIState.levels[0].gen2XSP =
341 pi->acpi_pcie_gen2;
342 } else {
343 rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
344 &table->ACPIState.levels[0].vddc);
345 table->ACPIState.levels[0].gen2PCIE = 0;
346 }
347
348 mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
349
350 mpll_dq_func_cntl_2 |= BYPASS | BIAS_GEN_PDNB | RESET_EN;
351
352 mclk_pwrmgt_cntl |= (MRDCKA0_RESET |
353 MRDCKA1_RESET |
354 MRDCKB0_RESET |
355 MRDCKB1_RESET |
356 MRDCKC0_RESET |
357 MRDCKC1_RESET |
358 MRDCKD0_RESET |
359 MRDCKD1_RESET);
360
361 dll_cntl |= (MRDCKA0_BYPASS |
362 MRDCKA1_BYPASS |
363 MRDCKB0_BYPASS |
364 MRDCKB1_BYPASS |
365 MRDCKC0_BYPASS |
366 MRDCKC1_BYPASS |
367 MRDCKD0_BYPASS |
368 MRDCKD1_BYPASS);
369
370 spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN;
371
372 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
373 spll_func_cntl_2 |= SCLK_MUX_SEL(4);
374
375 table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
376 table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
377 table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
378 table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
379 table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
380 table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
381
382 table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0;
383
384 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
385 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
386 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
387
388 table->ACPIState.levels[0].sclk.sclk_value = 0;
389
390 table->ACPIState.levels[1] = table->ACPIState.levels[0];
391 table->ACPIState.levels[2] = table->ACPIState.levels[0];
392
393 rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
394
395 return 0;
396}
397
398void rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev,
399 bool enable)
400{
401 if (enable)
402 WREG32_P(MPLL_CNTL_MODE, SS_SSEN, ~SS_SSEN);
403 else
404 WREG32_P(MPLL_CNTL_MODE, 0, ~SS_SSEN);
405}
406
407u8 rv740_get_mclk_frequency_ratio(u32 memory_clock)
408{
409 u8 mc_para_index;
410
411 if ((memory_clock < 10000) || (memory_clock > 47500))
412 mc_para_index = 0x00;
413 else
414 mc_para_index = (u8)((memory_clock - 10000) / 2500);
415
416 return mc_para_index;
417}
diff --git a/drivers/gpu/drm/radeon/rv740d.h b/drivers/gpu/drm/radeon/rv740d.h
new file mode 100644
index 000000000000..fe5ab075dc17
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv740d.h
@@ -0,0 +1,117 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef RV740_H
24#define RV740_H
25
26#define CG_SPLL_FUNC_CNTL 0x600
27#define SPLL_RESET (1 << 0)
28#define SPLL_SLEEP (1 << 1)
29#define SPLL_BYPASS_EN (1 << 3)
30#define SPLL_REF_DIV(x) ((x) << 4)
31#define SPLL_REF_DIV_MASK (0x3f << 4)
32#define SPLL_PDIV_A(x) ((x) << 20)
33#define SPLL_PDIV_A_MASK (0x7f << 20)
34#define CG_SPLL_FUNC_CNTL_2 0x604
35#define SCLK_MUX_SEL(x) ((x) << 0)
36#define SCLK_MUX_SEL_MASK (0x1ff << 0)
37#define CG_SPLL_FUNC_CNTL_3 0x608
38#define SPLL_FB_DIV(x) ((x) << 0)
39#define SPLL_FB_DIV_MASK (0x3ffffff << 0)
40#define SPLL_DITHEN (1 << 28)
41
42#define MPLL_CNTL_MODE 0x61c
43#define SS_SSEN (1 << 24)
44
45#define MPLL_AD_FUNC_CNTL 0x624
46#define CLKF(x) ((x) << 0)
47#define CLKF_MASK (0x7f << 0)
48#define CLKR(x) ((x) << 7)
49#define CLKR_MASK (0x1f << 7)
50#define CLKFRAC(x) ((x) << 12)
51#define CLKFRAC_MASK (0x1f << 12)
52#define YCLK_POST_DIV(x) ((x) << 17)
53#define YCLK_POST_DIV_MASK (3 << 17)
54#define IBIAS(x) ((x) << 20)
55#define IBIAS_MASK (0x3ff << 20)
56#define RESET (1 << 30)
57#define PDNB (1 << 31)
58#define MPLL_AD_FUNC_CNTL_2 0x628
59#define BYPASS (1 << 19)
60#define BIAS_GEN_PDNB (1 << 24)
61#define RESET_EN (1 << 25)
62#define VCO_MODE (1 << 29)
63#define MPLL_DQ_FUNC_CNTL 0x62c
64#define MPLL_DQ_FUNC_CNTL_2 0x630
65
66#define MCLK_PWRMGT_CNTL 0x648
67#define DLL_SPEED(x) ((x) << 0)
68#define DLL_SPEED_MASK (0x1f << 0)
69# define MPLL_PWRMGT_OFF (1 << 5)
70# define DLL_READY (1 << 6)
71# define MC_INT_CNTL (1 << 7)
72# define MRDCKA0_SLEEP (1 << 8)
73# define MRDCKA1_SLEEP (1 << 9)
74# define MRDCKB0_SLEEP (1 << 10)
75# define MRDCKB1_SLEEP (1 << 11)
76# define MRDCKC0_SLEEP (1 << 12)
77# define MRDCKC1_SLEEP (1 << 13)
78# define MRDCKD0_SLEEP (1 << 14)
79# define MRDCKD1_SLEEP (1 << 15)
80# define MRDCKA0_RESET (1 << 16)
81# define MRDCKA1_RESET (1 << 17)
82# define MRDCKB0_RESET (1 << 18)
83# define MRDCKB1_RESET (1 << 19)
84# define MRDCKC0_RESET (1 << 20)
85# define MRDCKC1_RESET (1 << 21)
86# define MRDCKD0_RESET (1 << 22)
87# define MRDCKD1_RESET (1 << 23)
88# define DLL_READY_READ (1 << 24)
89# define USE_DISPLAY_GAP (1 << 25)
90# define USE_DISPLAY_URGENT_NORMAL (1 << 26)
91# define MPLL_TURNOFF_D2 (1 << 28)
92#define DLL_CNTL 0x64c
93# define MRDCKA0_BYPASS (1 << 24)
94# define MRDCKA1_BYPASS (1 << 25)
95# define MRDCKB0_BYPASS (1 << 26)
96# define MRDCKB1_BYPASS (1 << 27)
97# define MRDCKC0_BYPASS (1 << 28)
98# define MRDCKC1_BYPASS (1 << 29)
99# define MRDCKD0_BYPASS (1 << 30)
100# define MRDCKD1_BYPASS (1 << 31)
101
102#define CG_SPLL_SPREAD_SPECTRUM 0x790
103#define SSEN (1 << 0)
104#define CLK_S(x) ((x) << 4)
105#define CLK_S_MASK (0xfff << 4)
106#define CG_SPLL_SPREAD_SPECTRUM_2 0x794
107#define CLK_V(x) ((x) << 0)
108#define CLK_V_MASK (0x3ffffff << 0)
109
110#define MPLL_SS1 0x85c
111#define CLKV(x) ((x) << 0)
112#define CLKV_MASK (0x3ffffff << 0)
113#define MPLL_SS2 0x860
114#define CLKS(x) ((x) << 0)
115#define CLKS_MASK (0xfff << 0)
116
117#endif
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c
new file mode 100644
index 000000000000..232b2fdf57eb
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv770_dpm.c
@@ -0,0 +1,2337 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Alex Deucher
23 */
24
25#include "drmP.h"
26#include "radeon.h"
27#include "rv770d.h"
28#include "r600_dpm.h"
29#include "rv770_dpm.h"
30#include "atom.h"
31
32#define MC_CG_ARB_FREQ_F0 0x0a
33#define MC_CG_ARB_FREQ_F1 0x0b
34#define MC_CG_ARB_FREQ_F2 0x0c
35#define MC_CG_ARB_FREQ_F3 0x0d
36
37#define MC_CG_SEQ_DRAMCONF_S0 0x05
38#define MC_CG_SEQ_DRAMCONF_S1 0x06
39
40#define PCIE_BUS_CLK 10000
41#define TCLK (PCIE_BUS_CLK / 10)
42
43#define SMC_RAM_END 0xC000
44
45struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps)
46{
47 struct rv7xx_ps *ps = rps->ps_priv;
48
49 return ps;
50}
51
52struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev)
53{
54 struct rv7xx_power_info *pi = rdev->pm.dpm.priv;
55
56 return pi;
57}
58
59static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
60 bool enable)
61{
62 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
63 u32 tmp;
64
65 tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
66 if (enable) {
67 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
68 tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
69 tmp |= LC_GEN2_EN_STRAP;
70 } else {
71 if (!pi->boot_in_gen2) {
72 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
73 tmp &= ~LC_GEN2_EN_STRAP;
74 }
75 }
76 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
77 (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
78 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
79
80}
81
82static void rv770_enable_l0s(struct radeon_device *rdev)
83{
84 u32 tmp;
85
86 tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L0S_INACTIVITY_MASK;
87 tmp |= LC_L0S_INACTIVITY(3);
88 WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
89}
90
91static void rv770_enable_l1(struct radeon_device *rdev)
92{
93 u32 tmp;
94
95 tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL);
96 tmp &= ~LC_L1_INACTIVITY_MASK;
97 tmp |= LC_L1_INACTIVITY(4);
98 tmp &= ~LC_PMI_TO_L1_DIS;
99 tmp &= ~LC_ASPM_TO_L1_DIS;
100 WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
101}
102
103static void rv770_enable_pll_sleep_in_l1(struct radeon_device *rdev)
104{
105 u32 tmp;
106
107 tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L1_INACTIVITY_MASK;
108 tmp |= LC_L1_INACTIVITY(8);
109 WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
110
111 /* NOTE, this is a PCIE indirect reg, not PCIE PORT */
112 tmp = RREG32_PCIE(PCIE_P_CNTL);
113 tmp |= P_PLL_PWRDN_IN_L1L23;
114 tmp &= ~P_PLL_BUF_PDNB;
115 tmp &= ~P_PLL_PDNB;
116 tmp |= P_ALLOW_PRX_FRONTEND_SHUTOFF;
117 WREG32_PCIE(PCIE_P_CNTL, tmp);
118}
119
120static void rv770_gfx_clock_gating_enable(struct radeon_device *rdev,
121 bool enable)
122{
123 if (enable)
124 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
125 else {
126 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
127 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
128 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
129 RREG32(GB_TILING_CONFIG);
130 }
131}
132
133static void rv770_mg_clock_gating_enable(struct radeon_device *rdev,
134 bool enable)
135{
136 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
137
138 if (enable) {
139 u32 mgcg_cgtt_local0;
140
141 if (rdev->family == CHIP_RV770)
142 mgcg_cgtt_local0 = RV770_MGCGTTLOCAL0_DFLT;
143 else
144 mgcg_cgtt_local0 = RV7XX_MGCGTTLOCAL0_DFLT;
145
146 WREG32(CG_CGTT_LOCAL_0, mgcg_cgtt_local0);
147 WREG32(CG_CGTT_LOCAL_1, (RV770_MGCGTTLOCAL1_DFLT & 0xFFFFCFFF));
148
149 if (pi->mgcgtssm)
150 WREG32(CGTS_SM_CTRL_REG, RV770_MGCGCGTSSMCTRL_DFLT);
151 } else {
152 WREG32(CG_CGTT_LOCAL_0, 0xFFFFFFFF);
153 WREG32(CG_CGTT_LOCAL_1, 0xFFFFCFFF);
154 }
155}
156
157void rv770_restore_cgcg(struct radeon_device *rdev)
158{
159 bool dpm_en = false, cg_en = false;
160
161 if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
162 dpm_en = true;
163 if (RREG32(SCLK_PWRMGT_CNTL) & DYN_GFX_CLK_OFF_EN)
164 cg_en = true;
165
166 if (dpm_en && !cg_en)
167 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
168}
169
170static void rv770_start_dpm(struct radeon_device *rdev)
171{
172 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
173
174 WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
175
176 WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
177}
178
179void rv770_stop_dpm(struct radeon_device *rdev)
180{
181 PPSMC_Result result;
182
183 result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
184
185 if (result != PPSMC_Result_OK)
186 DRM_ERROR("Could not force DPM to low.\n");
187
188 WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
189
190 WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
191
192 WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
193}
194
195bool rv770_dpm_enabled(struct radeon_device *rdev)
196{
197 if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
198 return true;
199 else
200 return false;
201}
202
203void rv770_enable_thermal_protection(struct radeon_device *rdev,
204 bool enable)
205{
206 if (enable)
207 WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
208 else
209 WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
210}
211
212void rv770_enable_acpi_pm(struct radeon_device *rdev)
213{
214 WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
215}
216
217u8 rv770_get_seq_value(struct radeon_device *rdev,
218 struct rv7xx_pl *pl)
219{
220 return (pl->flags & ATOM_PPLIB_R600_FLAGS_LOWPOWER) ?
221 MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1;
222}
223
224int rv770_read_smc_soft_register(struct radeon_device *rdev,
225 u16 reg_offset, u32 *value)
226{
227 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
228
229 return rv770_read_smc_sram_dword(rdev,
230 pi->soft_regs_start + reg_offset,
231 value, pi->sram_end);
232}
233
234int rv770_write_smc_soft_register(struct radeon_device *rdev,
235 u16 reg_offset, u32 value)
236{
237 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
238
239 return rv770_write_smc_sram_dword(rdev,
240 pi->soft_regs_start + reg_offset,
241 value, pi->sram_end);
242}
243
244int rv770_populate_smc_t(struct radeon_device *rdev,
245 struct radeon_ps *radeon_state,
246 RV770_SMC_SWSTATE *smc_state)
247{
248 struct rv7xx_ps *state = rv770_get_ps(radeon_state);
249 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
250 int i;
251 int a_n;
252 int a_d;
253 u8 l[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
254 u8 r[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
255 u32 a_t;
256
257 l[0] = 0;
258 r[2] = 100;
259
260 a_n = (int)state->medium.sclk * RV770_LMP_DFLT +
261 (int)state->low.sclk * (R600_AH_DFLT - RV770_RLP_DFLT);
262 a_d = (int)state->low.sclk * (100 - (int)RV770_RLP_DFLT) +
263 (int)state->medium.sclk * RV770_LMP_DFLT;
264
265 l[1] = (u8)(RV770_LMP_DFLT - (int)RV770_LMP_DFLT * a_n / a_d);
266 r[0] = (u8)(RV770_RLP_DFLT + (100 - (int)RV770_RLP_DFLT) * a_n / a_d);
267
268 a_n = (int)state->high.sclk * RV770_LHP_DFLT +
269 (int)state->medium.sclk *
270 (R600_AH_DFLT - RV770_RMP_DFLT);
271 a_d = (int)state->medium.sclk * (100 - (int)RV770_RMP_DFLT) +
272 (int)state->high.sclk * RV770_LHP_DFLT;
273
274 l[2] = (u8)(RV770_LHP_DFLT - (int)RV770_LHP_DFLT * a_n / a_d);
275 r[1] = (u8)(RV770_RMP_DFLT + (100 - (int)RV770_RMP_DFLT) * a_n / a_d);
276
277 for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++) {
278 a_t = CG_R(r[i] * pi->bsp / 200) | CG_L(l[i] * pi->bsp / 200);
279 smc_state->levels[i].aT = cpu_to_be32(a_t);
280 }
281
282 a_t = CG_R(r[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1] * pi->pbsp / 200) |
283 CG_L(l[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1] * pi->pbsp / 200);
284
285 smc_state->levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1].aT =
286 cpu_to_be32(a_t);
287
288 return 0;
289}
290
291int rv770_populate_smc_sp(struct radeon_device *rdev,
292 struct radeon_ps *radeon_state,
293 RV770_SMC_SWSTATE *smc_state)
294{
295 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
296 int i;
297
298 for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++)
299 smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
300
301 smc_state->levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1].bSP =
302 cpu_to_be32(pi->psp);
303
304 return 0;
305}
306
307static void rv770_calculate_fractional_mpll_feedback_divider(u32 memory_clock,
308 u32 reference_clock,
309 bool gddr5,
310 struct atom_clock_dividers *dividers,
311 u32 *clkf,
312 u32 *clkfrac)
313{
314 u32 post_divider, reference_divider, feedback_divider8;
315 u32 fyclk;
316
317 if (gddr5)
318 fyclk = (memory_clock * 8) / 2;
319 else
320 fyclk = (memory_clock * 4) / 2;
321
322 post_divider = dividers->post_div;
323 reference_divider = dividers->ref_div;
324
325 feedback_divider8 =
326 (8 * fyclk * reference_divider * post_divider) / reference_clock;
327
328 *clkf = feedback_divider8 / 8;
329 *clkfrac = feedback_divider8 % 8;
330}
331
332static int rv770_encode_yclk_post_div(u32 postdiv, u32 *encoded_postdiv)
333{
334 int ret = 0;
335
336 switch (postdiv) {
337 case 1:
338 *encoded_postdiv = 0;
339 break;
340 case 2:
341 *encoded_postdiv = 1;
342 break;
343 case 4:
344 *encoded_postdiv = 2;
345 break;
346 case 8:
347 *encoded_postdiv = 3;
348 break;
349 case 16:
350 *encoded_postdiv = 4;
351 break;
352 default:
353 ret = -EINVAL;
354 break;
355 }
356
357 return ret;
358}
359
360u32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
361{
362 if (clkf <= 0x10)
363 return 0x4B;
364 if (clkf <= 0x19)
365 return 0x5B;
366 if (clkf <= 0x21)
367 return 0x2B;
368 if (clkf <= 0x27)
369 return 0x6C;
370 if (clkf <= 0x31)
371 return 0x9D;
372 return 0xC6;
373}
374
375static int rv770_populate_mclk_value(struct radeon_device *rdev,
376 u32 engine_clock, u32 memory_clock,
377 RV7XX_SMC_MCLK_VALUE *mclk)
378{
379 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
380 u8 encoded_reference_dividers[] = { 0, 16, 17, 20, 21 };
381 u32 mpll_ad_func_cntl =
382 pi->clk_regs.rv770.mpll_ad_func_cntl;
383 u32 mpll_ad_func_cntl_2 =
384 pi->clk_regs.rv770.mpll_ad_func_cntl_2;
385 u32 mpll_dq_func_cntl =
386 pi->clk_regs.rv770.mpll_dq_func_cntl;
387 u32 mpll_dq_func_cntl_2 =
388 pi->clk_regs.rv770.mpll_dq_func_cntl_2;
389 u32 mclk_pwrmgt_cntl =
390 pi->clk_regs.rv770.mclk_pwrmgt_cntl;
391 u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
392 struct atom_clock_dividers dividers;
393 u32 reference_clock = rdev->clock.mpll.reference_freq;
394 u32 clkf, clkfrac;
395 u32 postdiv_yclk;
396 u32 ibias;
397 int ret;
398
399 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
400 memory_clock, false, &dividers);
401 if (ret)
402 return ret;
403
404 if ((dividers.ref_div < 1) || (dividers.ref_div > 5))
405 return -EINVAL;
406
407 rv770_calculate_fractional_mpll_feedback_divider(memory_clock, reference_clock,
408 pi->mem_gddr5,
409 &dividers, &clkf, &clkfrac);
410
411 ret = rv770_encode_yclk_post_div(dividers.post_div, &postdiv_yclk);
412 if (ret)
413 return ret;
414
415 ibias = rv770_map_clkf_to_ibias(rdev, clkf);
416
417 mpll_ad_func_cntl &= ~(CLKR_MASK |
418 YCLK_POST_DIV_MASK |
419 CLKF_MASK |
420 CLKFRAC_MASK |
421 IBIAS_MASK);
422 mpll_ad_func_cntl |= CLKR(encoded_reference_dividers[dividers.ref_div - 1]);
423 mpll_ad_func_cntl |= YCLK_POST_DIV(postdiv_yclk);
424 mpll_ad_func_cntl |= CLKF(clkf);
425 mpll_ad_func_cntl |= CLKFRAC(clkfrac);
426 mpll_ad_func_cntl |= IBIAS(ibias);
427
428 if (dividers.vco_mode)
429 mpll_ad_func_cntl_2 |= VCO_MODE;
430 else
431 mpll_ad_func_cntl_2 &= ~VCO_MODE;
432
433 if (pi->mem_gddr5) {
434 rv770_calculate_fractional_mpll_feedback_divider(memory_clock,
435 reference_clock,
436 pi->mem_gddr5,
437 &dividers, &clkf, &clkfrac);
438
439 ibias = rv770_map_clkf_to_ibias(rdev, clkf);
440
441 ret = rv770_encode_yclk_post_div(dividers.post_div, &postdiv_yclk);
442 if (ret)
443 return ret;
444
445 mpll_dq_func_cntl &= ~(CLKR_MASK |
446 YCLK_POST_DIV_MASK |
447 CLKF_MASK |
448 CLKFRAC_MASK |
449 IBIAS_MASK);
450 mpll_dq_func_cntl |= CLKR(encoded_reference_dividers[dividers.ref_div - 1]);
451 mpll_dq_func_cntl |= YCLK_POST_DIV(postdiv_yclk);
452 mpll_dq_func_cntl |= CLKF(clkf);
453 mpll_dq_func_cntl |= CLKFRAC(clkfrac);
454 mpll_dq_func_cntl |= IBIAS(ibias);
455
456 if (dividers.vco_mode)
457 mpll_dq_func_cntl_2 |= VCO_MODE;
458 else
459 mpll_dq_func_cntl_2 &= ~VCO_MODE;
460 }
461
462 mclk->mclk770.mclk_value = cpu_to_be32(memory_clock);
463 mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
464 mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
465 mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
466 mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
467 mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
468 mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
469
470 return 0;
471}
472
473static int rv770_populate_sclk_value(struct radeon_device *rdev,
474 u32 engine_clock,
475 RV770_SMC_SCLK_VALUE *sclk)
476{
477 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
478 struct atom_clock_dividers dividers;
479 u32 spll_func_cntl =
480 pi->clk_regs.rv770.cg_spll_func_cntl;
481 u32 spll_func_cntl_2 =
482 pi->clk_regs.rv770.cg_spll_func_cntl_2;
483 u32 spll_func_cntl_3 =
484 pi->clk_regs.rv770.cg_spll_func_cntl_3;
485 u32 cg_spll_spread_spectrum =
486 pi->clk_regs.rv770.cg_spll_spread_spectrum;
487 u32 cg_spll_spread_spectrum_2 =
488 pi->clk_regs.rv770.cg_spll_spread_spectrum_2;
489 u64 tmp;
490 u32 reference_clock = rdev->clock.spll.reference_freq;
491 u32 reference_divider, post_divider;
492 u32 fbdiv;
493 int ret;
494
495 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
496 engine_clock, false, &dividers);
497 if (ret)
498 return ret;
499
500 reference_divider = 1 + dividers.ref_div;
501
502 if (dividers.enable_post_div)
503 post_divider = (0x0f & (dividers.post_div >> 4)) + (0x0f & dividers.post_div) + 2;
504 else
505 post_divider = 1;
506
507 tmp = (u64) engine_clock * reference_divider * post_divider * 16384;
508 do_div(tmp, reference_clock);
509 fbdiv = (u32) tmp;
510
511 if (dividers.enable_post_div)
512 spll_func_cntl |= SPLL_DIVEN;
513 else
514 spll_func_cntl &= ~SPLL_DIVEN;
515 spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK);
516 spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
517 spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf);
518 spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf);
519
520 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
521 spll_func_cntl_2 |= SCLK_MUX_SEL(2);
522
523 spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
524 spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
525 spll_func_cntl_3 |= SPLL_DITHEN;
526
527 if (pi->sclk_ss) {
528 struct radeon_atom_ss ss;
529 u32 vco_freq = engine_clock * post_divider;
530
531 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
532 ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
533 u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
534 u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
535
536 cg_spll_spread_spectrum &= ~CLKS_MASK;
537 cg_spll_spread_spectrum |= CLKS(clk_s);
538 cg_spll_spread_spectrum |= SSEN;
539
540 cg_spll_spread_spectrum_2 &= ~CLKV_MASK;
541 cg_spll_spread_spectrum_2 |= CLKV(clk_v);
542 }
543 }
544
545 sclk->sclk_value = cpu_to_be32(engine_clock);
546 sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
547 sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
548 sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
549 sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
550 sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
551
552 return 0;
553}
554
555int rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc,
556 RV770_SMC_VOLTAGE_VALUE *voltage)
557{
558 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
559 int i;
560
561 if (!pi->voltage_control) {
562 voltage->index = 0;
563 voltage->value = 0;
564 return 0;
565 }
566
567 for (i = 0; i < pi->valid_vddc_entries; i++) {
568 if (vddc <= pi->vddc_table[i].vddc) {
569 voltage->index = pi->vddc_table[i].vddc_index;
570 voltage->value = cpu_to_be16(vddc);
571 break;
572 }
573 }
574
575 if (i == pi->valid_vddc_entries)
576 return -EINVAL;
577
578 return 0;
579}
580
581int rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
582 RV770_SMC_VOLTAGE_VALUE *voltage)
583{
584 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
585
586 if (!pi->mvdd_control) {
587 voltage->index = MVDD_HIGH_INDEX;
588 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
589 return 0;
590 }
591
592 if (mclk <= pi->mvdd_split_frequency) {
593 voltage->index = MVDD_LOW_INDEX;
594 voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
595 } else {
596 voltage->index = MVDD_HIGH_INDEX;
597 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
598 }
599
600 return 0;
601}
602
603static int rv770_convert_power_level_to_smc(struct radeon_device *rdev,
604 struct rv7xx_pl *pl,
605 RV770_SMC_HW_PERFORMANCE_LEVEL *level,
606 u8 watermark_level)
607{
608 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
609 int ret;
610
611 level->gen2PCIE = pi->pcie_gen2 ?
612 ((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
613 level->gen2XSP = (pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0;
614 level->backbias = (pl->flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? 1 : 0;
615 level->displayWatermark = watermark_level;
616
617 if (rdev->family == CHIP_RV740)
618 ret = rv740_populate_sclk_value(rdev, pl->sclk,
619 &level->sclk);
620 else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
621 ret = rv730_populate_sclk_value(rdev, pl->sclk,
622 &level->sclk);
623 else
624 ret = rv770_populate_sclk_value(rdev, pl->sclk,
625 &level->sclk);
626 if (ret)
627 return ret;
628
629 if (rdev->family == CHIP_RV740) {
630 if (pi->mem_gddr5) {
631 if (pl->mclk <= pi->mclk_strobe_mode_threshold)
632 level->strobeMode =
633 rv740_get_mclk_frequency_ratio(pl->mclk) | 0x10;
634 else
635 level->strobeMode = 0;
636
637 if (pl->mclk > pi->mclk_edc_enable_threshold)
638 level->mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
639 else
640 level->mcFlags = 0;
641 }
642 ret = rv740_populate_mclk_value(rdev, pl->sclk,
643 pl->mclk, &level->mclk);
644 } else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
645 ret = rv730_populate_mclk_value(rdev, pl->sclk,
646 pl->mclk, &level->mclk);
647 else
648 ret = rv770_populate_mclk_value(rdev, pl->sclk,
649 pl->mclk, &level->mclk);
650 if (ret)
651 return ret;
652
653 ret = rv770_populate_vddc_value(rdev, pl->vddc,
654 &level->vddc);
655 if (ret)
656 return ret;
657
658 ret = rv770_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
659
660 return ret;
661}
662
663static int rv770_convert_power_state_to_smc(struct radeon_device *rdev,
664 struct radeon_ps *radeon_state,
665 RV770_SMC_SWSTATE *smc_state)
666{
667 struct rv7xx_ps *state = rv770_get_ps(radeon_state);
668 int ret;
669
670 if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
671 smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
672
673 ret = rv770_convert_power_level_to_smc(rdev,
674 &state->low,
675 &smc_state->levels[0],
676 PPSMC_DISPLAY_WATERMARK_LOW);
677 if (ret)
678 return ret;
679
680 ret = rv770_convert_power_level_to_smc(rdev,
681 &state->medium,
682 &smc_state->levels[1],
683 PPSMC_DISPLAY_WATERMARK_LOW);
684 if (ret)
685 return ret;
686
687 ret = rv770_convert_power_level_to_smc(rdev,
688 &state->high,
689 &smc_state->levels[2],
690 PPSMC_DISPLAY_WATERMARK_HIGH);
691 if (ret)
692 return ret;
693
694 smc_state->levels[0].arbValue = MC_CG_ARB_FREQ_F1;
695 smc_state->levels[1].arbValue = MC_CG_ARB_FREQ_F2;
696 smc_state->levels[2].arbValue = MC_CG_ARB_FREQ_F3;
697
698 smc_state->levels[0].seqValue = rv770_get_seq_value(rdev,
699 &state->low);
700 smc_state->levels[1].seqValue = rv770_get_seq_value(rdev,
701 &state->medium);
702 smc_state->levels[2].seqValue = rv770_get_seq_value(rdev,
703 &state->high);
704
705 rv770_populate_smc_sp(rdev, radeon_state, smc_state);
706
707 return rv770_populate_smc_t(rdev, radeon_state, smc_state);
708
709}
710
711u32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev,
712 u32 engine_clock)
713{
714 u32 dram_rows;
715 u32 dram_refresh_rate;
716 u32 mc_arb_rfsh_rate;
717 u32 tmp;
718
719 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
720 dram_rows = 1 << (tmp + 10);
721 tmp = RREG32(MC_SEQ_MISC0) & 3;
722 dram_refresh_rate = 1 << (tmp + 3);
723 mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
724
725 return mc_arb_rfsh_rate;
726}
727
728static void rv770_program_memory_timing_parameters(struct radeon_device *rdev,
729 struct radeon_ps *radeon_state)
730{
731 struct rv7xx_ps *state = rv770_get_ps(radeon_state);
732 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
733 u32 sqm_ratio;
734 u32 arb_refresh_rate;
735 u32 high_clock;
736
737 if (state->high.sclk < (state->low.sclk * 0xFF / 0x40))
738 high_clock = state->high.sclk;
739 else
740 high_clock = (state->low.sclk * 0xFF / 0x40);
741
742 radeon_atom_set_engine_dram_timings(rdev, high_clock,
743 state->high.mclk);
744
745 sqm_ratio =
746 STATE0(64 * high_clock / pi->boot_sclk) |
747 STATE1(64 * high_clock / state->low.sclk) |
748 STATE2(64 * high_clock / state->medium.sclk) |
749 STATE3(64 * high_clock / state->high.sclk);
750 WREG32(MC_ARB_SQM_RATIO, sqm_ratio);
751
752 arb_refresh_rate =
753 POWERMODE0(rv770_calculate_memory_refresh_rate(rdev, pi->boot_sclk)) |
754 POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) |
755 POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) |
756 POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk));
757 WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate);
758}
759
760void rv770_enable_backbias(struct radeon_device *rdev,
761 bool enable)
762{
763 if (enable)
764 WREG32_P(GENERAL_PWRMGT, BACKBIAS_PAD_EN, ~BACKBIAS_PAD_EN);
765 else
766 WREG32_P(GENERAL_PWRMGT, 0, ~(BACKBIAS_VALUE | BACKBIAS_PAD_EN));
767}
768
769static void rv770_enable_spread_spectrum(struct radeon_device *rdev,
770 bool enable)
771{
772 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
773
774 if (enable) {
775 if (pi->sclk_ss)
776 WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
777
778 if (pi->mclk_ss) {
779 if (rdev->family == CHIP_RV740)
780 rv740_enable_mclk_spread_spectrum(rdev, true);
781 }
782 } else {
783 WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
784
785 WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
786
787 WREG32_P(CG_MPLL_SPREAD_SPECTRUM, 0, ~SSEN);
788
789 if (rdev->family == CHIP_RV740)
790 rv740_enable_mclk_spread_spectrum(rdev, false);
791 }
792}
793
794static void rv770_program_mpll_timing_parameters(struct radeon_device *rdev)
795{
796 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
797
798 if ((rdev->family == CHIP_RV770) && !pi->mem_gddr5) {
799 WREG32(MPLL_TIME,
800 (MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div) |
801 MPLL_RESET_TIME(R600_MPLLRESETTIME_DFLT)));
802 }
803}
804
805void rv770_setup_bsp(struct radeon_device *rdev)
806{
807 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
808 u32 xclk = radeon_get_xclk(rdev);
809
810 r600_calculate_u_and_p(pi->asi,
811 xclk,
812 16,
813 &pi->bsp,
814 &pi->bsu);
815
816 r600_calculate_u_and_p(pi->pasi,
817 xclk,
818 16,
819 &pi->pbsp,
820 &pi->pbsu);
821
822 pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
823 pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
824
825 WREG32(CG_BSP, pi->dsp);
826
827}
828
829void rv770_program_git(struct radeon_device *rdev)
830{
831 WREG32_P(CG_GIT, CG_GICST(R600_GICST_DFLT), ~CG_GICST_MASK);
832}
833
834void rv770_program_tp(struct radeon_device *rdev)
835{
836 int i;
837 enum r600_td td = R600_TD_DFLT;
838
839 for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
840 WREG32(CG_FFCT_0 + (i * 4), (UTC_0(r600_utc[i]) | DTC_0(r600_dtc[i])));
841
842 if (td == R600_TD_AUTO)
843 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
844 else
845 WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
846 if (td == R600_TD_UP)
847 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
848 if (td == R600_TD_DOWN)
849 WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
850}
851
852void rv770_program_tpp(struct radeon_device *rdev)
853{
854 WREG32(CG_TPC, R600_TPC_DFLT);
855}
856
857void rv770_program_sstp(struct radeon_device *rdev)
858{
859 WREG32(CG_SSP, (SSTU(R600_SSTU_DFLT) | SST(R600_SST_DFLT)));
860}
861
862void rv770_program_engine_speed_parameters(struct radeon_device *rdev)
863{
864 WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC);
865}
866
867static void rv770_enable_display_gap(struct radeon_device *rdev)
868{
869 u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
870
871 tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
872 tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) |
873 DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
874 WREG32(CG_DISPLAY_GAP_CNTL, tmp);
875}
876
877void rv770_program_vc(struct radeon_device *rdev)
878{
879 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
880
881 WREG32(CG_FTV, pi->vrc);
882}
883
884void rv770_clear_vc(struct radeon_device *rdev)
885{
886 WREG32(CG_FTV, 0);
887}
888
889int rv770_upload_firmware(struct radeon_device *rdev)
890{
891 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
892 int ret;
893
894 rv770_reset_smc(rdev);
895 rv770_stop_smc_clock(rdev);
896
897 ret = rv770_load_smc_ucode(rdev, pi->sram_end);
898 if (ret)
899 return ret;
900
901 return 0;
902}
903
904static int rv770_populate_smc_acpi_state(struct radeon_device *rdev,
905 RV770_SMC_STATETABLE *table)
906{
907 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
908
909 u32 mpll_ad_func_cntl =
910 pi->clk_regs.rv770.mpll_ad_func_cntl;
911 u32 mpll_ad_func_cntl_2 =
912 pi->clk_regs.rv770.mpll_ad_func_cntl_2;
913 u32 mpll_dq_func_cntl =
914 pi->clk_regs.rv770.mpll_dq_func_cntl;
915 u32 mpll_dq_func_cntl_2 =
916 pi->clk_regs.rv770.mpll_dq_func_cntl_2;
917 u32 spll_func_cntl =
918 pi->clk_regs.rv770.cg_spll_func_cntl;
919 u32 spll_func_cntl_2 =
920 pi->clk_regs.rv770.cg_spll_func_cntl_2;
921 u32 spll_func_cntl_3 =
922 pi->clk_regs.rv770.cg_spll_func_cntl_3;
923 u32 mclk_pwrmgt_cntl;
924 u32 dll_cntl;
925
926 table->ACPIState = table->initialState;
927
928 table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
929
930 if (pi->acpi_vddc) {
931 rv770_populate_vddc_value(rdev, pi->acpi_vddc,
932 &table->ACPIState.levels[0].vddc);
933 if (pi->pcie_gen2) {
934 if (pi->acpi_pcie_gen2)
935 table->ACPIState.levels[0].gen2PCIE = 1;
936 else
937 table->ACPIState.levels[0].gen2PCIE = 0;
938 } else
939 table->ACPIState.levels[0].gen2PCIE = 0;
940 if (pi->acpi_pcie_gen2)
941 table->ACPIState.levels[0].gen2XSP = 1;
942 else
943 table->ACPIState.levels[0].gen2XSP = 0;
944 } else {
945 rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
946 &table->ACPIState.levels[0].vddc);
947 table->ACPIState.levels[0].gen2PCIE = 0;
948 }
949
950
951 mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
952
953 mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
954
955 mclk_pwrmgt_cntl = (MRDCKA0_RESET |
956 MRDCKA1_RESET |
957 MRDCKB0_RESET |
958 MRDCKB1_RESET |
959 MRDCKC0_RESET |
960 MRDCKC1_RESET |
961 MRDCKD0_RESET |
962 MRDCKD1_RESET);
963
964 dll_cntl = 0xff000000;
965
966 spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN;
967
968 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
969 spll_func_cntl_2 |= SCLK_MUX_SEL(4);
970
971 table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
972 table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
973 table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
974 table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
975
976 table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
977 table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
978
979 table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0;
980
981 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
982 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
983 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
984
985 table->ACPIState.levels[0].sclk.sclk_value = 0;
986
987 rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
988
989 table->ACPIState.levels[1] = table->ACPIState.levels[0];
990 table->ACPIState.levels[2] = table->ACPIState.levels[0];
991
992 return 0;
993}
994
995int rv770_populate_initial_mvdd_value(struct radeon_device *rdev,
996 RV770_SMC_VOLTAGE_VALUE *voltage)
997{
998 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
999
1000 if ((pi->s0_vid_lower_smio_cntl & pi->mvdd_mask_low) ==
1001 (pi->mvdd_low_smio[MVDD_LOW_INDEX] & pi->mvdd_mask_low) ) {
1002 voltage->index = MVDD_LOW_INDEX;
1003 voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
1004 } else {
1005 voltage->index = MVDD_HIGH_INDEX;
1006 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
1007 }
1008
1009 return 0;
1010}
1011
1012static int rv770_populate_smc_initial_state(struct radeon_device *rdev,
1013 struct radeon_ps *radeon_state,
1014 RV770_SMC_STATETABLE *table)
1015{
1016 struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state);
1017 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1018 u32 a_t;
1019
1020 table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL =
1021 cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl);
1022 table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 =
1023 cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl_2);
1024 table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL =
1025 cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl);
1026 table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 =
1027 cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl_2);
1028 table->initialState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL =
1029 cpu_to_be32(pi->clk_regs.rv770.mclk_pwrmgt_cntl);
1030 table->initialState.levels[0].mclk.mclk770.vDLL_CNTL =
1031 cpu_to_be32(pi->clk_regs.rv770.dll_cntl);
1032
1033 table->initialState.levels[0].mclk.mclk770.vMPLL_SS =
1034 cpu_to_be32(pi->clk_regs.rv770.mpll_ss1);
1035 table->initialState.levels[0].mclk.mclk770.vMPLL_SS2 =
1036 cpu_to_be32(pi->clk_regs.rv770.mpll_ss2);
1037
1038 table->initialState.levels[0].mclk.mclk770.mclk_value =
1039 cpu_to_be32(initial_state->low.mclk);
1040
1041 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
1042 cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl);
1043 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
1044 cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_2);
1045 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
1046 cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_3);
1047 table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
1048 cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum);
1049 table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
1050 cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum_2);
1051
1052 table->initialState.levels[0].sclk.sclk_value =
1053 cpu_to_be32(initial_state->low.sclk);
1054
1055 table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
1056
1057 table->initialState.levels[0].seqValue =
1058 rv770_get_seq_value(rdev, &initial_state->low);
1059
1060 rv770_populate_vddc_value(rdev,
1061 initial_state->low.vddc,
1062 &table->initialState.levels[0].vddc);
1063 rv770_populate_initial_mvdd_value(rdev,
1064 &table->initialState.levels[0].mvdd);
1065
1066 a_t = CG_R(0xffff) | CG_L(0);
1067 table->initialState.levels[0].aT = cpu_to_be32(a_t);
1068
1069 table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
1070
1071 if (pi->boot_in_gen2)
1072 table->initialState.levels[0].gen2PCIE = 1;
1073 else
1074 table->initialState.levels[0].gen2PCIE = 0;
1075 if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
1076 table->initialState.levels[0].gen2XSP = 1;
1077 else
1078 table->initialState.levels[0].gen2XSP = 0;
1079
1080 if (rdev->family == CHIP_RV740) {
1081 if (pi->mem_gddr5) {
1082 if (initial_state->low.mclk <= pi->mclk_strobe_mode_threshold)
1083 table->initialState.levels[0].strobeMode =
1084 rv740_get_mclk_frequency_ratio(initial_state->low.mclk) | 0x10;
1085 else
1086 table->initialState.levels[0].strobeMode = 0;
1087
1088 if (initial_state->low.mclk >= pi->mclk_edc_enable_threshold)
1089 table->initialState.levels[0].mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
1090 else
1091 table->initialState.levels[0].mcFlags = 0;
1092 }
1093 }
1094
1095 table->initialState.levels[1] = table->initialState.levels[0];
1096 table->initialState.levels[2] = table->initialState.levels[0];
1097
1098 table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
1099
1100 return 0;
1101}
1102
1103static int rv770_populate_smc_vddc_table(struct radeon_device *rdev,
1104 RV770_SMC_STATETABLE *table)
1105{
1106 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1107 int i;
1108
1109 for (i = 0; i < pi->valid_vddc_entries; i++) {
1110 table->highSMIO[pi->vddc_table[i].vddc_index] =
1111 pi->vddc_table[i].high_smio;
1112 table->lowSMIO[pi->vddc_table[i].vddc_index] =
1113 cpu_to_be32(pi->vddc_table[i].low_smio);
1114 }
1115
1116 table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDC] = 0;
1117 table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDC] =
1118 cpu_to_be32(pi->vddc_mask_low);
1119
1120 for (i = 0;
1121 ((i < pi->valid_vddc_entries) &&
1122 (pi->max_vddc_in_table >
1123 pi->vddc_table[i].vddc));
1124 i++);
1125
1126 table->maxVDDCIndexInPPTable =
1127 pi->vddc_table[i].vddc_index;
1128
1129 return 0;
1130}
1131
1132static int rv770_populate_smc_mvdd_table(struct radeon_device *rdev,
1133 RV770_SMC_STATETABLE *table)
1134{
1135 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1136
1137 if (pi->mvdd_control) {
1138 table->lowSMIO[MVDD_HIGH_INDEX] |=
1139 cpu_to_be32(pi->mvdd_low_smio[MVDD_HIGH_INDEX]);
1140 table->lowSMIO[MVDD_LOW_INDEX] |=
1141 cpu_to_be32(pi->mvdd_low_smio[MVDD_LOW_INDEX]);
1142
1143 table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_MVDD] = 0;
1144 table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_MVDD] =
1145 cpu_to_be32(pi->mvdd_mask_low);
1146 }
1147
1148 return 0;
1149}
1150
1151static int rv770_init_smc_table(struct radeon_device *rdev)
1152{
1153 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1154 struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
1155 struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
1156 RV770_SMC_STATETABLE *table = &pi->smc_statetable;
1157 int ret;
1158
1159 memset(table, 0, sizeof(RV770_SMC_STATETABLE));
1160
1161 pi->boot_sclk = boot_state->low.sclk;
1162
1163 rv770_populate_smc_vddc_table(rdev, table);
1164 rv770_populate_smc_mvdd_table(rdev, table);
1165
1166 switch (rdev->pm.int_thermal_type) {
1167 case THERMAL_TYPE_RV770:
1168 case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
1169 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
1170 break;
1171 case THERMAL_TYPE_NONE:
1172 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
1173 break;
1174 case THERMAL_TYPE_EXTERNAL_GPIO:
1175 default:
1176 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
1177 break;
1178 }
1179
1180 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC) {
1181 table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1182
1183 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT)
1184 table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK;
1185
1186 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT)
1187 table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE;
1188 }
1189
1190 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
1191 table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1192
1193 if (pi->mem_gddr5)
1194 table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1195
1196 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1197 ret = rv730_populate_smc_initial_state(rdev, radeon_boot_state, table);
1198 else
1199 ret = rv770_populate_smc_initial_state(rdev, radeon_boot_state, table);
1200 if (ret)
1201 return ret;
1202
1203 if (rdev->family == CHIP_RV740)
1204 ret = rv740_populate_smc_acpi_state(rdev, table);
1205 else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1206 ret = rv730_populate_smc_acpi_state(rdev, table);
1207 else
1208 ret = rv770_populate_smc_acpi_state(rdev, table);
1209 if (ret)
1210 return ret;
1211
1212 table->driverState = table->initialState;
1213
1214 return rv770_copy_bytes_to_smc(rdev,
1215 pi->state_table_start,
1216 (const u8 *)table,
1217 sizeof(RV770_SMC_STATETABLE),
1218 pi->sram_end);
1219}
1220
1221static int rv770_construct_vddc_table(struct radeon_device *rdev)
1222{
1223 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1224 u16 min, max, step;
1225 u32 steps = 0;
1226 u8 vddc_index = 0;
1227 u32 i;
1228
1229 radeon_atom_get_min_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &min);
1230 radeon_atom_get_max_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &max);
1231 radeon_atom_get_voltage_step(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &step);
1232
1233 steps = (max - min) / step + 1;
1234
1235 if (steps > MAX_NO_VREG_STEPS)
1236 return -EINVAL;
1237
1238 for (i = 0; i < steps; i++) {
1239 u32 gpio_pins, gpio_mask;
1240
1241 pi->vddc_table[i].vddc = (u16)(min + i * step);
1242 radeon_atom_get_voltage_gpio_settings(rdev,
1243 pi->vddc_table[i].vddc,
1244 SET_VOLTAGE_TYPE_ASIC_VDDC,
1245 &gpio_pins, &gpio_mask);
1246 pi->vddc_table[i].low_smio = gpio_pins & gpio_mask;
1247 pi->vddc_table[i].high_smio = 0;
1248 pi->vddc_mask_low = gpio_mask;
1249 if (i > 0) {
1250 if ((pi->vddc_table[i].low_smio !=
1251 pi->vddc_table[i - 1].low_smio ) ||
1252 (pi->vddc_table[i].high_smio !=
1253 pi->vddc_table[i - 1].high_smio))
1254 vddc_index++;
1255 }
1256 pi->vddc_table[i].vddc_index = vddc_index;
1257 }
1258
1259 pi->valid_vddc_entries = (u8)steps;
1260
1261 return 0;
1262}
1263
1264static u32 rv770_get_mclk_split_point(struct atom_memory_info *memory_info)
1265{
1266 if (memory_info->mem_type == MEM_TYPE_GDDR3)
1267 return 30000;
1268
1269 return 0;
1270}
1271
1272static int rv770_get_mvdd_pin_configuration(struct radeon_device *rdev)
1273{
1274 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1275 u32 gpio_pins, gpio_mask;
1276
1277 radeon_atom_get_voltage_gpio_settings(rdev,
1278 MVDD_HIGH_VALUE, SET_VOLTAGE_TYPE_ASIC_MVDDC,
1279 &gpio_pins, &gpio_mask);
1280 pi->mvdd_mask_low = gpio_mask;
1281 pi->mvdd_low_smio[MVDD_HIGH_INDEX] =
1282 gpio_pins & gpio_mask;
1283
1284 radeon_atom_get_voltage_gpio_settings(rdev,
1285 MVDD_LOW_VALUE, SET_VOLTAGE_TYPE_ASIC_MVDDC,
1286 &gpio_pins, &gpio_mask);
1287 pi->mvdd_low_smio[MVDD_LOW_INDEX] =
1288 gpio_pins & gpio_mask;
1289
1290 return 0;
1291}
1292
1293u8 rv770_get_memory_module_index(struct radeon_device *rdev)
1294{
1295 return (u8) ((RREG32(BIOS_SCRATCH_4) >> 16) & 0xff);
1296}
1297
1298static int rv770_get_mvdd_configuration(struct radeon_device *rdev)
1299{
1300 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1301 u8 memory_module_index;
1302 struct atom_memory_info memory_info;
1303
1304 memory_module_index = rv770_get_memory_module_index(rdev);
1305
1306 if (radeon_atom_get_memory_info(rdev, memory_module_index, &memory_info)) {
1307 pi->mvdd_control = false;
1308 return 0;
1309 }
1310
1311 pi->mvdd_split_frequency =
1312 rv770_get_mclk_split_point(&memory_info);
1313
1314 if (pi->mvdd_split_frequency == 0) {
1315 pi->mvdd_control = false;
1316 return 0;
1317 }
1318
1319 return rv770_get_mvdd_pin_configuration(rdev);
1320}
1321
1322void rv770_enable_voltage_control(struct radeon_device *rdev,
1323 bool enable)
1324{
1325 if (enable)
1326 WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
1327 else
1328 WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
1329}
1330
1331static void rv770_program_display_gap(struct radeon_device *rdev)
1332{
1333 u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
1334
1335 tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
1336 if (RREG32(AVIVO_D1CRTC_CONTROL) & AVIVO_CRTC_EN) {
1337 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
1338 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
1339 } else if (RREG32(AVIVO_D2CRTC_CONTROL) & AVIVO_CRTC_EN) {
1340 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
1341 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
1342 } else {
1343 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
1344 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
1345 }
1346 WREG32(CG_DISPLAY_GAP_CNTL, tmp);
1347}
1348
1349static void rv770_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
1350 bool enable)
1351{
1352 rv770_enable_bif_dynamic_pcie_gen2(rdev, enable);
1353
1354 if (enable)
1355 WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
1356 else
1357 WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
1358}
1359
1360static void r7xx_program_memory_timing_parameters(struct radeon_device *rdev)
1361{
1362 struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
1363
1364 if ((rdev->family == CHIP_RV730) ||
1365 (rdev->family == CHIP_RV710) ||
1366 (rdev->family == CHIP_RV740))
1367 rv730_program_memory_timing_parameters(rdev, radeon_new_state);
1368 else
1369 rv770_program_memory_timing_parameters(rdev, radeon_new_state);
1370}
1371
1372static int rv770_upload_sw_state(struct radeon_device *rdev)
1373{
1374 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1375 struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
1376 u16 address = pi->state_table_start +
1377 offsetof(RV770_SMC_STATETABLE, driverState);
1378 RV770_SMC_SWSTATE state = { 0 };
1379 int ret;
1380
1381 ret = rv770_convert_power_state_to_smc(rdev, radeon_new_state, &state);
1382 if (ret)
1383 return ret;
1384
1385 return rv770_copy_bytes_to_smc(rdev, address, (const u8 *)&state,
1386 sizeof(RV770_SMC_SWSTATE),
1387 pi->sram_end);
1388}
1389
1390int rv770_halt_smc(struct radeon_device *rdev)
1391{
1392 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_Halt) != PPSMC_Result_OK)
1393 return -EINVAL;
1394
1395 if (rv770_wait_for_smc_inactive(rdev) != PPSMC_Result_OK)
1396 return -EINVAL;
1397
1398 return 0;
1399}
1400
1401int rv770_resume_smc(struct radeon_device *rdev)
1402{
1403 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_Resume) != PPSMC_Result_OK)
1404 return -EINVAL;
1405 return 0;
1406}
1407
1408int rv770_set_sw_state(struct radeon_device *rdev)
1409{
1410 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK)
1411 return -EINVAL;
1412 return 0;
1413}
1414
1415int rv770_set_boot_state(struct radeon_device *rdev)
1416{
1417 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) != PPSMC_Result_OK)
1418 return -EINVAL;
1419 return 0;
1420}
1421
1422int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev)
1423{
1424 if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_NoForcedLevel)) != PPSMC_Result_OK)
1425 return -EINVAL;
1426
1427 if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_TwoLevelsDisabled)) != PPSMC_Result_OK)
1428 return -EINVAL;
1429
1430 return 0;
1431}
1432
1433int rv770_unrestrict_performance_levels_after_switch(struct radeon_device *rdev)
1434{
1435 if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_NoForcedLevel)) != PPSMC_Result_OK)
1436 return -EINVAL;
1437
1438 if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_ZeroLevelsDisabled)) != PPSMC_Result_OK)
1439 return -EINVAL;
1440
1441 return 0;
1442}
1443
1444void r7xx_start_smc(struct radeon_device *rdev)
1445{
1446 rv770_start_smc(rdev);
1447 rv770_start_smc_clock(rdev);
1448}
1449
1450
1451void r7xx_stop_smc(struct radeon_device *rdev)
1452{
1453 rv770_reset_smc(rdev);
1454 rv770_stop_smc_clock(rdev);
1455}
1456
1457static void rv770_read_clock_registers(struct radeon_device *rdev)
1458{
1459 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1460
1461 pi->clk_regs.rv770.cg_spll_func_cntl =
1462 RREG32(CG_SPLL_FUNC_CNTL);
1463 pi->clk_regs.rv770.cg_spll_func_cntl_2 =
1464 RREG32(CG_SPLL_FUNC_CNTL_2);
1465 pi->clk_regs.rv770.cg_spll_func_cntl_3 =
1466 RREG32(CG_SPLL_FUNC_CNTL_3);
1467 pi->clk_regs.rv770.cg_spll_spread_spectrum =
1468 RREG32(CG_SPLL_SPREAD_SPECTRUM);
1469 pi->clk_regs.rv770.cg_spll_spread_spectrum_2 =
1470 RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
1471 pi->clk_regs.rv770.mpll_ad_func_cntl =
1472 RREG32(MPLL_AD_FUNC_CNTL);
1473 pi->clk_regs.rv770.mpll_ad_func_cntl_2 =
1474 RREG32(MPLL_AD_FUNC_CNTL_2);
1475 pi->clk_regs.rv770.mpll_dq_func_cntl =
1476 RREG32(MPLL_DQ_FUNC_CNTL);
1477 pi->clk_regs.rv770.mpll_dq_func_cntl_2 =
1478 RREG32(MPLL_DQ_FUNC_CNTL_2);
1479 pi->clk_regs.rv770.mclk_pwrmgt_cntl =
1480 RREG32(MCLK_PWRMGT_CNTL);
1481 pi->clk_regs.rv770.dll_cntl = RREG32(DLL_CNTL);
1482}
1483
1484static void r7xx_read_clock_registers(struct radeon_device *rdev)
1485{
1486 if (rdev->family == CHIP_RV740)
1487 rv740_read_clock_registers(rdev);
1488 else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1489 rv730_read_clock_registers(rdev);
1490 else
1491 rv770_read_clock_registers(rdev);
1492}
1493
1494void rv770_read_voltage_smio_registers(struct radeon_device *rdev)
1495{
1496 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1497
1498 pi->s0_vid_lower_smio_cntl =
1499 RREG32(S0_VID_LOWER_SMIO_CNTL);
1500}
1501
1502void rv770_reset_smio_status(struct radeon_device *rdev)
1503{
1504 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1505 u32 sw_smio_index, vid_smio_cntl;
1506
1507 sw_smio_index =
1508 (RREG32(GENERAL_PWRMGT) & SW_SMIO_INDEX_MASK) >> SW_SMIO_INDEX_SHIFT;
1509 switch (sw_smio_index) {
1510 case 3:
1511 vid_smio_cntl = RREG32(S3_VID_LOWER_SMIO_CNTL);
1512 break;
1513 case 2:
1514 vid_smio_cntl = RREG32(S2_VID_LOWER_SMIO_CNTL);
1515 break;
1516 case 1:
1517 vid_smio_cntl = RREG32(S1_VID_LOWER_SMIO_CNTL);
1518 break;
1519 case 0:
1520 return;
1521 default:
1522 vid_smio_cntl = pi->s0_vid_lower_smio_cntl;
1523 break;
1524 }
1525
1526 WREG32(S0_VID_LOWER_SMIO_CNTL, vid_smio_cntl);
1527 WREG32_P(GENERAL_PWRMGT, SW_SMIO_INDEX(0), ~SW_SMIO_INDEX_MASK);
1528}
1529
1530void rv770_get_memory_type(struct radeon_device *rdev)
1531{
1532 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1533 u32 tmp;
1534
1535 tmp = RREG32(MC_SEQ_MISC0);
1536
1537 if (((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT) ==
1538 MC_SEQ_MISC0_GDDR5_VALUE)
1539 pi->mem_gddr5 = true;
1540 else
1541 pi->mem_gddr5 = false;
1542
1543}
1544
1545void rv770_get_pcie_gen2_status(struct radeon_device *rdev)
1546{
1547 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1548 u32 tmp;
1549
1550 tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
1551
1552 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
1553 (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
1554 pi->pcie_gen2 = true;
1555 else
1556 pi->pcie_gen2 = false;
1557
1558 if (pi->pcie_gen2) {
1559 if (tmp & LC_CURRENT_DATA_RATE)
1560 pi->boot_in_gen2 = true;
1561 else
1562 pi->boot_in_gen2 = false;
1563 } else
1564 pi->boot_in_gen2 = false;
1565}
1566
1567#if 0
1568static int rv770_enter_ulp_state(struct radeon_device *rdev)
1569{
1570 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1571
1572 if (pi->gfx_clock_gating) {
1573 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
1574 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
1575 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
1576 RREG32(GB_TILING_CONFIG);
1577 }
1578
1579 WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
1580 ~HOST_SMC_MSG_MASK);
1581
1582 udelay(7000);
1583
1584 return 0;
1585}
1586
1587static int rv770_exit_ulp_state(struct radeon_device *rdev)
1588{
1589 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1590 int i;
1591
1592 WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_ResumeFromMinimumPower),
1593 ~HOST_SMC_MSG_MASK);
1594
1595 udelay(7000);
1596
1597 for (i = 0; i < rdev->usec_timeout; i++) {
1598 if (((RREG32(SMC_MSG) & HOST_SMC_RESP_MASK) >> HOST_SMC_RESP_SHIFT) == 1)
1599 break;
1600 udelay(1000);
1601 }
1602
1603 if (pi->gfx_clock_gating)
1604 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
1605
1606 return 0;
1607}
1608#endif
1609
1610static void rv770_get_mclk_odt_threshold(struct radeon_device *rdev)
1611{
1612 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1613 u8 memory_module_index;
1614 struct atom_memory_info memory_info;
1615
1616 pi->mclk_odt_threshold = 0;
1617
1618 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710)) {
1619 memory_module_index = rv770_get_memory_module_index(rdev);
1620
1621 if (radeon_atom_get_memory_info(rdev, memory_module_index, &memory_info))
1622 return;
1623
1624 if (memory_info.mem_type == MEM_TYPE_DDR2 ||
1625 memory_info.mem_type == MEM_TYPE_DDR3)
1626 pi->mclk_odt_threshold = 30000;
1627 }
1628}
1629
1630void rv770_get_max_vddc(struct radeon_device *rdev)
1631{
1632 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1633 u16 vddc;
1634
1635 if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc))
1636 pi->max_vddc = 0;
1637 else
1638 pi->max_vddc = vddc;
1639}
1640
1641void rv770_program_response_times(struct radeon_device *rdev)
1642{
1643 u32 voltage_response_time, backbias_response_time;
1644 u32 acpi_delay_time, vbi_time_out;
1645 u32 vddc_dly, bb_dly, acpi_dly, vbi_dly;
1646 u32 reference_clock;
1647
1648 voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
1649 backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
1650
1651 if (voltage_response_time == 0)
1652 voltage_response_time = 1000;
1653
1654 if (backbias_response_time == 0)
1655 backbias_response_time = 1000;
1656
1657 acpi_delay_time = 15000;
1658 vbi_time_out = 100000;
1659
1660 reference_clock = radeon_get_xclk(rdev);
1661
1662 vddc_dly = (voltage_response_time * reference_clock) / 1600;
1663 bb_dly = (backbias_response_time * reference_clock) / 1600;
1664 acpi_dly = (acpi_delay_time * reference_clock) / 1600;
1665 vbi_dly = (vbi_time_out * reference_clock) / 1600;
1666
1667 rv770_write_smc_soft_register(rdev,
1668 RV770_SMC_SOFT_REGISTER_delay_vreg, vddc_dly);
1669 rv770_write_smc_soft_register(rdev,
1670 RV770_SMC_SOFT_REGISTER_delay_bbias, bb_dly);
1671 rv770_write_smc_soft_register(rdev,
1672 RV770_SMC_SOFT_REGISTER_delay_acpi, acpi_dly);
1673 rv770_write_smc_soft_register(rdev,
1674 RV770_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
1675#if 0
1676 /* XXX look up hw revision */
1677 if (WEKIVA_A21)
1678 rv770_write_smc_soft_register(rdev,
1679 RV770_SMC_SOFT_REGISTER_baby_step_timer,
1680 0x10);
1681#endif
1682}
1683
1684static void rv770_program_dcodt_before_state_switch(struct radeon_device *rdev)
1685{
1686 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1687 struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
1688 struct radeon_ps *radeon_current_state = rdev->pm.dpm.current_ps;
1689 struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
1690 struct rv7xx_ps *current_state = rv770_get_ps(radeon_current_state);
1691 bool current_use_dc = false;
1692 bool new_use_dc = false;
1693
1694 if (pi->mclk_odt_threshold == 0)
1695 return;
1696
1697 if (current_state->high.mclk <= pi->mclk_odt_threshold)
1698 current_use_dc = true;
1699
1700 if (new_state->high.mclk <= pi->mclk_odt_threshold)
1701 new_use_dc = true;
1702
1703 if (current_use_dc == new_use_dc)
1704 return;
1705
1706 if (!current_use_dc && new_use_dc)
1707 return;
1708
1709 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1710 rv730_program_dcodt(rdev, new_use_dc);
1711}
1712
1713static void rv770_program_dcodt_after_state_switch(struct radeon_device *rdev)
1714{
1715 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1716 struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
1717 struct radeon_ps *radeon_current_state = rdev->pm.dpm.current_ps;
1718 struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
1719 struct rv7xx_ps *current_state = rv770_get_ps(radeon_current_state);
1720 bool current_use_dc = false;
1721 bool new_use_dc = false;
1722
1723 if (pi->mclk_odt_threshold == 0)
1724 return;
1725
1726 if (current_state->high.mclk <= pi->mclk_odt_threshold)
1727 current_use_dc = true;
1728
1729 if (new_state->high.mclk <= pi->mclk_odt_threshold)
1730 new_use_dc = true;
1731
1732 if (current_use_dc == new_use_dc)
1733 return;
1734
1735 if (current_use_dc && !new_use_dc)
1736 return;
1737
1738 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1739 rv730_program_dcodt(rdev, new_use_dc);
1740}
1741
1742static void rv770_retrieve_odt_values(struct radeon_device *rdev)
1743{
1744 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1745
1746 if (pi->mclk_odt_threshold == 0)
1747 return;
1748
1749 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1750 rv730_get_odt_values(rdev);
1751}
1752
1753static void rv770_set_dpm_event_sources(struct radeon_device *rdev, u32 sources)
1754{
1755 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1756 bool want_thermal_protection;
1757 enum radeon_dpm_event_src dpm_event_src;
1758
1759 switch (sources) {
1760 case 0:
1761 default:
1762 want_thermal_protection = false;
1763 break;
1764 case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL):
1765 want_thermal_protection = true;
1766 dpm_event_src = RADEON_DPM_EVENT_SRC_DIGITAL;
1767 break;
1768
1769 case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
1770 want_thermal_protection = true;
1771 dpm_event_src = RADEON_DPM_EVENT_SRC_EXTERNAL;
1772 break;
1773
1774 case ((1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
1775 (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL)):
1776 want_thermal_protection = true;
1777 dpm_event_src = RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
1778 break;
1779 }
1780
1781 if (want_thermal_protection) {
1782 WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
1783 if (pi->thermal_protection)
1784 WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
1785 } else {
1786 WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
1787 }
1788}
1789
1790void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
1791 enum radeon_dpm_auto_throttle_src source,
1792 bool enable)
1793{
1794 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1795
1796 if (enable) {
1797 if (!(pi->active_auto_throttle_sources & (1 << source))) {
1798 pi->active_auto_throttle_sources |= 1 << source;
1799 rv770_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
1800 }
1801 } else {
1802 if (pi->active_auto_throttle_sources & (1 << source)) {
1803 pi->active_auto_throttle_sources &= ~(1 << source);
1804 rv770_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
1805 }
1806 }
1807}
1808
1809static int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
1810 int min_temp, int max_temp)
1811{
1812 int low_temp = 0 * 1000;
1813 int high_temp = 255 * 1000;
1814
1815 if (low_temp < min_temp)
1816 low_temp = min_temp;
1817 if (high_temp > max_temp)
1818 high_temp = max_temp;
1819 if (high_temp < low_temp) {
1820 DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
1821 return -EINVAL;
1822 }
1823
1824 WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
1825 WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
1826 WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
1827
1828 rdev->pm.dpm.thermal.min_temp = low_temp;
1829 rdev->pm.dpm.thermal.max_temp = high_temp;
1830
1831 return 0;
1832}
1833
1834int rv770_dpm_enable(struct radeon_device *rdev)
1835{
1836 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1837
1838 if (pi->gfx_clock_gating)
1839 rv770_restore_cgcg(rdev);
1840
1841 if (rv770_dpm_enabled(rdev))
1842 return -EINVAL;
1843
1844 if (pi->voltage_control) {
1845 rv770_enable_voltage_control(rdev, true);
1846 rv770_construct_vddc_table(rdev);
1847 }
1848
1849 if (pi->dcodt)
1850 rv770_retrieve_odt_values(rdev);
1851
1852 if (pi->mvdd_control)
1853 rv770_get_mvdd_configuration(rdev);
1854
1855 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
1856 rv770_enable_backbias(rdev, true);
1857
1858 rv770_enable_spread_spectrum(rdev, true);
1859
1860 if (pi->thermal_protection)
1861 rv770_enable_thermal_protection(rdev, true);
1862
1863 rv770_program_mpll_timing_parameters(rdev);
1864 rv770_setup_bsp(rdev);
1865 rv770_program_git(rdev);
1866 rv770_program_tp(rdev);
1867 rv770_program_tpp(rdev);
1868 rv770_program_sstp(rdev);
1869 rv770_program_engine_speed_parameters(rdev);
1870 rv770_enable_display_gap(rdev);
1871 rv770_program_vc(rdev);
1872
1873 if (pi->dynamic_pcie_gen2)
1874 rv770_enable_dynamic_pcie_gen2(rdev, true);
1875
1876 if (rv770_upload_firmware(rdev))
1877 return -EINVAL;
1878 /* get ucode version ? */
1879 if (rv770_init_smc_table(rdev))
1880 return -EINVAL;
1881 rv770_program_response_times(rdev);
1882 r7xx_start_smc(rdev);
1883
1884 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1885 rv730_start_dpm(rdev);
1886 else
1887 rv770_start_dpm(rdev);
1888
1889 if (pi->gfx_clock_gating)
1890 rv770_gfx_clock_gating_enable(rdev, true);
1891
1892 if (pi->mg_clock_gating)
1893 rv770_mg_clock_gating_enable(rdev, true);
1894
1895 if (rdev->irq.installed &&
1896 r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1897 PPSMC_Result result;
1898
1899 rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
1900 rdev->irq.dpm_thermal = true;
1901 radeon_irq_set(rdev);
1902 result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
1903
1904 if (result != PPSMC_Result_OK)
1905 DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
1906 }
1907
1908 rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
1909
1910 return 0;
1911}
1912
1913void rv770_dpm_disable(struct radeon_device *rdev)
1914{
1915 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1916
1917 if (!rv770_dpm_enabled(rdev))
1918 return;
1919
1920 rv770_clear_vc(rdev);
1921
1922 if (pi->thermal_protection)
1923 rv770_enable_thermal_protection(rdev, false);
1924
1925 rv770_enable_spread_spectrum(rdev, false);
1926
1927 if (pi->dynamic_pcie_gen2)
1928 rv770_enable_dynamic_pcie_gen2(rdev, false);
1929
1930 if (rdev->irq.installed &&
1931 r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1932 rdev->irq.dpm_thermal = false;
1933 radeon_irq_set(rdev);
1934 }
1935
1936 if (pi->gfx_clock_gating)
1937 rv770_gfx_clock_gating_enable(rdev, false);
1938
1939 if (pi->mg_clock_gating)
1940 rv770_mg_clock_gating_enable(rdev, false);
1941
1942 if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
1943 rv730_stop_dpm(rdev);
1944 else
1945 rv770_stop_dpm(rdev);
1946
1947 r7xx_stop_smc(rdev);
1948 rv770_reset_smio_status(rdev);
1949}
1950
1951int rv770_dpm_set_power_state(struct radeon_device *rdev)
1952{
1953 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1954
1955 rv770_restrict_performance_levels_before_switch(rdev);
1956 rv770_halt_smc(rdev);
1957 rv770_upload_sw_state(rdev);
1958 r7xx_program_memory_timing_parameters(rdev);
1959 if (pi->dcodt)
1960 rv770_program_dcodt_before_state_switch(rdev);
1961 rv770_resume_smc(rdev);
1962 rv770_set_sw_state(rdev);
1963 if (pi->dcodt)
1964 rv770_program_dcodt_after_state_switch(rdev);
1965 rv770_unrestrict_performance_levels_after_switch(rdev);
1966
1967 return 0;
1968}
1969
1970void rv770_dpm_reset_asic(struct radeon_device *rdev)
1971{
1972 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1973
1974 rv770_restrict_performance_levels_before_switch(rdev);
1975 if (pi->dcodt)
1976 rv770_program_dcodt_before_state_switch(rdev);
1977 rv770_set_boot_state(rdev);
1978 if (pi->dcodt)
1979 rv770_program_dcodt_after_state_switch(rdev);
1980}
1981
1982void rv770_dpm_setup_asic(struct radeon_device *rdev)
1983{
1984 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1985
1986 r7xx_read_clock_registers(rdev);
1987 rv770_read_voltage_smio_registers(rdev);
1988 rv770_get_memory_type(rdev);
1989 if (pi->dcodt)
1990 rv770_get_mclk_odt_threshold(rdev);
1991 rv770_get_pcie_gen2_status(rdev);
1992
1993 rv770_enable_acpi_pm(rdev);
1994
1995 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s)
1996 rv770_enable_l0s(rdev);
1997 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1)
1998 rv770_enable_l1(rdev);
1999 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1)
2000 rv770_enable_pll_sleep_in_l1(rdev);
2001}
2002
2003void rv770_dpm_display_configuration_changed(struct radeon_device *rdev)
2004{
2005 rv770_program_display_gap(rdev);
2006}
2007
2008union power_info {
2009 struct _ATOM_POWERPLAY_INFO info;
2010 struct _ATOM_POWERPLAY_INFO_V2 info_2;
2011 struct _ATOM_POWERPLAY_INFO_V3 info_3;
2012 struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
2013 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
2014 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
2015};
2016
2017union pplib_clock_info {
2018 struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
2019 struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
2020 struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
2021 struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
2022};
2023
2024union pplib_power_state {
2025 struct _ATOM_PPLIB_STATE v1;
2026 struct _ATOM_PPLIB_STATE_V2 v2;
2027};
2028
2029static void rv7xx_parse_pplib_non_clock_info(struct radeon_device *rdev,
2030 struct radeon_ps *rps,
2031 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
2032 u8 table_rev)
2033{
2034 rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
2035 rps->class = le16_to_cpu(non_clock_info->usClassification);
2036 rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
2037
2038 if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
2039 rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
2040 rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
2041 } else if (r600_is_uvd_state(rps->class, rps->class2)) {
2042 rps->vclk = RV770_DEFAULT_VCLK_FREQ;
2043 rps->dclk = RV770_DEFAULT_DCLK_FREQ;
2044 } else {
2045 rps->vclk = 0;
2046 rps->dclk = 0;
2047 }
2048
2049 if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
2050 rdev->pm.dpm.boot_ps = rps;
2051 if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
2052 rdev->pm.dpm.uvd_ps = rps;
2053}
2054
2055static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
2056 struct radeon_ps *rps, int index,
2057 union pplib_clock_info *clock_info)
2058{
2059 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2060 struct rv7xx_ps *ps = rv770_get_ps(rps);
2061 u32 sclk, mclk;
2062 u16 vddc;
2063 struct rv7xx_pl *pl;
2064
2065 switch (index) {
2066 case 0:
2067 pl = &ps->low;
2068 break;
2069 case 1:
2070 pl = &ps->medium;
2071 break;
2072 case 2:
2073 default:
2074 pl = &ps->high;
2075 break;
2076 }
2077
2078 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
2079 sclk |= clock_info->r600.ucEngineClockHigh << 16;
2080 mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
2081 mclk |= clock_info->r600.ucMemoryClockHigh << 16;
2082
2083 pl->vddc = le16_to_cpu(clock_info->r600.usVDDC);
2084 pl->flags = le32_to_cpu(clock_info->r600.ulFlags);
2085
2086 pl->mclk = mclk;
2087 pl->sclk = sclk;
2088
2089 /* patch up vddc if necessary */
2090 if (pl->vddc == 0xff01) {
2091 if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0)
2092 pl->vddc = vddc;
2093 }
2094
2095 if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
2096 pi->acpi_vddc = pl->vddc;
2097 if (ps->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
2098 pi->acpi_pcie_gen2 = true;
2099 else
2100 pi->acpi_pcie_gen2 = false;
2101 }
2102
2103 if (pi->min_vddc_in_table > pl->vddc)
2104 pi->min_vddc_in_table = pl->vddc;
2105
2106 if (pi->max_vddc_in_table < pl->vddc)
2107 pi->max_vddc_in_table = pl->vddc;
2108
2109 /* patch up boot state */
2110 if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
2111 u16 vddc, vddci;
2112 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci);
2113 pl->mclk = rdev->clock.default_mclk;
2114 pl->sclk = rdev->clock.default_sclk;
2115 pl->vddc = vddc;
2116 pl->vddci = vddci;
2117 }
2118}
2119
2120int rv7xx_parse_power_table(struct radeon_device *rdev)
2121{
2122 struct radeon_mode_info *mode_info = &rdev->mode_info;
2123 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
2124 union pplib_power_state *power_state;
2125 int i, j;
2126 union pplib_clock_info *clock_info;
2127 union power_info *power_info;
2128 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
2129 u16 data_offset;
2130 u8 frev, crev;
2131 struct rv7xx_ps *ps;
2132
2133 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
2134 &frev, &crev, &data_offset))
2135 return -EINVAL;
2136 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
2137
2138 rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
2139 power_info->pplib.ucNumStates, GFP_KERNEL);
2140 if (!rdev->pm.dpm.ps)
2141 return -ENOMEM;
2142 rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
2143 rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
2144 rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
2145
2146 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
2147 power_state = (union pplib_power_state *)
2148 (mode_info->atom_context->bios + data_offset +
2149 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
2150 i * power_info->pplib.ucStateEntrySize);
2151 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
2152 (mode_info->atom_context->bios + data_offset +
2153 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
2154 (power_state->v1.ucNonClockStateIndex *
2155 power_info->pplib.ucNonClockSize));
2156 if (power_info->pplib.ucStateEntrySize - 1) {
2157 ps = kzalloc(sizeof(struct rv7xx_ps), GFP_KERNEL);
2158 if (ps == NULL) {
2159 kfree(rdev->pm.dpm.ps);
2160 return -ENOMEM;
2161 }
2162 rdev->pm.dpm.ps[i].ps_priv = ps;
2163 rv7xx_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
2164 non_clock_info,
2165 power_info->pplib.ucNonClockSize);
2166 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
2167 clock_info = (union pplib_clock_info *)
2168 (mode_info->atom_context->bios + data_offset +
2169 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
2170 (power_state->v1.ucClockStateIndices[j] *
2171 power_info->pplib.ucClockInfoSize));
2172 rv7xx_parse_pplib_clock_info(rdev,
2173 &rdev->pm.dpm.ps[i], j,
2174 clock_info);
2175 }
2176 }
2177 }
2178 rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
2179 return 0;
2180}
2181
2182int rv770_dpm_init(struct radeon_device *rdev)
2183{
2184 struct rv7xx_power_info *pi;
2185 int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
2186 uint16_t data_offset, size;
2187 uint8_t frev, crev;
2188 struct atom_clock_dividers dividers;
2189 int ret;
2190
2191 pi = kzalloc(sizeof(struct rv7xx_power_info), GFP_KERNEL);
2192 if (pi == NULL)
2193 return -ENOMEM;
2194 rdev->pm.dpm.priv = pi;
2195
2196 rv770_get_max_vddc(rdev);
2197
2198 pi->acpi_vddc = 0;
2199 pi->min_vddc_in_table = 0;
2200 pi->max_vddc_in_table = 0;
2201
2202 ret = rv7xx_parse_power_table(rdev);
2203 if (ret)
2204 return ret;
2205
2206 if (rdev->pm.dpm.voltage_response_time == 0)
2207 rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
2208 if (rdev->pm.dpm.backbias_response_time == 0)
2209 rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
2210
2211 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2212 0, false, &dividers);
2213 if (ret)
2214 pi->ref_div = dividers.ref_div + 1;
2215 else
2216 pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
2217
2218 pi->mclk_strobe_mode_threshold = 30000;
2219 pi->mclk_edc_enable_threshold = 30000;
2220
2221 pi->voltage_control =
2222 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
2223
2224 pi->mvdd_control =
2225 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC);
2226
2227 if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
2228 &frev, &crev, &data_offset)) {
2229 pi->sclk_ss = true;
2230 pi->mclk_ss = true;
2231 pi->dynamic_ss = true;
2232 } else {
2233 pi->sclk_ss = false;
2234 pi->mclk_ss = false;
2235 pi->dynamic_ss = false;
2236 }
2237
2238 pi->asi = RV770_ASI_DFLT;
2239 pi->pasi = RV770_HASI_DFLT;
2240 pi->vrc = RV770_VRC_DFLT;
2241
2242 pi->power_gating = false;
2243
2244 pi->gfx_clock_gating = true;
2245
2246 pi->mg_clock_gating = true;
2247 pi->mgcgtssm = true;
2248
2249 pi->dynamic_pcie_gen2 = true;
2250
2251 if (pi->gfx_clock_gating &&
2252 (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
2253 pi->thermal_protection = true;
2254 else
2255 pi->thermal_protection = false;
2256
2257 pi->display_gap = true;
2258
2259 if (rdev->flags & RADEON_IS_MOBILITY)
2260 pi->dcodt = true;
2261 else
2262 pi->dcodt = false;
2263
2264 pi->ulps = true;
2265
2266 pi->mclk_stutter_mode_threshold = 0;
2267
2268 pi->sram_end = SMC_RAM_END;
2269 pi->state_table_start = RV770_SMC_TABLE_ADDRESS;
2270 pi->soft_regs_start = RV770_SMC_SOFT_REGISTERS_START;
2271
2272 return 0;
2273}
2274
2275void rv770_dpm_print_power_state(struct radeon_device *rdev,
2276 struct radeon_ps *rps)
2277{
2278 struct rv7xx_ps *ps = rv770_get_ps(rps);
2279 struct rv7xx_pl *pl;
2280
2281 r600_dpm_print_class_info(rps->class, rps->class2);
2282 r600_dpm_print_cap_info(rps->caps);
2283 printk("\tuvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2284 if (rdev->family >= CHIP_CEDAR) {
2285 pl = &ps->low;
2286 printk("\t\tpower level 0 sclk: %u mclk: %u vddc: %u vddci: %u\n",
2287 pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2288 pl = &ps->medium;
2289 printk("\t\tpower level 1 sclk: %u mclk: %u vddc: %u vddci: %u\n",
2290 pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2291 pl = &ps->high;
2292 printk("\t\tpower level 2 sclk: %u mclk: %u vddc: %u vddci: %u\n",
2293 pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2294 } else {
2295 pl = &ps->low;
2296 printk("\t\tpower level 0 sclk: %u mclk: %u vddc: %u\n",
2297 pl->sclk, pl->mclk, pl->vddc);
2298 pl = &ps->medium;
2299 printk("\t\tpower level 1 sclk: %u mclk: %u vddc: %u\n",
2300 pl->sclk, pl->mclk, pl->vddc);
2301 pl = &ps->high;
2302 printk("\t\tpower level 2 sclk: %u mclk: %u vddc: %u\n",
2303 pl->sclk, pl->mclk, pl->vddc);
2304 }
2305 r600_dpm_print_ps_status(rdev, rps);
2306}
2307
2308void rv770_dpm_fini(struct radeon_device *rdev)
2309{
2310 int i;
2311
2312 for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2313 kfree(rdev->pm.dpm.ps[i].ps_priv);
2314 }
2315 kfree(rdev->pm.dpm.ps);
2316 kfree(rdev->pm.dpm.priv);
2317}
2318
2319u32 rv770_dpm_get_sclk(struct radeon_device *rdev, bool low)
2320{
2321 struct rv7xx_ps *requested_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
2322
2323 if (low)
2324 return requested_state->low.sclk;
2325 else
2326 return requested_state->high.sclk;
2327}
2328
2329u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low)
2330{
2331 struct rv7xx_ps *requested_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
2332
2333 if (low)
2334 return requested_state->low.mclk;
2335 else
2336 return requested_state->high.mclk;
2337}
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h
new file mode 100644
index 000000000000..0f33f9bb244f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv770_dpm.h
@@ -0,0 +1,273 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef __RV770_DPM_H__
24#define __RV770_DPM_H__
25
26#include "rv770_smc.h"
27
28struct rv770_clock_registers {
29 u32 cg_spll_func_cntl;
30 u32 cg_spll_func_cntl_2;
31 u32 cg_spll_func_cntl_3;
32 u32 cg_spll_spread_spectrum;
33 u32 cg_spll_spread_spectrum_2;
34 u32 mpll_ad_func_cntl;
35 u32 mpll_ad_func_cntl_2;
36 u32 mpll_dq_func_cntl;
37 u32 mpll_dq_func_cntl_2;
38 u32 mclk_pwrmgt_cntl;
39 u32 dll_cntl;
40 u32 mpll_ss1;
41 u32 mpll_ss2;
42};
43
44struct rv730_clock_registers {
45 u32 cg_spll_func_cntl;
46 u32 cg_spll_func_cntl_2;
47 u32 cg_spll_func_cntl_3;
48 u32 cg_spll_spread_spectrum;
49 u32 cg_spll_spread_spectrum_2;
50 u32 mclk_pwrmgt_cntl;
51 u32 dll_cntl;
52 u32 mpll_func_cntl;
53 u32 mpll_func_cntl2;
54 u32 mpll_func_cntl3;
55 u32 mpll_ss;
56 u32 mpll_ss2;
57};
58
59union r7xx_clock_registers {
60 struct rv770_clock_registers rv770;
61 struct rv730_clock_registers rv730;
62};
63
64struct vddc_table_entry {
65 u16 vddc;
66 u8 vddc_index;
67 u8 high_smio;
68 u32 low_smio;
69};
70
71#define MAX_NO_OF_MVDD_VALUES 2
72#define MAX_NO_VREG_STEPS 32
73
74struct rv7xx_power_info {
75 /* flags */
76 bool mem_gddr5;
77 bool pcie_gen2;
78 bool dynamic_pcie_gen2;
79 bool acpi_pcie_gen2;
80 bool boot_in_gen2;
81 bool voltage_control; /* vddc */
82 bool mvdd_control;
83 bool sclk_ss;
84 bool mclk_ss;
85 bool dynamic_ss;
86 bool gfx_clock_gating;
87 bool mg_clock_gating;
88 bool mgcgtssm;
89 bool power_gating;
90 bool thermal_protection;
91 bool display_gap;
92 bool dcodt;
93 bool ulps;
94 /* registers */
95 union r7xx_clock_registers clk_regs;
96 u32 s0_vid_lower_smio_cntl;
97 /* voltage */
98 u32 vddc_mask_low;
99 u32 mvdd_mask_low;
100 u32 mvdd_split_frequency;
101 u32 mvdd_low_smio[MAX_NO_OF_MVDD_VALUES];
102 u16 max_vddc;
103 u16 max_vddc_in_table;
104 u16 min_vddc_in_table;
105 struct vddc_table_entry vddc_table[MAX_NO_VREG_STEPS];
106 u8 valid_vddc_entries;
107 /* dc odt */
108 u32 mclk_odt_threshold;
109 u8 odt_value_0[2];
110 u8 odt_value_1[2];
111 /* stored values */
112 u32 boot_sclk;
113 u16 acpi_vddc;
114 u32 ref_div;
115 u32 active_auto_throttle_sources;
116 u32 mclk_stutter_mode_threshold;
117 u32 mclk_strobe_mode_threshold;
118 u32 mclk_edc_enable_threshold;
119 u32 bsp;
120 u32 bsu;
121 u32 pbsp;
122 u32 pbsu;
123 u32 dsp;
124 u32 psp;
125 u32 asi;
126 u32 pasi;
127 u32 vrc;
128 u32 restricted_levels;
129 /* smc offsets */
130 u16 state_table_start;
131 u16 soft_regs_start;
132 u16 sram_end;
133 /* scratch structs */
134 RV770_SMC_STATETABLE smc_statetable;
135};
136
137struct rv7xx_pl {
138 u32 sclk;
139 u32 mclk;
140 u16 vddc;
141 u16 vddci; /* eg+ only */
142 u32 flags;
143};
144
145struct rv7xx_ps {
146 struct rv7xx_pl high;
147 struct rv7xx_pl medium;
148 struct rv7xx_pl low;
149 bool dc_compatible;
150};
151
152#define RV770_RLP_DFLT 10
153#define RV770_RMP_DFLT 25
154#define RV770_LHP_DFLT 25
155#define RV770_LMP_DFLT 10
156#define RV770_VRC_DFLT 0x003f
157#define RV770_ASI_DFLT 1000
158#define RV770_HASI_DFLT 200000
159#define RV770_MGCGTTLOCAL0_DFLT 0x00100000
160#define RV7XX_MGCGTTLOCAL0_DFLT 0
161#define RV770_MGCGTTLOCAL1_DFLT 0xFFFF0000
162#define RV770_MGCGCGTSSMCTRL_DFLT 0x55940000
163
164#define MVDD_LOW_INDEX 0
165#define MVDD_HIGH_INDEX 1
166
167#define MVDD_LOW_VALUE 0
168#define MVDD_HIGH_VALUE 0xffff
169
170#define RV770_DEFAULT_VCLK_FREQ 53300 /* 10 khz */
171#define RV770_DEFAULT_DCLK_FREQ 40000 /* 10 khz */
172
173/* rv730/rv710 */
174int rv730_populate_sclk_value(struct radeon_device *rdev,
175 u32 engine_clock,
176 RV770_SMC_SCLK_VALUE *sclk);
177int rv730_populate_mclk_value(struct radeon_device *rdev,
178 u32 engine_clock, u32 memory_clock,
179 LPRV7XX_SMC_MCLK_VALUE mclk);
180void rv730_read_clock_registers(struct radeon_device *rdev);
181int rv730_populate_smc_acpi_state(struct radeon_device *rdev,
182 RV770_SMC_STATETABLE *table);
183int rv730_populate_smc_initial_state(struct radeon_device *rdev,
184 struct radeon_ps *radeon_initial_state,
185 RV770_SMC_STATETABLE *table);
186void rv730_program_memory_timing_parameters(struct radeon_device *rdev,
187 struct radeon_ps *radeon_state);
188void rv730_power_gating_enable(struct radeon_device *rdev,
189 bool enable);
190void rv730_start_dpm(struct radeon_device *rdev);
191void rv730_stop_dpm(struct radeon_device *rdev);
192void rv730_program_dcodt(struct radeon_device *rdev, bool use_dcodt);
193void rv730_get_odt_values(struct radeon_device *rdev);
194
195/* rv740 */
196int rv740_populate_sclk_value(struct radeon_device *rdev, u32 engine_clock,
197 RV770_SMC_SCLK_VALUE *sclk);
198int rv740_populate_mclk_value(struct radeon_device *rdev,
199 u32 engine_clock, u32 memory_clock,
200 RV7XX_SMC_MCLK_VALUE *mclk);
201void rv740_read_clock_registers(struct radeon_device *rdev);
202int rv740_populate_smc_acpi_state(struct radeon_device *rdev,
203 RV770_SMC_STATETABLE *table);
204void rv740_enable_mclk_spread_spectrum(struct radeon_device *rdev,
205 bool enable);
206u8 rv740_get_mclk_frequency_ratio(u32 memory_clock);
207u32 rv740_get_dll_speed(bool is_gddr5, u32 memory_clock);
208u32 rv740_get_decoded_reference_divider(u32 encoded_ref);
209
210/* rv770 */
211u32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf);
212int rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc,
213 RV770_SMC_VOLTAGE_VALUE *voltage);
214int rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
215 RV770_SMC_VOLTAGE_VALUE *voltage);
216u8 rv770_get_seq_value(struct radeon_device *rdev,
217 struct rv7xx_pl *pl);
218int rv770_populate_initial_mvdd_value(struct radeon_device *rdev,
219 RV770_SMC_VOLTAGE_VALUE *voltage);
220u32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev,
221 u32 engine_clock);
222void rv770_program_response_times(struct radeon_device *rdev);
223int rv770_populate_smc_sp(struct radeon_device *rdev,
224 struct radeon_ps *radeon_state,
225 RV770_SMC_SWSTATE *smc_state);
226int rv770_populate_smc_t(struct radeon_device *rdev,
227 struct radeon_ps *radeon_state,
228 RV770_SMC_SWSTATE *smc_state);
229void rv770_read_voltage_smio_registers(struct radeon_device *rdev);
230void rv770_get_memory_type(struct radeon_device *rdev);
231void r7xx_start_smc(struct radeon_device *rdev);
232u8 rv770_get_memory_module_index(struct radeon_device *rdev);
233void rv770_get_max_vddc(struct radeon_device *rdev);
234void rv770_get_pcie_gen2_status(struct radeon_device *rdev);
235void rv770_enable_acpi_pm(struct radeon_device *rdev);
236void rv770_restore_cgcg(struct radeon_device *rdev);
237bool rv770_dpm_enabled(struct radeon_device *rdev);
238void rv770_enable_voltage_control(struct radeon_device *rdev,
239 bool enable);
240void rv770_enable_backbias(struct radeon_device *rdev,
241 bool enable);
242void rv770_enable_thermal_protection(struct radeon_device *rdev,
243 bool enable);
244void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
245 enum radeon_dpm_auto_throttle_src source,
246 bool enable);
247void rv770_setup_bsp(struct radeon_device *rdev);
248void rv770_program_git(struct radeon_device *rdev);
249void rv770_program_tp(struct radeon_device *rdev);
250void rv770_program_tpp(struct radeon_device *rdev);
251void rv770_program_sstp(struct radeon_device *rdev);
252void rv770_program_engine_speed_parameters(struct radeon_device *rdev);
253void rv770_program_vc(struct radeon_device *rdev);
254void rv770_clear_vc(struct radeon_device *rdev);
255int rv770_upload_firmware(struct radeon_device *rdev);
256void rv770_stop_dpm(struct radeon_device *rdev);
257void r7xx_stop_smc(struct radeon_device *rdev);
258void rv770_reset_smio_status(struct radeon_device *rdev);
259int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev);
260int rv770_unrestrict_performance_levels_after_switch(struct radeon_device *rdev);
261int rv770_halt_smc(struct radeon_device *rdev);
262int rv770_resume_smc(struct radeon_device *rdev);
263int rv770_set_sw_state(struct radeon_device *rdev);
264int rv770_set_boot_state(struct radeon_device *rdev);
265int rv7xx_parse_power_table(struct radeon_device *rdev);
266
267/* smc */
268int rv770_read_smc_soft_register(struct radeon_device *rdev,
269 u16 reg_offset, u32 *value);
270int rv770_write_smc_soft_register(struct radeon_device *rdev,
271 u16 reg_offset, u32 value);
272
273#endif
diff --git a/drivers/gpu/drm/radeon/rv770_smc.c b/drivers/gpu/drm/radeon/rv770_smc.c
new file mode 100644
index 000000000000..8e071530fe9d
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv770_smc.c
@@ -0,0 +1,404 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Alex Deucher
23 */
24
25#include <linux/firmware.h>
26#include "drmP.h"
27#include "radeon.h"
28#include "rv770d.h"
29#include "rv770_dpm.h"
30#include "rv770_smc.h"
31#include "atom.h"
32#include "radeon_ucode.h"
33
34#define FIRST_SMC_INT_VECT_REG 0xFFD8
35#define FIRST_INT_VECT_S19 0xFFC0
36
37static const u8 rv770_smc_int_vectors[] =
38{
39 0x08, 0x10, 0x08, 0x10,
40 0x08, 0x10, 0x08, 0x10,
41 0x08, 0x10, 0x08, 0x10,
42 0x08, 0x10, 0x08, 0x10,
43 0x08, 0x10, 0x08, 0x10,
44 0x08, 0x10, 0x08, 0x10,
45 0x08, 0x10, 0x08, 0x10,
46 0x08, 0x10, 0x08, 0x10,
47 0x08, 0x10, 0x08, 0x10,
48 0x08, 0x10, 0x08, 0x10,
49 0x08, 0x10, 0x08, 0x10,
50 0x08, 0x10, 0x08, 0x10,
51 0x08, 0x10, 0x0C, 0xD7,
52 0x08, 0x2B, 0x08, 0x10,
53 0x03, 0x51, 0x03, 0x51,
54 0x03, 0x51, 0x03, 0x51
55};
56
57static const u8 rv730_smc_int_vectors[] =
58{
59 0x08, 0x15, 0x08, 0x15,
60 0x08, 0x15, 0x08, 0x15,
61 0x08, 0x15, 0x08, 0x15,
62 0x08, 0x15, 0x08, 0x15,
63 0x08, 0x15, 0x08, 0x15,
64 0x08, 0x15, 0x08, 0x15,
65 0x08, 0x15, 0x08, 0x15,
66 0x08, 0x15, 0x08, 0x15,
67 0x08, 0x15, 0x08, 0x15,
68 0x08, 0x15, 0x08, 0x15,
69 0x08, 0x15, 0x08, 0x15,
70 0x08, 0x15, 0x08, 0x15,
71 0x08, 0x15, 0x0C, 0xBB,
72 0x08, 0x30, 0x08, 0x15,
73 0x03, 0x56, 0x03, 0x56,
74 0x03, 0x56, 0x03, 0x56
75};
76
77static const u8 rv710_smc_int_vectors[] =
78{
79 0x08, 0x04, 0x08, 0x04,
80 0x08, 0x04, 0x08, 0x04,
81 0x08, 0x04, 0x08, 0x04,
82 0x08, 0x04, 0x08, 0x04,
83 0x08, 0x04, 0x08, 0x04,
84 0x08, 0x04, 0x08, 0x04,
85 0x08, 0x04, 0x08, 0x04,
86 0x08, 0x04, 0x08, 0x04,
87 0x08, 0x04, 0x08, 0x04,
88 0x08, 0x04, 0x08, 0x04,
89 0x08, 0x04, 0x08, 0x04,
90 0x08, 0x04, 0x08, 0x04,
91 0x08, 0x04, 0x0C, 0xCB,
92 0x08, 0x1F, 0x08, 0x04,
93 0x03, 0x51, 0x03, 0x51,
94 0x03, 0x51, 0x03, 0x51
95};
96
97static const u8 rv740_smc_int_vectors[] =
98{
99 0x08, 0x10, 0x08, 0x10,
100 0x08, 0x10, 0x08, 0x10,
101 0x08, 0x10, 0x08, 0x10,
102 0x08, 0x10, 0x08, 0x10,
103 0x08, 0x10, 0x08, 0x10,
104 0x08, 0x10, 0x08, 0x10,
105 0x08, 0x10, 0x08, 0x10,
106 0x08, 0x10, 0x08, 0x10,
107 0x08, 0x10, 0x08, 0x10,
108 0x08, 0x10, 0x08, 0x10,
109 0x08, 0x10, 0x08, 0x10,
110 0x08, 0x10, 0x08, 0x10,
111 0x08, 0x10, 0x0C, 0xD7,
112 0x08, 0x2B, 0x08, 0x10,
113 0x03, 0x51, 0x03, 0x51,
114 0x03, 0x51, 0x03, 0x51
115};
116
117int rv770_set_smc_sram_address(struct radeon_device *rdev,
118 u16 smc_address, u16 limit)
119{
120 u32 addr;
121
122 if (smc_address & 3)
123 return -EINVAL;
124 if ((smc_address + 3) > limit)
125 return -EINVAL;
126
127 addr = smc_address;
128 addr |= SMC_SRAM_AUTO_INC_DIS;
129
130 WREG32(SMC_SRAM_ADDR, addr);
131
132 return 0;
133}
134
135int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
136 u16 smc_start_address, const u8 *src,
137 u16 byte_count, u16 limit)
138{
139 u32 data, original_data, extra_shift;
140 u16 addr;
141 int ret;
142
143 if (smc_start_address & 3)
144 return -EINVAL;
145 if ((smc_start_address + byte_count) > limit)
146 return -EINVAL;
147
148 addr = smc_start_address;
149
150 while (byte_count >= 4) {
151 /* SMC address space is BE */
152 data = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
153
154 ret = rv770_set_smc_sram_address(rdev, addr, limit);
155 if (ret)
156 return ret;
157
158 WREG32(SMC_SRAM_DATA, data);
159
160 src += 4;
161 byte_count -= 4;
162 addr += 4;
163 }
164
165 /* RMW for final bytes */
166 if (byte_count > 0) {
167 data = 0;
168
169 ret = rv770_set_smc_sram_address(rdev, addr, limit);
170 if (ret)
171 return ret;
172
173 original_data = RREG32(SMC_SRAM_DATA);
174
175 extra_shift = 8 * (4 - byte_count);
176
177 while (byte_count > 0) {
178 /* SMC address space is BE */
179 data = (data << 8) + *src++;
180 byte_count--;
181 }
182
183 data <<= extra_shift;
184
185 data |= (original_data & ~((~0UL) << extra_shift));
186
187 ret = rv770_set_smc_sram_address(rdev, addr, limit);
188 if (ret)
189 return ret;
190
191 WREG32(SMC_SRAM_DATA, data);
192 }
193
194 return 0;
195}
196
197static int rv770_program_interrupt_vectors(struct radeon_device *rdev,
198 u32 smc_first_vector, const u8 *src,
199 u32 byte_count)
200{
201 u32 tmp, i;
202
203 if (byte_count % 4)
204 return -EINVAL;
205
206 if (smc_first_vector < FIRST_SMC_INT_VECT_REG) {
207 tmp = FIRST_SMC_INT_VECT_REG - smc_first_vector;
208
209 if (tmp > byte_count)
210 return 0;
211
212 byte_count -= tmp;
213 src += tmp;
214 smc_first_vector = FIRST_SMC_INT_VECT_REG;
215 }
216
217 for (i = 0; i < byte_count; i += 4) {
218 /* SMC address space is BE */
219 tmp = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
220
221 WREG32(SMC_ISR_FFD8_FFDB + i, tmp);
222 }
223
224 return 0;
225}
226
227void rv770_start_smc(struct radeon_device *rdev)
228{
229 WREG32_P(SMC_IO, SMC_RST_N, ~SMC_RST_N);
230}
231
232void rv770_reset_smc(struct radeon_device *rdev)
233{
234 WREG32_P(SMC_IO, 0, ~SMC_RST_N);
235}
236
237void rv770_stop_smc_clock(struct radeon_device *rdev)
238{
239 WREG32_P(SMC_IO, 0, ~SMC_CLK_EN);
240}
241
242void rv770_start_smc_clock(struct radeon_device *rdev)
243{
244 WREG32_P(SMC_IO, SMC_CLK_EN, ~SMC_CLK_EN);
245}
246
247bool rv770_is_smc_running(struct radeon_device *rdev)
248{
249 u32 tmp;
250
251 tmp = RREG32(SMC_IO);
252
253 if ((tmp & SMC_RST_N) && (tmp & SMC_CLK_EN))
254 return true;
255 else
256 return false;
257}
258
259PPSMC_Result rv770_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg)
260{
261 u32 tmp;
262 int i;
263 PPSMC_Result result;
264
265 if (!rv770_is_smc_running(rdev))
266 return PPSMC_Result_Failed;
267
268 WREG32_P(SMC_MSG, HOST_SMC_MSG(msg), ~HOST_SMC_MSG_MASK);
269
270 for (i = 0; i < rdev->usec_timeout; i++) {
271 tmp = RREG32(SMC_MSG) & HOST_SMC_RESP_MASK;
272 tmp >>= HOST_SMC_RESP_SHIFT;
273 if (tmp != 0)
274 break;
275 udelay(1);
276 }
277
278 tmp = RREG32(SMC_MSG) & HOST_SMC_RESP_MASK;
279 tmp >>= HOST_SMC_RESP_SHIFT;
280
281 result = (PPSMC_Result)tmp;
282 return result;
283}
284
285PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev)
286{
287 int i;
288 PPSMC_Result result = PPSMC_Result_OK;
289
290 if (!rv770_is_smc_running(rdev))
291 return result;
292
293 for (i = 0; i < rdev->usec_timeout; i++) {
294 if (RREG32(SMC_IO) & SMC_STOP_MODE)
295 break;
296 udelay(1);
297 }
298
299 return result;
300}
301
302static void rv770_clear_smc_sram(struct radeon_device *rdev, u16 limit)
303{
304 u16 i;
305
306 for (i = 0; i < limit; i += 4) {
307 rv770_set_smc_sram_address(rdev, i, limit);
308 WREG32(SMC_SRAM_DATA, 0);
309 }
310}
311
312int rv770_load_smc_ucode(struct radeon_device *rdev,
313 u16 limit)
314{
315 int ret;
316 const u8 *int_vect;
317 u16 int_vect_start_address;
318 u16 int_vect_size;
319 const u8 *ucode_data;
320 u16 ucode_start_address;
321 u16 ucode_size;
322
323 if (!rdev->smc_fw)
324 return -EINVAL;
325
326 rv770_clear_smc_sram(rdev, limit);
327
328 switch (rdev->family) {
329 case CHIP_RV770:
330 ucode_start_address = RV770_SMC_UCODE_START;
331 ucode_size = RV770_SMC_UCODE_SIZE;
332 int_vect = (const u8 *)&rv770_smc_int_vectors;
333 int_vect_start_address = RV770_SMC_INT_VECTOR_START;
334 int_vect_size = RV770_SMC_INT_VECTOR_SIZE;
335 break;
336 case CHIP_RV730:
337 ucode_start_address = RV730_SMC_UCODE_START;
338 ucode_size = RV730_SMC_UCODE_SIZE;
339 int_vect = (const u8 *)&rv730_smc_int_vectors;
340 int_vect_start_address = RV730_SMC_INT_VECTOR_START;
341 int_vect_size = RV730_SMC_INT_VECTOR_SIZE;
342 break;
343 case CHIP_RV710:
344 ucode_start_address = RV710_SMC_UCODE_START;
345 ucode_size = RV710_SMC_UCODE_SIZE;
346 int_vect = (const u8 *)&rv710_smc_int_vectors;
347 int_vect_start_address = RV710_SMC_INT_VECTOR_START;
348 int_vect_size = RV710_SMC_INT_VECTOR_SIZE;
349 break;
350 case CHIP_RV740:
351 ucode_start_address = RV740_SMC_UCODE_START;
352 ucode_size = RV740_SMC_UCODE_SIZE;
353 int_vect = (const u8 *)&rv740_smc_int_vectors;
354 int_vect_start_address = RV740_SMC_INT_VECTOR_START;
355 int_vect_size = RV740_SMC_INT_VECTOR_SIZE;
356 break;
357 default:
358 DRM_ERROR("unknown asic in smc ucode loader\n");
359 BUG();
360 }
361
362 /* load the ucode */
363 ucode_data = (const u8 *)rdev->smc_fw->data;
364 ret = rv770_copy_bytes_to_smc(rdev, ucode_start_address,
365 ucode_data, ucode_size, limit);
366 if (ret)
367 return ret;
368
369 /* set up the int vectors */
370 ret = rv770_program_interrupt_vectors(rdev, int_vect_start_address,
371 int_vect, int_vect_size);
372 if (ret)
373 return ret;
374
375 return 0;
376}
377
378int rv770_read_smc_sram_dword(struct radeon_device *rdev,
379 u16 smc_address, u32 *value, u16 limit)
380{
381 int ret;
382
383 ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
384 if (ret)
385 return ret;
386
387 *value = RREG32(SMC_SRAM_DATA);
388
389 return 0;
390}
391
392int rv770_write_smc_sram_dword(struct radeon_device *rdev,
393 u16 smc_address, u32 value, u16 limit)
394{
395 int ret;
396
397 ret = rv770_set_smc_sram_address(rdev, smc_address, limit);
398 if (ret)
399 return ret;
400
401 WREG32(SMC_SRAM_DATA, value);
402
403 return 0;
404}
diff --git a/drivers/gpu/drm/radeon/rv770_smc.h b/drivers/gpu/drm/radeon/rv770_smc.h
new file mode 100644
index 000000000000..bdb652c90815
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv770_smc.h
@@ -0,0 +1,208 @@
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef __RV770_SMC_H__
24#define __RV770_SMC_H__
25
26#include "ppsmc.h"
27
28#pragma pack(push, 1)
29
30#define RV770_SMC_TABLE_ADDRESS 0xB000
31
32#define RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE 3
33
34struct RV770_SMC_SCLK_VALUE
35{
36 uint32_t vCG_SPLL_FUNC_CNTL;
37 uint32_t vCG_SPLL_FUNC_CNTL_2;
38 uint32_t vCG_SPLL_FUNC_CNTL_3;
39 uint32_t vCG_SPLL_SPREAD_SPECTRUM;
40 uint32_t vCG_SPLL_SPREAD_SPECTRUM_2;
41 uint32_t sclk_value;
42};
43
44typedef struct RV770_SMC_SCLK_VALUE RV770_SMC_SCLK_VALUE;
45
46struct RV770_SMC_MCLK_VALUE
47{
48 uint32_t vMPLL_AD_FUNC_CNTL;
49 uint32_t vMPLL_AD_FUNC_CNTL_2;
50 uint32_t vMPLL_DQ_FUNC_CNTL;
51 uint32_t vMPLL_DQ_FUNC_CNTL_2;
52 uint32_t vMCLK_PWRMGT_CNTL;
53 uint32_t vDLL_CNTL;
54 uint32_t vMPLL_SS;
55 uint32_t vMPLL_SS2;
56 uint32_t mclk_value;
57};
58
59typedef struct RV770_SMC_MCLK_VALUE RV770_SMC_MCLK_VALUE;
60
61
62struct RV730_SMC_MCLK_VALUE
63{
64 uint32_t vMCLK_PWRMGT_CNTL;
65 uint32_t vDLL_CNTL;
66 uint32_t vMPLL_FUNC_CNTL;
67 uint32_t vMPLL_FUNC_CNTL2;
68 uint32_t vMPLL_FUNC_CNTL3;
69 uint32_t vMPLL_SS;
70 uint32_t vMPLL_SS2;
71 uint32_t mclk_value;
72};
73
74typedef struct RV730_SMC_MCLK_VALUE RV730_SMC_MCLK_VALUE;
75
76struct RV770_SMC_VOLTAGE_VALUE
77{
78 uint16_t value;
79 uint8_t index;
80 uint8_t padding;
81};
82
83typedef struct RV770_SMC_VOLTAGE_VALUE RV770_SMC_VOLTAGE_VALUE;
84
85union RV7XX_SMC_MCLK_VALUE
86{
87 RV770_SMC_MCLK_VALUE mclk770;
88 RV730_SMC_MCLK_VALUE mclk730;
89};
90
91typedef union RV7XX_SMC_MCLK_VALUE RV7XX_SMC_MCLK_VALUE, *LPRV7XX_SMC_MCLK_VALUE;
92
93struct RV770_SMC_HW_PERFORMANCE_LEVEL
94{
95 uint8_t arbValue;
96 union{
97 uint8_t seqValue;
98 uint8_t ACIndex;
99 };
100 uint8_t displayWatermark;
101 uint8_t gen2PCIE;
102 uint8_t gen2XSP;
103 uint8_t backbias;
104 uint8_t strobeMode;
105 uint8_t mcFlags;
106 uint32_t aT;
107 uint32_t bSP;
108 RV770_SMC_SCLK_VALUE sclk;
109 RV7XX_SMC_MCLK_VALUE mclk;
110 RV770_SMC_VOLTAGE_VALUE vddc;
111 RV770_SMC_VOLTAGE_VALUE mvdd;
112 RV770_SMC_VOLTAGE_VALUE vddci;
113 uint8_t reserved1;
114 uint8_t reserved2;
115 uint8_t stateFlags;
116 uint8_t padding;
117};
118
119#define SMC_STROBE_RATIO 0x0F
120#define SMC_STROBE_ENABLE 0x10
121
122#define SMC_MC_EDC_RD_FLAG 0x01
123#define SMC_MC_EDC_WR_FLAG 0x02
124#define SMC_MC_RTT_ENABLE 0x04
125#define SMC_MC_STUTTER_EN 0x08
126
127typedef struct RV770_SMC_HW_PERFORMANCE_LEVEL RV770_SMC_HW_PERFORMANCE_LEVEL;
128
129struct RV770_SMC_SWSTATE
130{
131 uint8_t flags;
132 uint8_t padding1;
133 uint8_t padding2;
134 uint8_t padding3;
135 RV770_SMC_HW_PERFORMANCE_LEVEL levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
136};
137
138typedef struct RV770_SMC_SWSTATE RV770_SMC_SWSTATE;
139
140#define RV770_SMC_VOLTAGEMASK_VDDC 0
141#define RV770_SMC_VOLTAGEMASK_MVDD 1
142#define RV770_SMC_VOLTAGEMASK_VDDCI 2
143#define RV770_SMC_VOLTAGEMASK_MAX 4
144
145struct RV770_SMC_VOLTAGEMASKTABLE
146{
147 uint8_t highMask[RV770_SMC_VOLTAGEMASK_MAX];
148 uint32_t lowMask[RV770_SMC_VOLTAGEMASK_MAX];
149};
150
151typedef struct RV770_SMC_VOLTAGEMASKTABLE RV770_SMC_VOLTAGEMASKTABLE;
152
153#define MAX_NO_VREG_STEPS 32
154
155struct RV770_SMC_STATETABLE
156{
157 uint8_t thermalProtectType;
158 uint8_t systemFlags;
159 uint8_t maxVDDCIndexInPPTable;
160 uint8_t extraFlags;
161 uint8_t highSMIO[MAX_NO_VREG_STEPS];
162 uint32_t lowSMIO[MAX_NO_VREG_STEPS];
163 RV770_SMC_VOLTAGEMASKTABLE voltageMaskTable;
164 RV770_SMC_SWSTATE initialState;
165 RV770_SMC_SWSTATE ACPIState;
166 RV770_SMC_SWSTATE driverState;
167 RV770_SMC_SWSTATE ULVState;
168};
169
170typedef struct RV770_SMC_STATETABLE RV770_SMC_STATETABLE;
171
172#define PPSMC_STATEFLAG_AUTO_PULSE_SKIP 0x01
173
174#pragma pack(pop)
175
176#define RV770_SMC_SOFT_REGISTERS_START 0x104
177
178#define RV770_SMC_SOFT_REGISTER_mclk_chg_timeout 0x0
179#define RV770_SMC_SOFT_REGISTER_baby_step_timer 0x8
180#define RV770_SMC_SOFT_REGISTER_delay_bbias 0xC
181#define RV770_SMC_SOFT_REGISTER_delay_vreg 0x10
182#define RV770_SMC_SOFT_REGISTER_delay_acpi 0x2C
183#define RV770_SMC_SOFT_REGISTER_seq_index 0x64
184#define RV770_SMC_SOFT_REGISTER_mvdd_chg_time 0x68
185#define RV770_SMC_SOFT_REGISTER_mclk_switch_lim 0x78
186#define RV770_SMC_SOFT_REGISTER_mc_block_delay 0x90
187#define RV770_SMC_SOFT_REGISTER_is_asic_lombok 0xA0
188
189int rv770_set_smc_sram_address(struct radeon_device *rdev,
190 u16 smc_address, u16 limit);
191int rv770_copy_bytes_to_smc(struct radeon_device *rdev,
192 u16 smc_start_address, const u8 *src,
193 u16 byte_count, u16 limit);
194void rv770_start_smc(struct radeon_device *rdev);
195void rv770_reset_smc(struct radeon_device *rdev);
196void rv770_stop_smc_clock(struct radeon_device *rdev);
197void rv770_start_smc_clock(struct radeon_device *rdev);
198bool rv770_is_smc_running(struct radeon_device *rdev);
199PPSMC_Result rv770_send_msg_to_smc(struct radeon_device *rdev, PPSMC_Msg msg);
200PPSMC_Result rv770_wait_for_smc_inactive(struct radeon_device *rdev);
201int rv770_read_smc_sram_dword(struct radeon_device *rdev,
202 u16 smc_address, u32 *value, u16 limit);
203int rv770_write_smc_sram_dword(struct radeon_device *rdev,
204 u16 smc_address, u32 value, u16 limit);
205int rv770_load_smc_ucode(struct radeon_device *rdev,
206 u16 limit);
207
208#endif
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h
index 85b16266f748..784eeaf315c3 100644
--- a/drivers/gpu/drm/radeon/rv770d.h
+++ b/drivers/gpu/drm/radeon/rv770d.h
@@ -62,6 +62,242 @@
62# define UPLL_FB_DIV(x) ((x) << 0) 62# define UPLL_FB_DIV(x) ((x) << 0)
63# define UPLL_FB_DIV_MASK 0x01FFFFFF 63# define UPLL_FB_DIV_MASK 0x01FFFFFF
64 64
65/* pm registers */
66#define SMC_SRAM_ADDR 0x200
67#define SMC_SRAM_AUTO_INC_DIS (1 << 16)
68#define SMC_SRAM_DATA 0x204
69#define SMC_IO 0x208
70#define SMC_RST_N (1 << 0)
71#define SMC_STOP_MODE (1 << 2)
72#define SMC_CLK_EN (1 << 11)
73#define SMC_MSG 0x20c
74#define HOST_SMC_MSG(x) ((x) << 0)
75#define HOST_SMC_MSG_MASK (0xff << 0)
76#define HOST_SMC_MSG_SHIFT 0
77#define HOST_SMC_RESP(x) ((x) << 8)
78#define HOST_SMC_RESP_MASK (0xff << 8)
79#define HOST_SMC_RESP_SHIFT 8
80#define SMC_HOST_MSG(x) ((x) << 16)
81#define SMC_HOST_MSG_MASK (0xff << 16)
82#define SMC_HOST_MSG_SHIFT 16
83#define SMC_HOST_RESP(x) ((x) << 24)
84#define SMC_HOST_RESP_MASK (0xff << 24)
85#define SMC_HOST_RESP_SHIFT 24
86
87#define SMC_ISR_FFD8_FFDB 0x218
88
89#define CG_SPLL_FUNC_CNTL 0x600
90#define SPLL_RESET (1 << 0)
91#define SPLL_SLEEP (1 << 1)
92#define SPLL_DIVEN (1 << 2)
93#define SPLL_BYPASS_EN (1 << 3)
94#define SPLL_REF_DIV(x) ((x) << 4)
95#define SPLL_REF_DIV_MASK (0x3f << 4)
96#define SPLL_HILEN(x) ((x) << 12)
97#define SPLL_HILEN_MASK (0xf << 12)
98#define SPLL_LOLEN(x) ((x) << 16)
99#define SPLL_LOLEN_MASK (0xf << 16)
100#define CG_SPLL_FUNC_CNTL_2 0x604
101#define SCLK_MUX_SEL(x) ((x) << 0)
102#define SCLK_MUX_SEL_MASK (0x1ff << 0)
103#define CG_SPLL_FUNC_CNTL_3 0x608
104#define SPLL_FB_DIV(x) ((x) << 0)
105#define SPLL_FB_DIV_MASK (0x3ffffff << 0)
106#define SPLL_DITHEN (1 << 28)
107
108#define SPLL_CNTL_MODE 0x610
109#define SPLL_DIV_SYNC (1 << 5)
110
111#define MPLL_AD_FUNC_CNTL 0x624
112#define CLKF(x) ((x) << 0)
113#define CLKF_MASK (0x7f << 0)
114#define CLKR(x) ((x) << 7)
115#define CLKR_MASK (0x1f << 7)
116#define CLKFRAC(x) ((x) << 12)
117#define CLKFRAC_MASK (0x1f << 12)
118#define YCLK_POST_DIV(x) ((x) << 17)
119#define YCLK_POST_DIV_MASK (3 << 17)
120#define IBIAS(x) ((x) << 20)
121#define IBIAS_MASK (0x3ff << 20)
122#define RESET (1 << 30)
123#define PDNB (1 << 31)
124#define MPLL_AD_FUNC_CNTL_2 0x628
125#define BYPASS (1 << 19)
126#define BIAS_GEN_PDNB (1 << 24)
127#define RESET_EN (1 << 25)
128#define VCO_MODE (1 << 29)
129#define MPLL_DQ_FUNC_CNTL 0x62c
130#define MPLL_DQ_FUNC_CNTL_2 0x630
131
132#define GENERAL_PWRMGT 0x63c
133# define GLOBAL_PWRMGT_EN (1 << 0)
134# define STATIC_PM_EN (1 << 1)
135# define THERMAL_PROTECTION_DIS (1 << 2)
136# define THERMAL_PROTECTION_TYPE (1 << 3)
137# define ENABLE_GEN2PCIE (1 << 4)
138# define ENABLE_GEN2XSP (1 << 5)
139# define SW_SMIO_INDEX(x) ((x) << 6)
140# define SW_SMIO_INDEX_MASK (3 << 6)
141# define SW_SMIO_INDEX_SHIFT 6
142# define LOW_VOLT_D2_ACPI (1 << 8)
143# define LOW_VOLT_D3_ACPI (1 << 9)
144# define VOLT_PWRMGT_EN (1 << 10)
145# define BACKBIAS_PAD_EN (1 << 18)
146# define BACKBIAS_VALUE (1 << 19)
147# define DYN_SPREAD_SPECTRUM_EN (1 << 23)
148# define AC_DC_SW (1 << 24)
149
150#define CG_TPC 0x640
151#define SCLK_PWRMGT_CNTL 0x644
152# define SCLK_PWRMGT_OFF (1 << 0)
153# define SCLK_LOW_D1 (1 << 1)
154# define FIR_RESET (1 << 4)
155# define FIR_FORCE_TREND_SEL (1 << 5)
156# define FIR_TREND_MODE (1 << 6)
157# define DYN_GFX_CLK_OFF_EN (1 << 7)
158# define GFX_CLK_FORCE_ON (1 << 8)
159# define GFX_CLK_REQUEST_OFF (1 << 9)
160# define GFX_CLK_FORCE_OFF (1 << 10)
161# define GFX_CLK_OFF_ACPI_D1 (1 << 11)
162# define GFX_CLK_OFF_ACPI_D2 (1 << 12)
163# define GFX_CLK_OFF_ACPI_D3 (1 << 13)
164#define MCLK_PWRMGT_CNTL 0x648
165# define DLL_SPEED(x) ((x) << 0)
166# define DLL_SPEED_MASK (0x1f << 0)
167# define MPLL_PWRMGT_OFF (1 << 5)
168# define DLL_READY (1 << 6)
169# define MC_INT_CNTL (1 << 7)
170# define MRDCKA0_SLEEP (1 << 8)
171# define MRDCKA1_SLEEP (1 << 9)
172# define MRDCKB0_SLEEP (1 << 10)
173# define MRDCKB1_SLEEP (1 << 11)
174# define MRDCKC0_SLEEP (1 << 12)
175# define MRDCKC1_SLEEP (1 << 13)
176# define MRDCKD0_SLEEP (1 << 14)
177# define MRDCKD1_SLEEP (1 << 15)
178# define MRDCKA0_RESET (1 << 16)
179# define MRDCKA1_RESET (1 << 17)
180# define MRDCKB0_RESET (1 << 18)
181# define MRDCKB1_RESET (1 << 19)
182# define MRDCKC0_RESET (1 << 20)
183# define MRDCKC1_RESET (1 << 21)
184# define MRDCKD0_RESET (1 << 22)
185# define MRDCKD1_RESET (1 << 23)
186# define DLL_READY_READ (1 << 24)
187# define USE_DISPLAY_GAP (1 << 25)
188# define USE_DISPLAY_URGENT_NORMAL (1 << 26)
189# define MPLL_TURNOFF_D2 (1 << 28)
190#define DLL_CNTL 0x64c
191# define MRDCKA0_BYPASS (1 << 24)
192# define MRDCKA1_BYPASS (1 << 25)
193# define MRDCKB0_BYPASS (1 << 26)
194# define MRDCKB1_BYPASS (1 << 27)
195# define MRDCKC0_BYPASS (1 << 28)
196# define MRDCKC1_BYPASS (1 << 29)
197# define MRDCKD0_BYPASS (1 << 30)
198# define MRDCKD1_BYPASS (1 << 31)
199
200#define MPLL_TIME 0x654
201# define MPLL_LOCK_TIME(x) ((x) << 0)
202# define MPLL_LOCK_TIME_MASK (0xffff << 0)
203# define MPLL_RESET_TIME(x) ((x) << 16)
204# define MPLL_RESET_TIME_MASK (0xffff << 16)
205
206#define CG_CLKPIN_CNTL 0x660
207# define MUX_TCLK_TO_XCLK (1 << 8)
208# define XTALIN_DIVIDE (1 << 9)
209
210#define S0_VID_LOWER_SMIO_CNTL 0x678
211#define S1_VID_LOWER_SMIO_CNTL 0x67c
212#define S2_VID_LOWER_SMIO_CNTL 0x680
213#define S3_VID_LOWER_SMIO_CNTL 0x684
214
215#define CG_FTV 0x690
216#define CG_FFCT_0 0x694
217# define UTC_0(x) ((x) << 0)
218# define UTC_0_MASK (0x3ff << 0)
219# define DTC_0(x) ((x) << 10)
220# define DTC_0_MASK (0x3ff << 10)
221
222#define CG_BSP 0x6d0
223# define BSP(x) ((x) << 0)
224# define BSP_MASK (0xffff << 0)
225# define BSU(x) ((x) << 16)
226# define BSU_MASK (0xf << 16)
227#define CG_AT 0x6d4
228# define CG_R(x) ((x) << 0)
229# define CG_R_MASK (0xffff << 0)
230# define CG_L(x) ((x) << 16)
231# define CG_L_MASK (0xffff << 16)
232#define CG_GIT 0x6d8
233# define CG_GICST(x) ((x) << 0)
234# define CG_GICST_MASK (0xffff << 0)
235# define CG_GIPOT(x) ((x) << 16)
236# define CG_GIPOT_MASK (0xffff << 16)
237
238#define CG_SSP 0x6e8
239# define SST(x) ((x) << 0)
240# define SST_MASK (0xffff << 0)
241# define SSTU(x) ((x) << 16)
242# define SSTU_MASK (0xf << 16)
243
244#define CG_DISPLAY_GAP_CNTL 0x714
245# define DISP1_GAP(x) ((x) << 0)
246# define DISP1_GAP_MASK (3 << 0)
247# define DISP2_GAP(x) ((x) << 2)
248# define DISP2_GAP_MASK (3 << 2)
249# define VBI_TIMER_COUNT(x) ((x) << 4)
250# define VBI_TIMER_COUNT_MASK (0x3fff << 4)
251# define VBI_TIMER_UNIT(x) ((x) << 20)
252# define VBI_TIMER_UNIT_MASK (7 << 20)
253# define DISP1_GAP_MCHG(x) ((x) << 24)
254# define DISP1_GAP_MCHG_MASK (3 << 24)
255# define DISP2_GAP_MCHG(x) ((x) << 26)
256# define DISP2_GAP_MCHG_MASK (3 << 26)
257
258#define CG_SPLL_SPREAD_SPECTRUM 0x790
259#define SSEN (1 << 0)
260#define CLKS(x) ((x) << 4)
261#define CLKS_MASK (0xfff << 4)
262#define CG_SPLL_SPREAD_SPECTRUM_2 0x794
263#define CLKV(x) ((x) << 0)
264#define CLKV_MASK (0x3ffffff << 0)
265#define CG_MPLL_SPREAD_SPECTRUM 0x798
266#define CG_UPLL_SPREAD_SPECTRUM 0x79c
267# define SSEN_MASK 0x00000001
268
269#define CG_CGTT_LOCAL_0 0x7d0
270#define CG_CGTT_LOCAL_1 0x7d4
271
272#define BIOS_SCRATCH_4 0x1734
273
274#define MC_SEQ_MISC0 0x2a00
275#define MC_SEQ_MISC0_GDDR5_SHIFT 28
276#define MC_SEQ_MISC0_GDDR5_MASK 0xf0000000
277#define MC_SEQ_MISC0_GDDR5_VALUE 5
278
279#define MC_ARB_SQM_RATIO 0x2770
280#define STATE0(x) ((x) << 0)
281#define STATE0_MASK (0xff << 0)
282#define STATE1(x) ((x) << 8)
283#define STATE1_MASK (0xff << 8)
284#define STATE2(x) ((x) << 16)
285#define STATE2_MASK (0xff << 16)
286#define STATE3(x) ((x) << 24)
287#define STATE3_MASK (0xff << 24)
288
289#define MC_ARB_RFSH_RATE 0x27b0
290#define POWERMODE0(x) ((x) << 0)
291#define POWERMODE0_MASK (0xff << 0)
292#define POWERMODE1(x) ((x) << 8)
293#define POWERMODE1_MASK (0xff << 8)
294#define POWERMODE2(x) ((x) << 16)
295#define POWERMODE2_MASK (0xff << 16)
296#define POWERMODE3(x) ((x) << 24)
297#define POWERMODE3_MASK (0xff << 24)
298
299#define CGTS_SM_CTRL_REG 0x9150
300
65/* Registers */ 301/* Registers */
66#define CB_COLOR0_BASE 0x28040 302#define CB_COLOR0_BASE 0x28040
67#define CB_COLOR1_BASE 0x28044 303#define CB_COLOR1_BASE 0x28044
@@ -86,8 +322,8 @@
86#define CONFIG_MEMSIZE 0x5428 322#define CONFIG_MEMSIZE 0x5428
87 323
88#define CP_ME_CNTL 0x86D8 324#define CP_ME_CNTL 0x86D8
89#define CP_ME_HALT (1<<28) 325#define CP_ME_HALT (1 << 28)
90#define CP_PFP_HALT (1<<26) 326#define CP_PFP_HALT (1 << 26)
91#define CP_ME_RAM_DATA 0xC160 327#define CP_ME_RAM_DATA 0xC160
92#define CP_ME_RAM_RADDR 0xC158 328#define CP_ME_RAM_RADDR 0xC158
93#define CP_ME_RAM_WADDR 0xC15C 329#define CP_ME_RAM_WADDR 0xC15C
@@ -157,9 +393,22 @@
157#define GUI_ACTIVE (1<<31) 393#define GUI_ACTIVE (1<<31)
158#define GRBM_STATUS2 0x8014 394#define GRBM_STATUS2 0x8014
159 395
160#define CG_CLKPIN_CNTL 0x660 396#define CG_THERMAL_CTRL 0x72C
161# define MUX_TCLK_TO_XCLK (1 << 8) 397#define DPM_EVENT_SRC(x) ((x) << 0)
162# define XTALIN_DIVIDE (1 << 9) 398#define DPM_EVENT_SRC_MASK (7 << 0)
399#define DIG_THERM_DPM(x) ((x) << 14)
400#define DIG_THERM_DPM_MASK 0x003FC000
401#define DIG_THERM_DPM_SHIFT 14
402
403#define CG_THERMAL_INT 0x734
404#define DIG_THERM_INTH(x) ((x) << 8)
405#define DIG_THERM_INTH_MASK 0x0000FF00
406#define DIG_THERM_INTH_SHIFT 8
407#define DIG_THERM_INTL(x) ((x) << 16)
408#define DIG_THERM_INTL_MASK 0x00FF0000
409#define DIG_THERM_INTL_SHIFT 16
410#define THERM_INT_MASK_HIGH (1 << 24)
411#define THERM_INT_MASK_LOW (1 << 25)
163 412
164#define CG_MULT_THERMAL_STATUS 0x740 413#define CG_MULT_THERMAL_STATUS 0x740
165#define ASIC_T(x) ((x) << 16) 414#define ASIC_T(x) ((x) << 16)
@@ -662,7 +911,22 @@
662#define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c 911#define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c
663#define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c 912#define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c
664 913
665/* PCIE link stuff */ 914/* PCIE indirect regs */
915#define PCIE_P_CNTL 0x40
916# define P_PLL_PWRDN_IN_L1L23 (1 << 3)
917# define P_PLL_BUF_PDNB (1 << 4)
918# define P_PLL_PDNB (1 << 9)
919# define P_ALLOW_PRX_FRONTEND_SHUTOFF (1 << 12)
920/* PCIE PORT regs */
921#define PCIE_LC_CNTL 0xa0
922# define LC_L0S_INACTIVITY(x) ((x) << 8)
923# define LC_L0S_INACTIVITY_MASK (0xf << 8)
924# define LC_L0S_INACTIVITY_SHIFT 8
925# define LC_L1_INACTIVITY(x) ((x) << 12)
926# define LC_L1_INACTIVITY_MASK (0xf << 12)
927# define LC_L1_INACTIVITY_SHIFT 12
928# define LC_PMI_TO_L1_DIS (1 << 16)
929# define LC_ASPM_TO_L1_DIS (1 << 24)
666#define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ 930#define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */
667#define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ 931#define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */
668# define LC_LINK_WIDTH_SHIFT 0 932# define LC_LINK_WIDTH_SHIFT 0
@@ -690,6 +954,9 @@
690# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) 954# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8)
691# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 955# define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3
692# define LC_CURRENT_DATA_RATE (1 << 11) 956# define LC_CURRENT_DATA_RATE (1 << 11)
957# define LC_HW_VOLTAGE_IF_CONTROL(x) ((x) << 12)
958# define LC_HW_VOLTAGE_IF_CONTROL_MASK (3 << 12)
959# define LC_HW_VOLTAGE_IF_CONTROL_SHIFT 12
693# define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) 960# define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14)
694# define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) 961# define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21)
695# define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) 962# define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23)