aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2013-10-09 12:17:56 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-10-15 03:56:41 -0400
commit7c4a395ff8f441acb7876281c6777624e6410349 (patch)
tree8d05ab2aae612c75b0b9d4483ca1ddaf762eabbe /drivers/gpu/drm/i915/intel_pm.c
parent0b2ae6d72e445b58ae39cfa6ec0b8d3f53ff7a6f (diff)
drm/i915: Don't re-compute pipe watermarks except for the affected pipe
No point in re-computing the watermarks for all pipes, when only one pipe has changed. The watermarks stored under intel_crtc.wm.active are still valid for the other pipes. We just need to redo the merging. We can also skip the merge/update procedure completely if the new watermarks for the affected pipe come out unchanged. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c67
1 files changed, 28 insertions, 39 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 3e1b50359afb..3699f1d574c5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2584,29 +2584,19 @@ static void intel_setup_wm_latency(struct drm_device *dev)
2584 intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency); 2584 intel_print_wm_latency(dev, "Cursor", dev_priv->wm.cur_latency);
2585} 2585}
2586 2586
2587static void hsw_compute_wm_parameters(struct drm_device *dev, 2587static void hsw_compute_wm_parameters(struct drm_crtc *crtc,
2588 struct hsw_pipe_wm_parameters *params, 2588 struct hsw_pipe_wm_parameters *p,
2589 struct hsw_wm_maximums *lp_max_1_2, 2589 struct hsw_wm_maximums *lp_max_1_2,
2590 struct hsw_wm_maximums *lp_max_5_6) 2590 struct hsw_wm_maximums *lp_max_5_6)
2591{ 2591{
2592 struct drm_crtc *crtc; 2592 struct drm_device *dev = crtc->dev;
2593 struct drm_plane *plane; 2593 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2594 enum pipe pipe; 2594 enum pipe pipe = intel_crtc->pipe;
2595 struct intel_wm_config config = {}; 2595 struct intel_wm_config config = {};
2596 struct drm_plane *plane;
2596 2597
2597 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 2598 p->active = intel_crtc_active(crtc);
2598 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2599 if (p->active) {
2599 struct hsw_pipe_wm_parameters *p;
2600
2601 pipe = intel_crtc->pipe;
2602 p = &params[pipe];
2603
2604 p->active = intel_crtc_active(crtc);
2605 if (!p->active)
2606 continue;
2607
2608 config.num_pipes_active++;
2609
2610 p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal; 2600 p->pipe_htotal = intel_crtc->config.adjusted_mode.htotal;
2611 p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc); 2601 p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
2612 p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8; 2602 p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8;
@@ -2618,17 +2608,17 @@ static void hsw_compute_wm_parameters(struct drm_device *dev,
2618 p->cur.enabled = true; 2608 p->cur.enabled = true;
2619 } 2609 }
2620 2610
2611 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
2612 config.num_pipes_active += intel_crtc_active(crtc);
2613
2621 list_for_each_entry(plane, &dev->mode_config.plane_list, head) { 2614 list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
2622 struct intel_plane *intel_plane = to_intel_plane(plane); 2615 struct intel_plane *intel_plane = to_intel_plane(plane);
2623 struct hsw_pipe_wm_parameters *p;
2624
2625 pipe = intel_plane->pipe;
2626 p = &params[pipe];
2627 2616
2628 p->spr = intel_plane->wm; 2617 if (intel_plane->pipe == pipe)
2618 p->spr = intel_plane->wm;
2629 2619
2630 config.sprites_enabled |= p->spr.enabled; 2620 config.sprites_enabled |= intel_plane->wm.enabled;
2631 config.sprites_scaled |= p->spr.scaled; 2621 config.sprites_scaled |= intel_plane->wm.scaled;
2632 } 2622 }
2633 2623
2634 ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_1_2, lp_max_1_2); 2624 ilk_wm_max(dev, 1, &config, INTEL_DDB_PART_1_2, lp_max_1_2);
@@ -2656,8 +2646,6 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
2656 }; 2646 };
2657 struct hsw_wm_maximums max; 2647 struct hsw_wm_maximums max;
2658 2648
2659 memset(pipe_wm, 0, sizeof(*pipe_wm));
2660
2661 /* LP0 watermarks always use 1/2 DDB partitioning */ 2649 /* LP0 watermarks always use 1/2 DDB partitioning */
2662 ilk_wm_max(dev, 0, &config, INTEL_DDB_PART_1_2, &max); 2650 ilk_wm_max(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
2663 2651
@@ -2728,7 +2716,6 @@ static void ilk_wm_merge(struct drm_device *dev,
2728} 2716}
2729 2717
2730static void hsw_compute_wm_results(struct drm_device *dev, 2718static void hsw_compute_wm_results(struct drm_device *dev,
2731 const struct hsw_pipe_wm_parameters *params,
2732 const struct hsw_wm_maximums *lp_maximums, 2719 const struct hsw_wm_maximums *lp_maximums,
2733 struct hsw_wm_values *results) 2720 struct hsw_wm_values *results)
2734{ 2721{
@@ -2736,11 +2723,6 @@ static void hsw_compute_wm_results(struct drm_device *dev,
2736 int level, wm_lp; 2723 int level, wm_lp;
2737 struct intel_pipe_wm merged = {}; 2724 struct intel_pipe_wm merged = {};
2738 2725
2739 list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head)
2740 intel_compute_pipe_wm(&intel_crtc->base,
2741 &params[intel_crtc->pipe],
2742 &intel_crtc->wm.active);
2743
2744 ilk_wm_merge(dev, lp_maximums, &merged); 2726 ilk_wm_merge(dev, lp_maximums, &merged);
2745 2727
2746 memset(results, 0, sizeof(*results)); 2728 memset(results, 0, sizeof(*results));
@@ -2907,20 +2889,27 @@ static void hsw_write_wm_values(struct drm_i915_private *dev_priv,
2907 2889
2908static void haswell_update_wm(struct drm_crtc *crtc) 2890static void haswell_update_wm(struct drm_crtc *crtc)
2909{ 2891{
2892 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2910 struct drm_device *dev = crtc->dev; 2893 struct drm_device *dev = crtc->dev;
2911 struct drm_i915_private *dev_priv = dev->dev_private; 2894 struct drm_i915_private *dev_priv = dev->dev_private;
2912 struct hsw_wm_maximums lp_max_1_2, lp_max_5_6; 2895 struct hsw_wm_maximums lp_max_1_2, lp_max_5_6;
2913 struct hsw_pipe_wm_parameters params[3]; 2896 struct hsw_pipe_wm_parameters params = {};
2914 struct hsw_wm_values results_1_2, results_5_6, *best_results; 2897 struct hsw_wm_values results_1_2, results_5_6, *best_results;
2915 enum intel_ddb_partitioning partitioning; 2898 enum intel_ddb_partitioning partitioning;
2899 struct intel_pipe_wm pipe_wm = {};
2900
2901 hsw_compute_wm_parameters(crtc, &params, &lp_max_1_2, &lp_max_5_6);
2902
2903 intel_compute_pipe_wm(crtc, &params, &pipe_wm);
2904
2905 if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
2906 return;
2916 2907
2917 hsw_compute_wm_parameters(dev, params, &lp_max_1_2, &lp_max_5_6); 2908 intel_crtc->wm.active = pipe_wm;
2918 2909
2919 hsw_compute_wm_results(dev, params, 2910 hsw_compute_wm_results(dev, &lp_max_1_2, &results_1_2);
2920 &lp_max_1_2, &results_1_2);
2921 if (lp_max_1_2.pri != lp_max_5_6.pri) { 2911 if (lp_max_1_2.pri != lp_max_5_6.pri) {
2922 hsw_compute_wm_results(dev, params, 2912 hsw_compute_wm_results(dev, &lp_max_5_6, &results_5_6);
2923 &lp_max_5_6, &results_5_6);
2924 best_results = hsw_find_best_result(&results_1_2, &results_5_6); 2913 best_results = hsw_find_best_result(&results_1_2, &results_5_6);
2925 } else { 2914 } else {
2926 best_results = &results_1_2; 2915 best_results = &results_1_2;