aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2011-04-12 14:49:24 -0400
committerDave Airlie <airlied@redhat.com>2011-04-12 19:09:44 -0400
commit2feea49ae34a2fcea1035136b85f5eaca56f5cd0 (patch)
treef07e9ef8c9493c177864fa24493d4efcd45a80df /drivers/gpu
parent8a83ec5ee824a6bd431b49bdb2428c8bf88f03eb (diff)
drm/radeon/kms: properly program vddci on evergreen+
Change vddci as well as vddc when changing power modes on evergreen/ni. Also, properly set vddci on boot up for ni cards. The vbios only sets the limited clocks and voltages on boot until the mc ucode is loaded. This should fix stability problems on some btc cards. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c11
-rw-r--r--drivers/gpu/drm/radeon/radeon.h10
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c20
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c4
4 files changed, 33 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index f2448170086e..3453910ee0f3 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -120,11 +120,16 @@ void evergreen_pm_misc(struct radeon_device *rdev)
120 struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; 120 struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
121 struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; 121 struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
122 122
123 if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { 123 if (voltage->type == VOLTAGE_SW) {
124 if (voltage->voltage != rdev->pm.current_vddc) { 124 if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
125 radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); 125 radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
126 rdev->pm.current_vddc = voltage->voltage; 126 rdev->pm.current_vddc = voltage->voltage;
127 DRM_DEBUG("Setting: v: %d\n", voltage->voltage); 127 DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
128 }
129 if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
130 radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
131 rdev->pm.current_vddci = voltage->vddci;
132 DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci);
128 } 133 }
129 } 134 }
130} 135}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 99557407cdce..ba643b576054 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -767,7 +767,9 @@ struct radeon_voltage {
767 u8 vddci_id; /* index into vddci voltage table */ 767 u8 vddci_id; /* index into vddci voltage table */
768 bool vddci_enabled; 768 bool vddci_enabled;
769 /* r6xx+ sw */ 769 /* r6xx+ sw */
770 u32 voltage; 770 u16 voltage;
771 /* evergreen+ vddci */
772 u16 vddci;
771}; 773};
772 774
773/* clock mode flags */ 775/* clock mode flags */
@@ -835,10 +837,12 @@ struct radeon_pm {
835 int default_power_state_index; 837 int default_power_state_index;
836 u32 current_sclk; 838 u32 current_sclk;
837 u32 current_mclk; 839 u32 current_mclk;
838 u32 current_vddc; 840 u16 current_vddc;
841 u16 current_vddci;
839 u32 default_sclk; 842 u32 default_sclk;
840 u32 default_mclk; 843 u32 default_mclk;
841 u32 default_vddc; 844 u16 default_vddc;
845 u16 default_vddci;
842 struct radeon_i2c_chan *i2c_bus; 846 struct radeon_i2c_chan *i2c_bus;
843 /* selected pm method */ 847 /* selected pm method */
844 enum radeon_pm_method pm_method; 848 enum radeon_pm_method pm_method;
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 330a5b56602b..f5d12fb103fa 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -2176,24 +2176,27 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
2176 } 2176 }
2177} 2177}
2178 2178
2179static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) 2179static void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
2180 u16 *vddc, u16 *vddci)
2180{ 2181{
2181 struct radeon_mode_info *mode_info = &rdev->mode_info; 2182 struct radeon_mode_info *mode_info = &rdev->mode_info;
2182 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); 2183 int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
2183 u8 frev, crev; 2184 u8 frev, crev;
2184 u16 data_offset; 2185 u16 data_offset;
2185 union firmware_info *firmware_info; 2186 union firmware_info *firmware_info;
2186 u16 vddc = 0; 2187
2188 *vddc = 0;
2189 *vddci = 0;
2187 2190
2188 if (atom_parse_data_header(mode_info->atom_context, index, NULL, 2191 if (atom_parse_data_header(mode_info->atom_context, index, NULL,
2189 &frev, &crev, &data_offset)) { 2192 &frev, &crev, &data_offset)) {
2190 firmware_info = 2193 firmware_info =
2191 (union firmware_info *)(mode_info->atom_context->bios + 2194 (union firmware_info *)(mode_info->atom_context->bios +
2192 data_offset); 2195 data_offset);
2193 vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); 2196 *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
2197 if ((frev == 2) && (crev >= 2))
2198 *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
2194 } 2199 }
2195
2196 return vddc;
2197} 2200}
2198 2201
2199static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, 2202static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,
@@ -2203,7 +2206,9 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
2203 int j; 2206 int j;
2204 u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); 2207 u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
2205 u32 misc2 = le16_to_cpu(non_clock_info->usClassification); 2208 u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
2206 u16 vddc = radeon_atombios_get_default_vddc(rdev); 2209 u16 vddc, vddci;
2210
2211 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci);
2207 2212
2208 rdev->pm.power_state[state_index].misc = misc; 2213 rdev->pm.power_state[state_index].misc = misc;
2209 rdev->pm.power_state[state_index].misc2 = misc2; 2214 rdev->pm.power_state[state_index].misc2 = misc2;
@@ -2244,6 +2249,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
2244 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; 2249 rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
2245 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; 2250 rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
2246 rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; 2251 rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
2252 rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
2247 } else { 2253 } else {
2248 /* patch the table values with the default slck/mclk from firmware info */ 2254 /* patch the table values with the default slck/mclk from firmware info */
2249 for (j = 0; j < mode_index; j++) { 2255 for (j = 0; j < mode_index; j++) {
@@ -2286,6 +2292,8 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
2286 VOLTAGE_SW; 2292 VOLTAGE_SW;
2287 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = 2293 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
2288 le16_to_cpu(clock_info->evergreen.usVDDC); 2294 le16_to_cpu(clock_info->evergreen.usVDDC);
2295 rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
2296 le16_to_cpu(clock_info->evergreen.usVDDCI);
2289 } else { 2297 } else {
2290 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); 2298 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
2291 sclk |= clock_info->r600.ucEngineClockHigh << 16; 2299 sclk |= clock_info->r600.ucEngineClockHigh << 16;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 4010571def3a..86eda1ea94df 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -538,6 +538,9 @@ void radeon_pm_resume(struct radeon_device *rdev)
538 if (rdev->pm.default_vddc) 538 if (rdev->pm.default_vddc)
539 radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, 539 radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
540 SET_VOLTAGE_TYPE_ASIC_VDDC); 540 SET_VOLTAGE_TYPE_ASIC_VDDC);
541 if (rdev->pm.default_vddci)
542 radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
543 SET_VOLTAGE_TYPE_ASIC_VDDCI);
541 if (rdev->pm.default_sclk) 544 if (rdev->pm.default_sclk)
542 radeon_set_engine_clock(rdev, rdev->pm.default_sclk); 545 radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
543 if (rdev->pm.default_mclk) 546 if (rdev->pm.default_mclk)
@@ -550,6 +553,7 @@ void radeon_pm_resume(struct radeon_device *rdev)
550 rdev->pm.current_sclk = rdev->pm.default_sclk; 553 rdev->pm.current_sclk = rdev->pm.default_sclk;
551 rdev->pm.current_mclk = rdev->pm.default_mclk; 554 rdev->pm.current_mclk = rdev->pm.default_mclk;
552 rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; 555 rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
556 rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci;
553 if (rdev->pm.pm_method == PM_METHOD_DYNPM 557 if (rdev->pm.pm_method == PM_METHOD_DYNPM
554 && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { 558 && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
555 rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; 559 rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;