diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2013-10-09 12:17:56 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-10-15 03:56:41 -0400 |
commit | 7c4a395ff8f441acb7876281c6777624e6410349 (patch) | |
tree | 8d05ab2aae612c75b0b9d4483ca1ddaf762eabbe /drivers/gpu/drm/i915/intel_pm.c | |
parent | 0b2ae6d72e445b58ae39cfa6ec0b8d3f53ff7a6f (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.c | 67 |
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 | ||
2587 | static void hsw_compute_wm_parameters(struct drm_device *dev, | 2587 | static 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 = ¶ms[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 = ¶ms[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 | ||
2730 | static void hsw_compute_wm_results(struct drm_device *dev, | 2718 | static 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 | ¶ms[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 | ||
2908 | static void haswell_update_wm(struct drm_crtc *crtc) | 2890 | static 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, ¶ms, &lp_max_1_2, &lp_max_5_6); | ||
2902 | |||
2903 | intel_compute_pipe_wm(crtc, ¶ms, &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; |