diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 479 |
1 files changed, 256 insertions, 223 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d031d74abd27..9dda3eaebd12 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -52,56 +52,10 @@ | |||
52 | #define INTEL_RC6p_ENABLE (1<<1) | 52 | #define INTEL_RC6p_ENABLE (1<<1) |
53 | #define INTEL_RC6pp_ENABLE (1<<2) | 53 | #define INTEL_RC6pp_ENABLE (1<<2) |
54 | 54 | ||
55 | static void gen9_init_clock_gating(struct drm_device *dev) | ||
56 | { | ||
57 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
58 | |||
59 | /* WaEnableLbsSlaRetryTimerDecrement:skl */ | ||
60 | I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) | | ||
61 | GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); | ||
62 | |||
63 | /* WaDisableKillLogic:bxt,skl */ | ||
64 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | | ||
65 | ECOCHK_DIS_TLB); | ||
66 | } | ||
67 | |||
68 | static void skl_init_clock_gating(struct drm_device *dev) | ||
69 | { | ||
70 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
71 | |||
72 | gen9_init_clock_gating(dev); | ||
73 | |||
74 | if (INTEL_REVID(dev) <= SKL_REVID_D0) { | ||
75 | /* WaDisableHDCInvalidation:skl */ | ||
76 | I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | | ||
77 | BDW_DISABLE_HDC_INVALIDATION); | ||
78 | |||
79 | /* WaDisableChickenBitTSGBarrierAckForFFSliceCS:skl */ | ||
80 | I915_WRITE(FF_SLICE_CS_CHICKEN2, | ||
81 | _MASKED_BIT_ENABLE(GEN9_TSG_BARRIER_ACK_DISABLE)); | ||
82 | } | ||
83 | |||
84 | /* GEN8_L3SQCREG4 has a dependency with WA batch so any new changes | ||
85 | * involving this register should also be added to WA batch as required. | ||
86 | */ | ||
87 | if (INTEL_REVID(dev) <= SKL_REVID_E0) | ||
88 | /* WaDisableLSQCROPERFforOCL:skl */ | ||
89 | I915_WRITE(GEN8_L3SQCREG4, I915_READ(GEN8_L3SQCREG4) | | ||
90 | GEN8_LQSC_RO_PERF_DIS); | ||
91 | |||
92 | /* WaEnableGapsTsvCreditFix:skl */ | ||
93 | if (IS_SKYLAKE(dev) && (INTEL_REVID(dev) >= SKL_REVID_C0)) { | ||
94 | I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) | | ||
95 | GEN9_GAPS_TSV_CREDIT_DISABLE)); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static void bxt_init_clock_gating(struct drm_device *dev) | 55 | static void bxt_init_clock_gating(struct drm_device *dev) |
100 | { | 56 | { |
101 | struct drm_i915_private *dev_priv = dev->dev_private; | 57 | struct drm_i915_private *dev_priv = dev->dev_private; |
102 | 58 | ||
103 | gen9_init_clock_gating(dev); | ||
104 | |||
105 | /* WaDisableSDEUnitClockGating:bxt */ | 59 | /* WaDisableSDEUnitClockGating:bxt */ |
106 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | 60 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
107 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); | 61 | GEN8_SDEUNIT_CLOCK_GATE_DISABLE); |
@@ -112,17 +66,6 @@ static void bxt_init_clock_gating(struct drm_device *dev) | |||
112 | */ | 66 | */ |
113 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | | 67 | I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) | |
114 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); | 68 | GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); |
115 | |||
116 | /* WaStoreMultiplePTEenable:bxt */ | ||
117 | /* This is a requirement according to Hardware specification */ | ||
118 | if (INTEL_REVID(dev) == BXT_REVID_A0) | ||
119 | I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF); | ||
120 | |||
121 | /* WaSetClckGatingDisableMedia:bxt */ | ||
122 | if (INTEL_REVID(dev) == BXT_REVID_A0) { | ||
123 | I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) & | ||
124 | ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE)); | ||
125 | } | ||
126 | } | 69 | } |
127 | 70 | ||
128 | static void i915_pineview_get_mem_freq(struct drm_device *dev) | 71 | static void i915_pineview_get_mem_freq(struct drm_device *dev) |
@@ -1765,6 +1708,13 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels, | |||
1765 | return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; | 1708 | return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2; |
1766 | } | 1709 | } |
1767 | 1710 | ||
1711 | struct skl_pipe_wm_parameters { | ||
1712 | bool active; | ||
1713 | uint32_t pipe_htotal; | ||
1714 | uint32_t pixel_rate; /* in KHz */ | ||
1715 | struct intel_plane_wm_parameters plane[I915_MAX_PLANES]; | ||
1716 | }; | ||
1717 | |||
1768 | struct ilk_wm_maximums { | 1718 | struct ilk_wm_maximums { |
1769 | uint16_t pri; | 1719 | uint16_t pri; |
1770 | uint16_t spr; | 1720 | uint16_t spr; |
@@ -2805,40 +2755,18 @@ static bool ilk_disable_lp_wm(struct drm_device *dev) | |||
2805 | #define SKL_DDB_SIZE 896 /* in blocks */ | 2755 | #define SKL_DDB_SIZE 896 /* in blocks */ |
2806 | #define BXT_DDB_SIZE 512 | 2756 | #define BXT_DDB_SIZE 512 |
2807 | 2757 | ||
2808 | /* | ||
2809 | * Return the index of a plane in the SKL DDB and wm result arrays. Primary | ||
2810 | * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and | ||
2811 | * other universal planes are in indices 1..n. Note that this may leave unused | ||
2812 | * indices between the top "sprite" plane and the cursor. | ||
2813 | */ | ||
2814 | static int | ||
2815 | skl_wm_plane_id(const struct intel_plane *plane) | ||
2816 | { | ||
2817 | switch (plane->base.type) { | ||
2818 | case DRM_PLANE_TYPE_PRIMARY: | ||
2819 | return 0; | ||
2820 | case DRM_PLANE_TYPE_CURSOR: | ||
2821 | return PLANE_CURSOR; | ||
2822 | case DRM_PLANE_TYPE_OVERLAY: | ||
2823 | return plane->plane + 1; | ||
2824 | default: | ||
2825 | MISSING_CASE(plane->base.type); | ||
2826 | return plane->plane; | ||
2827 | } | ||
2828 | } | ||
2829 | |||
2830 | static void | 2758 | static void |
2831 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, | 2759 | skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, |
2832 | const struct intel_crtc_state *cstate, | 2760 | struct drm_crtc *for_crtc, |
2833 | const struct intel_wm_config *config, | 2761 | const struct intel_wm_config *config, |
2762 | const struct skl_pipe_wm_parameters *params, | ||
2834 | struct skl_ddb_entry *alloc /* out */) | 2763 | struct skl_ddb_entry *alloc /* out */) |
2835 | { | 2764 | { |
2836 | struct drm_crtc *for_crtc = cstate->base.crtc; | ||
2837 | struct drm_crtc *crtc; | 2765 | struct drm_crtc *crtc; |
2838 | unsigned int pipe_size, ddb_size; | 2766 | unsigned int pipe_size, ddb_size; |
2839 | int nth_active_pipe; | 2767 | int nth_active_pipe; |
2840 | 2768 | ||
2841 | if (!cstate->base.active) { | 2769 | if (!params->active) { |
2842 | alloc->start = 0; | 2770 | alloc->start = 0; |
2843 | alloc->end = 0; | 2771 | alloc->end = 0; |
2844 | return; | 2772 | return; |
@@ -2904,29 +2832,19 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, | |||
2904 | } | 2832 | } |
2905 | 2833 | ||
2906 | static unsigned int | 2834 | static unsigned int |
2907 | skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, | 2835 | skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y) |
2908 | const struct drm_plane_state *pstate, | ||
2909 | int y) | ||
2910 | { | 2836 | { |
2911 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | ||
2912 | struct drm_framebuffer *fb = pstate->fb; | ||
2913 | 2837 | ||
2914 | /* for planar format */ | 2838 | /* for planar format */ |
2915 | if (fb->pixel_format == DRM_FORMAT_NV12) { | 2839 | if (p->y_bytes_per_pixel) { |
2916 | if (y) /* y-plane data rate */ | 2840 | if (y) /* y-plane data rate */ |
2917 | return intel_crtc->config->pipe_src_w * | 2841 | return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel; |
2918 | intel_crtc->config->pipe_src_h * | ||
2919 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
2920 | else /* uv-plane data rate */ | 2842 | else /* uv-plane data rate */ |
2921 | return (intel_crtc->config->pipe_src_w/2) * | 2843 | return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel; |
2922 | (intel_crtc->config->pipe_src_h/2) * | ||
2923 | drm_format_plane_cpp(fb->pixel_format, 1); | ||
2924 | } | 2844 | } |
2925 | 2845 | ||
2926 | /* for packed formats */ | 2846 | /* for packed formats */ |
2927 | return intel_crtc->config->pipe_src_w * | 2847 | return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel; |
2928 | intel_crtc->config->pipe_src_h * | ||
2929 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
2930 | } | 2848 | } |
2931 | 2849 | ||
2932 | /* | 2850 | /* |
@@ -2935,51 +2853,46 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate, | |||
2935 | * 3 * 4096 * 8192 * 4 < 2^32 | 2853 | * 3 * 4096 * 8192 * 4 < 2^32 |
2936 | */ | 2854 | */ |
2937 | static unsigned int | 2855 | static unsigned int |
2938 | skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate) | 2856 | skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc, |
2857 | const struct skl_pipe_wm_parameters *params) | ||
2939 | { | 2858 | { |
2940 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | ||
2941 | struct drm_device *dev = intel_crtc->base.dev; | ||
2942 | const struct intel_plane *intel_plane; | ||
2943 | unsigned int total_data_rate = 0; | 2859 | unsigned int total_data_rate = 0; |
2860 | int plane; | ||
2944 | 2861 | ||
2945 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | 2862 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { |
2946 | const struct drm_plane_state *pstate = intel_plane->base.state; | 2863 | const struct intel_plane_wm_parameters *p; |
2947 | 2864 | ||
2948 | if (pstate->fb == NULL) | 2865 | p = ¶ms->plane[plane]; |
2866 | if (!p->enabled) | ||
2949 | continue; | 2867 | continue; |
2950 | 2868 | ||
2951 | /* packed/uv */ | 2869 | total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */ |
2952 | total_data_rate += skl_plane_relative_data_rate(cstate, | 2870 | if (p->y_bytes_per_pixel) { |
2953 | pstate, | 2871 | total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */ |
2954 | 0); | 2872 | } |
2955 | |||
2956 | if (pstate->fb->pixel_format == DRM_FORMAT_NV12) | ||
2957 | /* y-plane */ | ||
2958 | total_data_rate += skl_plane_relative_data_rate(cstate, | ||
2959 | pstate, | ||
2960 | 1); | ||
2961 | } | 2873 | } |
2962 | 2874 | ||
2963 | return total_data_rate; | 2875 | return total_data_rate; |
2964 | } | 2876 | } |
2965 | 2877 | ||
2966 | static void | 2878 | static void |
2967 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | 2879 | skl_allocate_pipe_ddb(struct drm_crtc *crtc, |
2968 | const struct intel_wm_config *config, | 2880 | const struct intel_wm_config *config, |
2881 | const struct skl_pipe_wm_parameters *params, | ||
2969 | struct skl_ddb_allocation *ddb /* out */) | 2882 | struct skl_ddb_allocation *ddb /* out */) |
2970 | { | 2883 | { |
2971 | struct drm_crtc *crtc = cstate->base.crtc; | ||
2972 | struct drm_device *dev = crtc->dev; | 2884 | struct drm_device *dev = crtc->dev; |
2885 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2973 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2886 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2974 | struct intel_plane *intel_plane; | ||
2975 | enum pipe pipe = intel_crtc->pipe; | 2887 | enum pipe pipe = intel_crtc->pipe; |
2976 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; | 2888 | struct skl_ddb_entry *alloc = &ddb->pipe[pipe]; |
2977 | uint16_t alloc_size, start, cursor_blocks; | 2889 | uint16_t alloc_size, start, cursor_blocks; |
2978 | uint16_t minimum[I915_MAX_PLANES]; | 2890 | uint16_t minimum[I915_MAX_PLANES]; |
2979 | uint16_t y_minimum[I915_MAX_PLANES]; | 2891 | uint16_t y_minimum[I915_MAX_PLANES]; |
2980 | unsigned int total_data_rate; | 2892 | unsigned int total_data_rate; |
2893 | int plane; | ||
2981 | 2894 | ||
2982 | skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc); | 2895 | skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc); |
2983 | alloc_size = skl_ddb_entry_size(alloc); | 2896 | alloc_size = skl_ddb_entry_size(alloc); |
2984 | if (alloc_size == 0) { | 2897 | if (alloc_size == 0) { |
2985 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); | 2898 | memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe])); |
@@ -2996,20 +2909,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
2996 | alloc->end -= cursor_blocks; | 2909 | alloc->end -= cursor_blocks; |
2997 | 2910 | ||
2998 | /* 1. Allocate the mininum required blocks for each active plane */ | 2911 | /* 1. Allocate the mininum required blocks for each active plane */ |
2999 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | 2912 | for_each_plane(dev_priv, pipe, plane) { |
3000 | struct drm_plane *plane = &intel_plane->base; | 2913 | const struct intel_plane_wm_parameters *p; |
3001 | struct drm_framebuffer *fb = plane->fb; | ||
3002 | int id = skl_wm_plane_id(intel_plane); | ||
3003 | 2914 | ||
3004 | if (fb == NULL) | 2915 | p = ¶ms->plane[plane]; |
3005 | continue; | 2916 | if (!p->enabled) |
3006 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
3007 | continue; | 2917 | continue; |
3008 | 2918 | ||
3009 | minimum[id] = 8; | 2919 | minimum[plane] = 8; |
3010 | alloc_size -= minimum[id]; | 2920 | alloc_size -= minimum[plane]; |
3011 | y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0; | 2921 | y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0; |
3012 | alloc_size -= y_minimum[id]; | 2922 | alloc_size -= y_minimum[plane]; |
3013 | } | 2923 | } |
3014 | 2924 | ||
3015 | /* | 2925 | /* |
@@ -3018,50 +2928,45 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | |||
3018 | * | 2928 | * |
3019 | * FIXME: we may not allocate every single block here. | 2929 | * FIXME: we may not allocate every single block here. |
3020 | */ | 2930 | */ |
3021 | total_data_rate = skl_get_total_relative_data_rate(cstate); | 2931 | total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params); |
3022 | 2932 | ||
3023 | start = alloc->start; | 2933 | start = alloc->start; |
3024 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | 2934 | for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) { |
3025 | struct drm_plane *plane = &intel_plane->base; | 2935 | const struct intel_plane_wm_parameters *p; |
3026 | struct drm_plane_state *pstate = intel_plane->base.state; | ||
3027 | unsigned int data_rate, y_data_rate; | 2936 | unsigned int data_rate, y_data_rate; |
3028 | uint16_t plane_blocks, y_plane_blocks = 0; | 2937 | uint16_t plane_blocks, y_plane_blocks = 0; |
3029 | int id = skl_wm_plane_id(intel_plane); | ||
3030 | 2938 | ||
3031 | if (pstate->fb == NULL) | 2939 | p = ¶ms->plane[plane]; |
3032 | continue; | 2940 | if (!p->enabled) |
3033 | if (plane->type == DRM_PLANE_TYPE_CURSOR) | ||
3034 | continue; | 2941 | continue; |
3035 | 2942 | ||
3036 | data_rate = skl_plane_relative_data_rate(cstate, pstate, 0); | 2943 | data_rate = skl_plane_relative_data_rate(p, 0); |
3037 | 2944 | ||
3038 | /* | 2945 | /* |
3039 | * allocation for (packed formats) or (uv-plane part of planar format): | 2946 | * allocation for (packed formats) or (uv-plane part of planar format): |
3040 | * promote the expression to 64 bits to avoid overflowing, the | 2947 | * promote the expression to 64 bits to avoid overflowing, the |
3041 | * result is < available as data_rate / total_data_rate < 1 | 2948 | * result is < available as data_rate / total_data_rate < 1 |
3042 | */ | 2949 | */ |
3043 | plane_blocks = minimum[id]; | 2950 | plane_blocks = minimum[plane]; |
3044 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, | 2951 | plane_blocks += div_u64((uint64_t)alloc_size * data_rate, |
3045 | total_data_rate); | 2952 | total_data_rate); |
3046 | 2953 | ||
3047 | ddb->plane[pipe][id].start = start; | 2954 | ddb->plane[pipe][plane].start = start; |
3048 | ddb->plane[pipe][id].end = start + plane_blocks; | 2955 | ddb->plane[pipe][plane].end = start + plane_blocks; |
3049 | 2956 | ||
3050 | start += plane_blocks; | 2957 | start += plane_blocks; |
3051 | 2958 | ||
3052 | /* | 2959 | /* |
3053 | * allocation for y_plane part of planar format: | 2960 | * allocation for y_plane part of planar format: |
3054 | */ | 2961 | */ |
3055 | if (pstate->fb->pixel_format == DRM_FORMAT_NV12) { | 2962 | if (p->y_bytes_per_pixel) { |
3056 | y_data_rate = skl_plane_relative_data_rate(cstate, | 2963 | y_data_rate = skl_plane_relative_data_rate(p, 1); |
3057 | pstate, | 2964 | y_plane_blocks = y_minimum[plane]; |
3058 | 1); | ||
3059 | y_plane_blocks = y_minimum[id]; | ||
3060 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, | 2965 | y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate, |
3061 | total_data_rate); | 2966 | total_data_rate); |
3062 | 2967 | ||
3063 | ddb->y_plane[pipe][id].start = start; | 2968 | ddb->y_plane[pipe][plane].start = start; |
3064 | ddb->y_plane[pipe][id].end = start + y_plane_blocks; | 2969 | ddb->y_plane[pipe][plane].end = start + y_plane_blocks; |
3065 | 2970 | ||
3066 | start += y_plane_blocks; | 2971 | start += y_plane_blocks; |
3067 | } | 2972 | } |
@@ -3148,21 +3053,87 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev, | |||
3148 | struct intel_wm_config *config) | 3053 | struct intel_wm_config *config) |
3149 | { | 3054 | { |
3150 | struct drm_crtc *crtc; | 3055 | struct drm_crtc *crtc; |
3056 | struct drm_plane *plane; | ||
3151 | 3057 | ||
3152 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | 3058 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) |
3153 | config->num_pipes_active += to_intel_crtc(crtc)->active; | 3059 | config->num_pipes_active += to_intel_crtc(crtc)->active; |
3060 | |||
3061 | /* FIXME: I don't think we need those two global parameters on SKL */ | ||
3062 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { | ||
3063 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3064 | |||
3065 | config->sprites_enabled |= intel_plane->wm.enabled; | ||
3066 | config->sprites_scaled |= intel_plane->wm.scaled; | ||
3067 | } | ||
3068 | } | ||
3069 | |||
3070 | static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc, | ||
3071 | struct skl_pipe_wm_parameters *p) | ||
3072 | { | ||
3073 | struct drm_device *dev = crtc->dev; | ||
3074 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3075 | enum pipe pipe = intel_crtc->pipe; | ||
3076 | struct drm_plane *plane; | ||
3077 | struct drm_framebuffer *fb; | ||
3078 | int i = 1; /* Index for sprite planes start */ | ||
3079 | |||
3080 | p->active = intel_crtc->active; | ||
3081 | if (p->active) { | ||
3082 | p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal; | ||
3083 | p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config); | ||
3084 | |||
3085 | fb = crtc->primary->state->fb; | ||
3086 | /* For planar: Bpp is for uv plane, y_Bpp is for y plane */ | ||
3087 | if (fb) { | ||
3088 | p->plane[0].enabled = true; | ||
3089 | p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? | ||
3090 | drm_format_plane_cpp(fb->pixel_format, 1) : | ||
3091 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
3092 | p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ? | ||
3093 | drm_format_plane_cpp(fb->pixel_format, 0) : 0; | ||
3094 | p->plane[0].tiling = fb->modifier[0]; | ||
3095 | } else { | ||
3096 | p->plane[0].enabled = false; | ||
3097 | p->plane[0].bytes_per_pixel = 0; | ||
3098 | p->plane[0].y_bytes_per_pixel = 0; | ||
3099 | p->plane[0].tiling = DRM_FORMAT_MOD_NONE; | ||
3100 | } | ||
3101 | p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w; | ||
3102 | p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h; | ||
3103 | p->plane[0].rotation = crtc->primary->state->rotation; | ||
3104 | |||
3105 | fb = crtc->cursor->state->fb; | ||
3106 | p->plane[PLANE_CURSOR].y_bytes_per_pixel = 0; | ||
3107 | if (fb) { | ||
3108 | p->plane[PLANE_CURSOR].enabled = true; | ||
3109 | p->plane[PLANE_CURSOR].bytes_per_pixel = fb->bits_per_pixel / 8; | ||
3110 | p->plane[PLANE_CURSOR].horiz_pixels = crtc->cursor->state->crtc_w; | ||
3111 | p->plane[PLANE_CURSOR].vert_pixels = crtc->cursor->state->crtc_h; | ||
3112 | } else { | ||
3113 | p->plane[PLANE_CURSOR].enabled = false; | ||
3114 | p->plane[PLANE_CURSOR].bytes_per_pixel = 0; | ||
3115 | p->plane[PLANE_CURSOR].horiz_pixels = 64; | ||
3116 | p->plane[PLANE_CURSOR].vert_pixels = 64; | ||
3117 | } | ||
3118 | } | ||
3119 | |||
3120 | list_for_each_entry(plane, &dev->mode_config.plane_list, head) { | ||
3121 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3122 | |||
3123 | if (intel_plane->pipe == pipe && | ||
3124 | plane->type == DRM_PLANE_TYPE_OVERLAY) | ||
3125 | p->plane[i++] = intel_plane->wm; | ||
3126 | } | ||
3154 | } | 3127 | } |
3155 | 3128 | ||
3156 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | 3129 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
3157 | struct intel_crtc_state *cstate, | 3130 | struct skl_pipe_wm_parameters *p, |
3158 | struct intel_plane *intel_plane, | 3131 | struct intel_plane_wm_parameters *p_params, |
3159 | uint16_t ddb_allocation, | 3132 | uint16_t ddb_allocation, |
3160 | int level, | 3133 | int level, |
3161 | uint16_t *out_blocks, /* out */ | 3134 | uint16_t *out_blocks, /* out */ |
3162 | uint8_t *out_lines /* out */) | 3135 | uint8_t *out_lines /* out */) |
3163 | { | 3136 | { |
3164 | struct drm_plane *plane = &intel_plane->base; | ||
3165 | struct drm_framebuffer *fb = plane->state->fb; | ||
3166 | uint32_t latency = dev_priv->wm.skl_latency[level]; | 3137 | uint32_t latency = dev_priv->wm.skl_latency[level]; |
3167 | uint32_t method1, method2; | 3138 | uint32_t method1, method2; |
3168 | uint32_t plane_bytes_per_line, plane_blocks_per_line; | 3139 | uint32_t plane_bytes_per_line, plane_blocks_per_line; |
@@ -3170,35 +3141,31 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3170 | uint32_t selected_result; | 3141 | uint32_t selected_result; |
3171 | uint8_t bytes_per_pixel; | 3142 | uint8_t bytes_per_pixel; |
3172 | 3143 | ||
3173 | if (latency == 0 || !cstate->base.active || !fb) | 3144 | if (latency == 0 || !p->active || !p_params->enabled) |
3174 | return false; | 3145 | return false; |
3175 | 3146 | ||
3176 | bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ? | 3147 | bytes_per_pixel = p_params->y_bytes_per_pixel ? |
3177 | drm_format_plane_cpp(DRM_FORMAT_NV12, 0) : | 3148 | p_params->y_bytes_per_pixel : |
3178 | drm_format_plane_cpp(DRM_FORMAT_NV12, 1); | 3149 | p_params->bytes_per_pixel; |
3179 | method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate), | 3150 | method1 = skl_wm_method1(p->pixel_rate, |
3180 | bytes_per_pixel, | 3151 | bytes_per_pixel, |
3181 | latency); | 3152 | latency); |
3182 | method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate), | 3153 | method2 = skl_wm_method2(p->pixel_rate, |
3183 | cstate->base.adjusted_mode.crtc_htotal, | 3154 | p->pipe_htotal, |
3184 | cstate->pipe_src_w, | 3155 | p_params->horiz_pixels, |
3185 | bytes_per_pixel, | 3156 | bytes_per_pixel, |
3186 | fb->modifier[0], | 3157 | p_params->tiling, |
3187 | latency); | 3158 | latency); |
3188 | 3159 | ||
3189 | plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel; | 3160 | plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel; |
3190 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); | 3161 | plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512); |
3191 | 3162 | ||
3192 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || | 3163 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || |
3193 | fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) { | 3164 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) { |
3194 | uint32_t min_scanlines = 4; | 3165 | uint32_t min_scanlines = 4; |
3195 | uint32_t y_tile_minimum; | 3166 | uint32_t y_tile_minimum; |
3196 | if (intel_rotation_90_or_270(plane->state->rotation)) { | 3167 | if (intel_rotation_90_or_270(p_params->rotation)) { |
3197 | int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ? | 3168 | switch (p_params->bytes_per_pixel) { |
3198 | drm_format_plane_cpp(fb->pixel_format, 1) : | ||
3199 | drm_format_plane_cpp(fb->pixel_format, 0); | ||
3200 | |||
3201 | switch (bpp) { | ||
3202 | case 1: | 3169 | case 1: |
3203 | min_scanlines = 16; | 3170 | min_scanlines = 16; |
3204 | break; | 3171 | break; |
@@ -3222,8 +3189,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3222 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); | 3189 | res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line); |
3223 | 3190 | ||
3224 | if (level >= 1 && level <= 7) { | 3191 | if (level >= 1 && level <= 7) { |
3225 | if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED || | 3192 | if (p_params->tiling == I915_FORMAT_MOD_Y_TILED || |
3226 | fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) | 3193 | p_params->tiling == I915_FORMAT_MOD_Yf_TILED) |
3227 | res_lines += 4; | 3194 | res_lines += 4; |
3228 | else | 3195 | else |
3229 | res_blocks++; | 3196 | res_blocks++; |
@@ -3240,80 +3207,84 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | |||
3240 | 3207 | ||
3241 | static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, | 3208 | static void skl_compute_wm_level(const struct drm_i915_private *dev_priv, |
3242 | struct skl_ddb_allocation *ddb, | 3209 | struct skl_ddb_allocation *ddb, |
3243 | struct intel_crtc_state *cstate, | 3210 | struct skl_pipe_wm_parameters *p, |
3211 | enum pipe pipe, | ||
3244 | int level, | 3212 | int level, |
3213 | int num_planes, | ||
3245 | struct skl_wm_level *result) | 3214 | struct skl_wm_level *result) |
3246 | { | 3215 | { |
3247 | struct drm_device *dev = dev_priv->dev; | ||
3248 | struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); | ||
3249 | struct intel_plane *intel_plane; | ||
3250 | uint16_t ddb_blocks; | 3216 | uint16_t ddb_blocks; |
3251 | enum pipe pipe = intel_crtc->pipe; | 3217 | int i; |
3252 | |||
3253 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | ||
3254 | int i = skl_wm_plane_id(intel_plane); | ||
3255 | 3218 | ||
3219 | for (i = 0; i < num_planes; i++) { | ||
3256 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); | 3220 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); |
3257 | 3221 | ||
3258 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, | 3222 | result->plane_en[i] = skl_compute_plane_wm(dev_priv, |
3259 | cstate, | 3223 | p, &p->plane[i], |
3260 | intel_plane, | ||
3261 | ddb_blocks, | 3224 | ddb_blocks, |
3262 | level, | 3225 | level, |
3263 | &result->plane_res_b[i], | 3226 | &result->plane_res_b[i], |
3264 | &result->plane_res_l[i]); | 3227 | &result->plane_res_l[i]); |
3265 | } | 3228 | } |
3229 | |||
3230 | ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][PLANE_CURSOR]); | ||
3231 | result->plane_en[PLANE_CURSOR] = skl_compute_plane_wm(dev_priv, p, | ||
3232 | &p->plane[PLANE_CURSOR], | ||
3233 | ddb_blocks, level, | ||
3234 | &result->plane_res_b[PLANE_CURSOR], | ||
3235 | &result->plane_res_l[PLANE_CURSOR]); | ||
3266 | } | 3236 | } |
3267 | 3237 | ||
3268 | static uint32_t | 3238 | static uint32_t |
3269 | skl_compute_linetime_wm(struct intel_crtc_state *cstate) | 3239 | skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p) |
3270 | { | 3240 | { |
3271 | if (!cstate->base.active) | 3241 | if (!to_intel_crtc(crtc)->active) |
3272 | return 0; | 3242 | return 0; |
3273 | 3243 | ||
3274 | if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0)) | 3244 | if (WARN_ON(p->pixel_rate == 0)) |
3275 | return 0; | 3245 | return 0; |
3276 | 3246 | ||
3277 | return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000, | 3247 | return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate); |
3278 | skl_pipe_pixel_rate(cstate)); | ||
3279 | } | 3248 | } |
3280 | 3249 | ||
3281 | static void skl_compute_transition_wm(struct intel_crtc_state *cstate, | 3250 | static void skl_compute_transition_wm(struct drm_crtc *crtc, |
3251 | struct skl_pipe_wm_parameters *params, | ||
3282 | struct skl_wm_level *trans_wm /* out */) | 3252 | struct skl_wm_level *trans_wm /* out */) |
3283 | { | 3253 | { |
3284 | struct drm_crtc *crtc = cstate->base.crtc; | ||
3285 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3254 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3286 | struct intel_plane *intel_plane; | 3255 | int i; |
3287 | 3256 | ||
3288 | if (!cstate->base.active) | 3257 | if (!params->active) |
3289 | return; | 3258 | return; |
3290 | 3259 | ||
3291 | /* Until we know more, just disable transition WMs */ | 3260 | /* Until we know more, just disable transition WMs */ |
3292 | for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) { | 3261 | for (i = 0; i < intel_num_planes(intel_crtc); i++) |
3293 | int i = skl_wm_plane_id(intel_plane); | ||
3294 | |||
3295 | trans_wm->plane_en[i] = false; | 3262 | trans_wm->plane_en[i] = false; |
3296 | } | 3263 | trans_wm->plane_en[PLANE_CURSOR] = false; |
3297 | } | 3264 | } |
3298 | 3265 | ||
3299 | static void skl_compute_pipe_wm(struct intel_crtc_state *cstate, | 3266 | static void skl_compute_pipe_wm(struct drm_crtc *crtc, |
3300 | struct skl_ddb_allocation *ddb, | 3267 | struct skl_ddb_allocation *ddb, |
3268 | struct skl_pipe_wm_parameters *params, | ||
3301 | struct skl_pipe_wm *pipe_wm) | 3269 | struct skl_pipe_wm *pipe_wm) |
3302 | { | 3270 | { |
3303 | struct drm_device *dev = cstate->base.crtc->dev; | 3271 | struct drm_device *dev = crtc->dev; |
3304 | const struct drm_i915_private *dev_priv = dev->dev_private; | 3272 | const struct drm_i915_private *dev_priv = dev->dev_private; |
3273 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3305 | int level, max_level = ilk_wm_max_level(dev); | 3274 | int level, max_level = ilk_wm_max_level(dev); |
3306 | 3275 | ||
3307 | for (level = 0; level <= max_level; level++) { | 3276 | for (level = 0; level <= max_level; level++) { |
3308 | skl_compute_wm_level(dev_priv, ddb, cstate, | 3277 | skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe, |
3309 | level, &pipe_wm->wm[level]); | 3278 | level, intel_num_planes(intel_crtc), |
3279 | &pipe_wm->wm[level]); | ||
3310 | } | 3280 | } |
3311 | pipe_wm->linetime = skl_compute_linetime_wm(cstate); | 3281 | pipe_wm->linetime = skl_compute_linetime_wm(crtc, params); |
3312 | 3282 | ||
3313 | skl_compute_transition_wm(cstate, &pipe_wm->trans_wm); | 3283 | skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm); |
3314 | } | 3284 | } |
3315 | 3285 | ||
3316 | static void skl_compute_wm_results(struct drm_device *dev, | 3286 | static void skl_compute_wm_results(struct drm_device *dev, |
3287 | struct skl_pipe_wm_parameters *p, | ||
3317 | struct skl_pipe_wm *p_wm, | 3288 | struct skl_pipe_wm *p_wm, |
3318 | struct skl_wm_values *r, | 3289 | struct skl_wm_values *r, |
3319 | struct intel_crtc *intel_crtc) | 3290 | struct intel_crtc *intel_crtc) |
@@ -3557,15 +3528,16 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, | |||
3557 | } | 3528 | } |
3558 | 3529 | ||
3559 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, | 3530 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, |
3531 | struct skl_pipe_wm_parameters *params, | ||
3560 | struct intel_wm_config *config, | 3532 | struct intel_wm_config *config, |
3561 | struct skl_ddb_allocation *ddb, /* out */ | 3533 | struct skl_ddb_allocation *ddb, /* out */ |
3562 | struct skl_pipe_wm *pipe_wm /* out */) | 3534 | struct skl_pipe_wm *pipe_wm /* out */) |
3563 | { | 3535 | { |
3564 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3536 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3565 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | ||
3566 | 3537 | ||
3567 | skl_allocate_pipe_ddb(cstate, config, ddb); | 3538 | skl_compute_wm_pipe_parameters(crtc, params); |
3568 | skl_compute_pipe_wm(cstate, ddb, pipe_wm); | 3539 | skl_allocate_pipe_ddb(crtc, config, params, ddb); |
3540 | skl_compute_pipe_wm(crtc, ddb, params, pipe_wm); | ||
3569 | 3541 | ||
3570 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) | 3542 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) |
3571 | return false; | 3543 | return false; |
@@ -3598,6 +3570,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3598 | */ | 3570 | */ |
3599 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, | 3571 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, |
3600 | base.head) { | 3572 | base.head) { |
3573 | struct skl_pipe_wm_parameters params = {}; | ||
3601 | struct skl_pipe_wm pipe_wm = {}; | 3574 | struct skl_pipe_wm pipe_wm = {}; |
3602 | bool wm_changed; | 3575 | bool wm_changed; |
3603 | 3576 | ||
@@ -3607,7 +3580,8 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3607 | if (!intel_crtc->active) | 3580 | if (!intel_crtc->active) |
3608 | continue; | 3581 | continue; |
3609 | 3582 | ||
3610 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, config, | 3583 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, |
3584 | ¶ms, config, | ||
3611 | &r->ddb, &pipe_wm); | 3585 | &r->ddb, &pipe_wm); |
3612 | 3586 | ||
3613 | /* | 3587 | /* |
@@ -3617,7 +3591,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3617 | */ | 3591 | */ |
3618 | WARN_ON(!wm_changed); | 3592 | WARN_ON(!wm_changed); |
3619 | 3593 | ||
3620 | skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc); | 3594 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc); |
3621 | r->dirty[intel_crtc->pipe] = true; | 3595 | r->dirty[intel_crtc->pipe] = true; |
3622 | } | 3596 | } |
3623 | } | 3597 | } |
@@ -3647,6 +3621,7 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3647 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3621 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3648 | struct drm_device *dev = crtc->dev; | 3622 | struct drm_device *dev = crtc->dev; |
3649 | struct drm_i915_private *dev_priv = dev->dev_private; | 3623 | struct drm_i915_private *dev_priv = dev->dev_private; |
3624 | struct skl_pipe_wm_parameters params = {}; | ||
3650 | struct skl_wm_values *results = &dev_priv->wm.skl_results; | 3625 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3651 | struct skl_pipe_wm pipe_wm = {}; | 3626 | struct skl_pipe_wm pipe_wm = {}; |
3652 | struct intel_wm_config config = {}; | 3627 | struct intel_wm_config config = {}; |
@@ -3659,10 +3634,11 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3659 | 3634 | ||
3660 | skl_compute_wm_global_parameters(dev, &config); | 3635 | skl_compute_wm_global_parameters(dev, &config); |
3661 | 3636 | ||
3662 | if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm)) | 3637 | if (!skl_update_pipe_wm(crtc, ¶ms, &config, |
3638 | &results->ddb, &pipe_wm)) | ||
3663 | return; | 3639 | return; |
3664 | 3640 | ||
3665 | skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc); | 3641 | skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc); |
3666 | results->dirty[intel_crtc->pipe] = true; | 3642 | results->dirty[intel_crtc->pipe] = true; |
3667 | 3643 | ||
3668 | skl_update_other_pipe_wm(dev, crtc, &config, results); | 3644 | skl_update_other_pipe_wm(dev, crtc, &config, results); |
@@ -3673,6 +3649,39 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3673 | dev_priv->wm.skl_hw = *results; | 3649 | dev_priv->wm.skl_hw = *results; |
3674 | } | 3650 | } |
3675 | 3651 | ||
3652 | static void | ||
3653 | skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc, | ||
3654 | uint32_t sprite_width, uint32_t sprite_height, | ||
3655 | int pixel_size, bool enabled, bool scaled) | ||
3656 | { | ||
3657 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3658 | struct drm_framebuffer *fb = plane->state->fb; | ||
3659 | |||
3660 | intel_plane->wm.enabled = enabled; | ||
3661 | intel_plane->wm.scaled = scaled; | ||
3662 | intel_plane->wm.horiz_pixels = sprite_width; | ||
3663 | intel_plane->wm.vert_pixels = sprite_height; | ||
3664 | intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE; | ||
3665 | |||
3666 | /* For planar: Bpp is for UV plane, y_Bpp is for Y plane */ | ||
3667 | intel_plane->wm.bytes_per_pixel = | ||
3668 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? | ||
3669 | drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size; | ||
3670 | intel_plane->wm.y_bytes_per_pixel = | ||
3671 | (fb && fb->pixel_format == DRM_FORMAT_NV12) ? | ||
3672 | drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0; | ||
3673 | |||
3674 | /* | ||
3675 | * Framebuffer can be NULL on plane disable, but it does not | ||
3676 | * matter for watermarks if we assume no tiling in that case. | ||
3677 | */ | ||
3678 | if (fb) | ||
3679 | intel_plane->wm.tiling = fb->modifier[0]; | ||
3680 | intel_plane->wm.rotation = plane->state->rotation; | ||
3681 | |||
3682 | skl_update_wm(crtc); | ||
3683 | } | ||
3684 | |||
3676 | static void ilk_update_wm(struct drm_crtc *crtc) | 3685 | static void ilk_update_wm(struct drm_crtc *crtc) |
3677 | { | 3686 | { |
3678 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3687 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -3688,18 +3697,6 @@ static void ilk_update_wm(struct drm_crtc *crtc) | |||
3688 | 3697 | ||
3689 | WARN_ON(cstate->base.active != intel_crtc->active); | 3698 | WARN_ON(cstate->base.active != intel_crtc->active); |
3690 | 3699 | ||
3691 | /* | ||
3692 | * IVB workaround: must disable low power watermarks for at least | ||
3693 | * one frame before enabling scaling. LP watermarks can be re-enabled | ||
3694 | * when scaling is disabled. | ||
3695 | * | ||
3696 | * WaCxSRDisabledForSpriteScaling:ivb | ||
3697 | */ | ||
3698 | if (cstate->disable_lp_wm) { | ||
3699 | ilk_disable_lp_wm(dev); | ||
3700 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
3701 | } | ||
3702 | |||
3703 | intel_compute_pipe_wm(cstate, &pipe_wm); | 3700 | intel_compute_pipe_wm(cstate, &pipe_wm); |
3704 | 3701 | ||
3705 | if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm))) | 3702 | if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm))) |
@@ -3731,6 +3728,28 @@ static void ilk_update_wm(struct drm_crtc *crtc) | |||
3731 | ilk_write_wm_values(dev_priv, &results); | 3728 | ilk_write_wm_values(dev_priv, &results); |
3732 | } | 3729 | } |
3733 | 3730 | ||
3731 | static void | ||
3732 | ilk_update_sprite_wm(struct drm_plane *plane, | ||
3733 | struct drm_crtc *crtc, | ||
3734 | uint32_t sprite_width, uint32_t sprite_height, | ||
3735 | int pixel_size, bool enabled, bool scaled) | ||
3736 | { | ||
3737 | struct drm_device *dev = plane->dev; | ||
3738 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
3739 | |||
3740 | /* | ||
3741 | * IVB workaround: must disable low power watermarks for at least | ||
3742 | * one frame before enabling scaling. LP watermarks can be re-enabled | ||
3743 | * when scaling is disabled. | ||
3744 | * | ||
3745 | * WaCxSRDisabledForSpriteScaling:ivb | ||
3746 | */ | ||
3747 | if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev)) | ||
3748 | intel_wait_for_vblank(dev, intel_plane->pipe); | ||
3749 | |||
3750 | ilk_update_wm(crtc); | ||
3751 | } | ||
3752 | |||
3734 | static void skl_pipe_wm_active_state(uint32_t val, | 3753 | static void skl_pipe_wm_active_state(uint32_t val, |
3735 | struct skl_pipe_wm *active, | 3754 | struct skl_pipe_wm *active, |
3736 | bool is_transwm, | 3755 | bool is_transwm, |
@@ -4108,6 +4127,21 @@ void intel_update_watermarks(struct drm_crtc *crtc) | |||
4108 | dev_priv->display.update_wm(crtc); | 4127 | dev_priv->display.update_wm(crtc); |
4109 | } | 4128 | } |
4110 | 4129 | ||
4130 | void intel_update_sprite_watermarks(struct drm_plane *plane, | ||
4131 | struct drm_crtc *crtc, | ||
4132 | uint32_t sprite_width, | ||
4133 | uint32_t sprite_height, | ||
4134 | int pixel_size, | ||
4135 | bool enabled, bool scaled) | ||
4136 | { | ||
4137 | struct drm_i915_private *dev_priv = plane->dev->dev_private; | ||
4138 | |||
4139 | if (dev_priv->display.update_sprite_wm) | ||
4140 | dev_priv->display.update_sprite_wm(plane, crtc, | ||
4141 | sprite_width, sprite_height, | ||
4142 | pixel_size, enabled, scaled); | ||
4143 | } | ||
4144 | |||
4111 | /** | 4145 | /** |
4112 | * Lock protecting IPS related data structures | 4146 | * Lock protecting IPS related data structures |
4113 | */ | 4147 | */ |
@@ -7018,10 +7052,8 @@ void intel_init_pm(struct drm_device *dev) | |||
7018 | if (IS_BROXTON(dev)) | 7052 | if (IS_BROXTON(dev)) |
7019 | dev_priv->display.init_clock_gating = | 7053 | dev_priv->display.init_clock_gating = |
7020 | bxt_init_clock_gating; | 7054 | bxt_init_clock_gating; |
7021 | else if (IS_SKYLAKE(dev)) | ||
7022 | dev_priv->display.init_clock_gating = | ||
7023 | skl_init_clock_gating; | ||
7024 | dev_priv->display.update_wm = skl_update_wm; | 7055 | dev_priv->display.update_wm = skl_update_wm; |
7056 | dev_priv->display.update_sprite_wm = skl_update_sprite_wm; | ||
7025 | } else if (HAS_PCH_SPLIT(dev)) { | 7057 | } else if (HAS_PCH_SPLIT(dev)) { |
7026 | ilk_setup_wm_latency(dev); | 7058 | ilk_setup_wm_latency(dev); |
7027 | 7059 | ||
@@ -7030,6 +7062,7 @@ void intel_init_pm(struct drm_device *dev) | |||
7030 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && | 7062 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && |
7031 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { | 7063 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { |
7032 | dev_priv->display.update_wm = ilk_update_wm; | 7064 | dev_priv->display.update_wm = ilk_update_wm; |
7065 | dev_priv->display.update_sprite_wm = ilk_update_sprite_wm; | ||
7033 | } else { | 7066 | } else { |
7034 | DRM_DEBUG_KMS("Failed to read display plane latency. " | 7067 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
7035 | "Disable CxSR\n"); | 7068 | "Disable CxSR\n"); |