Merge tag 'mfd-next-5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_dsb.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2019 Intel Corporation
4  *
5  */
6
7 #include "i915_drv.h"
8 #include "intel_display_types.h"
9
10 #define DSB_BUF_SIZE    (2 * PAGE_SIZE)
11
12 /**
13  * DOC: DSB
14  *
15  * A DSB (Display State Buffer) is a queue of MMIO instructions in the memory
16  * which can be offloaded to DSB HW in Display Controller. DSB HW is a DMA
17  * engine that can be programmed to download the DSB from memory.
18  * It allows driver to batch submit display HW programming. This helps to
19  * reduce loading time and CPU activity, thereby making the context switch
20  * faster. DSB Support added from Gen12 Intel graphics based platform.
21  *
22  * DSB's can access only the pipe, plane, and transcoder Data Island Packet
23  * registers.
24  *
25  * DSB HW can support only register writes (both indexed and direct MMIO
26  * writes). There are no registers reads possible with DSB HW engine.
27  */
28
29 /* DSB opcodes. */
30 #define DSB_OPCODE_SHIFT                24
31 #define DSB_OPCODE_MMIO_WRITE           0x1
32 #define DSB_OPCODE_INDEXED_WRITE        0x9
33 #define DSB_BYTE_EN                     0xF
34 #define DSB_BYTE_EN_SHIFT               20
35 #define DSB_REG_VALUE_MASK              0xfffff
36
37 static bool is_dsb_busy(struct drm_i915_private *i915, enum pipe pipe,
38                         enum dsb_id id)
39 {
40         return DSB_STATUS & intel_de_read(i915, DSB_CTRL(pipe, id));
41 }
42
43 static bool intel_dsb_enable_engine(struct drm_i915_private *i915,
44                                     enum pipe pipe, enum dsb_id id)
45 {
46         u32 dsb_ctrl;
47
48         dsb_ctrl = intel_de_read(i915, DSB_CTRL(pipe, id));
49         if (DSB_STATUS & dsb_ctrl) {
50                 drm_dbg_kms(&i915->drm, "DSB engine is busy.\n");
51                 return false;
52         }
53
54         dsb_ctrl |= DSB_ENABLE;
55         intel_de_write(i915, DSB_CTRL(pipe, id), dsb_ctrl);
56
57         intel_de_posting_read(i915, DSB_CTRL(pipe, id));
58         return true;
59 }
60
61 static bool intel_dsb_disable_engine(struct drm_i915_private *i915,
62                                      enum pipe pipe, enum dsb_id id)
63 {
64         u32 dsb_ctrl;
65
66         dsb_ctrl = intel_de_read(i915, DSB_CTRL(pipe, id));
67         if (DSB_STATUS & dsb_ctrl) {
68                 drm_dbg_kms(&i915->drm, "DSB engine is busy.\n");
69                 return false;
70         }
71
72         dsb_ctrl &= ~DSB_ENABLE;
73         intel_de_write(i915, DSB_CTRL(pipe, id), dsb_ctrl);
74
75         intel_de_posting_read(i915, DSB_CTRL(pipe, id));
76         return true;
77 }
78
79 /**
80  * intel_dsb_indexed_reg_write() -Write to the DSB context for auto
81  * increment register.
82  * @crtc_state: intel_crtc_state structure
83  * @reg: register address.
84  * @val: value.
85  *
86  * This function is used for writing register-value pair in command
87  * buffer of DSB for auto-increment register. During command buffer overflow,
88  * a warning is thrown and rest all erroneous condition register programming
89  * is done through mmio write.
90  */
91
92 void intel_dsb_indexed_reg_write(const struct intel_crtc_state *crtc_state,
93                                  i915_reg_t reg, u32 val)
94 {
95         struct intel_dsb *dsb = crtc_state->dsb;
96         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
97         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
98         u32 *buf;
99         u32 reg_val;
100
101         if (!dsb) {
102                 intel_de_write(dev_priv, reg, val);
103                 return;
104         }
105         buf = dsb->cmd_buf;
106         if (drm_WARN_ON(&dev_priv->drm, dsb->free_pos >= DSB_BUF_SIZE)) {
107                 drm_dbg_kms(&dev_priv->drm, "DSB buffer overflow\n");
108                 return;
109         }
110
111         /*
112          * For example the buffer will look like below for 3 dwords for auto
113          * increment register:
114          * +--------------------------------------------------------+
115          * | size = 3 | offset &| value1 | value2 | value3 | zero   |
116          * |          | opcode  |        |        |        |        |
117          * +--------------------------------------------------------+
118          * +          +         +        +        +        +        +
119          * 0          4         8        12       16       20       24
120          * Byte
121          *
122          * As every instruction is 8 byte aligned the index of dsb instruction
123          * will start always from even number while dealing with u32 array. If
124          * we are writing odd no of dwords, Zeros will be added in the end for
125          * padding.
126          */
127         reg_val = buf[dsb->ins_start_offset + 1] & DSB_REG_VALUE_MASK;
128         if (reg_val != i915_mmio_reg_offset(reg)) {
129                 /* Every instruction should be 8 byte aligned. */
130                 dsb->free_pos = ALIGN(dsb->free_pos, 2);
131
132                 dsb->ins_start_offset = dsb->free_pos;
133
134                 /* Update the size. */
135                 buf[dsb->free_pos++] = 1;
136
137                 /* Update the opcode and reg. */
138                 buf[dsb->free_pos++] = (DSB_OPCODE_INDEXED_WRITE  <<
139                                         DSB_OPCODE_SHIFT) |
140                                         i915_mmio_reg_offset(reg);
141
142                 /* Update the value. */
143                 buf[dsb->free_pos++] = val;
144         } else {
145                 /* Update the new value. */
146                 buf[dsb->free_pos++] = val;
147
148                 /* Update the size. */
149                 buf[dsb->ins_start_offset]++;
150         }
151
152         /* if number of data words is odd, then the last dword should be 0.*/
153         if (dsb->free_pos & 0x1)
154                 buf[dsb->free_pos] = 0;
155 }
156
157 /**
158  * intel_dsb_reg_write() -Write to the DSB context for normal
159  * register.
160  * @crtc_state: intel_crtc_state structure
161  * @reg: register address.
162  * @val: value.
163  *
164  * This function is used for writing register-value pair in command
165  * buffer of DSB. During command buffer overflow, a warning  is thrown
166  * and rest all erroneous condition register programming is done
167  * through mmio write.
168  */
169 void intel_dsb_reg_write(const struct intel_crtc_state *crtc_state,
170                          i915_reg_t reg, u32 val)
171 {
172         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
173         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
174         struct intel_dsb *dsb;
175         u32 *buf;
176
177         dsb = crtc_state->dsb;
178         if (!dsb) {
179                 intel_de_write(dev_priv, reg, val);
180                 return;
181         }
182
183         buf = dsb->cmd_buf;
184         if (drm_WARN_ON(&dev_priv->drm, dsb->free_pos >= DSB_BUF_SIZE)) {
185                 drm_dbg_kms(&dev_priv->drm, "DSB buffer overflow\n");
186                 return;
187         }
188
189         dsb->ins_start_offset = dsb->free_pos;
190         buf[dsb->free_pos++] = val;
191         buf[dsb->free_pos++] = (DSB_OPCODE_MMIO_WRITE  << DSB_OPCODE_SHIFT) |
192                                (DSB_BYTE_EN << DSB_BYTE_EN_SHIFT) |
193                                i915_mmio_reg_offset(reg);
194 }
195
196 /**
197  * intel_dsb_commit() - Trigger workload execution of DSB.
198  * @crtc_state: intel_crtc_state structure
199  *
200  * This function is used to do actual write to hardware using DSB.
201  * On errors, fall back to MMIO. Also this function help to reset the context.
202  */
203 void intel_dsb_commit(const struct intel_crtc_state *crtc_state)
204 {
205         struct intel_dsb *dsb = crtc_state->dsb;
206         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
207         struct drm_device *dev = crtc->base.dev;
208         struct drm_i915_private *dev_priv = to_i915(dev);
209         enum pipe pipe = crtc->pipe;
210         u32 tail;
211
212         if (!(dsb && dsb->free_pos))
213                 return;
214
215         if (!intel_dsb_enable_engine(dev_priv, pipe, dsb->id))
216                 goto reset;
217
218         if (is_dsb_busy(dev_priv, pipe, dsb->id)) {
219                 drm_err(&dev_priv->drm,
220                         "HEAD_PTR write failed - dsb engine is busy.\n");
221                 goto reset;
222         }
223         intel_de_write(dev_priv, DSB_HEAD(pipe, dsb->id),
224                        i915_ggtt_offset(dsb->vma));
225
226         tail = ALIGN(dsb->free_pos * 4, CACHELINE_BYTES);
227         if (tail > dsb->free_pos * 4)
228                 memset(&dsb->cmd_buf[dsb->free_pos], 0,
229                        (tail - dsb->free_pos * 4));
230
231         if (is_dsb_busy(dev_priv, pipe, dsb->id)) {
232                 drm_err(&dev_priv->drm,
233                         "TAIL_PTR write failed - dsb engine is busy.\n");
234                 goto reset;
235         }
236         drm_dbg_kms(&dev_priv->drm,
237                     "DSB execution started - head 0x%x, tail 0x%x\n",
238                     i915_ggtt_offset(dsb->vma), tail);
239         intel_de_write(dev_priv, DSB_TAIL(pipe, dsb->id),
240                        i915_ggtt_offset(dsb->vma) + tail);
241         if (wait_for(!is_dsb_busy(dev_priv, pipe, dsb->id), 1)) {
242                 drm_err(&dev_priv->drm,
243                         "Timed out waiting for DSB workload completion.\n");
244                 goto reset;
245         }
246
247 reset:
248         dsb->free_pos = 0;
249         dsb->ins_start_offset = 0;
250         intel_dsb_disable_engine(dev_priv, pipe, dsb->id);
251 }
252
253 /**
254  * intel_dsb_prepare() - Allocate, pin and map the DSB command buffer.
255  * @crtc_state: intel_crtc_state structure to prepare associated dsb instance.
256  *
257  * This function prepare the command buffer which is used to store dsb
258  * instructions with data.
259  */
260 void intel_dsb_prepare(struct intel_crtc_state *crtc_state)
261 {
262         struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
263         struct drm_i915_private *i915 = to_i915(crtc->base.dev);
264         struct intel_dsb *dsb;
265         struct drm_i915_gem_object *obj;
266         struct i915_vma *vma;
267         u32 *buf;
268         intel_wakeref_t wakeref;
269
270         if (!HAS_DSB(i915))
271                 return;
272
273         dsb = kmalloc(sizeof(*dsb), GFP_KERNEL);
274         if (!dsb) {
275                 drm_err(&i915->drm, "DSB object creation failed\n");
276                 return;
277         }
278
279         wakeref = intel_runtime_pm_get(&i915->runtime_pm);
280
281         obj = i915_gem_object_create_internal(i915, DSB_BUF_SIZE);
282         if (IS_ERR(obj)) {
283                 drm_err(&i915->drm, "Gem object creation failed\n");
284                 kfree(dsb);
285                 goto out;
286         }
287
288         vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
289         if (IS_ERR(vma)) {
290                 drm_err(&i915->drm, "Vma creation failed\n");
291                 i915_gem_object_put(obj);
292                 kfree(dsb);
293                 goto out;
294         }
295
296         buf = i915_gem_object_pin_map(vma->obj, I915_MAP_WC);
297         if (IS_ERR(buf)) {
298                 drm_err(&i915->drm, "Command buffer creation failed\n");
299                 i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP);
300                 kfree(dsb);
301                 goto out;
302         }
303
304         dsb->id = DSB1;
305         dsb->vma = vma;
306         dsb->cmd_buf = buf;
307         dsb->free_pos = 0;
308         dsb->ins_start_offset = 0;
309         crtc_state->dsb = dsb;
310 out:
311         intel_runtime_pm_put(&i915->runtime_pm, wakeref);
312 }
313
314 /**
315  * intel_dsb_cleanup() - To cleanup DSB context.
316  * @crtc_state: intel_crtc_state structure to cleanup associated dsb instance.
317  *
318  * This function cleanup the DSB context by unpinning and releasing
319  * the VMA object associated with it.
320  */
321 void intel_dsb_cleanup(struct intel_crtc_state *crtc_state)
322 {
323         if (!crtc_state->dsb)
324                 return;
325
326         i915_vma_unpin_and_release(&crtc_state->dsb->vma, I915_VMA_RELEASE_MAP);
327         kfree(crtc_state->dsb);
328         crtc_state->dsb = NULL;
329 }