aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c119
1 files changed, 107 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d7bb61efca2d..a4c3c5497941 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2270,6 +2270,104 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params,
2270 params->pri_bytes_per_pixel); 2270 params->pri_bytes_per_pixel);
2271} 2271}
2272 2272
2273static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
2274{
2275 if (INTEL_INFO(dev)->gen >= 7)
2276 return 768;
2277 else
2278 return 512;
2279}
2280
2281/* Calculate the maximum primary/sprite plane watermark */
2282static unsigned int ilk_plane_wm_max(const struct drm_device *dev,
2283 int level,
2284 unsigned int num_pipes_active,
2285 bool sprite_enabled,
2286 enum intel_ddb_partitioning ddb_partitioning,
2287 bool is_sprite)
2288{
2289 unsigned int fifo_size = ilk_display_fifo_size(dev);
2290 unsigned int max;
2291
2292 /* if sprites aren't enabled, sprites get nothing */
2293 if (is_sprite && !sprite_enabled)
2294 return 0;
2295
2296 /* HSW allows LP1+ watermarks even with multiple pipes */
2297 if (level == 0 || num_pipes_active > 1) {
2298 fifo_size /= INTEL_INFO(dev)->num_pipes;
2299
2300 /*
2301 * For some reason the non self refresh
2302 * FIFO size is only half of the self
2303 * refresh FIFO size on ILK/SNB.
2304 */
2305 if (INTEL_INFO(dev)->gen <= 6)
2306 fifo_size /= 2;
2307 }
2308
2309 if (sprite_enabled) {
2310 /* level 0 is always calculated with 1:1 split */
2311 if (level > 0 && ddb_partitioning == INTEL_DDB_PART_5_6) {
2312 if (is_sprite)
2313 fifo_size *= 5;
2314 fifo_size /= 6;
2315 } else {
2316 fifo_size /= 2;
2317 }
2318 }
2319
2320 /* clamp to max that the registers can hold */
2321 if (INTEL_INFO(dev)->gen >= 7)
2322 /* IVB/HSW primary/sprite plane watermarks */
2323 max = level == 0 ? 127 : 1023;
2324 else if (!is_sprite)
2325 /* ILK/SNB primary plane watermarks */
2326 max = level == 0 ? 127 : 511;
2327 else
2328 /* ILK/SNB sprite plane watermarks */
2329 max = level == 0 ? 63 : 255;
2330
2331 return min(fifo_size, max);
2332}
2333
2334/* Calculate the maximum cursor plane watermark */
2335static unsigned int ilk_cursor_wm_max(const struct drm_device *dev,
2336 int level, unsigned int num_pipes_active)
2337{
2338 /* HSW LP1+ watermarks w/ multiple pipes */
2339 if (level > 0 && num_pipes_active > 1)
2340 return 64;
2341
2342 /* otherwise just report max that registers can hold */
2343 if (INTEL_INFO(dev)->gen >= 7)
2344 return level == 0 ? 63 : 255;
2345 else
2346 return level == 0 ? 31 : 63;
2347}
2348
2349/* Calculate the maximum FBC watermark */
2350static unsigned int ilk_fbc_wm_max(void)
2351{
2352 /* max that registers can hold */
2353 return 15;
2354}
2355
2356static void ilk_wm_max(struct drm_device *dev,
2357 int level,
2358 unsigned int num_pipes_active,
2359 bool sprite_enabled,
2360 enum intel_ddb_partitioning ddb_partitioning,
2361 struct hsw_wm_maximums *max)
2362{
2363 max->pri = ilk_plane_wm_max(dev, level, num_pipes_active,
2364 sprite_enabled, ddb_partitioning, false);
2365 max->spr = ilk_plane_wm_max(dev, level, num_pipes_active,
2366 sprite_enabled, ddb_partitioning, true);
2367 max->cur = ilk_cursor_wm_max(dev, level, num_pipes_active);
2368 max->fbc = ilk_fbc_wm_max();
2369}
2370
2273static bool ilk_check_wm(int level, 2371static bool ilk_check_wm(int level,
2274 const struct hsw_wm_maximums *max, 2372 const struct hsw_wm_maximums *max,
2275 struct intel_wm_level *result) 2373 struct intel_wm_level *result)
@@ -2555,18 +2653,15 @@ static void hsw_compute_wm_parameters(struct drm_device *dev,
2555 sprites_enabled++; 2653 sprites_enabled++;
2556 } 2654 }
2557 2655
2558 if (pipes_active > 1) { 2656 ilk_wm_max(dev, 1, pipes_active, sprites_enabled,
2559 lp_max_1_2->pri = lp_max_5_6->pri = sprites_enabled ? 128 : 256; 2657 INTEL_DDB_PART_1_2, lp_max_1_2);
2560 lp_max_1_2->spr = lp_max_5_6->spr = 128; 2658
2561 lp_max_1_2->cur = lp_max_5_6->cur = 64; 2659 /* 5/6 split only in single pipe config on IVB+ */
2562 } else { 2660 if (INTEL_INFO(dev)->gen >= 7 && pipes_active <= 1)
2563 lp_max_1_2->pri = sprites_enabled ? 384 : 768; 2661 ilk_wm_max(dev, 1, pipes_active, sprites_enabled,
2564 lp_max_5_6->pri = sprites_enabled ? 128 : 768; 2662 INTEL_DDB_PART_5_6, lp_max_5_6);
2565 lp_max_1_2->spr = 384; 2663 else
2566 lp_max_5_6->spr = 640; 2664 *lp_max_5_6 = *lp_max_1_2;
2567 lp_max_1_2->cur = lp_max_5_6->cur = 255;
2568 }
2569 lp_max_1_2->fbc = lp_max_5_6->fbc = 15;
2570} 2665}
2571 2666
2572static void hsw_compute_wm_results(struct drm_device *dev, 2667static void hsw_compute_wm_results(struct drm_device *dev,