]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/display/hsw_ips.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[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         u32 val;
18
19         if (!crtc_state->ips_enabled)
20                 return;
21
22         /*
23          * We can only enable IPS after we enable a plane and wait for a vblank
24          * This function is called from post_plane_update, which is run after
25          * a vblank wait.
26          */
27         drm_WARN_ON(&i915->drm,
28                     !(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
29
30         val = IPS_ENABLE;
31
32         if (i915->display.ips.false_color)
33                 val |= IPS_FALSE_COLOR;
34
35         if (IS_BROADWELL(i915)) {
36                 drm_WARN_ON(&i915->drm,
37                             snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL,
38                                             val | IPS_PCODE_CONTROL));
39                 /*
40                  * Quoting Art Runyan: "its not safe to expect any particular
41                  * value in IPS_CTL bit 31 after enabling IPS through the
42                  * mailbox." Moreover, the mailbox may return a bogus state,
43                  * so we need to just enable it and continue on.
44                  */
45         } else {
46                 intel_de_write(i915, IPS_CTL, val);
47                 /*
48                  * The bit only becomes 1 in the next vblank, so this wait here
49                  * is essentially intel_wait_for_vblank. If we don't have this
50                  * and don't wait for vblanks until the end of crtc_enable, then
51                  * the HW state readout code will complain that the expected
52                  * IPS_CTL value is not the one we read.
53                  */
54                 if (intel_de_wait_for_set(i915, IPS_CTL, IPS_ENABLE, 50))
55                         drm_err(&i915->drm,
56                                 "Timed out waiting for IPS enable\n");
57         }
58 }
59
60 bool hsw_ips_disable(const struct intel_crtc_state *crtc_state)
61 {
62         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
63         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
64         bool need_vblank_wait = false;
65
66         if (!crtc_state->ips_enabled)
67                 return need_vblank_wait;
68
69         if (IS_BROADWELL(i915)) {
70                 drm_WARN_ON(&i915->drm,
71                             snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, 0));
72                 /*
73                  * Wait for PCODE to finish disabling IPS. The BSpec specified
74                  * 42ms timeout value leads to occasional timeouts so use 100ms
75                  * instead.
76                  */
77                 if (intel_de_wait_for_clear(i915, IPS_CTL, IPS_ENABLE, 100))
78                         drm_err(&i915->drm,
79                                 "Timed out waiting for IPS disable\n");
80         } else {
81                 intel_de_write(i915, IPS_CTL, 0);
82                 intel_de_posting_read(i915, IPS_CTL);
83         }
84
85         /* We need to wait for a vblank before we can disable the plane. */
86         need_vblank_wait = true;
87
88         return need_vblank_wait;
89 }
90
91 static bool hsw_ips_need_disable(struct intel_atomic_state *state,
92                                  struct intel_crtc *crtc)
93 {
94         struct drm_i915_private *i915 = to_i915(state->base.dev);
95         const struct intel_crtc_state *old_crtc_state =
96                 intel_atomic_get_old_crtc_state(state, crtc);
97         const struct intel_crtc_state *new_crtc_state =
98                 intel_atomic_get_new_crtc_state(state, crtc);
99
100         if (!old_crtc_state->ips_enabled)
101                 return false;
102
103         if (intel_crtc_needs_modeset(new_crtc_state))
104                 return true;
105
106         /*
107          * Workaround : Do not read or write the pipe palette/gamma data while
108          * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
109          *
110          * Disable IPS before we program the LUT.
111          */
112         if (IS_HASWELL(i915) &&
113             intel_crtc_needs_color_update(new_crtc_state) &&
114             new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
115                 return true;
116
117         return !new_crtc_state->ips_enabled;
118 }
119
120 bool hsw_ips_pre_update(struct intel_atomic_state *state,
121                         struct intel_crtc *crtc)
122 {
123         const struct intel_crtc_state *old_crtc_state =
124                 intel_atomic_get_old_crtc_state(state, crtc);
125
126         if (!hsw_ips_need_disable(state, crtc))
127                 return false;
128
129         return hsw_ips_disable(old_crtc_state);
130 }
131
132 static bool hsw_ips_need_enable(struct intel_atomic_state *state,
133                                 struct intel_crtc *crtc)
134 {
135         struct drm_i915_private *i915 = to_i915(state->base.dev);
136         const struct intel_crtc_state *old_crtc_state =
137                 intel_atomic_get_old_crtc_state(state, crtc);
138         const struct intel_crtc_state *new_crtc_state =
139                 intel_atomic_get_new_crtc_state(state, crtc);
140
141         if (!new_crtc_state->ips_enabled)
142                 return false;
143
144         if (intel_crtc_needs_modeset(new_crtc_state))
145                 return true;
146
147         /*
148          * Workaround : Do not read or write the pipe palette/gamma data while
149          * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
150          *
151          * Re-enable IPS after the LUT has been programmed.
152          */
153         if (IS_HASWELL(i915) &&
154             intel_crtc_needs_color_update(new_crtc_state) &&
155             new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
156                 return true;
157
158         /*
159          * We can't read out IPS on broadwell, assume the worst and
160          * forcibly enable IPS on the first fastset.
161          */
162         if (intel_crtc_needs_fastset(new_crtc_state) && old_crtc_state->inherited)
163                 return true;
164
165         return !old_crtc_state->ips_enabled;
166 }
167
168 void hsw_ips_post_update(struct intel_atomic_state *state,
169                          struct intel_crtc *crtc)
170 {
171         const struct intel_crtc_state *new_crtc_state =
172                 intel_atomic_get_new_crtc_state(state, crtc);
173
174         if (!hsw_ips_need_enable(state, crtc))
175                 return;
176
177         hsw_ips_enable(new_crtc_state);
178 }
179
180 /* IPS only exists on ULT machines and is tied to pipe A. */
181 bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
182 {
183         return HAS_IPS(to_i915(crtc->base.dev)) && crtc->pipe == PIPE_A;
184 }
185
186 bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
187 {
188         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
189         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
190
191         /* IPS only exists on ULT machines and is tied to pipe A. */
192         if (!hsw_crtc_supports_ips(crtc))
193                 return false;
194
195         if (!i915->params.enable_ips)
196                 return false;
197
198         if (crtc_state->pipe_bpp > 24)
199                 return false;
200
201         /*
202          * We compare against max which means we must take
203          * the increased cdclk requirement into account when
204          * calculating the new cdclk.
205          *
206          * Should measure whether using a lower cdclk w/o IPS
207          */
208         if (IS_BROADWELL(i915) &&
209             crtc_state->pixel_rate > i915->display.cdclk.max_cdclk_freq * 95 / 100)
210                 return false;
211
212         return true;
213 }
214
215 int hsw_ips_compute_config(struct intel_atomic_state *state,
216                            struct intel_crtc *crtc)
217 {
218         struct drm_i915_private *i915 = to_i915(state->base.dev);
219         struct intel_crtc_state *crtc_state =
220                 intel_atomic_get_new_crtc_state(state, crtc);
221
222         crtc_state->ips_enabled = false;
223
224         if (!hsw_crtc_state_ips_capable(crtc_state))
225                 return 0;
226
227         /*
228          * When IPS gets enabled, the pipe CRC changes. Since IPS gets
229          * enabled and disabled dynamically based on package C states,
230          * user space can't make reliable use of the CRCs, so let's just
231          * completely disable it.
232          */
233         if (crtc_state->crc_enabled)
234                 return 0;
235
236         /* IPS should be fine as long as at least one plane is enabled. */
237         if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)))
238                 return 0;
239
240         if (IS_BROADWELL(i915)) {
241                 const struct intel_cdclk_state *cdclk_state;
242
243                 cdclk_state = intel_atomic_get_cdclk_state(state);
244                 if (IS_ERR(cdclk_state))
245                         return PTR_ERR(cdclk_state);
246
247                 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
248                 if (crtc_state->pixel_rate > cdclk_state->logical.cdclk * 95 / 100)
249                         return 0;
250         }
251
252         crtc_state->ips_enabled = true;
253
254         return 0;
255 }
256
257 void hsw_ips_get_config(struct intel_crtc_state *crtc_state)
258 {
259         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
260         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
261
262         if (!hsw_crtc_supports_ips(crtc))
263                 return;
264
265         if (IS_HASWELL(i915)) {
266                 crtc_state->ips_enabled = intel_de_read(i915, IPS_CTL) & IPS_ENABLE;
267         } else {
268                 /*
269                  * We cannot readout IPS state on broadwell, set to
270                  * true so we can set it to a defined state on first
271                  * commit.
272                  */
273                 crtc_state->ips_enabled = true;
274         }
275 }
276
277 static int hsw_ips_debugfs_false_color_get(void *data, u64 *val)
278 {
279         struct intel_crtc *crtc = data;
280         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
281
282         *val = i915->display.ips.false_color;
283
284         return 0;
285 }
286
287 static int hsw_ips_debugfs_false_color_set(void *data, u64 val)
288 {
289         struct intel_crtc *crtc = data;
290         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
291         struct intel_crtc_state *crtc_state;
292         int ret;
293
294         ret = drm_modeset_lock(&crtc->base.mutex, NULL);
295         if (ret)
296                 return ret;
297
298         i915->display.ips.false_color = val;
299
300         crtc_state = to_intel_crtc_state(crtc->base.state);
301
302         if (!crtc_state->hw.active)
303                 goto unlock;
304
305         if (crtc_state->uapi.commit &&
306             !try_wait_for_completion(&crtc_state->uapi.commit->hw_done))
307                 goto unlock;
308
309         hsw_ips_enable(crtc_state);
310
311  unlock:
312         drm_modeset_unlock(&crtc->base.mutex);
313
314         return ret;
315 }
316
317 DEFINE_DEBUGFS_ATTRIBUTE(hsw_ips_debugfs_false_color_fops,
318                          hsw_ips_debugfs_false_color_get,
319                          hsw_ips_debugfs_false_color_set,
320                          "%llu\n");
321
322 static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused)
323 {
324         struct intel_crtc *crtc = m->private;
325         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
326         intel_wakeref_t wakeref;
327
328         wakeref = intel_runtime_pm_get(&i915->runtime_pm);
329
330         seq_printf(m, "Enabled by kernel parameter: %s\n",
331                    str_yes_no(i915->params.enable_ips));
332
333         if (DISPLAY_VER(i915) >= 8) {
334                 seq_puts(m, "Currently: unknown\n");
335         } else {
336                 if (intel_de_read(i915, IPS_CTL) & IPS_ENABLE)
337                         seq_puts(m, "Currently: enabled\n");
338                 else
339                         seq_puts(m, "Currently: disabled\n");
340         }
341
342         intel_runtime_pm_put(&i915->runtime_pm, wakeref);
343
344         return 0;
345 }
346
347 DEFINE_SHOW_ATTRIBUTE(hsw_ips_debugfs_status);
348
349 void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc)
350 {
351         if (!hsw_crtc_supports_ips(crtc))
352                 return;
353
354         debugfs_create_file("i915_ips_false_color", 0644, crtc->base.debugfs_entry,
355                             crtc, &hsw_ips_debugfs_false_color_fops);
356
357         debugfs_create_file("i915_ips_status", 0444, crtc->base.debugfs_entry,
358                             crtc, &hsw_ips_debugfs_status_fops);
359 }
This page took 0.057724 seconds and 4 git commands to generate.