aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2018-03-22 16:18:48 -0400
committerDave Airlie <airlied@redhat.com>2018-03-22 16:18:48 -0400
commit2a2553cc45c889f15a1df0355891a809f17ca43d (patch)
treee5664857265d4c1d47c5191ea0b71d569ba69613
parentf3924ae723d84746546bd74bdefc99c17da2a467 (diff)
parent43bfefedd0281ef476f8154397cd283a710d8baf (diff)
Merge branch 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux into drm-next
A relative large set of various improvements for vmwgfx. Some of them have been around for a while, some are relatively new, but functionality should have been tested in our standalone repo. * 'vmwgfx-next' of git://people.freedesktop.org/~thomash/linux: drm/vmwgfx: Bump version patchlevel and date drm/vmwgfx: use monotonic event timestamps drm/vmwgfx: Unpin the screen object backup buffer when not used drm/vmwgfx: Stricter count of legacy surface device resources drm/vmwgfx: Use kasprintf drm/vmwgfx: Get rid of the device-private suspended member drm/vmwgfx: Improve on hibernation drm/vmwgfx: Avoid pinning fbdev framebuffers drm/vmwgfx: Fix multiple command buffer context use drm/vmwgfx: Use the cpu blit utility for framebuffer to screen target blits drm/vmwgfx: Add a cpu blit utility that can be used for page-backed bos drm/ttm: Export the ttm_k[un]map_atomic_prot API. drm/ttm: Clean up kmap_atomic_prot selection code drm/vmwgfx: Cursor update fixes drm/vmwgfx: Send the correct nonblock option for atomic_commit drm/vmwgfx: Move the stdu vblank event to atomic function drm/vmwgfx: Move screen object page flip to atomic function drm/vmwgfx: Remove drm_crtc_arm_vblank_event from atomic flush drm/vmwgfx: Move surface copy cmd to atomic function drm/vmwgfx: Avoid iterating over display unit if crtc is available
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c85
-rw-r--r--drivers/gpu/drm/vmwgfx/Makefile2
-rw-r--r--drivers/gpu/drm/vmwgfx/device_include/svga_reg.h12
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_blit.c506
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c24
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c57
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c51
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c80
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h64
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c104
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c9
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c177
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h21
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_msg.c13
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_resource.c23
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c163
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c280
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_surface.c8
-rw-r--r--include/drm/ttm/ttm_bo_api.h4
19 files changed, 1227 insertions, 456 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 1f730b3f18e5..2ebbae6067ab 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -255,6 +255,54 @@ static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
255 return 0; 255 return 0;
256} 256}
257 257
258#ifdef CONFIG_X86
259#define __ttm_kmap_atomic_prot(__page, __prot) kmap_atomic_prot(__page, __prot)
260#define __ttm_kunmap_atomic(__addr) kunmap_atomic(__addr)
261#else
262#define __ttm_kmap_atomic_prot(__page, __prot) vmap(&__page, 1, 0, __prot)
263#define __ttm_kunmap_atomic(__addr) vunmap(__addr)
264#endif
265
266
267/**
268 * ttm_kmap_atomic_prot - Efficient kernel map of a single page with
269 * specified page protection.
270 *
271 * @page: The page to map.
272 * @prot: The page protection.
273 *
274 * This function maps a TTM page using the kmap_atomic api if available,
275 * otherwise falls back to vmap. The user must make sure that the
276 * specified page does not have an aliased mapping with a different caching
277 * policy unless the architecture explicitly allows it. Also mapping and
278 * unmapping using this api must be correctly nested. Unmapping should
279 * occur in the reverse order of mapping.
280 */
281void *ttm_kmap_atomic_prot(struct page *page, pgprot_t prot)
282{
283 if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
284 return kmap_atomic(page);
285 else
286 return __ttm_kmap_atomic_prot(page, prot);
287}
288EXPORT_SYMBOL(ttm_kmap_atomic_prot);
289
290/**
291 * ttm_kunmap_atomic_prot - Unmap a page that was mapped using
292 * ttm_kmap_atomic_prot.
293 *
294 * @addr: The virtual address from the map.
295 * @prot: The page protection.
296 */
297void ttm_kunmap_atomic_prot(void *addr, pgprot_t prot)
298{
299 if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
300 kunmap_atomic(addr);
301 else
302 __ttm_kunmap_atomic(addr);
303}
304EXPORT_SYMBOL(ttm_kunmap_atomic_prot);
305
258static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, 306static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
259 unsigned long page, 307 unsigned long page,
260 pgprot_t prot) 308 pgprot_t prot)
@@ -266,28 +314,13 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
266 return -ENOMEM; 314 return -ENOMEM;
267 315
268 src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); 316 src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
269 317 dst = ttm_kmap_atomic_prot(d, prot);
270#ifdef CONFIG_X86
271 dst = kmap_atomic_prot(d, prot);
272#else
273 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
274 dst = vmap(&d, 1, 0, prot);
275 else
276 dst = kmap(d);
277#endif
278 if (!dst) 318 if (!dst)
279 return -ENOMEM; 319 return -ENOMEM;
280 320
281 memcpy_fromio(dst, src, PAGE_SIZE); 321 memcpy_fromio(dst, src, PAGE_SIZE);
282 322
283#ifdef CONFIG_X86 323 ttm_kunmap_atomic_prot(dst, prot);
284 kunmap_atomic(dst);
285#else
286 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
287 vunmap(dst);
288 else
289 kunmap(d);
290#endif
291 324
292 return 0; 325 return 0;
293} 326}
@@ -303,27 +336,13 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
303 return -ENOMEM; 336 return -ENOMEM;
304 337
305 dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); 338 dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
306#ifdef CONFIG_X86 339 src = ttm_kmap_atomic_prot(s, prot);
307 src = kmap_atomic_prot(s, prot);
308#else
309 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
310 src = vmap(&s, 1, 0, prot);
311 else
312 src = kmap(s);
313#endif
314 if (!src) 340 if (!src)
315 return -ENOMEM; 341 return -ENOMEM;
316 342
317 memcpy_toio(dst, src, PAGE_SIZE); 343 memcpy_toio(dst, src, PAGE_SIZE);
318 344
319#ifdef CONFIG_X86 345 ttm_kunmap_atomic_prot(src, prot);
320 kunmap_atomic(src);
321#else
322 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
323 vunmap(src);
324 else
325 kunmap(s);
326#endif
327 346
328 return 0; 347 return 0;
329} 348}
diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index ad80211e1098..794cc9d5c9b0 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -7,6 +7,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
7 vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \ 7 vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
8 vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \ 8 vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
9 vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \ 9 vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
10 vmwgfx_simple_resource.o vmwgfx_va.o 10 vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o
11 11
12obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o 12obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h b/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h
index 6e0ccb70a700..88e72bf9a534 100644
--- a/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h
+++ b/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h
@@ -372,6 +372,14 @@ SVGAGuestPtr;
372 * PA, not biased by the offset. When the command buffer is finished 372 * PA, not biased by the offset. When the command buffer is finished
373 * the guest should not read the offset field as there is no guarantee 373 * the guest should not read the offset field as there is no guarantee
374 * what it will set to. 374 * what it will set to.
375 *
376 * When the SVGA_CAP_HP_CMD_QUEUE cap bit is set a new command queue
377 * SVGA_CB_CONTEXT_1 is available. Commands submitted to this queue
378 * will be executed as quickly as possible by the SVGA device
379 * potentially before already queued commands on SVGA_CB_CONTEXT_0.
380 * The SVGA device guarantees that any command buffers submitted to
381 * SVGA_CB_CONTEXT_0 will be executed after any _already_ submitted
382 * command buffers to SVGA_CB_CONTEXT_1.
375 */ 383 */
376 384
377#define SVGA_CB_MAX_SIZE (512 * 1024) /* 512 KB */ 385#define SVGA_CB_MAX_SIZE (512 * 1024) /* 512 KB */
@@ -382,7 +390,8 @@ SVGAGuestPtr;
382typedef enum { 390typedef enum {
383 SVGA_CB_CONTEXT_DEVICE = 0x3f, 391 SVGA_CB_CONTEXT_DEVICE = 0x3f,
384 SVGA_CB_CONTEXT_0 = 0x0, 392 SVGA_CB_CONTEXT_0 = 0x0,
385 SVGA_CB_CONTEXT_MAX = 0x1, 393 SVGA_CB_CONTEXT_1 = 0x1, /* Supported with SVGA_CAP_HP_CMD_QUEUE */
394 SVGA_CB_CONTEXT_MAX = 0x2,
386} SVGACBContext; 395} SVGACBContext;
387 396
388 397
@@ -689,6 +698,7 @@ SVGASignedPoint;
689#define SVGA_CAP_CMD_BUFFERS_2 0x04000000 698#define SVGA_CAP_CMD_BUFFERS_2 0x04000000
690#define SVGA_CAP_GBOBJECTS 0x08000000 699#define SVGA_CAP_GBOBJECTS 0x08000000
691#define SVGA_CAP_DX 0x10000000 700#define SVGA_CAP_DX 0x10000000
701#define SVGA_CAP_HP_CMD_QUEUE 0x20000000
692 702
693#define SVGA_CAP_CMD_RESERVED 0x80000000 703#define SVGA_CAP_CMD_RESERVED 0x80000000
694 704
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
new file mode 100644
index 000000000000..e8c94b19db7b
--- /dev/null
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
@@ -0,0 +1,506 @@
1/**************************************************************************
2 *
3 * Copyright © 2017 VMware, Inc., Palo Alto, CA., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include "vmwgfx_drv.h"
29
30/*
31 * Template that implements find_first_diff() for a generic
32 * unsigned integer type. @size and return value are in bytes.
33 */
34#define VMW_FIND_FIRST_DIFF(_type) \
35static size_t vmw_find_first_diff_ ## _type \
36 (const _type * dst, const _type * src, size_t size)\
37{ \
38 size_t i; \
39 \
40 for (i = 0; i < size; i += sizeof(_type)) { \
41 if (*dst++ != *src++) \
42 break; \
43 } \
44 \
45 return i; \
46}
47
48
49/*
50 * Template that implements find_last_diff() for a generic
51 * unsigned integer type. Pointers point to the item following the
52 * *end* of the area to be examined. @size and return value are in
53 * bytes.
54 */
55#define VMW_FIND_LAST_DIFF(_type) \
56static ssize_t vmw_find_last_diff_ ## _type( \
57 const _type * dst, const _type * src, size_t size) \
58{ \
59 while (size) { \
60 if (*--dst != *--src) \
61 break; \
62 \
63 size -= sizeof(_type); \
64 } \
65 return size; \
66}
67
68
69/*
70 * Instantiate find diff functions for relevant unsigned integer sizes,
71 * assuming that wider integers are faster (including aligning) up to the
72 * architecture native width, which is assumed to be 32 bit unless
73 * CONFIG_64BIT is defined.
74 */
75VMW_FIND_FIRST_DIFF(u8);
76VMW_FIND_LAST_DIFF(u8);
77
78VMW_FIND_FIRST_DIFF(u16);
79VMW_FIND_LAST_DIFF(u16);
80
81VMW_FIND_FIRST_DIFF(u32);
82VMW_FIND_LAST_DIFF(u32);
83
84#ifdef CONFIG_64BIT
85VMW_FIND_FIRST_DIFF(u64);
86VMW_FIND_LAST_DIFF(u64);
87#endif
88
89
90/* We use size aligned copies. This computes (addr - align(addr)) */
91#define SPILL(_var, _type) ((unsigned long) _var & (sizeof(_type) - 1))
92
93
94/*
95 * Template to compute find_first_diff() for a certain integer type
96 * including a head copy for alignment, and adjustment of parameters
97 * for tail find or increased resolution find using an unsigned integer find
98 * of smaller width. If finding is complete, and resolution is sufficient,
99 * the macro executes a return statement. Otherwise it falls through.
100 */
101#define VMW_TRY_FIND_FIRST_DIFF(_type) \
102do { \
103 unsigned int spill = SPILL(dst, _type); \
104 size_t diff_offs; \
105 \
106 if (spill && spill == SPILL(src, _type) && \
107 sizeof(_type) - spill <= size) { \
108 spill = sizeof(_type) - spill; \
109 diff_offs = vmw_find_first_diff_u8(dst, src, spill); \
110 if (diff_offs < spill) \
111 return round_down(offset + diff_offs, granularity); \
112 \
113 dst += spill; \
114 src += spill; \
115 size -= spill; \
116 offset += spill; \
117 spill = 0; \
118 } \
119 if (!spill && !SPILL(src, _type)) { \
120 size_t to_copy = size & ~(sizeof(_type) - 1); \
121 \
122 diff_offs = vmw_find_first_diff_ ## _type \
123 ((_type *) dst, (_type *) src, to_copy); \
124 if (diff_offs >= size || granularity == sizeof(_type)) \
125 return (offset + diff_offs); \
126 \
127 dst += diff_offs; \
128 src += diff_offs; \
129 size -= diff_offs; \
130 offset += diff_offs; \
131 } \
132} while (0) \
133
134
135/**
136 * vmw_find_first_diff - find the first difference between dst and src
137 *
138 * @dst: The destination address
139 * @src: The source address
140 * @size: Number of bytes to compare
141 * @granularity: The granularity needed for the return value in bytes.
142 * return: The offset from find start where the first difference was
143 * encountered in bytes. If no difference was found, the function returns
144 * a value >= @size.
145 */
146static size_t vmw_find_first_diff(const u8 *dst, const u8 *src, size_t size,
147 size_t granularity)
148{
149 size_t offset = 0;
150
151 /*
152 * Try finding with large integers if alignment allows, or we can
153 * fix it. Fall through if we need better resolution or alignment
154 * was bad.
155 */
156#ifdef CONFIG_64BIT
157 VMW_TRY_FIND_FIRST_DIFF(u64);
158#endif
159 VMW_TRY_FIND_FIRST_DIFF(u32);
160 VMW_TRY_FIND_FIRST_DIFF(u16);
161
162 return round_down(offset + vmw_find_first_diff_u8(dst, src, size),
163 granularity);
164}
165
166
167/*
168 * Template to compute find_last_diff() for a certain integer type
169 * including a tail copy for alignment, and adjustment of parameters
170 * for head find or increased resolution find using an unsigned integer find
171 * of smaller width. If finding is complete, and resolution is sufficient,
172 * the macro executes a return statement. Otherwise it falls through.
173 */
174#define VMW_TRY_FIND_LAST_DIFF(_type) \
175do { \
176 unsigned int spill = SPILL(dst, _type); \
177 ssize_t location; \
178 ssize_t diff_offs; \
179 \
180 if (spill && spill <= size && spill == SPILL(src, _type)) { \
181 diff_offs = vmw_find_last_diff_u8(dst, src, spill); \
182 if (diff_offs) { \
183 location = size - spill + diff_offs - 1; \
184 return round_down(location, granularity); \
185 } \
186 \
187 dst -= spill; \
188 src -= spill; \
189 size -= spill; \
190 spill = 0; \
191 } \
192 if (!spill && !SPILL(src, _type)) { \
193 size_t to_copy = round_down(size, sizeof(_type)); \
194 \
195 diff_offs = vmw_find_last_diff_ ## _type \
196 ((_type *) dst, (_type *) src, to_copy); \
197 location = size - to_copy + diff_offs - sizeof(_type); \
198 if (location < 0 || granularity == sizeof(_type)) \
199 return location; \
200 \
201 dst -= to_copy - diff_offs; \
202 src -= to_copy - diff_offs; \
203 size -= to_copy - diff_offs; \
204 } \
205} while (0)
206
207
208/**
209 * vmw_find_last_diff - find the last difference between dst and src
210 *
211 * @dst: The destination address
212 * @src: The source address
213 * @size: Number of bytes to compare
214 * @granularity: The granularity needed for the return value in bytes.
215 * return: The offset from find start where the last difference was
216 * encountered in bytes, or a negative value if no difference was found.
217 */
218static ssize_t vmw_find_last_diff(const u8 *dst, const u8 *src, size_t size,
219 size_t granularity)
220{
221 dst += size;
222 src += size;
223
224#ifdef CONFIG_64BIT
225 VMW_TRY_FIND_LAST_DIFF(u64);
226#endif
227 VMW_TRY_FIND_LAST_DIFF(u32);
228 VMW_TRY_FIND_LAST_DIFF(u16);
229
230 return round_down(vmw_find_last_diff_u8(dst, src, size) - 1,
231 granularity);
232}
233
234
235/**
236 * vmw_memcpy - A wrapper around kernel memcpy with allowing to plug it into a
237 * struct vmw_diff_cpy.
238 *
239 * @diff: The struct vmw_diff_cpy closure argument (unused).
240 * @dest: The copy destination.
241 * @src: The copy source.
242 * @n: Number of bytes to copy.
243 */
244void vmw_memcpy(struct vmw_diff_cpy *diff, u8 *dest, const u8 *src, size_t n)
245{
246 memcpy(dest, src, n);
247}
248
249
250/**
251 * vmw_adjust_rect - Adjust rectangle coordinates for newly found difference
252 *
253 * @diff: The struct vmw_diff_cpy used to track the modified bounding box.
254 * @diff_offs: The offset from @diff->line_offset where the difference was
255 * found.
256 */
257static void vmw_adjust_rect(struct vmw_diff_cpy *diff, size_t diff_offs)
258{
259 size_t offs = (diff_offs + diff->line_offset) / diff->cpp;
260 struct drm_rect *rect = &diff->rect;
261
262 rect->x1 = min_t(int, rect->x1, offs);
263 rect->x2 = max_t(int, rect->x2, offs + 1);
264 rect->y1 = min_t(int, rect->y1, diff->line);
265 rect->y2 = max_t(int, rect->y2, diff->line + 1);
266}
267
268/**
269 * vmw_diff_memcpy - memcpy that creates a bounding box of modified content.
270 *
271 * @diff: The struct vmw_diff_cpy used to track the modified bounding box.
272 * @dest: The copy destination.
273 * @src: The copy source.
274 * @n: Number of bytes to copy.
275 *
276 * In order to correctly track the modified content, the field @diff->line must
277 * be pre-loaded with the current line number, the field @diff->line_offset must
278 * be pre-loaded with the line offset in bytes where the copy starts, and
279 * finally the field @diff->cpp need to be preloaded with the number of bytes
280 * per unit in the horizontal direction of the area we're examining.
281 * Typically bytes per pixel.
282 * This is needed to know the needed granularity of the difference computing
283 * operations. A higher cpp generally leads to faster execution at the cost of
284 * bounding box width precision.
285 */
286void vmw_diff_memcpy(struct vmw_diff_cpy *diff, u8 *dest, const u8 *src,
287 size_t n)
288{
289 ssize_t csize, byte_len;
290
291 if (WARN_ON_ONCE(round_down(n, diff->cpp) != n))
292 return;
293
294 /* TODO: Possibly use a single vmw_find_first_diff per line? */
295 csize = vmw_find_first_diff(dest, src, n, diff->cpp);
296 if (csize < n) {
297 vmw_adjust_rect(diff, csize);
298 byte_len = diff->cpp;
299
300 /*
301 * Starting from where first difference was found, find
302 * location of last difference, and then copy.
303 */
304 diff->line_offset += csize;
305 dest += csize;
306 src += csize;
307 n -= csize;
308 csize = vmw_find_last_diff(dest, src, n, diff->cpp);
309 if (csize >= 0) {
310 byte_len += csize;
311 vmw_adjust_rect(diff, csize);
312 }
313 memcpy(dest, src, byte_len);
314 }
315 diff->line_offset += n;
316}
317
318/**
319 * struct vmw_bo_blit_line_data - Convenience argument to vmw_bo_cpu_blit_line
320 *
321 * @mapped_dst: Already mapped destination page index in @dst_pages.
322 * @dst_addr: Kernel virtual address of mapped destination page.
323 * @dst_pages: Array of destination bo pages.
324 * @dst_num_pages: Number of destination bo pages.
325 * @dst_prot: Destination bo page protection.
326 * @mapped_src: Already mapped source page index in @dst_pages.
327 * @src_addr: Kernel virtual address of mapped source page.
328 * @src_pages: Array of source bo pages.
329 * @src_num_pages: Number of source bo pages.
330 * @src_prot: Source bo page protection.
331 * @diff: Struct vmw_diff_cpy, in the end forwarded to the memcpy routine.
332 */
333struct vmw_bo_blit_line_data {
334 u32 mapped_dst;
335 u8 *dst_addr;
336 struct page **dst_pages;
337 u32 dst_num_pages;
338 pgprot_t dst_prot;
339 u32 mapped_src;
340 u8 *src_addr;
341 struct page **src_pages;
342 u32 src_num_pages;
343 pgprot_t src_prot;
344 struct vmw_diff_cpy *diff;
345};
346
347/**
348 * vmw_bo_cpu_blit_line - Blit part of a line from one bo to another.
349 *
350 * @d: Blit data as described above.
351 * @dst_offset: Destination copy start offset from start of bo.
352 * @src_offset: Source copy start offset from start of bo.
353 * @bytes_to_copy: Number of bytes to copy in this line.
354 */
355static int vmw_bo_cpu_blit_line(struct vmw_bo_blit_line_data *d,
356 u32 dst_offset,
357 u32 src_offset,
358 u32 bytes_to_copy)
359{
360 struct vmw_diff_cpy *diff = d->diff;
361
362 while (bytes_to_copy) {
363 u32 copy_size = bytes_to_copy;
364 u32 dst_page = dst_offset >> PAGE_SHIFT;
365 u32 src_page = src_offset >> PAGE_SHIFT;
366 u32 dst_page_offset = dst_offset & ~PAGE_MASK;
367 u32 src_page_offset = src_offset & ~PAGE_MASK;
368 bool unmap_dst = d->dst_addr && dst_page != d->mapped_dst;
369 bool unmap_src = d->src_addr && (src_page != d->mapped_src ||
370 unmap_dst);
371
372 copy_size = min_t(u32, copy_size, PAGE_SIZE - dst_page_offset);
373 copy_size = min_t(u32, copy_size, PAGE_SIZE - src_page_offset);
374
375 if (unmap_src) {
376 ttm_kunmap_atomic_prot(d->src_addr, d->src_prot);
377 d->src_addr = NULL;
378 }
379
380 if (unmap_dst) {
381 ttm_kunmap_atomic_prot(d->dst_addr, d->dst_prot);
382 d->dst_addr = NULL;
383 }
384
385 if (!d->dst_addr) {
386 if (WARN_ON_ONCE(dst_page >= d->dst_num_pages))
387 return -EINVAL;
388
389 d->dst_addr =
390 ttm_kmap_atomic_prot(d->dst_pages[dst_page],
391 d->dst_prot);
392 if (!d->dst_addr)
393 return -ENOMEM;
394
395 d->mapped_dst = dst_page;
396 }
397
398 if (!d->src_addr) {
399 if (WARN_ON_ONCE(src_page >= d->src_num_pages))
400 return -EINVAL;
401
402 d->src_addr =
403 ttm_kmap_atomic_prot(d->src_pages[src_page],
404 d->src_prot);
405 if (!d->src_addr)
406 return -ENOMEM;
407
408 d->mapped_src = src_page;
409 }
410 diff->do_cpy(diff, d->dst_addr + dst_page_offset,
411 d->src_addr + src_page_offset, copy_size);
412
413 bytes_to_copy -= copy_size;
414 dst_offset += copy_size;
415 src_offset += copy_size;
416 }
417
418 return 0;
419}
420
421/**
422 * ttm_bo_cpu_blit - in-kernel cpu blit.
423 *
424 * @dst: Destination buffer object.
425 * @dst_offset: Destination offset of blit start in bytes.
426 * @dst_stride: Destination stride in bytes.
427 * @src: Source buffer object.
428 * @src_offset: Source offset of blit start in bytes.
429 * @src_stride: Source stride in bytes.
430 * @w: Width of blit.
431 * @h: Height of blit.
432 * return: Zero on success. Negative error value on failure. Will print out
433 * kernel warnings on caller bugs.
434 *
435 * Performs a CPU blit from one buffer object to another avoiding a full
436 * bo vmap which may exhaust- or fragment vmalloc space.
437 * On supported architectures (x86), we're using kmap_atomic which avoids
438 * cross-processor TLB- and cache flushes and may, on non-HIGHMEM systems
439 * reference already set-up mappings.
440 *
441 * Neither of the buffer objects may be placed in PCI memory
442 * (Fixed memory in TTM terminology) when using this function.
443 */
444int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
445 u32 dst_offset, u32 dst_stride,
446 struct ttm_buffer_object *src,
447 u32 src_offset, u32 src_stride,
448 u32 w, u32 h,
449 struct vmw_diff_cpy *diff)
450{
451 struct ttm_operation_ctx ctx = {
452 .interruptible = false,
453 .no_wait_gpu = false
454 };
455 u32 j, initial_line = dst_offset / dst_stride;
456 struct vmw_bo_blit_line_data d;
457 int ret = 0;
458
459 /* Buffer objects need to be either pinned or reserved: */
460 if (!(dst->mem.placement & TTM_PL_FLAG_NO_EVICT))
461 lockdep_assert_held(&dst->resv->lock.base);
462 if (!(src->mem.placement & TTM_PL_FLAG_NO_EVICT))
463 lockdep_assert_held(&src->resv->lock.base);
464
465 if (dst->ttm->state == tt_unpopulated) {
466 ret = dst->ttm->bdev->driver->ttm_tt_populate(dst->ttm, &ctx);
467 if (ret)
468 return ret;
469 }
470
471 if (src->ttm->state == tt_unpopulated) {
472 ret = src->ttm->bdev->driver->ttm_tt_populate(src->ttm, &ctx);
473 if (ret)
474 return ret;
475 }
476
477 d.mapped_dst = 0;
478 d.mapped_src = 0;
479 d.dst_addr = NULL;
480 d.src_addr = NULL;
481 d.dst_pages = dst->ttm->pages;
482 d.src_pages = src->ttm->pages;
483 d.dst_num_pages = dst->num_pages;
484 d.src_num_pages = src->num_pages;
485 d.dst_prot = ttm_io_prot(dst->mem.placement, PAGE_KERNEL);
486 d.src_prot = ttm_io_prot(src->mem.placement, PAGE_KERNEL);
487 d.diff = diff;
488
489 for (j = 0; j < h; ++j) {
490 diff->line = j + initial_line;
491 diff->line_offset = dst_offset % dst_stride;
492 ret = vmw_bo_cpu_blit_line(&d, dst_offset, src_offset, w);
493 if (ret)
494 goto out;
495
496 dst_offset += dst_stride;
497 src_offset += src_stride;
498 }
499out:
500 if (d.src_addr)
501 ttm_kunmap_atomic_prot(d.src_addr, d.src_prot);
502 if (d.dst_addr)
503 ttm_kunmap_atomic_prot(d.dst_addr, d.dst_prot);
504
505 return ret;
506}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
index 7177eecb8c9f..21111fd091f9 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
@@ -185,6 +185,22 @@ static const struct ttm_place evictable_placement_flags[] = {
185 } 185 }
186}; 186};
187 187
188static const struct ttm_place nonfixed_placement_flags[] = {
189 {
190 .fpfn = 0,
191 .lpfn = 0,
192 .flags = TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED
193 }, {
194 .fpfn = 0,
195 .lpfn = 0,
196 .flags = VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED
197 }, {
198 .fpfn = 0,
199 .lpfn = 0,
200 .flags = VMW_PL_FLAG_MOB | TTM_PL_FLAG_CACHED
201 }
202};
203
188struct ttm_placement vmw_evictable_placement = { 204struct ttm_placement vmw_evictable_placement = {
189 .num_placement = 4, 205 .num_placement = 4,
190 .placement = evictable_placement_flags, 206 .placement = evictable_placement_flags,
@@ -213,6 +229,13 @@ struct ttm_placement vmw_mob_ne_placement = {
213 .busy_placement = &mob_ne_placement_flags 229 .busy_placement = &mob_ne_placement_flags
214}; 230};
215 231
232struct ttm_placement vmw_nonfixed_placement = {
233 .num_placement = 3,
234 .placement = nonfixed_placement_flags,
235 .num_busy_placement = 1,
236 .busy_placement = &sys_placement_flags
237};
238
216struct vmw_ttm_tt { 239struct vmw_ttm_tt {
217 struct ttm_dma_tt dma_ttm; 240 struct ttm_dma_tt dma_ttm;
218 struct vmw_private *dev_priv; 241 struct vmw_private *dev_priv;
@@ -841,6 +864,7 @@ static void vmw_move_notify(struct ttm_buffer_object *bo,
841 */ 864 */
842static void vmw_swap_notify(struct ttm_buffer_object *bo) 865static void vmw_swap_notify(struct ttm_buffer_object *bo)
843{ 866{
867 vmw_resource_swap_notify(bo);
844 (void) ttm_bo_wait(bo, false, false); 868 (void) ttm_bo_wait(bo, false, false);
845} 869}
846 870
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
index f283324ce598..9f45d5004cae 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c
@@ -101,6 +101,7 @@ struct vmw_cmdbuf_context {
101 * @handle: DMA address handle for the command buffer space if @using_mob is 101 * @handle: DMA address handle for the command buffer space if @using_mob is
102 * false. Immutable. 102 * false. Immutable.
103 * @size: The size of the command buffer space. Immutable. 103 * @size: The size of the command buffer space. Immutable.
104 * @num_contexts: Number of contexts actually enabled.
104 */ 105 */
105struct vmw_cmdbuf_man { 106struct vmw_cmdbuf_man {
106 struct mutex cur_mutex; 107 struct mutex cur_mutex;
@@ -128,6 +129,7 @@ struct vmw_cmdbuf_man {
128 bool has_pool; 129 bool has_pool;
129 dma_addr_t handle; 130 dma_addr_t handle;
130 size_t size; 131 size_t size;
132 u32 num_contexts;
131}; 133};
132 134
133/** 135/**
@@ -185,7 +187,7 @@ struct vmw_cmdbuf_alloc_info {
185 187
186/* Loop over each context in the command buffer manager. */ 188/* Loop over each context in the command buffer manager. */
187#define for_each_cmdbuf_ctx(_man, _i, _ctx) \ 189#define for_each_cmdbuf_ctx(_man, _i, _ctx) \
188 for (_i = 0, _ctx = &(_man)->ctx[0]; (_i) < SVGA_CB_CONTEXT_MAX; \ 190 for (_i = 0, _ctx = &(_man)->ctx[0]; (_i) < (_man)->num_contexts; \
189 ++(_i), ++(_ctx)) 191 ++(_i), ++(_ctx))
190 192
191static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man, u32 context, 193static int vmw_cmdbuf_startstop(struct vmw_cmdbuf_man *man, u32 context,
@@ -514,6 +516,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
514 struct list_head restart_head[SVGA_CB_CONTEXT_MAX]; 516 struct list_head restart_head[SVGA_CB_CONTEXT_MAX];
515 int i; 517 int i;
516 struct vmw_cmdbuf_context *ctx; 518 struct vmw_cmdbuf_context *ctx;
519 bool global_block = false;
517 520
518 for_each_cmdbuf_ctx(man, i, ctx) { 521 for_each_cmdbuf_ctx(man, i, ctx) {
519 INIT_LIST_HEAD(&restart_head[i]); 522 INIT_LIST_HEAD(&restart_head[i]);
@@ -531,6 +534,7 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
531 534
532 list_del_init(&entry->list); 535 list_del_init(&entry->list);
533 restart[entry->cb_context] = true; 536 restart[entry->cb_context] = true;
537 global_block = true;
534 538
535 if (!vmw_cmd_describe(header, &error_cmd_size, &cmd_name)) { 539 if (!vmw_cmd_describe(header, &error_cmd_size, &cmd_name)) {
536 DRM_ERROR("Unknown command causing device error.\n"); 540 DRM_ERROR("Unknown command causing device error.\n");
@@ -564,23 +568,21 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
564 cb_hdr->length -= new_start_offset; 568 cb_hdr->length -= new_start_offset;
565 cb_hdr->errorOffset = 0; 569 cb_hdr->errorOffset = 0;
566 cb_hdr->offset = 0; 570 cb_hdr->offset = 0;
571
567 list_add_tail(&entry->list, &restart_head[entry->cb_context]); 572 list_add_tail(&entry->list, &restart_head[entry->cb_context]);
568 man->ctx[entry->cb_context].block_submission = true;
569 } 573 }
574
575 for_each_cmdbuf_ctx(man, i, ctx)
576 man->ctx[i].block_submission = true;
577
570 spin_unlock(&man->lock); 578 spin_unlock(&man->lock);
571 579
572 /* Preempt all contexts with errors */ 580 /* Preempt all contexts */
573 for_each_cmdbuf_ctx(man, i, ctx) { 581 if (global_block && vmw_cmdbuf_preempt(man, 0))
574 if (ctx->block_submission && vmw_cmdbuf_preempt(man, i)) 582 DRM_ERROR("Failed preempting command buffer contexts\n");
575 DRM_ERROR("Failed preempting command buffer "
576 "context %u.\n", i);
577 }
578 583
579 spin_lock(&man->lock); 584 spin_lock(&man->lock);
580 for_each_cmdbuf_ctx(man, i, ctx) { 585 for_each_cmdbuf_ctx(man, i, ctx) {
581 if (!ctx->block_submission)
582 continue;
583
584 /* Move preempted command buffers to the preempted queue. */ 586 /* Move preempted command buffers to the preempted queue. */
585 vmw_cmdbuf_ctx_process(man, ctx, &dummy); 587 vmw_cmdbuf_ctx_process(man, ctx, &dummy);
586 588
@@ -594,19 +596,16 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
594 * Finally add all command buffers first in the submitted 596 * Finally add all command buffers first in the submitted
595 * queue, to rerun them. 597 * queue, to rerun them.
596 */ 598 */
597 list_splice_init(&restart_head[i], &ctx->submitted);
598 599
599 ctx->block_submission = false; 600 ctx->block_submission = false;
601 list_splice_init(&restart_head[i], &ctx->submitted);
600 } 602 }
601 603
602 vmw_cmdbuf_man_process(man); 604 vmw_cmdbuf_man_process(man);
603 spin_unlock(&man->lock); 605 spin_unlock(&man->lock);
604 606
605 for_each_cmdbuf_ctx(man, i, ctx) { 607 if (global_block && vmw_cmdbuf_startstop(man, 0, true))
606 if (restart[i] && vmw_cmdbuf_startstop(man, i, true)) 608 DRM_ERROR("Failed restarting command buffer contexts\n");
607 DRM_ERROR("Failed restarting command buffer "
608 "context %u.\n", i);
609 }
610 609
611 /* Send a new fence in case one was removed */ 610 /* Send a new fence in case one was removed */
612 if (send_fence) { 611 if (send_fence) {
@@ -1307,6 +1306,8 @@ struct vmw_cmdbuf_man *vmw_cmdbuf_man_create(struct vmw_private *dev_priv)
1307 if (!man) 1306 if (!man)
1308 return ERR_PTR(-ENOMEM); 1307 return ERR_PTR(-ENOMEM);
1309 1308
1309 man->num_contexts = (dev_priv->capabilities & SVGA_CAP_HP_CMD_QUEUE) ?
1310 2 : 1;
1310 man->headers = dma_pool_create("vmwgfx cmdbuf", 1311 man->headers = dma_pool_create("vmwgfx cmdbuf",
1311 &dev_priv->dev->pdev->dev, 1312 &dev_priv->dev->pdev->dev,
1312 sizeof(SVGACBHeader), 1313 sizeof(SVGACBHeader),
@@ -1341,14 +1342,11 @@ struct vmw_cmdbuf_man *vmw_cmdbuf_man_create(struct vmw_private *dev_priv)
1341 INIT_WORK(&man->work, &vmw_cmdbuf_work_func); 1342 INIT_WORK(&man->work, &vmw_cmdbuf_work_func);
1342 vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_ERROR, 1343 vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_ERROR,
1343 &dev_priv->error_waiters); 1344 &dev_priv->error_waiters);
1344 for_each_cmdbuf_ctx(man, i, ctx) { 1345 ret = vmw_cmdbuf_startstop(man, 0, true);
1345 ret = vmw_cmdbuf_startstop(man, i, true); 1346 if (ret) {
1346 if (ret) { 1347 DRM_ERROR("Failed starting command buffer contexts\n");
1347 DRM_ERROR("Failed starting command buffer " 1348 vmw_cmdbuf_man_destroy(man);
1348 "context %u.\n", i); 1349 return ERR_PTR(ret);
1349 vmw_cmdbuf_man_destroy(man);
1350 return ERR_PTR(ret);
1351 }
1352 } 1350 }
1353 1351
1354 return man; 1352 return man;
@@ -1398,16 +1396,11 @@ void vmw_cmdbuf_remove_pool(struct vmw_cmdbuf_man *man)
1398 */ 1396 */
1399void vmw_cmdbuf_man_destroy(struct vmw_cmdbuf_man *man) 1397void vmw_cmdbuf_man_destroy(struct vmw_cmdbuf_man *man)
1400{ 1398{
1401 struct vmw_cmdbuf_context *ctx;
1402 unsigned int i;
1403
1404 WARN_ON_ONCE(man->has_pool); 1399 WARN_ON_ONCE(man->has_pool);
1405 (void) vmw_cmdbuf_idle(man, false, 10*HZ); 1400 (void) vmw_cmdbuf_idle(man, false, 10*HZ);
1406 1401
1407 for_each_cmdbuf_ctx(man, i, ctx) 1402 if (vmw_cmdbuf_startstop(man, 0, false))
1408 if (vmw_cmdbuf_startstop(man, i, false)) 1403 DRM_ERROR("Failed stopping command buffer contexts.\n");
1409 DRM_ERROR("Failed stopping command buffer "
1410 "context %u.\n", i);
1411 1404
1412 vmw_generic_waiter_remove(man->dev_priv, SVGA_IRQFLAG_ERROR, 1405 vmw_generic_waiter_remove(man->dev_priv, SVGA_IRQFLAG_ERROR,
1413 &man->dev_priv->error_waiters); 1406 &man->dev_priv->error_waiters);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
index d45d2caffa5a..d59d9dd16ebc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
@@ -323,3 +323,54 @@ void vmw_bo_pin_reserved(struct vmw_dma_buffer *vbo, bool pin)
323 323
324 BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type); 324 BUG_ON(ret != 0 || bo->mem.mem_type != old_mem_type);
325} 325}
326
327
328/*
329 * vmw_dma_buffer_unmap - Tear down a cached buffer object map.
330 *
331 * @vbo: The buffer object whose map we are tearing down.
332 *
333 * This function tears down a cached map set up using
334 * vmw_dma_buffer_map_and_cache().
335 */
336void vmw_dma_buffer_unmap(struct vmw_dma_buffer *vbo)
337{
338 if (vbo->map.bo == NULL)
339 return;
340
341 ttm_bo_kunmap(&vbo->map);
342}
343
344
345/*
346 * vmw_dma_buffer_map_and_cache - Map a buffer object and cache the map
347 *
348 * @vbo: The buffer object to map
349 * Return: A kernel virtual address or NULL if mapping failed.
350 *
351 * This function maps a buffer object into the kernel address space, or
352 * returns the virtual kernel address of an already existing map. The virtual
353 * address remains valid as long as the buffer object is pinned or reserved.
354 * The cached map is torn down on either
355 * 1) Buffer object move
356 * 2) Buffer object swapout
357 * 3) Buffer object destruction
358 *
359 */
360void *vmw_dma_buffer_map_and_cache(struct vmw_dma_buffer *vbo)
361{
362 struct ttm_buffer_object *bo = &vbo->base;
363 bool not_used;
364 void *virtual;
365 int ret;
366
367 virtual = ttm_kmap_obj_virtual(&vbo->map, &not_used);
368 if (virtual)
369 return virtual;
370
371 ret = ttm_bo_kmap(bo, 0, bo->num_pages, &vbo->map);
372 if (ret)
373 DRM_ERROR("Buffer object map failed: %d.\n", ret);
374
375 return ttm_kmap_obj_virtual(&vbo->map, &not_used);
376}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 184340d486c3..61a03ac90f8c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -301,6 +301,8 @@ static void vmw_print_capabilities(uint32_t capabilities)
301 DRM_INFO(" Guest Backed Resources.\n"); 301 DRM_INFO(" Guest Backed Resources.\n");
302 if (capabilities & SVGA_CAP_DX) 302 if (capabilities & SVGA_CAP_DX)
303 DRM_INFO(" DX Features.\n"); 303 DRM_INFO(" DX Features.\n");
304 if (capabilities & SVGA_CAP_HP_CMD_QUEUE)
305 DRM_INFO(" HP Command Queue.\n");
304} 306}
305 307
306/** 308/**
@@ -1277,8 +1279,7 @@ static void vmw_master_drop(struct drm_device *dev,
1277 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); 1279 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
1278 ttm_vt_unlock(&dev_priv->fbdev_master.lock); 1280 ttm_vt_unlock(&dev_priv->fbdev_master.lock);
1279 1281
1280 if (dev_priv->enable_fb) 1282 vmw_fb_refresh(dev_priv);
1281 vmw_fb_on(dev_priv);
1282} 1283}
1283 1284
1284/** 1285/**
@@ -1368,28 +1369,23 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
1368 1369
1369 switch (val) { 1370 switch (val) {
1370 case PM_HIBERNATION_PREPARE: 1371 case PM_HIBERNATION_PREPARE:
1371 if (dev_priv->enable_fb)
1372 vmw_fb_off(dev_priv);
1373 ttm_suspend_lock(&dev_priv->reservation_sem);
1374
1375 /* 1372 /*
1376 * This empties VRAM and unbinds all GMR bindings. 1373 * Take the reservation sem in write mode, which will make sure
1377 * Buffer contents is moved to swappable memory. 1374 * there are no other processes holding a buffer object
1375 * reservation, meaning we should be able to evict all buffer
1376 * objects if needed.
1377 * Once user-space processes have been frozen, we can release
1378 * the lock again.
1378 */ 1379 */
1379 vmw_execbuf_release_pinned_bo(dev_priv); 1380 ttm_suspend_lock(&dev_priv->reservation_sem);
1380 vmw_resource_evict_all(dev_priv); 1381 dev_priv->suspend_locked = true;
1381 vmw_release_device_early(dev_priv);
1382 ttm_bo_swapout_all(&dev_priv->bdev);
1383 vmw_fence_fifo_down(dev_priv->fman);
1384 break; 1382 break;
1385 case PM_POST_HIBERNATION: 1383 case PM_POST_HIBERNATION:
1386 case PM_POST_RESTORE: 1384 case PM_POST_RESTORE:
1387 vmw_fence_fifo_up(dev_priv->fman); 1385 if (READ_ONCE(dev_priv->suspend_locked)) {
1388 ttm_suspend_unlock(&dev_priv->reservation_sem); 1386 dev_priv->suspend_locked = false;
1389 if (dev_priv->enable_fb) 1387 ttm_suspend_unlock(&dev_priv->reservation_sem);
1390 vmw_fb_on(dev_priv); 1388 }
1391 break;
1392 case PM_RESTORE_PREPARE:
1393 break; 1389 break;
1394 default: 1390 default:
1395 break; 1391 break;
@@ -1440,25 +1436,48 @@ static int vmw_pm_freeze(struct device *kdev)
1440 struct pci_dev *pdev = to_pci_dev(kdev); 1436 struct pci_dev *pdev = to_pci_dev(kdev);
1441 struct drm_device *dev = pci_get_drvdata(pdev); 1437 struct drm_device *dev = pci_get_drvdata(pdev);
1442 struct vmw_private *dev_priv = vmw_priv(dev); 1438 struct vmw_private *dev_priv = vmw_priv(dev);
1439 int ret;
1443 1440
1444 dev_priv->suspended = true; 1441 /*
1442 * Unlock for vmw_kms_suspend.
1443 * No user-space processes should be running now.
1444 */
1445 ttm_suspend_unlock(&dev_priv->reservation_sem);
1446 ret = vmw_kms_suspend(dev_priv->dev);
1447 if (ret) {
1448 ttm_suspend_lock(&dev_priv->reservation_sem);
1449 DRM_ERROR("Failed to freeze modesetting.\n");
1450 return ret;
1451 }
1445 if (dev_priv->enable_fb) 1452 if (dev_priv->enable_fb)
1446 vmw_fifo_resource_dec(dev_priv); 1453 vmw_fb_off(dev_priv);
1447 1454
1455 ttm_suspend_lock(&dev_priv->reservation_sem);
1456 vmw_execbuf_release_pinned_bo(dev_priv);
1457 vmw_resource_evict_all(dev_priv);
1458 vmw_release_device_early(dev_priv);
1459 ttm_bo_swapout_all(&dev_priv->bdev);
1460 if (dev_priv->enable_fb)
1461 vmw_fifo_resource_dec(dev_priv);
1448 if (atomic_read(&dev_priv->num_fifo_resources) != 0) { 1462 if (atomic_read(&dev_priv->num_fifo_resources) != 0) {
1449 DRM_ERROR("Can't hibernate while 3D resources are active.\n"); 1463 DRM_ERROR("Can't hibernate while 3D resources are active.\n");
1450 if (dev_priv->enable_fb) 1464 if (dev_priv->enable_fb)
1451 vmw_fifo_resource_inc(dev_priv); 1465 vmw_fifo_resource_inc(dev_priv);
1452 WARN_ON(vmw_request_device_late(dev_priv)); 1466 WARN_ON(vmw_request_device_late(dev_priv));
1453 dev_priv->suspended = false; 1467 dev_priv->suspend_locked = false;
1468 ttm_suspend_unlock(&dev_priv->reservation_sem);
1469 if (dev_priv->suspend_state)
1470 vmw_kms_resume(dev);
1471 if (dev_priv->enable_fb)
1472 vmw_fb_on(dev_priv);
1473 vmw_fb_refresh(dev_priv);
1454 return -EBUSY; 1474 return -EBUSY;
1455 } 1475 }
1456 1476
1457 if (dev_priv->enable_fb) 1477 vmw_fence_fifo_down(dev_priv->fman);
1458 __vmw_svga_disable(dev_priv); 1478 __vmw_svga_disable(dev_priv);
1459 1479
1460 vmw_release_device_late(dev_priv); 1480 vmw_release_device_late(dev_priv);
1461
1462 return 0; 1481 return 0;
1463} 1482}
1464 1483
@@ -1482,7 +1501,16 @@ static int vmw_pm_restore(struct device *kdev)
1482 if (dev_priv->enable_fb) 1501 if (dev_priv->enable_fb)
1483 __vmw_svga_enable(dev_priv); 1502 __vmw_svga_enable(dev_priv);
1484 1503
1485 dev_priv->suspended = false; 1504 vmw_fence_fifo_up(dev_priv->fman);
1505 dev_priv->suspend_locked = false;
1506 ttm_suspend_unlock(&dev_priv->reservation_sem);
1507 if (dev_priv->suspend_state)
1508 vmw_kms_resume(dev_priv->dev);
1509
1510 if (dev_priv->enable_fb)
1511 vmw_fb_on(dev_priv);
1512
1513 vmw_fb_refresh(dev_priv);
1486 1514
1487 return 0; 1515 return 0;
1488} 1516}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index d08753e8fd94..9e60de95b863 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -43,10 +43,10 @@
43#include <linux/sync_file.h> 43#include <linux/sync_file.h>
44 44
45#define VMWGFX_DRIVER_NAME "vmwgfx" 45#define VMWGFX_DRIVER_NAME "vmwgfx"
46#define VMWGFX_DRIVER_DATE "20170612" 46#define VMWGFX_DRIVER_DATE "20180322"
47#define VMWGFX_DRIVER_MAJOR 2 47#define VMWGFX_DRIVER_MAJOR 2
48#define VMWGFX_DRIVER_MINOR 14 48#define VMWGFX_DRIVER_MINOR 14
49#define VMWGFX_DRIVER_PATCHLEVEL 0 49#define VMWGFX_DRIVER_PATCHLEVEL 1
50#define VMWGFX_FILE_PAGE_OFFSET 0x00100000 50#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
51#define VMWGFX_FIFO_STATIC_SIZE (1024*1024) 51#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
52#define VMWGFX_MAX_RELOCATIONS 2048 52#define VMWGFX_MAX_RELOCATIONS 2048
@@ -92,6 +92,8 @@ struct vmw_dma_buffer {
92 s32 pin_count; 92 s32 pin_count;
93 /* Not ref-counted. Protected by binding_mutex */ 93 /* Not ref-counted. Protected by binding_mutex */
94 struct vmw_resource *dx_query_ctx; 94 struct vmw_resource *dx_query_ctx;
95 /* Protected by reservation */
96 struct ttm_bo_kmap_obj map;
95}; 97};
96 98
97/** 99/**
@@ -423,6 +425,7 @@ struct vmw_private {
423 struct vmw_framebuffer *implicit_fb; 425 struct vmw_framebuffer *implicit_fb;
424 struct mutex global_kms_state_mutex; 426 struct mutex global_kms_state_mutex;
425 spinlock_t cursor_lock; 427 spinlock_t cursor_lock;
428 struct drm_atomic_state *suspend_state;
426 429
427 /* 430 /*
428 * Context and surface management. 431 * Context and surface management.
@@ -494,8 +497,8 @@ struct vmw_private {
494 struct vmw_master *active_master; 497 struct vmw_master *active_master;
495 struct vmw_master fbdev_master; 498 struct vmw_master fbdev_master;
496 struct notifier_block pm_nb; 499 struct notifier_block pm_nb;
497 bool suspended;
498 bool refuse_hibernation; 500 bool refuse_hibernation;
501 bool suspend_locked;
499 502
500 struct mutex release_mutex; 503 struct mutex release_mutex;
501 atomic_t num_fifo_resources; 504 atomic_t num_fifo_resources;
@@ -673,11 +676,13 @@ extern void vmw_resource_move_notify(struct ttm_buffer_object *bo,
673 struct ttm_mem_reg *mem); 676 struct ttm_mem_reg *mem);
674extern void vmw_query_move_notify(struct ttm_buffer_object *bo, 677extern void vmw_query_move_notify(struct ttm_buffer_object *bo,
675 struct ttm_mem_reg *mem); 678 struct ttm_mem_reg *mem);
679extern void vmw_resource_swap_notify(struct ttm_buffer_object *bo);
676extern int vmw_query_readback_all(struct vmw_dma_buffer *dx_query_mob); 680extern int vmw_query_readback_all(struct vmw_dma_buffer *dx_query_mob);
677extern void vmw_fence_single_bo(struct ttm_buffer_object *bo, 681extern void vmw_fence_single_bo(struct ttm_buffer_object *bo,
678 struct vmw_fence_obj *fence); 682 struct vmw_fence_obj *fence);
679extern void vmw_resource_evict_all(struct vmw_private *dev_priv); 683extern void vmw_resource_evict_all(struct vmw_private *dev_priv);
680 684
685
681/** 686/**
682 * DMA buffer helper routines - vmwgfx_dmabuf.c 687 * DMA buffer helper routines - vmwgfx_dmabuf.c
683 */ 688 */
@@ -700,6 +705,8 @@ extern int vmw_dmabuf_unpin(struct vmw_private *vmw_priv,
700extern void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf, 705extern void vmw_bo_get_guest_ptr(const struct ttm_buffer_object *buf,
701 SVGAGuestPtr *ptr); 706 SVGAGuestPtr *ptr);
702extern void vmw_bo_pin_reserved(struct vmw_dma_buffer *bo, bool pin); 707extern void vmw_bo_pin_reserved(struct vmw_dma_buffer *bo, bool pin);
708extern void *vmw_dma_buffer_map_and_cache(struct vmw_dma_buffer *vbo);
709extern void vmw_dma_buffer_unmap(struct vmw_dma_buffer *vbo);
703 710
704/** 711/**
705 * Misc Ioctl functionality - vmwgfx_ioctl.c 712 * Misc Ioctl functionality - vmwgfx_ioctl.c
@@ -766,6 +773,7 @@ extern struct ttm_placement vmw_evictable_placement;
766extern struct ttm_placement vmw_srf_placement; 773extern struct ttm_placement vmw_srf_placement;
767extern struct ttm_placement vmw_mob_placement; 774extern struct ttm_placement vmw_mob_placement;
768extern struct ttm_placement vmw_mob_ne_placement; 775extern struct ttm_placement vmw_mob_ne_placement;
776extern struct ttm_placement vmw_nonfixed_placement;
769extern struct ttm_bo_driver vmw_bo_driver; 777extern struct ttm_bo_driver vmw_bo_driver;
770extern int vmw_dma_quiescent(struct drm_device *dev); 778extern int vmw_dma_quiescent(struct drm_device *dev);
771extern int vmw_bo_map_dma(struct ttm_buffer_object *bo); 779extern int vmw_bo_map_dma(struct ttm_buffer_object *bo);
@@ -902,6 +910,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv);
902int vmw_fb_close(struct vmw_private *dev_priv); 910int vmw_fb_close(struct vmw_private *dev_priv);
903int vmw_fb_off(struct vmw_private *vmw_priv); 911int vmw_fb_off(struct vmw_private *vmw_priv);
904int vmw_fb_on(struct vmw_private *vmw_priv); 912int vmw_fb_on(struct vmw_private *vmw_priv);
913void vmw_fb_refresh(struct vmw_private *vmw_priv);
905 914
906/** 915/**
907 * Kernel modesetting - vmwgfx_kms.c 916 * Kernel modesetting - vmwgfx_kms.c
@@ -938,6 +947,8 @@ int vmw_kms_present(struct vmw_private *dev_priv,
938int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, 947int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
939 struct drm_file *file_priv); 948 struct drm_file *file_priv);
940void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv); 949void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
950int vmw_kms_suspend(struct drm_device *dev);
951int vmw_kms_resume(struct drm_device *dev);
941 952
942int vmw_dumb_create(struct drm_file *file_priv, 953int vmw_dumb_create(struct drm_file *file_priv,
943 struct drm_device *dev, 954 struct drm_device *dev,
@@ -1165,6 +1176,53 @@ extern int vmw_cmdbuf_cur_flush(struct vmw_cmdbuf_man *man,
1165 bool interruptible); 1176 bool interruptible);
1166extern void vmw_cmdbuf_irqthread(struct vmw_cmdbuf_man *man); 1177extern void vmw_cmdbuf_irqthread(struct vmw_cmdbuf_man *man);
1167 1178
1179/* CPU blit utilities - vmwgfx_blit.c */
1180
1181/**
1182 * struct vmw_diff_cpy - CPU blit information structure
1183 *
1184 * @rect: The output bounding box rectangle.
1185 * @line: The current line of the blit.
1186 * @line_offset: Offset of the current line segment.
1187 * @cpp: Bytes per pixel (granularity information).
1188 * @memcpy: Which memcpy function to use.
1189 */
1190struct vmw_diff_cpy {
1191 struct drm_rect rect;
1192 size_t line;
1193 size_t line_offset;
1194 int cpp;
1195 void (*do_cpy)(struct vmw_diff_cpy *diff, u8 *dest, const u8 *src,
1196 size_t n);
1197};
1198
1199#define VMW_CPU_BLIT_INITIALIZER { \
1200 .do_cpy = vmw_memcpy, \
1201}
1202
1203#define VMW_CPU_BLIT_DIFF_INITIALIZER(_cpp) { \
1204 .line = 0, \
1205 .line_offset = 0, \
1206 .rect = { .x1 = INT_MAX/2, \
1207 .y1 = INT_MAX/2, \
1208 .x2 = INT_MIN/2, \
1209 .y2 = INT_MIN/2 \
1210 }, \
1211 .cpp = _cpp, \
1212 .do_cpy = vmw_diff_memcpy, \
1213}
1214
1215void vmw_diff_memcpy(struct vmw_diff_cpy *diff, u8 *dest, const u8 *src,
1216 size_t n);
1217
1218void vmw_memcpy(struct vmw_diff_cpy *diff, u8 *dest, const u8 *src, size_t n);
1219
1220int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
1221 u32 dst_offset, u32 dst_stride,
1222 struct ttm_buffer_object *src,
1223 u32 src_offset, u32 src_stride,
1224 u32 w, u32 h,
1225 struct vmw_diff_cpy *diff);
1168 1226
1169/** 1227/**
1170 * Inline helper functions 1228 * Inline helper functions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index be7d7fb1b44b..2582ffd36bb5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -43,8 +43,6 @@ struct vmw_fb_par {
43 43
44 struct mutex bo_mutex; 44 struct mutex bo_mutex;
45 struct vmw_dma_buffer *vmw_bo; 45 struct vmw_dma_buffer *vmw_bo;
46 struct ttm_bo_kmap_obj map;
47 void *bo_ptr;
48 unsigned bo_size; 46 unsigned bo_size;
49 struct drm_framebuffer *set_fb; 47 struct drm_framebuffer *set_fb;
50 struct drm_display_mode *set_mode; 48 struct drm_display_mode *set_mode;
@@ -163,10 +161,17 @@ static int vmw_fb_blank(int blank, struct fb_info *info)
163 return 0; 161 return 0;
164} 162}
165 163
166/* 164/**
167 * Dirty code 165 * vmw_fb_dirty_flush - flush dirty regions to the kms framebuffer
166 *
167 * @work: The struct work_struct associated with this task.
168 *
169 * This function flushes the dirty regions of the vmalloc framebuffer to the
170 * kms framebuffer, and if the kms framebuffer is visible, also updated the
171 * corresponding displays. Note that this function runs even if the kms
172 * framebuffer is not bound to a crtc and thus not visible, but it's turned
173 * off during hibernation using the par->dirty.active bool.
168 */ 174 */
169
170static void vmw_fb_dirty_flush(struct work_struct *work) 175static void vmw_fb_dirty_flush(struct work_struct *work)
171{ 176{
172 struct vmw_fb_par *par = container_of(work, struct vmw_fb_par, 177 struct vmw_fb_par *par = container_of(work, struct vmw_fb_par,
@@ -174,13 +179,15 @@ static void vmw_fb_dirty_flush(struct work_struct *work)
174 struct vmw_private *vmw_priv = par->vmw_priv; 179 struct vmw_private *vmw_priv = par->vmw_priv;
175 struct fb_info *info = vmw_priv->fb_info; 180 struct fb_info *info = vmw_priv->fb_info;
176 unsigned long irq_flags; 181 unsigned long irq_flags;
177 s32 dst_x1, dst_x2, dst_y1, dst_y2, w, h; 182 s32 dst_x1, dst_x2, dst_y1, dst_y2, w = 0, h = 0;
178 u32 cpp, max_x, max_y; 183 u32 cpp, max_x, max_y;
179 struct drm_clip_rect clip; 184 struct drm_clip_rect clip;
180 struct drm_framebuffer *cur_fb; 185 struct drm_framebuffer *cur_fb;
181 u8 *src_ptr, *dst_ptr; 186 u8 *src_ptr, *dst_ptr;
187 struct vmw_dma_buffer *vbo = par->vmw_bo;
188 void *virtual;
182 189
183 if (vmw_priv->suspended) 190 if (!READ_ONCE(par->dirty.active))
184 return; 191 return;
185 192
186 mutex_lock(&par->bo_mutex); 193 mutex_lock(&par->bo_mutex);
@@ -188,10 +195,16 @@ static void vmw_fb_dirty_flush(struct work_struct *work)
188 if (!cur_fb) 195 if (!cur_fb)
189 goto out_unlock; 196 goto out_unlock;
190 197
198 (void) ttm_read_lock(&vmw_priv->reservation_sem, false);
199 (void) ttm_bo_reserve(&vbo->base, false, false, NULL);
200 virtual = vmw_dma_buffer_map_and_cache(vbo);
201 if (!virtual)
202 goto out_unreserve;
203
191 spin_lock_irqsave(&par->dirty.lock, irq_flags); 204 spin_lock_irqsave(&par->dirty.lock, irq_flags);
192 if (!par->dirty.active) { 205 if (!par->dirty.active) {
193 spin_unlock_irqrestore(&par->dirty.lock, irq_flags); 206 spin_unlock_irqrestore(&par->dirty.lock, irq_flags);
194 goto out_unlock; 207 goto out_unreserve;
195 } 208 }
196 209
197 /* 210 /*
@@ -221,7 +234,7 @@ static void vmw_fb_dirty_flush(struct work_struct *work)
221 spin_unlock_irqrestore(&par->dirty.lock, irq_flags); 234 spin_unlock_irqrestore(&par->dirty.lock, irq_flags);
222 235
223 if (w && h) { 236 if (w && h) {
224 dst_ptr = (u8 *)par->bo_ptr + 237 dst_ptr = (u8 *)virtual +
225 (dst_y1 * par->set_fb->pitches[0] + dst_x1 * cpp); 238 (dst_y1 * par->set_fb->pitches[0] + dst_x1 * cpp);
226 src_ptr = (u8 *)par->vmalloc + 239 src_ptr = (u8 *)par->vmalloc +
227 ((dst_y1 + par->fb_y) * info->fix.line_length + 240 ((dst_y1 + par->fb_y) * info->fix.line_length +
@@ -237,7 +250,12 @@ static void vmw_fb_dirty_flush(struct work_struct *work)
237 clip.x2 = dst_x2; 250 clip.x2 = dst_x2;
238 clip.y1 = dst_y1; 251 clip.y1 = dst_y1;
239 clip.y2 = dst_y2; 252 clip.y2 = dst_y2;
253 }
240 254
255out_unreserve:
256 ttm_bo_unreserve(&vbo->base);
257 ttm_read_unlock(&vmw_priv->reservation_sem);
258 if (w && h) {
241 WARN_ON_ONCE(par->set_fb->funcs->dirty(cur_fb, NULL, 0, 0, 259 WARN_ON_ONCE(par->set_fb->funcs->dirty(cur_fb, NULL, 0, 0,
242 &clip, 1)); 260 &clip, 1));
243 vmw_fifo_flush(vmw_priv, false); 261 vmw_fifo_flush(vmw_priv, false);
@@ -504,18 +522,8 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
504 par->set_fb = NULL; 522 par->set_fb = NULL;
505 } 523 }
506 524
507 if (par->vmw_bo && detach_bo) { 525 if (par->vmw_bo && detach_bo && unref_bo)
508 struct vmw_private *vmw_priv = par->vmw_priv; 526 vmw_dmabuf_unreference(&par->vmw_bo);
509
510 if (par->bo_ptr) {
511 ttm_bo_kunmap(&par->map);
512 par->bo_ptr = NULL;
513 }
514 if (unref_bo)
515 vmw_dmabuf_unreference(&par->vmw_bo);
516 else if (vmw_priv->active_display_unit != vmw_du_legacy)
517 vmw_dmabuf_unpin(par->vmw_priv, par->vmw_bo, false);
518 }
519 527
520 return 0; 528 return 0;
521} 529}
@@ -636,38 +644,6 @@ static int vmw_fb_set_par(struct fb_info *info)
636 if (ret) 644 if (ret)
637 goto out_unlock; 645 goto out_unlock;
638 646
639 if (!par->bo_ptr) {
640 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb);
641
642 /*
643 * Pin before mapping. Since we don't know in what placement
644 * to pin, call into KMS to do it for us. LDU doesn't require
645 * additional pinning because set_config() would've pinned
646 * it already
647 */
648 if (vmw_priv->active_display_unit != vmw_du_legacy) {
649 ret = vfb->pin(vfb);
650 if (ret) {
651 DRM_ERROR("Could not pin the fbdev "
652 "framebuffer.\n");
653 goto out_unlock;
654 }
655 }
656
657 ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
658 par->vmw_bo->base.num_pages, &par->map);
659 if (ret) {
660 if (vmw_priv->active_display_unit != vmw_du_legacy)
661 vfb->unpin(vfb);
662
663 DRM_ERROR("Could not map the fbdev framebuffer.\n");
664 goto out_unlock;
665 }
666
667 par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
668 }
669
670
671 vmw_fb_dirty_mark(par, par->fb_x, par->fb_y, 647 vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
672 par->set_fb->width, par->set_fb->height); 648 par->set_fb->width, par->set_fb->height);
673 649
@@ -883,12 +859,6 @@ int vmw_fb_off(struct vmw_private *vmw_priv)
883 flush_delayed_work(&info->deferred_work); 859 flush_delayed_work(&info->deferred_work);
884 flush_delayed_work(&par->local_work); 860 flush_delayed_work(&par->local_work);
885 861
886 mutex_lock(&par->bo_mutex);
887 drm_modeset_lock_all(vmw_priv->dev);
888 (void) vmw_fb_kms_detach(par, true, false);
889 drm_modeset_unlock_all(vmw_priv->dev);
890 mutex_unlock(&par->bo_mutex);
891
892 return 0; 862 return 0;
893} 863}
894 864
@@ -904,10 +874,24 @@ int vmw_fb_on(struct vmw_private *vmw_priv)
904 info = vmw_priv->fb_info; 874 info = vmw_priv->fb_info;
905 par = info->par; 875 par = info->par;
906 876
907 vmw_fb_set_par(info);
908 spin_lock_irqsave(&par->dirty.lock, flags); 877 spin_lock_irqsave(&par->dirty.lock, flags);
909 par->dirty.active = true; 878 par->dirty.active = true;
910 spin_unlock_irqrestore(&par->dirty.lock, flags); 879 spin_unlock_irqrestore(&par->dirty.lock, flags);
911 880
912 return 0; 881 return 0;
913} 882}
883
884/**
885 * vmw_fb_refresh - Refresh fb display
886 *
887 * @vmw_priv: Pointer to device private
888 *
889 * Call into kms to show the fbdev display(s).
890 */
891void vmw_fb_refresh(struct vmw_private *vmw_priv)
892{
893 if (!vmw_priv->fb_info)
894 return;
895
896 vmw_fb_set_par(vmw_priv->fb_info);
897}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index 6c5c75cf5e6c..9ed544f8958f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -901,11 +901,12 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
901 spin_lock_irq(&dev->event_lock); 901 spin_lock_irq(&dev->event_lock);
902 902
903 if (likely(eaction->tv_sec != NULL)) { 903 if (likely(eaction->tv_sec != NULL)) {
904 struct timeval tv; 904 struct timespec64 ts;
905 905
906 do_gettimeofday(&tv); 906 ktime_get_ts64(&ts);
907 *eaction->tv_sec = tv.tv_sec; 907 /* monotonic time, so no y2038 overflow */
908 *eaction->tv_usec = tv.tv_usec; 908 *eaction->tv_sec = ts.tv_sec;
909 *eaction->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
909 } 910 }
910 911
911 drm_send_event_locked(dev, eaction->event); 912 drm_send_event_locked(dev, eaction->event);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 34ecc27fc30a..3628a9fe705f 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -393,13 +393,13 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane,
393 du->cursor_surface = vps->surf; 393 du->cursor_surface = vps->surf;
394 du->cursor_dmabuf = vps->dmabuf; 394 du->cursor_dmabuf = vps->dmabuf;
395 395
396 /* setup new image */
397 if (vps->surf) { 396 if (vps->surf) {
398 du->cursor_age = du->cursor_surface->snooper.age; 397 du->cursor_age = du->cursor_surface->snooper.age;
399 398
400 ret = vmw_cursor_update_image(dev_priv, 399 ret = vmw_cursor_update_image(dev_priv,
401 vps->surf->snooper.image, 400 vps->surf->snooper.image,
402 64, 64, hotspot_x, hotspot_y); 401 64, 64, hotspot_x,
402 hotspot_y);
403 } else if (vps->dmabuf) { 403 } else if (vps->dmabuf) {
404 ret = vmw_cursor_update_dmabuf(dev_priv, vps->dmabuf, 404 ret = vmw_cursor_update_dmabuf(dev_priv, vps->dmabuf,
405 plane->state->crtc_w, 405 plane->state->crtc_w,
@@ -497,11 +497,22 @@ int vmw_du_cursor_plane_atomic_check(struct drm_plane *plane,
497 struct vmw_surface *surface = NULL; 497 struct vmw_surface *surface = NULL;
498 struct drm_framebuffer *fb = new_state->fb; 498 struct drm_framebuffer *fb = new_state->fb;
499 499
500 struct drm_rect src = drm_plane_state_src(new_state);
501 struct drm_rect dest = drm_plane_state_dest(new_state);
500 502
501 /* Turning off */ 503 /* Turning off */
502 if (!fb) 504 if (!fb)
503 return ret; 505 return ret;
504 506
507 ret = drm_plane_helper_check_update(plane, new_state->crtc, fb,
508 &src, &dest,
509 DRM_MODE_ROTATE_0,
510 DRM_PLANE_HELPER_NO_SCALING,
511 DRM_PLANE_HELPER_NO_SCALING,
512 true, true, &new_state->visible);
513 if (!ret)
514 return ret;
515
505 /* A lot of the code assumes this */ 516 /* A lot of the code assumes this */
506 if (new_state->crtc_w != 64 || new_state->crtc_h != 64) { 517 if (new_state->crtc_w != 64 || new_state->crtc_h != 64) {
507 DRM_ERROR("Invalid cursor dimensions (%d, %d)\n", 518 DRM_ERROR("Invalid cursor dimensions (%d, %d)\n",
@@ -566,13 +577,9 @@ void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
566 crtc->state->event = NULL; 577 crtc->state->event = NULL;
567 578
568 spin_lock_irq(&crtc->dev->event_lock); 579 spin_lock_irq(&crtc->dev->event_lock);
569 if (drm_crtc_vblank_get(crtc) == 0) 580 drm_crtc_send_vblank_event(crtc, event);
570 drm_crtc_arm_vblank_event(crtc, event);
571 else
572 drm_crtc_send_vblank_event(crtc, event);
573 spin_unlock_irq(&crtc->dev->event_lock); 581 spin_unlock_irq(&crtc->dev->event_lock);
574 } 582 }
575
576} 583}
577 584
578 585
@@ -675,9 +682,6 @@ vmw_du_plane_duplicate_state(struct drm_plane *plane)
675 return NULL; 682 return NULL;
676 683
677 vps->pinned = 0; 684 vps->pinned = 0;
678
679 /* Mapping is managed by prepare_fb/cleanup_fb */
680 memset(&vps->host_map, 0, sizeof(vps->host_map));
681 vps->cpp = 0; 685 vps->cpp = 0;
682 686
683 /* Each ref counted resource needs to be acquired again */ 687 /* Each ref counted resource needs to be acquired again */
@@ -739,11 +743,6 @@ vmw_du_plane_destroy_state(struct drm_plane *plane,
739 743
740 744
741 /* Should have been freed by cleanup_fb */ 745 /* Should have been freed by cleanup_fb */
742 if (vps->host_map.virtual) {
743 DRM_ERROR("Host mapping not freed\n");
744 ttm_bo_kunmap(&vps->host_map);
745 }
746
747 if (vps->surf) 746 if (vps->surf)
748 vmw_surface_unreference(&vps->surf); 747 vmw_surface_unreference(&vps->surf);
749 748
@@ -888,11 +887,11 @@ static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
888 if (dev_priv->active_display_unit == vmw_du_screen_object) 887 if (dev_priv->active_display_unit == vmw_du_screen_object)
889 ret = vmw_kms_sou_do_surface_dirty(dev_priv, &vfbs->base, 888 ret = vmw_kms_sou_do_surface_dirty(dev_priv, &vfbs->base,
890 clips, NULL, NULL, 0, 0, 889 clips, NULL, NULL, 0, 0,
891 num_clips, inc, NULL); 890 num_clips, inc, NULL, NULL);
892 else 891 else
893 ret = vmw_kms_stdu_surface_dirty(dev_priv, &vfbs->base, 892 ret = vmw_kms_stdu_surface_dirty(dev_priv, &vfbs->base,
894 clips, NULL, NULL, 0, 0, 893 clips, NULL, NULL, 0, 0,
895 num_clips, inc, NULL); 894 num_clips, inc, NULL, NULL);
896 895
897 vmw_fifo_flush(dev_priv, false); 896 vmw_fifo_flush(dev_priv, false);
898 ttm_read_unlock(&dev_priv->reservation_sem); 897 ttm_read_unlock(&dev_priv->reservation_sem);
@@ -928,11 +927,12 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
928 switch (dev_priv->active_display_unit) { 927 switch (dev_priv->active_display_unit) {
929 case vmw_du_screen_object: 928 case vmw_du_screen_object:
930 return vmw_kms_sou_readback(dev_priv, file_priv, vfb, 929 return vmw_kms_sou_readback(dev_priv, file_priv, vfb,
931 user_fence_rep, vclips, num_clips); 930 user_fence_rep, vclips, num_clips,
931 NULL);
932 case vmw_du_screen_target: 932 case vmw_du_screen_target:
933 return vmw_kms_stdu_dma(dev_priv, file_priv, vfb, 933 return vmw_kms_stdu_dma(dev_priv, file_priv, vfb,
934 user_fence_rep, NULL, vclips, num_clips, 934 user_fence_rep, NULL, vclips, num_clips,
935 1, false, true); 935 1, false, true, NULL);
936 default: 936 default:
937 WARN_ONCE(true, 937 WARN_ONCE(true,
938 "Readback called with invalid display system.\n"); 938 "Readback called with invalid display system.\n");
@@ -1090,12 +1090,12 @@ static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
1090 case vmw_du_screen_target: 1090 case vmw_du_screen_target:
1091 ret = vmw_kms_stdu_dma(dev_priv, NULL, &vfbd->base, NULL, 1091 ret = vmw_kms_stdu_dma(dev_priv, NULL, &vfbd->base, NULL,
1092 clips, NULL, num_clips, increment, 1092 clips, NULL, num_clips, increment,
1093 true, true); 1093 true, true, NULL);
1094 break; 1094 break;
1095 case vmw_du_screen_object: 1095 case vmw_du_screen_object:
1096 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base, 1096 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base,
1097 clips, NULL, num_clips, 1097 clips, NULL, num_clips,
1098 increment, true, NULL); 1098 increment, true, NULL, NULL);
1099 break; 1099 break;
1100 case vmw_du_legacy: 1100 case vmw_du_legacy:
1101 ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0, 1101 ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0,
@@ -1121,12 +1121,14 @@ static const struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
1121}; 1121};
1122 1122
1123/** 1123/**
1124 * Pin the dmabuffer to the start of vram. 1124 * Pin the dmabuffer in a location suitable for access by the
1125 * display system.
1125 */ 1126 */
1126static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb) 1127static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
1127{ 1128{
1128 struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); 1129 struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
1129 struct vmw_dma_buffer *buf; 1130 struct vmw_dma_buffer *buf;
1131 struct ttm_placement *placement;
1130 int ret; 1132 int ret;
1131 1133
1132 buf = vfb->dmabuf ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer : 1134 buf = vfb->dmabuf ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
@@ -1143,12 +1145,24 @@ static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
1143 break; 1145 break;
1144 case vmw_du_screen_object: 1146 case vmw_du_screen_object:
1145 case vmw_du_screen_target: 1147 case vmw_du_screen_target:
1146 if (vfb->dmabuf) 1148 if (vfb->dmabuf) {
1147 return vmw_dmabuf_pin_in_vram_or_gmr(dev_priv, buf, 1149 if (dev_priv->capabilities & SVGA_CAP_3D) {
1148 false); 1150 /*
1151 * Use surface DMA to get content to
1152 * sreen target surface.
1153 */
1154 placement = &vmw_vram_gmr_placement;
1155 } else {
1156 /* Use CPU blit. */
1157 placement = &vmw_sys_placement;
1158 }
1159 } else {
1160 /* Use surface / image update */
1161 placement = &vmw_mob_placement;
1162 }
1149 1163
1150 return vmw_dmabuf_pin_in_placement(dev_priv, buf, 1164 return vmw_dmabuf_pin_in_placement(dev_priv, buf, placement,
1151 &vmw_mob_placement, false); 1165 false);
1152 default: 1166 default:
1153 return -EINVAL; 1167 return -EINVAL;
1154 } 1168 }
@@ -1539,35 +1553,10 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev,
1539 return drm_atomic_helper_check(dev, state); 1553 return drm_atomic_helper_check(dev, state);
1540} 1554}
1541 1555
1542
1543/**
1544 * vmw_kms_atomic_commit - Perform an atomic state commit
1545 *
1546 * @dev: DRM device
1547 * @state: the driver state object
1548 * @nonblock: Whether nonblocking behaviour is requested
1549 *
1550 * This is a simple wrapper around drm_atomic_helper_commit() for
1551 * us to clear the nonblocking value.
1552 *
1553 * Nonblocking commits currently cause synchronization issues
1554 * for vmwgfx.
1555 *
1556 * RETURNS
1557 * Zero for success or negative error code on failure.
1558 */
1559int vmw_kms_atomic_commit(struct drm_device *dev,
1560 struct drm_atomic_state *state,
1561 bool nonblock)
1562{
1563 return drm_atomic_helper_commit(dev, state, false);
1564}
1565
1566
1567static const struct drm_mode_config_funcs vmw_kms_funcs = { 1556static const struct drm_mode_config_funcs vmw_kms_funcs = {
1568 .fb_create = vmw_kms_fb_create, 1557 .fb_create = vmw_kms_fb_create,
1569 .atomic_check = vmw_kms_atomic_check_modeset, 1558 .atomic_check = vmw_kms_atomic_check_modeset,
1570 .atomic_commit = vmw_kms_atomic_commit, 1559 .atomic_commit = drm_atomic_helper_commit,
1571}; 1560};
1572 1561
1573static int vmw_kms_generic_present(struct vmw_private *dev_priv, 1562static int vmw_kms_generic_present(struct vmw_private *dev_priv,
@@ -1581,7 +1570,7 @@ static int vmw_kms_generic_present(struct vmw_private *dev_priv,
1581{ 1570{
1582 return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips, 1571 return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips,
1583 &surface->res, destX, destY, 1572 &surface->res, destX, destY,
1584 num_clips, 1, NULL); 1573 num_clips, 1, NULL, NULL);
1585} 1574}
1586 1575
1587 1576
@@ -1600,7 +1589,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
1600 case vmw_du_screen_target: 1589 case vmw_du_screen_target:
1601 ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips, 1590 ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips,
1602 &surface->res, destX, destY, 1591 &surface->res, destX, destY,
1603 num_clips, 1, NULL); 1592 num_clips, 1, NULL, NULL);
1604 break; 1593 break;
1605 case vmw_du_screen_object: 1594 case vmw_du_screen_object:
1606 ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface, 1595 ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface,
@@ -2328,10 +2317,16 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
2328 2317
2329 dirty->dev_priv = dev_priv; 2318 dirty->dev_priv = dev_priv;
2330 2319
2331 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { 2320 /* If crtc is passed, no need to iterate over other display units */
2332 if (crtc->primary->fb != &framebuffer->base) 2321 if (dirty->crtc) {
2333 continue; 2322 units[num_units++] = vmw_crtc_to_du(dirty->crtc);
2334 units[num_units++] = vmw_crtc_to_du(crtc); 2323 } else {
2324 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
2325 head) {
2326 if (crtc->primary->fb != &framebuffer->base)
2327 continue;
2328 units[num_units++] = vmw_crtc_to_du(crtc);
2329 }
2335 } 2330 }
2336 2331
2337 for (k = 0; k < num_units; k++) { 2332 for (k = 0; k < num_units; k++) {
@@ -2430,14 +2425,21 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
2430int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv, 2425int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv,
2431 struct vmw_dma_buffer *buf, 2426 struct vmw_dma_buffer *buf,
2432 bool interruptible, 2427 bool interruptible,
2433 bool validate_as_mob) 2428 bool validate_as_mob,
2429 bool for_cpu_blit)
2434{ 2430{
2431 struct ttm_operation_ctx ctx = {
2432 .interruptible = interruptible,
2433 .no_wait_gpu = false};
2435 struct ttm_buffer_object *bo = &buf->base; 2434 struct ttm_buffer_object *bo = &buf->base;
2436 int ret; 2435 int ret;
2437 2436
2438 ttm_bo_reserve(bo, false, false, NULL); 2437 ttm_bo_reserve(bo, false, false, NULL);
2439 ret = vmw_validate_single_buffer(dev_priv, bo, interruptible, 2438 if (for_cpu_blit)
2440 validate_as_mob); 2439 ret = ttm_bo_validate(bo, &vmw_nonfixed_placement, &ctx);
2440 else
2441 ret = vmw_validate_single_buffer(dev_priv, bo, interruptible,
2442 validate_as_mob);
2441 if (ret) 2443 if (ret)
2442 ttm_bo_unreserve(bo); 2444 ttm_bo_unreserve(bo);
2443 2445
@@ -2549,7 +2551,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
2549 if (res->backup) { 2551 if (res->backup) {
2550 ret = vmw_kms_helper_buffer_prepare(res->dev_priv, res->backup, 2552 ret = vmw_kms_helper_buffer_prepare(res->dev_priv, res->backup,
2551 interruptible, 2553 interruptible,
2552 res->dev_priv->has_mob); 2554 res->dev_priv->has_mob,
2555 false);
2553 if (ret) 2556 if (ret)
2554 goto out_unreserve; 2557 goto out_unreserve;
2555 } 2558 }
@@ -2845,3 +2848,51 @@ int vmw_kms_set_config(struct drm_mode_set *set,
2845 2848
2846 return drm_atomic_helper_set_config(set, ctx); 2849 return drm_atomic_helper_set_config(set, ctx);
2847} 2850}
2851
2852
2853/**
2854 * vmw_kms_suspend - Save modesetting state and turn modesetting off.
2855 *
2856 * @dev: Pointer to the drm device
2857 * Return: 0 on success. Negative error code on failure.
2858 */
2859int vmw_kms_suspend(struct drm_device *dev)
2860{
2861 struct vmw_private *dev_priv = vmw_priv(dev);
2862
2863 dev_priv->suspend_state = drm_atomic_helper_suspend(dev);
2864 if (IS_ERR(dev_priv->suspend_state)) {
2865 int ret = PTR_ERR(dev_priv->suspend_state);
2866
2867 DRM_ERROR("Failed kms suspend: %d\n", ret);
2868 dev_priv->suspend_state = NULL;
2869
2870 return ret;
2871 }
2872
2873 return 0;
2874}
2875
2876
2877/**
2878 * vmw_kms_resume - Re-enable modesetting and restore state
2879 *
2880 * @dev: Pointer to the drm device
2881 * Return: 0 on success. Negative error code on failure.
2882 *
2883 * State is resumed from a previous vmw_kms_suspend(). It's illegal
2884 * to call this function without a previous vmw_kms_suspend().
2885 */
2886int vmw_kms_resume(struct drm_device *dev)
2887{
2888 struct vmw_private *dev_priv = vmw_priv(dev);
2889 int ret;
2890
2891 if (WARN_ON(!dev_priv->suspend_state))
2892 return 0;
2893
2894 ret = drm_atomic_helper_resume(dev, dev_priv->suspend_state);
2895 dev_priv->suspend_state = NULL;
2896
2897 return ret;
2898}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index cd9da2dd79af..4e8749a8717e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -50,6 +50,7 @@
50 * @unit: The current display unit. Set up by the helper before a call to @clip. 50 * @unit: The current display unit. Set up by the helper before a call to @clip.
51 * @cmd: The allocated fifo space. Set up by the helper before the first @clip 51 * @cmd: The allocated fifo space. Set up by the helper before the first @clip
52 * call. 52 * call.
53 * @crtc: The crtc for which to build dirty commands.
53 * @num_hits: Number of clip rect commands for this display unit. 54 * @num_hits: Number of clip rect commands for this display unit.
54 * Cleared by the helper before the first @clip call. Updated by the @clip 55 * Cleared by the helper before the first @clip call. Updated by the @clip
55 * callback. 56 * callback.
@@ -71,6 +72,7 @@ struct vmw_kms_dirty {
71 struct vmw_private *dev_priv; 72 struct vmw_private *dev_priv;
72 struct vmw_display_unit *unit; 73 struct vmw_display_unit *unit;
73 void *cmd; 74 void *cmd;
75 struct drm_crtc *crtc;
74 u32 num_hits; 76 u32 num_hits;
75 s32 fb_x; 77 s32 fb_x;
76 s32 fb_y; 78 s32 fb_y;
@@ -175,7 +177,6 @@ struct vmw_plane_state {
175 int pinned; 177 int pinned;
176 178
177 /* For CPU Blit */ 179 /* For CPU Blit */
178 struct ttm_bo_kmap_obj host_map;
179 unsigned int cpp; 180 unsigned int cpp;
180}; 181};
181 182
@@ -287,7 +288,8 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
287int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv, 288int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv,
288 struct vmw_dma_buffer *buf, 289 struct vmw_dma_buffer *buf,
289 bool interruptible, 290 bool interruptible,
290 bool validate_as_mob); 291 bool validate_as_mob,
292 bool for_cpu_blit);
291void vmw_kms_helper_buffer_revert(struct vmw_dma_buffer *buf); 293void vmw_kms_helper_buffer_revert(struct vmw_dma_buffer *buf);
292void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv, 294void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
293 struct drm_file *file_priv, 295 struct drm_file *file_priv,
@@ -398,20 +400,23 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
398 s32 dest_x, 400 s32 dest_x,
399 s32 dest_y, 401 s32 dest_y,
400 unsigned num_clips, int inc, 402 unsigned num_clips, int inc,
401 struct vmw_fence_obj **out_fence); 403 struct vmw_fence_obj **out_fence,
404 struct drm_crtc *crtc);
402int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv, 405int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
403 struct vmw_framebuffer *framebuffer, 406 struct vmw_framebuffer *framebuffer,
404 struct drm_clip_rect *clips, 407 struct drm_clip_rect *clips,
405 struct drm_vmw_rect *vclips, 408 struct drm_vmw_rect *vclips,
406 unsigned num_clips, int increment, 409 unsigned num_clips, int increment,
407 bool interruptible, 410 bool interruptible,
408 struct vmw_fence_obj **out_fence); 411 struct vmw_fence_obj **out_fence,
412 struct drm_crtc *crtc);
409int vmw_kms_sou_readback(struct vmw_private *dev_priv, 413int vmw_kms_sou_readback(struct vmw_private *dev_priv,
410 struct drm_file *file_priv, 414 struct drm_file *file_priv,
411 struct vmw_framebuffer *vfb, 415 struct vmw_framebuffer *vfb,
412 struct drm_vmw_fence_rep __user *user_fence_rep, 416 struct drm_vmw_fence_rep __user *user_fence_rep,
413 struct drm_vmw_rect *vclips, 417 struct drm_vmw_rect *vclips,
414 uint32_t num_clips); 418 uint32_t num_clips,
419 struct drm_crtc *crtc);
415 420
416/* 421/*
417 * Screen Target Display Unit functions - vmwgfx_stdu.c 422 * Screen Target Display Unit functions - vmwgfx_stdu.c
@@ -425,7 +430,8 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
425 s32 dest_x, 430 s32 dest_x,
426 s32 dest_y, 431 s32 dest_y,
427 unsigned num_clips, int inc, 432 unsigned num_clips, int inc,
428 struct vmw_fence_obj **out_fence); 433 struct vmw_fence_obj **out_fence,
434 struct drm_crtc *crtc);
429int vmw_kms_stdu_dma(struct vmw_private *dev_priv, 435int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
430 struct drm_file *file_priv, 436 struct drm_file *file_priv,
431 struct vmw_framebuffer *vfb, 437 struct vmw_framebuffer *vfb,
@@ -435,7 +441,8 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
435 uint32_t num_clips, 441 uint32_t num_clips,
436 int increment, 442 int increment,
437 bool to_surface, 443 bool to_surface,
438 bool interruptible); 444 bool interruptible,
445 struct drm_crtc *crtc);
439 446
440int vmw_kms_set_config(struct drm_mode_set *set, 447int vmw_kms_set_config(struct drm_mode_set *set,
441 struct drm_modeset_acquire_ctx *ctx); 448 struct drm_modeset_acquire_ctx *ctx);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
index 97000996b8dc..cdff99211602 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -328,7 +328,7 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
328{ 328{
329 struct rpc_channel channel; 329 struct rpc_channel channel;
330 char *msg, *reply = NULL; 330 char *msg, *reply = NULL;
331 size_t msg_len, reply_len = 0; 331 size_t reply_len = 0;
332 int ret = 0; 332 int ret = 0;
333 333
334 334
@@ -338,15 +338,12 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
338 if (!guest_info_param || !length) 338 if (!guest_info_param || !length)
339 return -EINVAL; 339 return -EINVAL;
340 340
341 msg_len = strlen(guest_info_param) + strlen("info-get ") + 1; 341 msg = kasprintf(GFP_KERNEL, "info-get %s", guest_info_param);
342 msg = kzalloc(msg_len, GFP_KERNEL);
343 if (!msg) { 342 if (!msg) {
344 DRM_ERROR("Cannot allocate memory to get %s", guest_info_param); 343 DRM_ERROR("Cannot allocate memory to get %s", guest_info_param);
345 return -ENOMEM; 344 return -ENOMEM;
346 } 345 }
347 346
348 sprintf(msg, "info-get %s", guest_info_param);
349
350 if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) || 347 if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) ||
351 vmw_send_msg(&channel, msg) || 348 vmw_send_msg(&channel, msg) ||
352 vmw_recv_msg(&channel, (void *) &reply, &reply_len) || 349 vmw_recv_msg(&channel, (void *) &reply, &reply_len) ||
@@ -388,7 +385,6 @@ int vmw_host_log(const char *log)
388{ 385{
389 struct rpc_channel channel; 386 struct rpc_channel channel;
390 char *msg; 387 char *msg;
391 int msg_len;
392 int ret = 0; 388 int ret = 0;
393 389
394 390
@@ -398,15 +394,12 @@ int vmw_host_log(const char *log)
398 if (!log) 394 if (!log)
399 return ret; 395 return ret;
400 396
401 msg_len = strlen(log) + strlen("log ") + 1; 397 msg = kasprintf(GFP_KERNEL, "log %s", log);
402 msg = kzalloc(msg_len, GFP_KERNEL);
403 if (!msg) { 398 if (!msg) {
404 DRM_ERROR("Cannot allocate memory for log message\n"); 399 DRM_ERROR("Cannot allocate memory for log message\n");
405 return -ENOMEM; 400 return -ENOMEM;
406 } 401 }
407 402
408 sprintf(msg, "log %s", log);
409
410 if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) || 403 if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) ||
411 vmw_send_msg(&channel, msg) || 404 vmw_send_msg(&channel, msg) ||
412 vmw_close_channel(&channel)) { 405 vmw_close_channel(&channel)) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 9e101450cc4d..6b3a942b18df 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -354,6 +354,7 @@ void vmw_dmabuf_bo_free(struct ttm_buffer_object *bo)
354{ 354{
355 struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo); 355 struct vmw_dma_buffer *vmw_bo = vmw_dma_buffer(bo);
356 356
357 vmw_dma_buffer_unmap(vmw_bo);
357 kfree(vmw_bo); 358 kfree(vmw_bo);
358} 359}
359 360
@@ -361,6 +362,7 @@ static void vmw_user_dmabuf_destroy(struct ttm_buffer_object *bo)
361{ 362{
362 struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo); 363 struct vmw_user_dma_buffer *vmw_user_bo = vmw_user_dma_buffer(bo);
363 364
365 vmw_dma_buffer_unmap(&vmw_user_bo->dma);
364 ttm_prime_object_kfree(vmw_user_bo, prime); 366 ttm_prime_object_kfree(vmw_user_bo, prime);
365} 367}
366 368
@@ -1239,6 +1241,12 @@ void vmw_resource_move_notify(struct ttm_buffer_object *bo,
1239 1241
1240 dma_buf = container_of(bo, struct vmw_dma_buffer, base); 1242 dma_buf = container_of(bo, struct vmw_dma_buffer, base);
1241 1243
1244 /*
1245 * Kill any cached kernel maps before move. An optimization could
1246 * be to do this iff source or destination memory type is VRAM.
1247 */
1248 vmw_dma_buffer_unmap(dma_buf);
1249
1242 if (mem->mem_type != VMW_PL_MOB) { 1250 if (mem->mem_type != VMW_PL_MOB) {
1243 struct vmw_resource *res, *n; 1251 struct vmw_resource *res, *n;
1244 struct ttm_validate_buffer val_buf; 1252 struct ttm_validate_buffer val_buf;
@@ -1262,6 +1270,21 @@ void vmw_resource_move_notify(struct ttm_buffer_object *bo,
1262} 1270}
1263 1271
1264 1272
1273/**
1274 * vmw_resource_swap_notify - swapout notify callback.
1275 *
1276 * @bo: The buffer object to be swapped out.
1277 */
1278void vmw_resource_swap_notify(struct ttm_buffer_object *bo)
1279{
1280 if (bo->destroy != vmw_dmabuf_bo_free &&
1281 bo->destroy != vmw_user_dmabuf_destroy)
1282 return;
1283
1284 /* Kill any cached kernel maps before swapout */
1285 vmw_dma_buffer_unmap(vmw_dma_buffer(bo));
1286}
1287
1265 1288
1266/** 1289/**
1267 * vmw_query_readback_all - Read back cached query states 1290 * vmw_query_readback_all - Read back cached query states
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 63a4cd794b73..419185f60278 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -316,69 +316,21 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
316 struct drm_modeset_acquire_ctx *ctx) 316 struct drm_modeset_acquire_ctx *ctx)
317{ 317{
318 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 318 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
319 struct drm_framebuffer *old_fb = crtc->primary->fb;
320 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb);
321 struct vmw_fence_obj *fence = NULL;
322 struct drm_vmw_rect vclips;
323 int ret; 319 int ret;
324 320
325 if (!vmw_kms_crtc_flippable(dev_priv, crtc)) 321 if (!vmw_kms_crtc_flippable(dev_priv, crtc))
326 return -EINVAL; 322 return -EINVAL;
327 323
328 flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; 324 ret = drm_atomic_helper_page_flip(crtc, new_fb, event, flags, ctx);
329 ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx);
330 if (ret) { 325 if (ret) {
331 DRM_ERROR("Page flip error %d.\n", ret); 326 DRM_ERROR("Page flip error %d.\n", ret);
332 return ret; 327 return ret;
333 } 328 }
334 329
335 /* do a full screen dirty update */
336 vclips.x = crtc->x;
337 vclips.y = crtc->y;
338 vclips.w = crtc->mode.hdisplay;
339 vclips.h = crtc->mode.vdisplay;
340
341 if (vfb->dmabuf)
342 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb,
343 NULL, &vclips, 1, 1,
344 true, &fence);
345 else
346 ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb,
347 NULL, &vclips, NULL,
348 0, 0, 1, 1, &fence);
349
350
351 if (ret != 0)
352 goto out_no_fence;
353 if (!fence) {
354 ret = -EINVAL;
355 goto out_no_fence;
356 }
357
358 if (event) {
359 struct drm_file *file_priv = event->base.file_priv;
360
361 ret = vmw_event_fence_action_queue(file_priv, fence,
362 &event->base,
363 &event->event.vbl.tv_sec,
364 &event->event.vbl.tv_usec,
365 true);
366 }
367
368 /*
369 * No need to hold on to this now. The only cleanup
370 * we need to do if we fail is unref the fence.
371 */
372 vmw_fence_obj_unreference(&fence);
373
374 if (vmw_crtc_to_du(crtc)->is_implicit) 330 if (vmw_crtc_to_du(crtc)->is_implicit)
375 vmw_kms_update_implicit_fb(dev_priv, crtc); 331 vmw_kms_update_implicit_fb(dev_priv, crtc);
376 332
377 return ret; 333 return ret;
378
379out_no_fence:
380 drm_atomic_set_fb_for_plane(crtc->primary->state, old_fb);
381 return ret;
382} 334}
383 335
384static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { 336static const struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
@@ -453,7 +405,11 @@ vmw_sou_primary_plane_cleanup_fb(struct drm_plane *plane,
453 struct drm_plane_state *old_state) 405 struct drm_plane_state *old_state)
454{ 406{
455 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); 407 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
408 struct drm_crtc *crtc = plane->state->crtc ?
409 plane->state->crtc : old_state->crtc;
456 410
411 if (vps->dmabuf)
412 vmw_dmabuf_unpin(vmw_priv(crtc->dev), vps->dmabuf, false);
457 vmw_dmabuf_unreference(&vps->dmabuf); 413 vmw_dmabuf_unreference(&vps->dmabuf);
458 vps->dmabuf_size = 0; 414 vps->dmabuf_size = 0;
459 415
@@ -491,10 +447,17 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,
491 } 447 }
492 448
493 size = new_state->crtc_w * new_state->crtc_h * 4; 449 size = new_state->crtc_w * new_state->crtc_h * 4;
450 dev_priv = vmw_priv(crtc->dev);
494 451
495 if (vps->dmabuf) { 452 if (vps->dmabuf) {
496 if (vps->dmabuf_size == size) 453 if (vps->dmabuf_size == size) {
497 return 0; 454 /*
455 * Note that this might temporarily up the pin-count
456 * to 2, until cleanup_fb() is called.
457 */
458 return vmw_dmabuf_pin_in_vram(dev_priv, vps->dmabuf,
459 true);
460 }
498 461
499 vmw_dmabuf_unreference(&vps->dmabuf); 462 vmw_dmabuf_unreference(&vps->dmabuf);
500 vps->dmabuf_size = 0; 463 vps->dmabuf_size = 0;
@@ -504,7 +467,6 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,
504 if (!vps->dmabuf) 467 if (!vps->dmabuf)
505 return -ENOMEM; 468 return -ENOMEM;
506 469
507 dev_priv = vmw_priv(crtc->dev);
508 vmw_svga_enable(dev_priv); 470 vmw_svga_enable(dev_priv);
509 471
510 /* After we have alloced the backing store might not be able to 472 /* After we have alloced the backing store might not be able to
@@ -515,13 +477,16 @@ vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,
515 &vmw_vram_ne_placement, 477 &vmw_vram_ne_placement,
516 false, &vmw_dmabuf_bo_free); 478 false, &vmw_dmabuf_bo_free);
517 vmw_overlay_resume_all(dev_priv); 479 vmw_overlay_resume_all(dev_priv);
518 480 if (ret) {
519 if (ret != 0)
520 vps->dmabuf = NULL; /* vmw_dmabuf_init frees on error */ 481 vps->dmabuf = NULL; /* vmw_dmabuf_init frees on error */
521 else 482 return ret;
522 vps->dmabuf_size = size; 483 }
523 484
524 return ret; 485 /*
486 * TTM already thinks the buffer is pinned, but make sure the
487 * pin_count is upped.
488 */
489 return vmw_dmabuf_pin_in_vram(dev_priv, vps->dmabuf, true);
525} 490}
526 491
527 492
@@ -530,9 +495,71 @@ vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,
530 struct drm_plane_state *old_state) 495 struct drm_plane_state *old_state)
531{ 496{
532 struct drm_crtc *crtc = plane->state->crtc; 497 struct drm_crtc *crtc = plane->state->crtc;
498 struct drm_pending_vblank_event *event = NULL;
499 struct vmw_fence_obj *fence = NULL;
500 int ret;
501
502 if (crtc && plane->state->fb) {
503 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
504 struct vmw_framebuffer *vfb =
505 vmw_framebuffer_to_vfb(plane->state->fb);
506 struct drm_vmw_rect vclips;
507
508 vclips.x = crtc->x;
509 vclips.y = crtc->y;
510 vclips.w = crtc->mode.hdisplay;
511 vclips.h = crtc->mode.vdisplay;
512
513 if (vfb->dmabuf)
514 ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, vfb, NULL,
515 &vclips, 1, 1, true,
516 &fence, crtc);
517 else
518 ret = vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL,
519 &vclips, NULL, 0, 0,
520 1, 1, &fence, crtc);
521
522 /*
523 * We cannot really fail this function, so if we do, then output
524 * an error and maintain consistent atomic state.
525 */
526 if (ret != 0)
527 DRM_ERROR("Failed to update screen.\n");
533 528
534 if (crtc)
535 crtc->primary->fb = plane->state->fb; 529 crtc->primary->fb = plane->state->fb;
530 } else {
531 /*
532 * When disabling a plane, CRTC and FB should always be NULL
533 * together, otherwise it's an error.
534 * Here primary plane is being disable so should really blank
535 * the screen object display unit, if not already done.
536 */
537 return;
538 }
539
540 event = crtc->state->event;
541 /*
542 * In case of failure and other cases, vblank event will be sent in
543 * vmw_du_crtc_atomic_flush.
544 */
545 if (event && fence) {
546 struct drm_file *file_priv = event->base.file_priv;
547
548 ret = vmw_event_fence_action_queue(file_priv,
549 fence,
550 &event->base,
551 &event->event.vbl.tv_sec,
552 &event->event.vbl.tv_usec,
553 true);
554
555 if (unlikely(ret != 0))
556 DRM_ERROR("Failed to queue event on fence.\n");
557 else
558 crtc->state->event = NULL;
559 }
560
561 if (fence)
562 vmw_fence_obj_unreference(&fence);
536} 563}
537 564
538 565
@@ -892,6 +919,7 @@ static void vmw_sou_surface_clip(struct vmw_kms_dirty *dirty)
892 * @out_fence: If non-NULL, will return a ref-counted pointer to a 919 * @out_fence: If non-NULL, will return a ref-counted pointer to a
893 * struct vmw_fence_obj. The returned fence pointer may be NULL in which 920 * struct vmw_fence_obj. The returned fence pointer may be NULL in which
894 * case the device has already synchronized. 921 * case the device has already synchronized.
922 * @crtc: If crtc is passed, perform surface dirty on that crtc only.
895 * 923 *
896 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if 924 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
897 * interrupted. 925 * interrupted.
@@ -904,7 +932,8 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
904 s32 dest_x, 932 s32 dest_x,
905 s32 dest_y, 933 s32 dest_y,
906 unsigned num_clips, int inc, 934 unsigned num_clips, int inc,
907 struct vmw_fence_obj **out_fence) 935 struct vmw_fence_obj **out_fence,
936 struct drm_crtc *crtc)
908{ 937{
909 struct vmw_framebuffer_surface *vfbs = 938 struct vmw_framebuffer_surface *vfbs =
910 container_of(framebuffer, typeof(*vfbs), base); 939 container_of(framebuffer, typeof(*vfbs), base);
@@ -923,6 +952,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
923 sdirty.base.dev_priv = dev_priv; 952 sdirty.base.dev_priv = dev_priv;
924 sdirty.base.fifo_reserve_size = sizeof(struct vmw_kms_sou_dirty_cmd) + 953 sdirty.base.fifo_reserve_size = sizeof(struct vmw_kms_sou_dirty_cmd) +
925 sizeof(SVGASignedRect) * num_clips; 954 sizeof(SVGASignedRect) * num_clips;
955 sdirty.base.crtc = crtc;
926 956
927 sdirty.sid = srf->id; 957 sdirty.sid = srf->id;
928 sdirty.left = sdirty.top = S32_MAX; 958 sdirty.left = sdirty.top = S32_MAX;
@@ -994,6 +1024,7 @@ static void vmw_sou_dmabuf_clip(struct vmw_kms_dirty *dirty)
994 * @out_fence: If non-NULL, will return a ref-counted pointer to a 1024 * @out_fence: If non-NULL, will return a ref-counted pointer to a
995 * struct vmw_fence_obj. The returned fence pointer may be NULL in which 1025 * struct vmw_fence_obj. The returned fence pointer may be NULL in which
996 * case the device has already synchronized. 1026 * case the device has already synchronized.
1027 * @crtc: If crtc is passed, perform dmabuf dirty on that crtc only.
997 * 1028 *
998 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if 1029 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
999 * interrupted. 1030 * interrupted.
@@ -1004,7 +1035,8 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
1004 struct drm_vmw_rect *vclips, 1035 struct drm_vmw_rect *vclips,
1005 unsigned num_clips, int increment, 1036 unsigned num_clips, int increment,
1006 bool interruptible, 1037 bool interruptible,
1007 struct vmw_fence_obj **out_fence) 1038 struct vmw_fence_obj **out_fence,
1039 struct drm_crtc *crtc)
1008{ 1040{
1009 struct vmw_dma_buffer *buf = 1041 struct vmw_dma_buffer *buf =
1010 container_of(framebuffer, struct vmw_framebuffer_dmabuf, 1042 container_of(framebuffer, struct vmw_framebuffer_dmabuf,
@@ -1013,7 +1045,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
1013 int ret; 1045 int ret;
1014 1046
1015 ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, interruptible, 1047 ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, interruptible,
1016 false); 1048 false, false);
1017 if (ret) 1049 if (ret)
1018 return ret; 1050 return ret;
1019 1051
@@ -1021,6 +1053,7 @@ int vmw_kms_sou_do_dmabuf_dirty(struct vmw_private *dev_priv,
1021 if (unlikely(ret != 0)) 1053 if (unlikely(ret != 0))
1022 goto out_revert; 1054 goto out_revert;
1023 1055
1056 dirty.crtc = crtc;
1024 dirty.fifo_commit = vmw_sou_dmabuf_fifo_commit; 1057 dirty.fifo_commit = vmw_sou_dmabuf_fifo_commit;
1025 dirty.clip = vmw_sou_dmabuf_clip; 1058 dirty.clip = vmw_sou_dmabuf_clip;
1026 dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) * 1059 dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_dmabuf_blit) *
@@ -1092,6 +1125,7 @@ static void vmw_sou_readback_clip(struct vmw_kms_dirty *dirty)
1092 * Must be set to non-NULL if @file_priv is non-NULL. 1125 * Must be set to non-NULL if @file_priv is non-NULL.
1093 * @vclips: Array of clip rects. 1126 * @vclips: Array of clip rects.
1094 * @num_clips: Number of clip rects in @vclips. 1127 * @num_clips: Number of clip rects in @vclips.
1128 * @crtc: If crtc is passed, readback on that crtc only.
1095 * 1129 *
1096 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if 1130 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
1097 * interrupted. 1131 * interrupted.
@@ -1101,14 +1135,16 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
1101 struct vmw_framebuffer *vfb, 1135 struct vmw_framebuffer *vfb,
1102 struct drm_vmw_fence_rep __user *user_fence_rep, 1136 struct drm_vmw_fence_rep __user *user_fence_rep,
1103 struct drm_vmw_rect *vclips, 1137 struct drm_vmw_rect *vclips,
1104 uint32_t num_clips) 1138 uint32_t num_clips,
1139 struct drm_crtc *crtc)
1105{ 1140{
1106 struct vmw_dma_buffer *buf = 1141 struct vmw_dma_buffer *buf =
1107 container_of(vfb, struct vmw_framebuffer_dmabuf, base)->buffer; 1142 container_of(vfb, struct vmw_framebuffer_dmabuf, base)->buffer;
1108 struct vmw_kms_dirty dirty; 1143 struct vmw_kms_dirty dirty;
1109 int ret; 1144 int ret;
1110 1145
1111 ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, true, false); 1146 ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, true, false,
1147 false);
1112 if (ret) 1148 if (ret)
1113 return ret; 1149 return ret;
1114 1150
@@ -1116,6 +1152,7 @@ int vmw_kms_sou_readback(struct vmw_private *dev_priv,
1116 if (unlikely(ret != 0)) 1152 if (unlikely(ret != 0))
1117 goto out_revert; 1153 goto out_revert;
1118 1154
1155 dirty.crtc = crtc;
1119 dirty.fifo_commit = vmw_sou_readback_fifo_commit; 1156 dirty.fifo_commit = vmw_sou_readback_fifo_commit;
1120 dirty.clip = vmw_sou_readback_clip; 1157 dirty.clip = vmw_sou_readback_clip;
1121 dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_readback_blit) * 1158 dirty.fifo_reserve_size = sizeof(struct vmw_kms_sou_readback_blit) *
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index b68d74888ab1..8eec88920851 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -114,7 +114,6 @@ struct vmw_screen_target_display_unit {
114 bool defined; 114 bool defined;
115 115
116 /* For CPU Blit */ 116 /* For CPU Blit */
117 struct ttm_bo_kmap_obj host_map;
118 unsigned int cpp; 117 unsigned int cpp;
119}; 118};
120 119
@@ -492,71 +491,17 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
492{ 491{
493 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 492 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
494 struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc); 493 struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc);
495 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb);
496 struct drm_vmw_rect vclips;
497 int ret; 494 int ret;
498 495
499 dev_priv = vmw_priv(crtc->dev);
500 stdu = vmw_crtc_to_stdu(crtc);
501
502 if (!stdu->defined || !vmw_kms_crtc_flippable(dev_priv, crtc)) 496 if (!stdu->defined || !vmw_kms_crtc_flippable(dev_priv, crtc))
503 return -EINVAL; 497 return -EINVAL;
504 498
505 /* 499 ret = drm_atomic_helper_page_flip(crtc, new_fb, event, flags, ctx);
506 * We're always async, but the helper doesn't know how to set async
507 * so lie to the helper. Also, the helper expects someone
508 * to pick the event up from the crtc state, and if nobody does,
509 * it will free it. Since we handle the event in this function,
510 * don't hand it to the helper.
511 */
512 flags &= ~DRM_MODE_PAGE_FLIP_ASYNC;
513 ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags, ctx);
514 if (ret) { 500 if (ret) {
515 DRM_ERROR("Page flip error %d.\n", ret); 501 DRM_ERROR("Page flip error %d.\n", ret);
516 return ret; 502 return ret;
517 } 503 }
518 504
519 if (stdu->base.is_implicit)
520 vmw_kms_update_implicit_fb(dev_priv, crtc);
521
522 /*
523 * Now that we've bound a new surface to the screen target,
524 * update the contents.
525 */
526 vclips.x = crtc->x;
527 vclips.y = crtc->y;
528 vclips.w = crtc->mode.hdisplay;
529 vclips.h = crtc->mode.vdisplay;
530
531 if (vfb->dmabuf)
532 ret = vmw_kms_stdu_dma(dev_priv, NULL, vfb, NULL, NULL, &vclips,
533 1, 1, true, false);
534 else
535 ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, &vclips,
536 NULL, 0, 0, 1, 1, NULL);
537 if (ret) {
538 DRM_ERROR("Page flip update error %d.\n", ret);
539 return ret;
540 }
541
542 if (event) {
543 struct vmw_fence_obj *fence = NULL;
544 struct drm_file *file_priv = event->base.file_priv;
545
546 vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
547 if (!fence)
548 return -ENOMEM;
549
550 ret = vmw_event_fence_action_queue(file_priv, fence,
551 &event->base,
552 &event->event.vbl.tv_sec,
553 &event->event.vbl.tv_usec,
554 true);
555 vmw_fence_obj_unreference(&fence);
556 } else {
557 (void) vmw_fifo_flush(dev_priv, false);
558 }
559
560 return 0; 505 return 0;
561} 506}
562 507
@@ -693,10 +638,9 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
693 container_of(dirty->unit, typeof(*stdu), base); 638 container_of(dirty->unit, typeof(*stdu), base);
694 s32 width, height; 639 s32 width, height;
695 s32 src_pitch, dst_pitch; 640 s32 src_pitch, dst_pitch;
696 u8 *src, *dst; 641 struct ttm_buffer_object *src_bo, *dst_bo;
697 bool not_used; 642 u32 src_offset, dst_offset;
698 struct ttm_bo_kmap_obj guest_map; 643 struct vmw_diff_cpy diff = VMW_CPU_BLIT_DIFF_INITIALIZER(stdu->cpp);
699 int ret;
700 644
701 if (!dirty->num_hits) 645 if (!dirty->num_hits)
702 return; 646 return;
@@ -707,57 +651,38 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
707 if (width == 0 || height == 0) 651 if (width == 0 || height == 0)
708 return; 652 return;
709 653
710 ret = ttm_bo_kmap(&ddirty->buf->base, 0, ddirty->buf->base.num_pages, 654 /* Assume we are blitting from Guest (dmabuf) to Host (display_srf) */
711 &guest_map); 655 dst_pitch = stdu->display_srf->base_size.width * stdu->cpp;
712 if (ret) { 656 dst_bo = &stdu->display_srf->res.backup->base;
713 DRM_ERROR("Failed mapping framebuffer for blit: %d\n", 657 dst_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp;
714 ret);
715 goto out_cleanup;
716 }
717
718 /* Assume we are blitting from Host (display_srf) to Guest (dmabuf) */
719 src_pitch = stdu->display_srf->base_size.width * stdu->cpp;
720 src = ttm_kmap_obj_virtual(&stdu->host_map, &not_used);
721 src += ddirty->top * src_pitch + ddirty->left * stdu->cpp;
722
723 dst_pitch = ddirty->pitch;
724 dst = ttm_kmap_obj_virtual(&guest_map, &not_used);
725 dst += ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp;
726
727
728 /* Figure out the real direction */
729 if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM) {
730 u8 *tmp;
731 s32 tmp_pitch;
732
733 tmp = src;
734 tmp_pitch = src_pitch;
735 658
736 src = dst; 659 src_pitch = ddirty->pitch;
737 src_pitch = dst_pitch; 660 src_bo = &ddirty->buf->base;
661 src_offset = ddirty->fb_top * src_pitch + ddirty->fb_left * stdu->cpp;
738 662
739 dst = tmp; 663 /* Swap src and dst if the assumption was wrong. */
740 dst_pitch = tmp_pitch; 664 if (ddirty->transfer != SVGA3D_WRITE_HOST_VRAM) {
665 swap(dst_pitch, src_pitch);
666 swap(dst_bo, src_bo);
667 swap(src_offset, dst_offset);
741 } 668 }
742 669
743 /* CPU Blit */ 670 (void) vmw_bo_cpu_blit(dst_bo, dst_offset, dst_pitch,
744 while (height-- > 0) { 671 src_bo, src_offset, src_pitch,
745 memcpy(dst, src, width * stdu->cpp); 672 width * stdu->cpp, height, &diff);
746 dst += dst_pitch;
747 src += src_pitch;
748 }
749 673
750 if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM) { 674 if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM &&
675 drm_rect_visible(&diff.rect)) {
751 struct vmw_private *dev_priv; 676 struct vmw_private *dev_priv;
752 struct vmw_stdu_update *cmd; 677 struct vmw_stdu_update *cmd;
753 struct drm_clip_rect region; 678 struct drm_clip_rect region;
754 int ret; 679 int ret;
755 680
756 /* We are updating the actual surface, not a proxy */ 681 /* We are updating the actual surface, not a proxy */
757 region.x1 = ddirty->left; 682 region.x1 = diff.rect.x1;
758 region.x2 = ddirty->right; 683 region.x2 = diff.rect.x2;
759 region.y1 = ddirty->top; 684 region.y1 = diff.rect.y1;
760 region.y2 = ddirty->bottom; 685 region.y2 = diff.rect.y2;
761 ret = vmw_kms_update_proxy( 686 ret = vmw_kms_update_proxy(
762 (struct vmw_resource *) &stdu->display_srf->res, 687 (struct vmw_resource *) &stdu->display_srf->res,
763 (const struct drm_clip_rect *) &region, 1, 1); 688 (const struct drm_clip_rect *) &region, 1, 1);
@@ -774,13 +699,12 @@ static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
774 } 699 }
775 700
776 vmw_stdu_populate_update(cmd, stdu->base.unit, 701 vmw_stdu_populate_update(cmd, stdu->base.unit,
777 ddirty->left, ddirty->right, 702 region.x1, region.x2,
778 ddirty->top, ddirty->bottom); 703 region.y1, region.y2);
779 704
780 vmw_fifo_commit(dev_priv, sizeof(*cmd)); 705 vmw_fifo_commit(dev_priv, sizeof(*cmd));
781 } 706 }
782 707
783 ttm_bo_kunmap(&guest_map);
784out_cleanup: 708out_cleanup:
785 ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX; 709 ddirty->left = ddirty->top = ddirty->fb_left = ddirty->fb_top = S32_MAX;
786 ddirty->right = ddirty->bottom = S32_MIN; 710 ddirty->right = ddirty->bottom = S32_MIN;
@@ -802,6 +726,7 @@ out_cleanup:
802 * @to_surface: Whether to DMA to the screen target system as opposed to 726 * @to_surface: Whether to DMA to the screen target system as opposed to
803 * from the screen target system. 727 * from the screen target system.
804 * @interruptible: Whether to perform waits interruptible if possible. 728 * @interruptible: Whether to perform waits interruptible if possible.
729 * @crtc: If crtc is passed, perform stdu dma on that crtc only.
805 * 730 *
806 * If DMA-ing till the screen target system, the function will also notify 731 * If DMA-ing till the screen target system, the function will also notify
807 * the screen target system that a bounding box of the cliprects has been 732 * the screen target system that a bounding box of the cliprects has been
@@ -818,15 +743,22 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
818 uint32_t num_clips, 743 uint32_t num_clips,
819 int increment, 744 int increment,
820 bool to_surface, 745 bool to_surface,
821 bool interruptible) 746 bool interruptible,
747 struct drm_crtc *crtc)
822{ 748{
823 struct vmw_dma_buffer *buf = 749 struct vmw_dma_buffer *buf =
824 container_of(vfb, struct vmw_framebuffer_dmabuf, base)->buffer; 750 container_of(vfb, struct vmw_framebuffer_dmabuf, base)->buffer;
825 struct vmw_stdu_dirty ddirty; 751 struct vmw_stdu_dirty ddirty;
826 int ret; 752 int ret;
753 bool cpu_blit = !(dev_priv->capabilities & SVGA_CAP_3D);
827 754
755 /*
756 * VMs without 3D support don't have the surface DMA command and
757 * we'll be using a CPU blit, and the framebuffer should be moved out
758 * of VRAM.
759 */
828 ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, interruptible, 760 ret = vmw_kms_helper_buffer_prepare(dev_priv, buf, interruptible,
829 false); 761 false, cpu_blit);
830 if (ret) 762 if (ret)
831 return ret; 763 return ret;
832 764
@@ -845,13 +777,15 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
845 if (to_surface) 777 if (to_surface)
846 ddirty.base.fifo_reserve_size += sizeof(struct vmw_stdu_update); 778 ddirty.base.fifo_reserve_size += sizeof(struct vmw_stdu_update);
847 779
848 /* 2D VMs cannot use SVGA_3D_CMD_SURFACE_DMA so do CPU blit instead */ 780
849 if (!(dev_priv->capabilities & SVGA_CAP_3D)) { 781 if (cpu_blit) {
850 ddirty.base.fifo_commit = vmw_stdu_dmabuf_cpu_commit; 782 ddirty.base.fifo_commit = vmw_stdu_dmabuf_cpu_commit;
851 ddirty.base.clip = vmw_stdu_dmabuf_cpu_clip; 783 ddirty.base.clip = vmw_stdu_dmabuf_cpu_clip;
852 ddirty.base.fifo_reserve_size = 0; 784 ddirty.base.fifo_reserve_size = 0;
853 } 785 }
854 786
787 ddirty.base.crtc = crtc;
788
855 ret = vmw_kms_helper_dirty(dev_priv, vfb, clips, vclips, 789 ret = vmw_kms_helper_dirty(dev_priv, vfb, clips, vclips,
856 0, 0, num_clips, increment, &ddirty.base); 790 0, 0, num_clips, increment, &ddirty.base);
857 vmw_kms_helper_buffer_finish(dev_priv, file_priv, buf, NULL, 791 vmw_kms_helper_buffer_finish(dev_priv, file_priv, buf, NULL,
@@ -963,6 +897,7 @@ static void vmw_kms_stdu_surface_fifo_commit(struct vmw_kms_dirty *dirty)
963 * @out_fence: If non-NULL, will return a ref-counted pointer to a 897 * @out_fence: If non-NULL, will return a ref-counted pointer to a
964 * struct vmw_fence_obj. The returned fence pointer may be NULL in which 898 * struct vmw_fence_obj. The returned fence pointer may be NULL in which
965 * case the device has already synchronized. 899 * case the device has already synchronized.
900 * @crtc: If crtc is passed, perform surface dirty on that crtc only.
966 * 901 *
967 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if 902 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
968 * interrupted. 903 * interrupted.
@@ -975,7 +910,8 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
975 s32 dest_x, 910 s32 dest_x,
976 s32 dest_y, 911 s32 dest_y,
977 unsigned num_clips, int inc, 912 unsigned num_clips, int inc,
978 struct vmw_fence_obj **out_fence) 913 struct vmw_fence_obj **out_fence,
914 struct drm_crtc *crtc)
979{ 915{
980 struct vmw_framebuffer_surface *vfbs = 916 struct vmw_framebuffer_surface *vfbs =
981 container_of(framebuffer, typeof(*vfbs), base); 917 container_of(framebuffer, typeof(*vfbs), base);
@@ -1000,6 +936,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
1000 sdirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_surface_copy) + 936 sdirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_surface_copy) +
1001 sizeof(SVGA3dCopyBox) * num_clips + 937 sizeof(SVGA3dCopyBox) * num_clips +
1002 sizeof(struct vmw_stdu_update); 938 sizeof(struct vmw_stdu_update);
939 sdirty.base.crtc = crtc;
1003 sdirty.sid = srf->id; 940 sdirty.sid = srf->id;
1004 sdirty.left = sdirty.top = S32_MAX; 941 sdirty.left = sdirty.top = S32_MAX;
1005 sdirty.right = sdirty.bottom = S32_MIN; 942 sdirty.right = sdirty.bottom = S32_MIN;
@@ -1118,9 +1055,6 @@ vmw_stdu_primary_plane_cleanup_fb(struct drm_plane *plane,
1118{ 1055{
1119 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state); 1056 struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
1120 1057
1121 if (vps->host_map.virtual)
1122 ttm_bo_kunmap(&vps->host_map);
1123
1124 if (vps->surf) 1058 if (vps->surf)
1125 WARN_ON(!vps->pinned); 1059 WARN_ON(!vps->pinned);
1126 1060
@@ -1282,24 +1216,11 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
1282 * so cache these mappings 1216 * so cache these mappings
1283 */ 1217 */
1284 if (vps->content_fb_type == SEPARATE_DMA && 1218 if (vps->content_fb_type == SEPARATE_DMA &&
1285 !(dev_priv->capabilities & SVGA_CAP_3D)) { 1219 !(dev_priv->capabilities & SVGA_CAP_3D))
1286 ret = ttm_bo_kmap(&vps->surf->res.backup->base, 0,
1287 vps->surf->res.backup->base.num_pages,
1288 &vps->host_map);
1289 if (ret) {
1290 DRM_ERROR("Failed to map display buffer to CPU\n");
1291 goto out_srf_unpin;
1292 }
1293
1294 vps->cpp = new_fb->pitches[0] / new_fb->width; 1220 vps->cpp = new_fb->pitches[0] / new_fb->width;
1295 }
1296 1221
1297 return 0; 1222 return 0;
1298 1223
1299out_srf_unpin:
1300 vmw_resource_unpin(&vps->surf->res);
1301 vps->pinned--;
1302
1303out_srf_unref: 1224out_srf_unref:
1304 vmw_surface_unreference(&vps->surf); 1225 vmw_surface_unreference(&vps->surf);
1305 return ret; 1226 return ret;
@@ -1322,41 +1243,104 @@ static void
1322vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane, 1243vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,
1323 struct drm_plane_state *old_state) 1244 struct drm_plane_state *old_state)
1324{ 1245{
1325 struct vmw_private *dev_priv;
1326 struct vmw_screen_target_display_unit *stdu;
1327 struct vmw_plane_state *vps = vmw_plane_state_to_vps(plane->state); 1246 struct vmw_plane_state *vps = vmw_plane_state_to_vps(plane->state);
1328 struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc; 1247 struct drm_crtc *crtc = plane->state->crtc;
1248 struct vmw_screen_target_display_unit *stdu;
1249 struct drm_pending_vblank_event *event;
1250 struct vmw_private *dev_priv;
1329 int ret; 1251 int ret;
1330 1252
1331 stdu = vmw_crtc_to_stdu(crtc); 1253 /*
1332 dev_priv = vmw_priv(crtc->dev); 1254 * We cannot really fail this function, so if we do, then output an
1255 * error and maintain consistent atomic state.
1256 */
1257 if (crtc && plane->state->fb) {
1258 struct vmw_framebuffer *vfb =
1259 vmw_framebuffer_to_vfb(plane->state->fb);
1260 struct drm_vmw_rect vclips;
1261 stdu = vmw_crtc_to_stdu(crtc);
1262 dev_priv = vmw_priv(crtc->dev);
1263
1264 stdu->display_srf = vps->surf;
1265 stdu->content_fb_type = vps->content_fb_type;
1266 stdu->cpp = vps->cpp;
1267
1268 vclips.x = crtc->x;
1269 vclips.y = crtc->y;
1270 vclips.w = crtc->mode.hdisplay;
1271 vclips.h = crtc->mode.vdisplay;
1272
1273 ret = vmw_stdu_bind_st(dev_priv, stdu, &stdu->display_srf->res);
1274 if (ret)
1275 DRM_ERROR("Failed to bind surface to STDU.\n");
1276
1277 if (vfb->dmabuf)
1278 ret = vmw_kms_stdu_dma(dev_priv, NULL, vfb, NULL, NULL,
1279 &vclips, 1, 1, true, false,
1280 crtc);
1281 else
1282 ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL,
1283 &vclips, NULL, 0, 0,
1284 1, 1, NULL, crtc);
1285 if (ret)
1286 DRM_ERROR("Failed to update STDU.\n");
1333 1287
1334 stdu->display_srf = vps->surf; 1288 crtc->primary->fb = plane->state->fb;
1335 stdu->content_fb_type = vps->content_fb_type; 1289 } else {
1336 stdu->cpp = vps->cpp; 1290 crtc = old_state->crtc;
1337 memcpy(&stdu->host_map, &vps->host_map, sizeof(vps->host_map)); 1291 stdu = vmw_crtc_to_stdu(crtc);
1292 dev_priv = vmw_priv(crtc->dev);
1338 1293
1339 if (!stdu->defined) 1294 /*
1340 return; 1295 * When disabling a plane, CRTC and FB should always be NULL
1296 * together, otherwise it's an error.
1297 * Here primary plane is being disable so blank the screen
1298 * target display unit, if not already done.
1299 */
1300 if (!stdu->defined)
1301 return;
1341 1302
1342 if (plane->state->fb)
1343 ret = vmw_stdu_bind_st(dev_priv, stdu, &stdu->display_srf->res);
1344 else
1345 ret = vmw_stdu_bind_st(dev_priv, stdu, NULL); 1303 ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
1304 if (ret)
1305 DRM_ERROR("Failed to blank STDU\n");
1306
1307 ret = vmw_stdu_update_st(dev_priv, stdu);
1308 if (ret)
1309 DRM_ERROR("Failed to update STDU.\n");
1310
1311 return;
1312 }
1346 1313
1314 event = crtc->state->event;
1347 /* 1315 /*
1348 * We cannot really fail this function, so if we do, then output an 1316 * In case of failure and other cases, vblank event will be sent in
1349 * error and quit 1317 * vmw_du_crtc_atomic_flush.
1350 */ 1318 */
1351 if (ret) 1319 if (event && (ret == 0)) {
1352 DRM_ERROR("Failed to bind surface to STDU.\n"); 1320 struct vmw_fence_obj *fence = NULL;
1353 else 1321 struct drm_file *file_priv = event->base.file_priv;
1354 crtc->primary->fb = plane->state->fb;
1355 1322
1356 ret = vmw_stdu_update_st(dev_priv, stdu); 1323 vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
1357 1324
1358 if (ret) 1325 /*
1359 DRM_ERROR("Failed to update STDU.\n"); 1326 * If fence is NULL, then already sync.
1327 */
1328 if (fence) {
1329 ret = vmw_event_fence_action_queue(
1330 file_priv, fence, &event->base,
1331 &event->event.vbl.tv_sec,
1332 &event->event.vbl.tv_usec,
1333 true);
1334 if (ret)
1335 DRM_ERROR("Failed to queue event on fence.\n");
1336 else
1337 crtc->state->event = NULL;
1338
1339 vmw_fence_obj_unreference(&fence);
1340 }
1341 } else {
1342 (void) vmw_fifo_flush(dev_priv, false);
1343 }
1360} 1344}
1361 1345
1362 1346
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index db1bb166845e..b236c48bf265 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -345,7 +345,6 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res)
345 dev_priv->used_memory_size -= res->backup_size; 345 dev_priv->used_memory_size -= res->backup_size;
346 mutex_unlock(&dev_priv->cmdbuf_mutex); 346 mutex_unlock(&dev_priv->cmdbuf_mutex);
347 } 347 }
348 vmw_fifo_resource_dec(dev_priv);
349} 348}
350 349
351/** 350/**
@@ -407,6 +406,8 @@ static int vmw_legacy_srf_create(struct vmw_resource *res)
407 406
408 vmw_surface_define_encode(srf, cmd); 407 vmw_surface_define_encode(srf, cmd);
409 vmw_fifo_commit(dev_priv, submit_size); 408 vmw_fifo_commit(dev_priv, submit_size);
409 vmw_fifo_resource_inc(dev_priv);
410
410 /* 411 /*
411 * Surface memory usage accounting. 412 * Surface memory usage accounting.
412 */ 413 */
@@ -558,6 +559,7 @@ static int vmw_legacy_srf_destroy(struct vmw_resource *res)
558 */ 559 */
559 560
560 vmw_resource_release_id(res); 561 vmw_resource_release_id(res);
562 vmw_fifo_resource_dec(dev_priv);
561 563
562 return 0; 564 return 0;
563} 565}
@@ -579,15 +581,11 @@ static int vmw_surface_init(struct vmw_private *dev_priv,
579 struct vmw_resource *res = &srf->res; 581 struct vmw_resource *res = &srf->res;
580 582
581 BUG_ON(!res_free); 583 BUG_ON(!res_free);
582 if (!dev_priv->has_mob)
583 vmw_fifo_resource_inc(dev_priv);
584 ret = vmw_resource_init(dev_priv, res, true, res_free, 584 ret = vmw_resource_init(dev_priv, res, true, res_free,
585 (dev_priv->has_mob) ? &vmw_gb_surface_func : 585 (dev_priv->has_mob) ? &vmw_gb_surface_func :
586 &vmw_legacy_surface_func); 586 &vmw_legacy_surface_func);
587 587
588 if (unlikely(ret != 0)) { 588 if (unlikely(ret != 0)) {
589 if (!dev_priv->has_mob)
590 vmw_fifo_resource_dec(dev_priv);
591 res_free(res); 589 res_free(res);
592 return ret; 590 return ret;
593 } 591 }
diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
index 8e2fb1ac4e0c..c67977aa1a0e 100644
--- a/include/drm/ttm/ttm_bo_api.h
+++ b/include/drm/ttm/ttm_bo_api.h
@@ -709,6 +709,10 @@ int ttm_fbdev_mmap(struct vm_area_struct *vma, struct ttm_buffer_object *bo);
709int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma, 709int ttm_bo_mmap(struct file *filp, struct vm_area_struct *vma,
710 struct ttm_bo_device *bdev); 710 struct ttm_bo_device *bdev);
711 711
712void *ttm_kmap_atomic_prot(struct page *page, pgprot_t prot);
713
714void ttm_kunmap_atomic_prot(void *addr, pgprot_t prot);
715
712/** 716/**
713 * ttm_bo_io 717 * ttm_bo_io
714 * 718 *