diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/btc_dpm.c | 340 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/btc_dpm.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cypress_dpm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 43 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770_dpm.c | 10 |
6 files changed, 400 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 6af91b7bcbb6..d88830778f58 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
@@ -1152,6 +1152,164 @@ static const u32 turks_sysls_enable[] = | |||
1152 | 1152 | ||
1153 | #endif | 1153 | #endif |
1154 | 1154 | ||
1155 | u32 btc_valid_sclk[] = | ||
1156 | { | ||
1157 | 5000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, | ||
1158 | 55000, 60000, 65000, 70000, 75000, 80000, 85000, 90000, 95000, 100000, | ||
1159 | 105000, 110000, 11500, 120000, 125000, 130000, 135000, 140000, 145000, 150000, | ||
1160 | 155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000 | ||
1161 | }; | ||
1162 | |||
1163 | static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = | ||
1164 | { | ||
1165 | { 10000, 30000, RADEON_SCLK_UP }, | ||
1166 | { 15000, 30000, RADEON_SCLK_UP }, | ||
1167 | { 20000, 30000, RADEON_SCLK_UP }, | ||
1168 | { 25000, 30000, RADEON_SCLK_UP } | ||
1169 | }; | ||
1170 | |||
1171 | static void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table, | ||
1172 | u32 clock, u16 max_voltage, u16 *voltage) | ||
1173 | { | ||
1174 | u32 i; | ||
1175 | |||
1176 | if ((table == NULL) || (table->count == 0)) | ||
1177 | return; | ||
1178 | |||
1179 | for (i= 0; i < table->count; i++) { | ||
1180 | if (clock <= table->entries[i].clk) { | ||
1181 | if (*voltage < table->entries[i].v) | ||
1182 | *voltage = (u16)((table->entries[i].v < max_voltage) ? | ||
1183 | table->entries[i].v : max_voltage); | ||
1184 | return; | ||
1185 | } | ||
1186 | } | ||
1187 | |||
1188 | *voltage = (*voltage > max_voltage) ? *voltage : max_voltage; | ||
1189 | } | ||
1190 | |||
1191 | static u32 btc_find_valid_clock(struct radeon_clock_array *clocks, | ||
1192 | u32 max_clock, u32 requested_clock) | ||
1193 | { | ||
1194 | unsigned int i; | ||
1195 | |||
1196 | if ((clocks == NULL) || (clocks->count == 0)) | ||
1197 | return (requested_clock < max_clock) ? requested_clock : max_clock; | ||
1198 | |||
1199 | for (i = 0; i < clocks->count; i++) { | ||
1200 | if (clocks->values[i] >= requested_clock) | ||
1201 | return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock; | ||
1202 | } | ||
1203 | |||
1204 | return (clocks->values[clocks->count - 1] < max_clock) ? | ||
1205 | clocks->values[clocks->count - 1] : max_clock; | ||
1206 | } | ||
1207 | |||
1208 | static u32 btc_get_valid_mclk(struct radeon_device *rdev, | ||
1209 | u32 max_mclk, u32 requested_mclk) | ||
1210 | { | ||
1211 | return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values, | ||
1212 | max_mclk, requested_mclk); | ||
1213 | } | ||
1214 | |||
1215 | static u32 btc_get_valid_sclk(struct radeon_device *rdev, | ||
1216 | u32 max_sclk, u32 requested_sclk) | ||
1217 | { | ||
1218 | return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values, | ||
1219 | max_sclk, requested_sclk); | ||
1220 | } | ||
1221 | |||
1222 | static void btc_skip_blacklist_clocks(struct radeon_device *rdev, | ||
1223 | const u32 max_sclk, const u32 max_mclk, | ||
1224 | u32 *sclk, u32 *mclk) | ||
1225 | { | ||
1226 | int i, num_blacklist_clocks; | ||
1227 | |||
1228 | if ((sclk == NULL) || (mclk == NULL)) | ||
1229 | return; | ||
1230 | |||
1231 | num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks); | ||
1232 | |||
1233 | for (i = 0; i < num_blacklist_clocks; i++) { | ||
1234 | if ((btc_blacklist_clocks[i].sclk == *sclk) && | ||
1235 | (btc_blacklist_clocks[i].mclk == *mclk)) | ||
1236 | break; | ||
1237 | } | ||
1238 | |||
1239 | if (i < num_blacklist_clocks) { | ||
1240 | if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) { | ||
1241 | *sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1); | ||
1242 | |||
1243 | if (*sclk < max_sclk) | ||
1244 | btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk); | ||
1245 | } | ||
1246 | } | ||
1247 | } | ||
1248 | |||
1249 | static void btc_adjust_clock_combinations(struct radeon_device *rdev, | ||
1250 | const struct radeon_clock_and_voltage_limits *max_limits, | ||
1251 | struct rv7xx_pl *pl) | ||
1252 | { | ||
1253 | |||
1254 | if ((pl->mclk == 0) || (pl->sclk == 0)) | ||
1255 | return; | ||
1256 | |||
1257 | if (pl->mclk == pl->sclk) | ||
1258 | return; | ||
1259 | |||
1260 | if (pl->mclk > pl->sclk) { | ||
1261 | if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio) | ||
1262 | pl->sclk = btc_get_valid_sclk(rdev, | ||
1263 | max_limits->sclk, | ||
1264 | (pl->mclk + | ||
1265 | (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) / | ||
1266 | rdev->pm.dpm.dyn_state.mclk_sclk_ratio); | ||
1267 | } else { | ||
1268 | if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta) | ||
1269 | pl->mclk = btc_get_valid_mclk(rdev, | ||
1270 | max_limits->mclk, | ||
1271 | pl->sclk - | ||
1272 | rdev->pm.dpm.dyn_state.sclk_mclk_delta); | ||
1273 | } | ||
1274 | } | ||
1275 | |||
1276 | static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage) | ||
1277 | { | ||
1278 | unsigned int i; | ||
1279 | |||
1280 | for (i = 0; i < table->count; i++) { | ||
1281 | if (voltage <= table->entries[i].value) | ||
1282 | return table->entries[i].value; | ||
1283 | } | ||
1284 | |||
1285 | return table->entries[table->count - 1].value; | ||
1286 | } | ||
1287 | |||
1288 | static void btc_apply_voltage_delta_rules(struct radeon_device *rdev, | ||
1289 | u16 max_vddc, u16 max_vddci, | ||
1290 | u16 *vddc, u16 *vddci) | ||
1291 | { | ||
1292 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1293 | u16 new_voltage; | ||
1294 | |||
1295 | if ((0 == *vddc) || (0 == *vddci)) | ||
1296 | return; | ||
1297 | |||
1298 | if (*vddc > *vddci) { | ||
1299 | if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) { | ||
1300 | new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table, | ||
1301 | (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta)); | ||
1302 | *vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci; | ||
1303 | } | ||
1304 | } else { | ||
1305 | if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) { | ||
1306 | new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table, | ||
1307 | (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta)); | ||
1308 | *vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc; | ||
1309 | } | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1155 | static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, | 1313 | static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, |
1156 | bool enable) | 1314 | bool enable) |
1157 | { | 1315 | { |
@@ -1901,6 +2059,169 @@ static void btc_init_stutter_mode(struct radeon_device *rdev) | |||
1901 | } | 2059 | } |
1902 | } | 2060 | } |
1903 | 2061 | ||
2062 | static void btc_apply_state_adjust_rules(struct radeon_device *rdev) | ||
2063 | { | ||
2064 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2065 | struct radeon_ps *rps = rdev->pm.dpm.requested_ps; | ||
2066 | struct rv7xx_ps *ps = rv770_get_ps(rps); | ||
2067 | struct radeon_clock_and_voltage_limits *max_limits; | ||
2068 | bool disable_mclk_switching; | ||
2069 | u32 mclk, sclk; | ||
2070 | u16 vddc, vddci; | ||
2071 | |||
2072 | /* point to the hw copy since this function will modify the ps */ | ||
2073 | eg_pi->hw_ps = *ps; | ||
2074 | rdev->pm.dpm.hw_ps.ps_priv = &eg_pi->hw_ps; | ||
2075 | ps = &eg_pi->hw_ps; | ||
2076 | |||
2077 | if (rdev->pm.dpm.new_active_crtc_count > 1) | ||
2078 | disable_mclk_switching = true; | ||
2079 | else | ||
2080 | disable_mclk_switching = false; | ||
2081 | |||
2082 | if (rdev->pm.dpm.ac_power) | ||
2083 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | ||
2084 | else | ||
2085 | max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc; | ||
2086 | |||
2087 | if (rdev->pm.dpm.ac_power == false) { | ||
2088 | if (ps->high.mclk > max_limits->mclk) | ||
2089 | ps->high.mclk = max_limits->mclk; | ||
2090 | if (ps->high.sclk > max_limits->sclk) | ||
2091 | ps->high.sclk = max_limits->sclk; | ||
2092 | if (ps->high.vddc > max_limits->vddc) | ||
2093 | ps->high.vddc = max_limits->vddc; | ||
2094 | if (ps->high.vddci > max_limits->vddci) | ||
2095 | ps->high.vddci = max_limits->vddci; | ||
2096 | |||
2097 | if (ps->medium.mclk > max_limits->mclk) | ||
2098 | ps->medium.mclk = max_limits->mclk; | ||
2099 | if (ps->medium.sclk > max_limits->sclk) | ||
2100 | ps->medium.sclk = max_limits->sclk; | ||
2101 | if (ps->medium.vddc > max_limits->vddc) | ||
2102 | ps->medium.vddc = max_limits->vddc; | ||
2103 | if (ps->medium.vddci > max_limits->vddci) | ||
2104 | ps->medium.vddci = max_limits->vddci; | ||
2105 | |||
2106 | if (ps->low.mclk > max_limits->mclk) | ||
2107 | ps->low.mclk = max_limits->mclk; | ||
2108 | if (ps->low.sclk > max_limits->sclk) | ||
2109 | ps->low.sclk = max_limits->sclk; | ||
2110 | if (ps->low.vddc > max_limits->vddc) | ||
2111 | ps->low.vddc = max_limits->vddc; | ||
2112 | if (ps->low.vddci > max_limits->vddci) | ||
2113 | ps->low.vddci = max_limits->vddci; | ||
2114 | } | ||
2115 | |||
2116 | /* XXX validate the min clocks required for display */ | ||
2117 | |||
2118 | if (disable_mclk_switching) { | ||
2119 | sclk = ps->low.sclk; | ||
2120 | mclk = ps->high.mclk; | ||
2121 | vddc = ps->low.vddc; | ||
2122 | vddci = ps->high.vddci; | ||
2123 | } else { | ||
2124 | sclk = ps->low.sclk; | ||
2125 | mclk = ps->low.mclk; | ||
2126 | vddc = ps->low.vddc; | ||
2127 | vddci = ps->low.vddci; | ||
2128 | } | ||
2129 | |||
2130 | /* adjusted low state */ | ||
2131 | ps->low.sclk = sclk; | ||
2132 | ps->low.mclk = mclk; | ||
2133 | ps->low.vddc = vddc; | ||
2134 | ps->low.vddci = vddci; | ||
2135 | |||
2136 | btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk, | ||
2137 | &ps->low.sclk, &ps->low.mclk); | ||
2138 | |||
2139 | /* adjusted medium, high states */ | ||
2140 | if (ps->medium.sclk < ps->low.sclk) | ||
2141 | ps->medium.sclk = ps->low.sclk; | ||
2142 | if (ps->medium.vddc < ps->low.vddc) | ||
2143 | ps->medium.vddc = ps->low.vddc; | ||
2144 | if (ps->high.sclk < ps->medium.sclk) | ||
2145 | ps->high.sclk = ps->medium.sclk; | ||
2146 | if (ps->high.vddc < ps->medium.vddc) | ||
2147 | ps->high.vddc = ps->medium.vddc; | ||
2148 | |||
2149 | if (disable_mclk_switching) { | ||
2150 | mclk = ps->low.mclk; | ||
2151 | if (mclk < ps->medium.mclk) | ||
2152 | mclk = ps->medium.mclk; | ||
2153 | if (mclk < ps->high.mclk) | ||
2154 | mclk = ps->high.mclk; | ||
2155 | ps->low.mclk = mclk; | ||
2156 | ps->low.vddci = vddci; | ||
2157 | ps->medium.mclk = mclk; | ||
2158 | ps->medium.vddci = vddci; | ||
2159 | ps->high.mclk = mclk; | ||
2160 | ps->high.vddci = vddci; | ||
2161 | } else { | ||
2162 | if (ps->medium.mclk < ps->low.mclk) | ||
2163 | ps->medium.mclk = ps->low.mclk; | ||
2164 | if (ps->medium.vddci < ps->low.vddci) | ||
2165 | ps->medium.vddci = ps->low.vddci; | ||
2166 | if (ps->high.mclk < ps->medium.mclk) | ||
2167 | ps->high.mclk = ps->medium.mclk; | ||
2168 | if (ps->high.vddci < ps->medium.vddci) | ||
2169 | ps->high.vddci = ps->medium.vddci; | ||
2170 | } | ||
2171 | |||
2172 | btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk, | ||
2173 | &ps->medium.sclk, &ps->medium.mclk); | ||
2174 | btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk, | ||
2175 | &ps->high.sclk, &ps->high.mclk); | ||
2176 | |||
2177 | btc_adjust_clock_combinations(rdev, max_limits, &ps->low); | ||
2178 | btc_adjust_clock_combinations(rdev, max_limits, &ps->medium); | ||
2179 | btc_adjust_clock_combinations(rdev, max_limits, &ps->high); | ||
2180 | |||
2181 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
2182 | ps->low.sclk, max_limits->vddc, &ps->low.vddc); | ||
2183 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
2184 | ps->low.mclk, max_limits->vddci, &ps->low.vddci); | ||
2185 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
2186 | ps->low.mclk, max_limits->vddc, &ps->low.vddc); | ||
2187 | /* XXX validate the voltage required for display */ | ||
2188 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
2189 | ps->medium.sclk, max_limits->vddc, &ps->medium.vddc); | ||
2190 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
2191 | ps->medium.mclk, max_limits->vddci, &ps->medium.vddci); | ||
2192 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
2193 | ps->medium.mclk, max_limits->vddc, &ps->medium.vddc); | ||
2194 | /* XXX validate the voltage required for display */ | ||
2195 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
2196 | ps->high.sclk, max_limits->vddc, &ps->high.vddc); | ||
2197 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
2198 | ps->high.mclk, max_limits->vddci, &ps->high.vddci); | ||
2199 | btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
2200 | ps->high.mclk, max_limits->vddc, &ps->high.vddc); | ||
2201 | /* XXX validate the voltage required for display */ | ||
2202 | |||
2203 | btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci, | ||
2204 | &ps->low.vddc, &ps->low.vddci); | ||
2205 | btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci, | ||
2206 | &ps->medium.vddc, &ps->medium.vddci); | ||
2207 | btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci, | ||
2208 | &ps->high.vddc, &ps->high.vddci); | ||
2209 | |||
2210 | if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) && | ||
2211 | (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) && | ||
2212 | (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)) | ||
2213 | ps->dc_compatible = true; | ||
2214 | else | ||
2215 | ps->dc_compatible = false; | ||
2216 | |||
2217 | if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2) | ||
2218 | ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2; | ||
2219 | if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2) | ||
2220 | ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2; | ||
2221 | if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2) | ||
2222 | ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2; | ||
2223 | } | ||
2224 | |||
1904 | void btc_dpm_reset_asic(struct radeon_device *rdev) | 2225 | void btc_dpm_reset_asic(struct radeon_device *rdev) |
1905 | { | 2226 | { |
1906 | rv770_restrict_performance_levels_before_switch(rdev); | 2227 | rv770_restrict_performance_levels_before_switch(rdev); |
@@ -1913,6 +2234,8 @@ int btc_dpm_set_power_state(struct radeon_device *rdev) | |||
1913 | { | 2234 | { |
1914 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 2235 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
1915 | 2236 | ||
2237 | btc_apply_state_adjust_rules(rdev); | ||
2238 | |||
1916 | btc_disable_ulv(rdev); | 2239 | btc_disable_ulv(rdev); |
1917 | btc_set_boot_state_timing(rdev); | 2240 | btc_set_boot_state_timing(rdev); |
1918 | rv770_restrict_performance_levels_before_switch(rdev); | 2241 | rv770_restrict_performance_levels_before_switch(rdev); |
@@ -2126,6 +2449,9 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
2126 | ret = rv7xx_parse_power_table(rdev); | 2449 | ret = rv7xx_parse_power_table(rdev); |
2127 | if (ret) | 2450 | if (ret) |
2128 | return ret; | 2451 | return ret; |
2452 | ret = r600_parse_extended_power_table(rdev); | ||
2453 | if (ret) | ||
2454 | return ret; | ||
2129 | 2455 | ||
2130 | if (rdev->pm.dpm.voltage_response_time == 0) | 2456 | if (rdev->pm.dpm.voltage_response_time == 0) |
2131 | rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT; | 2457 | rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT; |
@@ -2235,6 +2561,19 @@ int btc_dpm_init(struct radeon_device *rdev) | |||
2235 | 2561 | ||
2236 | pi->sram_end = SMC_RAM_END; | 2562 | pi->sram_end = SMC_RAM_END; |
2237 | 2563 | ||
2564 | rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4; | ||
2565 | rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200; | ||
2566 | rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900; | ||
2567 | rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk); | ||
2568 | rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk; | ||
2569 | rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0; | ||
2570 | rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL; | ||
2571 | |||
2572 | if (rdev->family == CHIP_TURKS) | ||
2573 | rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000; | ||
2574 | else | ||
2575 | rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000; | ||
2576 | |||
2238 | return 0; | 2577 | return 0; |
2239 | } | 2578 | } |
2240 | 2579 | ||
@@ -2247,4 +2586,5 @@ void btc_dpm_fini(struct radeon_device *rdev) | |||
2247 | } | 2586 | } |
2248 | kfree(rdev->pm.dpm.ps); | 2587 | kfree(rdev->pm.dpm.ps); |
2249 | kfree(rdev->pm.dpm.priv); | 2588 | kfree(rdev->pm.dpm.priv); |
2589 | r600_free_extended_power_table(rdev); | ||
2250 | } | 2590 | } |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.h b/drivers/gpu/drm/radeon/btc_dpm.h index 56b1957f0d29..807024df53a6 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.h +++ b/drivers/gpu/drm/radeon/btc_dpm.h | |||
@@ -33,4 +33,6 @@ | |||
33 | #define BTC_CGULVPARAMETER_DFLT 0x00040035 | 33 | #define BTC_CGULVPARAMETER_DFLT 0x00040035 |
34 | #define BTC_CGULVCONTROL_DFLT 0x00001450 | 34 | #define BTC_CGULVCONTROL_DFLT 0x00001450 |
35 | 35 | ||
36 | extern u32 btc_valid_sclk[]; | ||
37 | |||
36 | #endif | 38 | #endif |
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.h b/drivers/gpu/drm/radeon/cypress_dpm.h index 029bc9dbebde..9e24d7a268ba 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.h +++ b/drivers/gpu/drm/radeon/cypress_dpm.h | |||
@@ -88,6 +88,7 @@ struct evergreen_power_info { | |||
88 | struct at ats[2]; | 88 | struct at ats[2]; |
89 | /* smc offsets */ | 89 | /* smc offsets */ |
90 | u16 mc_reg_table_start; | 90 | u16 mc_reg_table_start; |
91 | struct rv7xx_ps hw_ps; | ||
91 | }; | 92 | }; |
92 | 93 | ||
93 | #define CYPRESS_HASI_DFLT 400000 | 94 | #define CYPRESS_HASI_DFLT 400000 |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 0c33887ca2ba..a0ab625553ea 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1217,6 +1217,19 @@ struct radeon_dpm_thermal { | |||
1217 | bool high_to_low; | 1217 | bool high_to_low; |
1218 | }; | 1218 | }; |
1219 | 1219 | ||
1220 | enum radeon_clk_action | ||
1221 | { | ||
1222 | RADEON_SCLK_UP = 1, | ||
1223 | RADEON_SCLK_DOWN | ||
1224 | }; | ||
1225 | |||
1226 | struct radeon_blacklist_clocks | ||
1227 | { | ||
1228 | u32 sclk; | ||
1229 | u32 mclk; | ||
1230 | enum radeon_clk_action action; | ||
1231 | }; | ||
1232 | |||
1220 | struct radeon_clock_and_voltage_limits { | 1233 | struct radeon_clock_and_voltage_limits { |
1221 | u32 sclk; | 1234 | u32 sclk; |
1222 | u32 mclk; | 1235 | u32 mclk; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 196c65a9df3b..cd18463444d6 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -719,17 +719,42 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) | |||
719 | else | 719 | else |
720 | return; | 720 | return; |
721 | 721 | ||
722 | /* no need to reprogram if nothing changed */ | 722 | /* no need to reprogram if nothing changed unless we are on BTC+ */ |
723 | if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { | 723 | if (rdev->pm.dpm.current_ps == rdev->pm.dpm.requested_ps) { |
724 | /* update display watermarks based on new power state */ | 724 | if ((rdev->family < CHIP_BARTS) || (rdev->flags & RADEON_IS_IGP)) { |
725 | if (rdev->pm.dpm.new_active_crtcs != rdev->pm.dpm.current_active_crtcs) { | 725 | /* for pre-BTC and APUs if the num crtcs changed but state is the same, |
726 | radeon_bandwidth_update(rdev); | 726 | * all we need to do is update the display configuration. |
727 | /* update displays */ | 727 | */ |
728 | radeon_dpm_display_configuration_changed(rdev); | 728 | if (rdev->pm.dpm.new_active_crtcs != rdev->pm.dpm.current_active_crtcs) { |
729 | rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; | 729 | /* update display watermarks based on new power state */ |
730 | rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; | 730 | radeon_bandwidth_update(rdev); |
731 | /* update displays */ | ||
732 | radeon_dpm_display_configuration_changed(rdev); | ||
733 | rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; | ||
734 | rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; | ||
735 | } | ||
736 | return; | ||
737 | } else { | ||
738 | /* for BTC+ if the num crtcs hasn't changed and state is the same, | ||
739 | * nothing to do, if the num crtcs is > 1 and state is the same, | ||
740 | * update display configuration. | ||
741 | */ | ||
742 | if (rdev->pm.dpm.new_active_crtcs == | ||
743 | rdev->pm.dpm.current_active_crtcs) { | ||
744 | return; | ||
745 | } else { | ||
746 | if ((rdev->pm.dpm.current_active_crtc_count > 1) && | ||
747 | (rdev->pm.dpm.new_active_crtc_count > 1)) { | ||
748 | /* update display watermarks based on new power state */ | ||
749 | radeon_bandwidth_update(rdev); | ||
750 | /* update displays */ | ||
751 | radeon_dpm_display_configuration_changed(rdev); | ||
752 | rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; | ||
753 | rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; | ||
754 | return; | ||
755 | } | ||
756 | } | ||
731 | } | 757 | } |
732 | return; | ||
733 | } | 758 | } |
734 | 759 | ||
735 | printk("switching from power state:\n"); | 760 | printk("switching from power state:\n"); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 75062c4f113d..d3a55b792bd6 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -2177,6 +2177,16 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2177 | pl->vddc = vddc; | 2177 | pl->vddc = vddc; |
2178 | pl->vddci = vddci; | 2178 | pl->vddci = vddci; |
2179 | } | 2179 | } |
2180 | |||
2181 | if (rdev->family >= CHIP_BARTS) { | ||
2182 | if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == | ||
2183 | ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) { | ||
2184 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk; | ||
2185 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk; | ||
2186 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc; | ||
2187 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci; | ||
2188 | } | ||
2189 | } | ||
2180 | } | 2190 | } |
2181 | 2191 | ||
2182 | int rv7xx_parse_power_table(struct radeon_device *rdev) | 2192 | int rv7xx_parse_power_table(struct radeon_device *rdev) |