]> Git Repo - J-linux.git/blob - drivers/gpu/drm/i915/display/hsw_ips.c
Merge tag 'x86_cleanups_for_v6.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[J-linux.git] / drivers / gpu / drm / i915 / display / hsw_ips.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5
6 #include "hsw_ips.h"
7 #include "i915_drv.h"
8 #include "i915_reg.h"
9 #include "intel_de.h"
10 #include "intel_display_types.h"
11 #include "intel_pcode.h"
12
13 static void hsw_ips_enable(const struct intel_crtc_state *crtc_state)
14 {
15         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
16         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
17
18         if (!crtc_state->ips_enabled)
19                 return;
20
21         /*
22          * We can only enable IPS after we enable a plane and wait for a vblank
23          * This function is called from post_plane_update, which is run after
24          * a vblank wait.
25          */
26         drm_WARN_ON(&i915->drm,
27                     !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
28
29         if (IS_BROADWELL(i915)) {
30                 drm_WARN_ON(&i915->drm,
31                             snb_pcode_write(i915, DISPLAY_IPS_CONTROL,
32                                             IPS_ENABLE | IPS_PCODE_CONTROL));
33                 /*
34                  * Quoting Art Runyan: "its not safe to expect any particular
35                  * value in IPS_CTL bit 31 after enabling IPS through the
36                  * mailbox." Moreover, the mailbox may return a bogus state,
37                  * so we need to just enable it and continue on.
38                  */
39         } else {
40                 intel_de_write(i915, IPS_CTL, IPS_ENABLE);
41                 /*
42                  * The bit only becomes 1 in the next vblank, so this wait here
43                  * is essentially intel_wait_for_vblank. If we don't have this
44                  * and don't wait for vblanks until the end of crtc_enable, then
45                  * the HW state readout code will complain that the expected
46                  * IPS_CTL value is not the one we read.
47                  */
48                 if (intel_de_wait_for_set(i915, IPS_CTL, IPS_ENABLE, 50))
49                         drm_err(&i915->drm,
50                                 "Timed out waiting for IPS enable\n");
51         }
52 }
53
54 bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
55 {
56         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
57         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
58         bool need_vblank_wait = false;
59
60         if (!crtc_state->ips_enabled)
61                 return need_vblank_wait;
62
63         if (IS_BROADWELL(i915)) {
64                 drm_WARN_ON(&i915->drm,
65                             snb_pcode_write(i915, DISPLAY_IPS_CONTROL, 0));
66                 /*
67                  * Wait for PCODE to finish disabling IPS. The BSpec specified
68                  * 42ms timeout value leads to occasional timeouts so use 100ms
69                  * instead.
70                  */
71                 if (intel_de_wait_for_clear(i915, IPS_CTL, IPS_ENABLE, 100))
72                         drm_err(&i915->drm,
73                                 "Timed out waiting for IPS disable\n");
74         } else {
75                 intel_de_write(i915, IPS_CTL, 0);
76                 intel_de_posting_read(i915, IPS_CTL);
77         }
78
79         /* We need to wait for a vblank before we can disable the plane. */
80         need_vblank_wait = true;
81
82         return need_vblank_wait;
83 }
84
85 static bool hsw_ips_need_disable(struct intel_atomic_state *state,
86                                  struct intel_crtc *crtc)
87 {
88         struct drm_i915_private *i915 = to_i915(state->base.dev);
89         const struct intel_crtc_state *old_crtc_state =
90                 intel_atomic_get_old_crtc_state(state, crtc);
91         const struct intel_crtc_state *new_crtc_state =
92                 intel_atomic_get_new_crtc_state(state, crtc);
93
94         if (!old_crtc_state->ips_enabled)
95                 return false;
96
97         if (intel_crtc_needs_modeset(new_crtc_state))
98                 return true;
99
100         /*
101          * Workaround : Do not read or write the pipe palette/gamma data while
102          * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
103          *
104          * Disable IPS before we program the LUT.
105          */
106         if (IS_HASWELL(i915) &&
107             (new_crtc_state->uapi.color_mgmt_changed ||
108              new_crtc_state->update_pipe) &&
109             new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
110                 return true;
111
112         return !new_crtc_state->ips_enabled;
113 }
114
115 bool hsw_ips_pre_update(struct intel_atomic_state *state,
116                         struct intel_crtc *crtc)
117 {
118         const struct intel_crtc_state *old_crtc_state =
119                 intel_atomic_get_old_crtc_state(state, crtc);
120
121         if (!hsw_ips_need_disable(state, crtc))
122                 return false;
123
124         return hsw_ips_disable(old_crtc_state);
125 }
126
127 static bool hsw_ips_need_enable(struct intel_atomic_state *state,
128                                 struct intel_crtc *crtc)
129 {
130         struct drm_i915_private *i915 = to_i915(state->base.dev);
131         const struct intel_crtc_state *old_crtc_state =
132                 intel_atomic_get_old_crtc_state(state, crtc);
133         const struct intel_crtc_state *new_crtc_state =
134                 intel_atomic_get_new_crtc_state(state, crtc);
135
136         if (!new_crtc_state->ips_enabled)
137                 return false;
138
139         if (intel_crtc_needs_modeset(new_crtc_state))
140                 return true;
141
142         /*
143          * Workaround : Do not read or write the pipe palette/gamma data while
144          * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
145          *
146          * Re-enable IPS after the LUT has been programmed.
147          */
148         if (IS_HASWELL(i915) &&
149             (new_crtc_state->uapi.color_mgmt_changed ||
150              new_crtc_state->update_pipe) &&
151             new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
152                 return true;
153
154         /*
155          * We can't read out IPS on broadwell, assume the worst and
156          * forcibly enable IPS on the first fastset.
157          */
158         if (new_crtc_state->update_pipe && old_crtc_state->inherited)
159                 return true;
160
161         return !old_crtc_state->ips_enabled;
162 }
163
164 void hsw_ips_post_update(struct intel_atomic_state *state,
165                          struct intel_crtc *crtc)
166 {
167         const struct intel_crtc_state *new_crtc_state =
168                 intel_atomic_get_new_crtc_state(state, crtc);
169
170         if (!hsw_ips_need_enable(state, crtc))
171                 return;
172
173         hsw_ips_enable(new_crtc_state);
174 }
175
176 /* IPS only exists on ULT machines and is tied to pipe A. */
177 bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
178 {
179         return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
180 }
181
182 bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
183 {
184         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
185         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
186
187         /* IPS only exists on ULT machines and is tied to pipe A. */
188         if (!hsw_crtc_supports_ips(crtc))
189                 return false;
190
191         if (!i915->params.enable_ips)
192                 return false;
193
194         if (crtc_state->pipe_bpp > 24)
195                 return false;
196
197         /*
198          * We compare against max which means we must take
199          * the increased cdclk requirement into account when
200          * calculating the new cdclk.
201          *
202          * Should measure whether using a lower cdclk w/o IPS
203          */
204         if (IS_BROADWELL(i915) &&
205             crtc_state->pixel_rate > i915->max_cdclk_freq * 95 / 100)
206                 return false;
207
208         return true;
209 }
210
211 int hsw_ips_compute_config(struct intel_atomic_state *state,
212                            struct intel_crtc *crtc)
213 {
214         struct drm_i915_private *i915 = to_i915(state->base.dev);
215         struct intel_crtc_state *crtc_state =
216                 intel_atomic_get_new_crtc_state(state, crtc);
217
218         crtc_state->ips_enabled = false;
219
220         if (!hsw_crtc_state_ips_capable(crtc_state))
221                 return 0;
222
223         /*
224          * When IPS gets enabled, the pipe CRC changes. Since IPS gets
225          * enabled and disabled dynamically based on package C states,
226          * user space can't make reliable use of the CRCs, so let's just
227          * completely disable it.
228          */
229         if (crtc_state->crc_enabled)
230                 return 0;
231
232         /* IPS should be fine as long as at least one plane is enabled. */
233         if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
234                 return 0;
235
236         if (IS_BROADWELL(i915)) {
237                 const struct intel_cdclk_state *cdclk_state;
238
239                 cdclk_state = intel_atomic_get_cdclk_state(state);
240                 if (IS_ERR(cdclk_state))
241                         return PTR_ERR(cdclk_state);
242
243                 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
244                 if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100)
245                         return 0;
246         }
247
248         crtc_state->ips_enabled = true;
249
250         return 0;
251 }
252
253 void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
254 {
255         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
256         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
257
258         if (!hsw_crtc_supports_ips(crtc))
259                 return;
260
261         if (IS_HASWELL(i915)) {
262                 crtc_state->ips_enabled = intel_de_read(i915, IPS_CTL) & IPS_ENABLE;
263         } else {
264                 /*
265                  * We cannot readout IPS state on broadwell, set to
266                  * true so we can set it to a defined state on first
267                  * commit.
268                  */
269                 crtc_state->ips_enabled = true;
270         }
271 }
This page took 0.041264 seconds and 4 git commands to generate.