Subversion Repositories Kolibri OS

Rev

Rev 5078 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5078 Rev 6296
Line 1... Line 1...
1
/**************************************************************************
1
/**************************************************************************
2
 *
2
 *
3
 * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
3
 * Copyright © 2009-2015 VMware, Inc., Palo Alto, CA., USA
4
 * All Rights Reserved.
4
 * All Rights Reserved.
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
8
 * "Software"), to deal in the Software without restriction, including
Line 29... Line 29...
29
 
29
 
30
 
30
 
Line 31... Line -...
31
/* Might need a hrtimer here? */
-
 
32
#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
-
 
33
 
-
 
34
 
-
 
35
struct vmw_clip_rect {
-
 
36
	int x1, x2, y1, y2;
-
 
37
};
-
 
38
 
-
 
39
/**
-
 
40
 * Clip @num_rects number of @rects against @clip storing the
-
 
41
 * results in @out_rects and the number of passed rects in @out_num.
-
 
42
 */
-
 
43
static void vmw_clip_cliprects(struct drm_clip_rect *rects,
-
 
44
			int num_rects,
-
 
45
			struct vmw_clip_rect clip,
-
 
46
			SVGASignedRect *out_rects,
-
 
47
			int *out_num)
-
 
48
{
-
 
49
	int i, k;
-
 
50
 
-
 
51
	for (i = 0, k = 0; i < num_rects; i++) {
-
 
52
		int x1 = max_t(int, clip.x1, rects[i].x1);
-
 
53
		int y1 = max_t(int, clip.y1, rects[i].y1);
-
 
54
		int x2 = min_t(int, clip.x2, rects[i].x2);
-
 
55
		int y2 = min_t(int, clip.y2, rects[i].y2);
-
 
56
 
-
 
57
		if (x1 >= x2)
-
 
58
			continue;
-
 
59
		if (y1 >= y2)
-
 
60
			continue;
-
 
61
 
-
 
62
		out_rects[k].left   = x1;
-
 
63
		out_rects[k].top    = y1;
-
 
64
		out_rects[k].right  = x2;
-
 
65
		out_rects[k].bottom = y2;
-
 
66
		k++;
-
 
67
	}
-
 
68
 
-
 
69
	*out_num = k;
31
/* Might need a hrtimer here? */
70
}
32
#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
71
 
33
 
72
void vmw_display_unit_cleanup(struct vmw_display_unit *du)
34
void vmw_du_cleanup(struct vmw_display_unit *du)
73
{
35
{
74
//   if (du->cursor_surface)
36
//   if (du->cursor_surface)
-
 
37
//       vmw_surface_unreference(&du->cursor_surface);
75
//       vmw_surface_unreference(&du->cursor_surface);
38
//   if (du->cursor_dmabuf)
76
//   if (du->cursor_dmabuf)
39
//       vmw_dmabuf_unreference(&du->cursor_dmabuf);
77
//       vmw_dmabuf_unreference(&du->cursor_dmabuf);
40
	drm_connector_unregister(&du->connector);
78
	drm_crtc_cleanup(&du->crtc);
41
	drm_crtc_cleanup(&du->crtc);
Line 118... Line 81...
118
            *dst++ = 0;
81
            *dst++ = 0;
119
    }
82
    }
120
    for(i = 0; i < 64*(64-32); i++)
83
    for(i = 0; i < 64*(64-32); i++)
121
        *dst++ = 0;
84
        *dst++ = 0;
Line 122... Line 85...
122
 
85
 
123
	cmd->cmd = cpu_to_le32(SVGA_CMD_DEFINE_ALPHA_CURSOR);
86
	cmd->cmd = SVGA_CMD_DEFINE_ALPHA_CURSOR;
124
	cmd->cursor.id = cpu_to_le32(0);
87
	cmd->cursor.id = 0;
125
	cmd->cursor.width = cpu_to_le32(width);
88
	cmd->cursor.width = width;
126
	cmd->cursor.height = cpu_to_le32(height);
89
	cmd->cursor.height = height;
127
	cmd->cursor.hotspotX = cpu_to_le32(hotspotX);
90
	cmd->cursor.hotspotX = hotspotX;
Line 128... Line 91...
128
	cmd->cursor.hotspotY = cpu_to_le32(hotspotY);
91
	cmd->cursor.hotspotY = hotspotY;
Line 129... Line 92...
129
 
92
 
130
	vmw_fifo_commit(dev_priv, cmd_size);
93
	vmw_fifo_commit_flush(dev_priv, cmd_size);
Line 131... Line 94...
131
 
94
 
Line 171... Line 134...
171
#endif
134
#endif
Line 172... Line 135...
172
 
135
 
173
void vmw_cursor_update_position(struct vmw_private *dev_priv,
136
void vmw_cursor_update_position(struct vmw_private *dev_priv,
174
				bool show, int x, int y)
137
				bool show, int x, int y)
175
{
138
{
176
	__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
139
	u32 *fifo_mem = dev_priv->mmio_virt;
Line 177... Line 140...
177
	uint32_t count;
140
	uint32_t count;
178
 
141
 
179
	iowrite32(show ? 1 : 0, fifo_mem + SVGA_FIFO_CURSOR_ON);
142
	vmw_mmio_write(show ? 1 : 0, fifo_mem + SVGA_FIFO_CURSOR_ON);
180
	iowrite32(x, fifo_mem + SVGA_FIFO_CURSOR_X);
143
	vmw_mmio_write(x, fifo_mem + SVGA_FIFO_CURSOR_X);
181
	iowrite32(y, fifo_mem + SVGA_FIFO_CURSOR_Y);
144
	vmw_mmio_write(y, fifo_mem + SVGA_FIFO_CURSOR_Y);
182
	count = ioread32(fifo_mem + SVGA_FIFO_CURSOR_COUNT);
145
	count = vmw_mmio_read(fifo_mem + SVGA_FIFO_CURSOR_COUNT);
Line 183... Line 146...
183
	iowrite32(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
146
	vmw_mmio_write(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT);
-
 
147
}
-
 
148
 
-
 
149
#if 0
184
}
150
/*
185
 
151
 * vmw_du_crtc_cursor_set2 - Driver cursor_set2 callback.
-
 
152
 */
186
#if 0
153
int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
187
int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
154
			    uint32_t handle, uint32_t width, uint32_t height,
188
			   uint32_t handle, uint32_t width, uint32_t height)
155
			    int32_t hot_x, int32_t hot_y)
189
{
156
{
190
	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
157
	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
-
 
158
	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
191
	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
159
	struct vmw_surface *surface = NULL;
Line 192... Line 160...
192
	struct vmw_surface *surface = NULL;
160
	struct vmw_dma_buffer *dmabuf = NULL;
193
	struct vmw_dma_buffer *dmabuf = NULL;
161
	s32 hotspot_x, hotspot_y;
194
	int ret;
162
	int ret;
195
 
163
 
196
	/*
164
	/*
197
	 * FIXME: Unclear whether there's any global state touched by the
165
	 * FIXME: Unclear whether there's any global state touched by the
198
	 * cursor_set function, especially vmw_cursor_update_position looks
166
	 * cursor_set function, especially vmw_cursor_update_position looks
199
	 * suspicious. For now take the easy route and reacquire all locks. We
167
	 * suspicious. For now take the easy route and reacquire all locks. We
200
	 * can do this since the caller in the drm core doesn't check anything
168
	 * can do this since the caller in the drm core doesn't check anything
-
 
169
	 * which is protected by any looks.
-
 
170
	 */
Line 201... Line 171...
201
	 * which is protected by any looks.
171
	drm_modeset_unlock_crtc(crtc);
202
	 */
172
	drm_modeset_lock_all(dev_priv->dev);
203
	drm_modeset_unlock(&crtc->mutex);
173
	hotspot_x = hot_x + du->hotspot_x;
204
	drm_modeset_lock_all(dev_priv->dev);
174
	hotspot_y = hot_y + du->hotspot_y;
Line 236... Line 206...
236
	}
206
	}
237
	if (du->cursor_dmabuf)
207
	if (du->cursor_dmabuf)
238
		vmw_dmabuf_unreference(&du->cursor_dmabuf);
208
		vmw_dmabuf_unreference(&du->cursor_dmabuf);
Line 239... Line 209...
239
 
209
 
-
 
210
	/* setup new image */
240
	/* setup new image */
211
	ret = 0;
241
	if (surface) {
212
	if (surface) {
242
		/* vmw_user_surface_lookup takes one reference */
213
		/* vmw_user_surface_lookup takes one reference */
Line 243... Line 214...
243
		du->cursor_surface = surface;
214
		du->cursor_surface = surface;
244
 
215
 
245
		du->cursor_surface->snooper.crtc = crtc;
216
		du->cursor_surface->snooper.crtc = crtc;
246
		du->cursor_age = du->cursor_surface->snooper.age;
217
		du->cursor_age = du->cursor_surface->snooper.age;
247
		vmw_cursor_update_image(dev_priv, surface->snooper.image,
218
		ret = vmw_cursor_update_image(dev_priv, surface->snooper.image,
248
					64, 64, du->hotspot_x, du->hotspot_y);
219
					      64, 64, hotspot_x, hotspot_y);
249
	} else if (dmabuf) {
220
	} else if (dmabuf) {
Line 250... Line 221...
250
		/* vmw_user_surface_lookup takes one reference */
221
		/* vmw_user_surface_lookup takes one reference */
251
		du->cursor_dmabuf = dmabuf;
222
		du->cursor_dmabuf = dmabuf;
252
 
223
 
253
		ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height,
224
		ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height,
254
					       du->hotspot_x, du->hotspot_y);
-
 
255
	} else {
225
					       hotspot_x, hotspot_y);
256
		vmw_cursor_update_position(dev_priv, false, 0, 0);
226
	} else {
Line -... Line 227...
-
 
227
		vmw_cursor_update_position(dev_priv, false, 0, 0);
257
		ret = 0;
228
		goto out;
258
		goto out;
229
	}
259
	}
230
 
-
 
231
	if (!ret) {
-
 
232
		vmw_cursor_update_position(dev_priv, true,
-
 
233
					   du->cursor_x + hotspot_x,
Line 260... Line -...
260
 
-
 
261
	vmw_cursor_update_position(dev_priv, true,
234
					   du->cursor_y + hotspot_y);
262
				   du->cursor_x + du->hotspot_x,
235
		du->core_hotspot_x = hot_x;
263
				   du->cursor_y + du->hotspot_y);
236
		du->core_hotspot_y = hot_y;
Line 264... Line 237...
264
 
237
	}
265
	ret = 0;
238
 
Line 266... Line 239...
266
out:
239
out:
Line 284... Line 257...
284
	 * cursor_set function, especially vmw_cursor_update_position looks
257
	 * cursor_set function, especially vmw_cursor_update_position looks
285
	 * suspicious. For now take the easy route and reacquire all locks. We
258
	 * suspicious. For now take the easy route and reacquire all locks. We
286
	 * can do this since the caller in the drm core doesn't check anything
259
	 * can do this since the caller in the drm core doesn't check anything
287
	 * which is protected by any looks.
260
	 * which is protected by any looks.
288
	 */
261
	 */
289
	drm_modeset_unlock(&crtc->mutex);
262
	drm_modeset_unlock_crtc(crtc);
290
	drm_modeset_lock_all(dev_priv->dev);
263
	drm_modeset_lock_all(dev_priv->dev);
Line 291... Line 264...
291
 
264
 
292
	vmw_cursor_update_position(dev_priv, shown,
265
	vmw_cursor_update_position(dev_priv, shown,
-
 
266
				   du->cursor_x + du->hotspot_x +
293
				   du->cursor_x + du->hotspot_x,
267
				   du->core_hotspot_x,
-
 
268
				   du->cursor_y + du->hotspot_y +
Line 294... Line 269...
294
				   du->cursor_y + du->hotspot_y);
269
				   du->core_hotspot_y);
295
 
270
 
Line 296... Line 271...
296
	drm_modeset_unlock_all(dev_priv->dev);
271
	drm_modeset_unlock_all(dev_priv->dev);
297
	drm_modeset_lock(&crtc->mutex, NULL);
272
	drm_modeset_lock_crtc(crtc, crtc->cursor);
Line 298... Line 273...
298
 
273
 
Line 378... Line 353...
378
			       box->w * 4);
353
			       box->w * 4);
379
	}
354
	}
Line 380... Line 355...
380
 
355
 
Line 381... Line -...
381
	srf->snooper.age++;
-
 
382
 
-
 
383
	/* we can't call this function from this function since execbuf has
-
 
384
	 * reserved fifo space.
-
 
385
	 *
-
 
386
	 * if (srf->snooper.crtc)
-
 
387
	 *	vmw_ldu_crtc_cursor_update_image(dev_priv,
-
 
388
	 *					 srf->snooper.image, 64, 64,
-
 
389
	 *					 du->hotspot_x, du->hotspot_y);
-
 
390
	 */
356
	srf->snooper.age++;
391
 
357
 
392
	ttm_bo_kunmap(&map);
358
	ttm_bo_kunmap(&map);
393
err_unreserve:
359
err_unreserve:
Line -... Line 360...
-
 
360
	ttm_bo_unreserve(bo);
-
 
361
}
-
 
362
 
-
 
363
/**
-
 
364
 * vmw_kms_legacy_hotspot_clear - Clear legacy hotspots
-
 
365
 *
-
 
366
 * @dev_priv: Pointer to the device private struct.
-
 
367
 *
-
 
368
 * Clears all legacy hotspots.
-
 
369
 */
-
 
370
void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv)
-
 
371
{
-
 
372
	struct drm_device *dev = dev_priv->dev;
-
 
373
	struct vmw_display_unit *du;
-
 
374
	struct drm_crtc *crtc;
-
 
375
 
-
 
376
	drm_modeset_lock_all(dev);
-
 
377
	drm_for_each_crtc(crtc, dev) {
-
 
378
		du = vmw_crtc_to_du(crtc);
-
 
379
 
-
 
380
		du->hotspot_x = 0;
-
 
381
		du->hotspot_y = 0;
-
 
382
	}
394
	ttm_bo_unreserve(bo);
383
	drm_modeset_unlock_all(dev);
395
}
384
}
396
 
385
 
397
void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
386
void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
398
{
387
{
Line 409... Line 398...
409
			continue;
398
			continue;
Line 410... Line 399...
410
 
399
 
411
		du->cursor_age = du->cursor_surface->snooper.age;
400
		du->cursor_age = du->cursor_surface->snooper.age;
412
		vmw_cursor_update_image(dev_priv,
401
		vmw_cursor_update_image(dev_priv,
-
 
402
					du->cursor_surface->snooper.image,
-
 
403
					64, 64,
413
					du->cursor_surface->snooper.image,
404
					du->hotspot_x + du->core_hotspot_x,
414
					64, 64, du->hotspot_x, du->hotspot_y);
405
					du->hotspot_y + du->core_hotspot_y);
Line 415... Line 406...
415
	}
406
	}
416
 
407
 
417
	mutex_unlock(&dev->mode_config.mutex);
408
	mutex_unlock(&dev->mode_config.mutex);
Line 424... Line 415...
424
 
415
 
425
/*
416
/*
426
 * Surface framebuffer code
417
 * Surface framebuffer code
Line 427... Line -...
427
 */
-
 
428
 
-
 
429
#define vmw_framebuffer_to_vfbs(x) \
-
 
430
	container_of(x, struct vmw_framebuffer_surface, base.base)
-
 
431
 
-
 
432
struct vmw_framebuffer_surface {
-
 
433
	struct vmw_framebuffer base;
-
 
434
	struct vmw_surface *surface;
-
 
435
	struct vmw_dma_buffer *buffer;
-
 
436
	struct list_head head;
-
 
437
	struct drm_master *master;
-
 
438
};
418
 */
439
 
419
 
440
static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
420
static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer)
441
{
421
{
442
	struct vmw_framebuffer_surface *vfbs =
-
 
443
		vmw_framebuffer_to_vfbs(framebuffer);
-
 
444
	struct vmw_master *vmaster = vmw_master(vfbs->master);
-
 
445
 
-
 
446
 
-
 
447
	mutex_lock(&vmaster->fb_surf_mutex);
-
 
Line -... Line 422...
-
 
422
	struct vmw_framebuffer_surface *vfbs =
-
 
423
		vmw_framebuffer_to_vfbs(framebuffer);
-
 
424
 
-
 
425
	drm_framebuffer_cleanup(framebuffer);
Line 448... Line 426...
448
	list_del(&vfbs->head);
426
	vmw_surface_unreference(&vfbs->surface);
449
	mutex_unlock(&vmaster->fb_surf_mutex);
427
	if (vfbs->base.user_obj)
Line 450... Line -...
450
 
-
 
451
 
-
 
452
	kfree(vfbs);
-
 
453
}
-
 
454
 
-
 
455
static int do_surface_dirty_sou(struct vmw_private *dev_priv,
-
 
456
				struct drm_file *file_priv,
-
 
457
				struct vmw_framebuffer *framebuffer,
-
 
458
				unsigned flags, unsigned color,
-
 
459
				struct drm_clip_rect *clips,
-
 
460
				unsigned num_clips, int inc,
-
 
461
				struct vmw_fence_obj **out_fence)
-
 
462
{
-
 
463
	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
-
 
464
	struct drm_clip_rect *clips_ptr;
-
 
465
	struct drm_clip_rect *tmp;
-
 
466
	struct drm_crtc *crtc;
-
 
467
	size_t fifo_size;
-
 
468
	int i, num_units;
-
 
469
	int ret = 0; /* silence warning */
-
 
470
	int left, right, top, bottom;
-
 
471
 
-
 
472
	struct {
-
 
473
		SVGA3dCmdHeader header;
-
 
474
		SVGA3dCmdBlitSurfaceToScreen body;
-
 
475
	} *cmd;
-
 
476
	SVGASignedRect *blits;
-
 
477
 
-
 
478
	num_units = 0;
-
 
479
	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list,
-
 
480
			    head) {
-
 
481
		if (crtc->primary->fb != &framebuffer->base)
-
 
482
			continue;
-
 
483
		units[num_units++] = vmw_crtc_to_du(crtc);
-
 
484
	}
-
 
485
 
-
 
486
	BUG_ON(!clips || !num_clips);
-
 
487
 
-
 
488
	tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL);
-
 
489
	if (unlikely(tmp == NULL)) {
-
 
490
		DRM_ERROR("Temporary cliprect memory alloc failed.\n");
-
 
491
		return -ENOMEM;
-
 
492
	}
-
 
493
 
-
 
494
	fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips;
-
 
495
	cmd = kzalloc(fifo_size, GFP_KERNEL);
-
 
496
	if (unlikely(cmd == NULL)) {
-
 
497
		DRM_ERROR("Temporary fifo memory alloc failed.\n");
-
 
498
		ret = -ENOMEM;
-
 
499
		goto out_free_tmp;
-
 
500
	}
-
 
501
 
-
 
502
	/* setup blits pointer */
-
 
503
	blits = (SVGASignedRect *)&cmd[1];
-
 
504
 
-
 
505
	/* initial clip region */
-
 
506
	left = clips->x1;
-
 
507
	right = clips->x2;
-
 
508
	top = clips->y1;
-
 
509
	bottom = clips->y2;
-
 
510
 
-
 
511
	/* skip the first clip rect */
-
 
512
	for (i = 1, clips_ptr = clips + inc;
-
 
513
	     i < num_clips; i++, clips_ptr += inc) {
-
 
514
		left = min_t(int, left, (int)clips_ptr->x1);
-
 
515
		right = max_t(int, right, (int)clips_ptr->x2);
-
 
516
		top = min_t(int, top, (int)clips_ptr->y1);
-
 
517
		bottom = max_t(int, bottom, (int)clips_ptr->y2);
-
 
518
	}
-
 
519
 
-
 
520
	/* only need to do this once */
-
 
521
	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
-
 
522
	cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
-
 
523
 
-
 
524
	cmd->body.srcRect.left = left;
-
 
525
	cmd->body.srcRect.right = right;
-
 
526
	cmd->body.srcRect.top = top;
-
 
527
	cmd->body.srcRect.bottom = bottom;
-
 
528
 
-
 
529
	clips_ptr = clips;
-
 
530
	for (i = 0; i < num_clips; i++, clips_ptr += inc) {
-
 
531
		tmp[i].x1 = clips_ptr->x1 - left;
-
 
532
		tmp[i].x2 = clips_ptr->x2 - left;
-
 
533
		tmp[i].y1 = clips_ptr->y1 - top;
-
 
534
		tmp[i].y2 = clips_ptr->y2 - top;
-
 
535
	}
-
 
536
 
-
 
537
	/* do per unit writing, reuse fifo for each */
-
 
538
	for (i = 0; i < num_units; i++) {
-
 
539
		struct vmw_display_unit *unit = units[i];
-
 
540
		struct vmw_clip_rect clip;
-
 
541
		int num;
-
 
542
 
-
 
543
		clip.x1 = left - unit->crtc.x;
-
 
544
		clip.y1 = top - unit->crtc.y;
-
 
545
		clip.x2 = right - unit->crtc.x;
-
 
546
		clip.y2 = bottom - unit->crtc.y;
-
 
547
 
-
 
548
		/* skip any crtcs that misses the clip region */
-
 
549
		if (clip.x1 >= unit->crtc.mode.hdisplay ||
-
 
550
		    clip.y1 >= unit->crtc.mode.vdisplay ||
-
 
551
		    clip.x2 <= 0 || clip.y2 <= 0)
-
 
552
			continue;
-
 
553
 
-
 
554
		/*
-
 
555
		 * In order for the clip rects to be correctly scaled
-
 
556
		 * the src and dest rects needs to be the same size.
-
 
557
		 */
-
 
558
		cmd->body.destRect.left = clip.x1;
-
 
559
		cmd->body.destRect.right = clip.x2;
-
 
560
		cmd->body.destRect.top = clip.y1;
-
 
561
		cmd->body.destRect.bottom = clip.y2;
-
 
562
 
-
 
563
		/* create a clip rect of the crtc in dest coords */
-
 
564
		clip.x2 = unit->crtc.mode.hdisplay - clip.x1;
-
 
565
		clip.y2 = unit->crtc.mode.vdisplay - clip.y1;
-
 
566
		clip.x1 = 0 - clip.x1;
-
 
567
		clip.y1 = 0 - clip.y1;
-
 
568
 
-
 
569
		/* need to reset sid as it is changed by execbuf */
-
 
570
		cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle);
-
 
571
		cmd->body.destScreenId = unit->unit;
-
 
572
 
-
 
573
		/* clip and write blits to cmd stream */
-
 
574
		vmw_clip_cliprects(tmp, num_clips, clip, blits, &num);
-
 
575
 
-
 
576
		/* if no cliprects hit skip this */
-
 
577
		if (num == 0)
-
 
578
			continue;
-
 
579
 
-
 
580
		/* only return the last fence */
-
 
581
		if (out_fence && *out_fence)
-
 
582
			vmw_fence_obj_unreference(out_fence);
-
 
583
 
-
 
584
		/* recalculate package length */
-
 
585
		fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
-
 
586
		cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
-
 
587
		ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-
 
588
					  fifo_size, 0, NULL, out_fence);
-
 
589
 
-
 
590
		if (unlikely(ret != 0))
-
 
591
			break;
-
 
592
	}
-
 
593
 
-
 
594
 
-
 
595
	kfree(cmd);
-
 
596
out_free_tmp:
-
 
597
	kfree(tmp);
428
		ttm_base_object_unref(&vfbs->base.user_obj);
598
 
429
 
599
	return ret;
430
	kfree(vfbs);
600
}
431
}
601
 
432
 
Line 609... Line 440...
609
	struct vmw_framebuffer_surface *vfbs =
440
	struct vmw_framebuffer_surface *vfbs =
610
		vmw_framebuffer_to_vfbs(framebuffer);
441
		vmw_framebuffer_to_vfbs(framebuffer);
611
	struct drm_clip_rect norect;
442
	struct drm_clip_rect norect;
612
	int ret, inc = 1;
443
	int ret, inc = 1;
Line 613... Line -...
613
 
-
 
614
	if (unlikely(vfbs->master != file_priv->master))
-
 
615
		return -EINVAL;
-
 
616
 
444
 
617
	/* Require ScreenObject support for 3D */
445
	/* Legacy Display Unit does not support 3D */
618
	if (!dev_priv->sou_priv)
446
	if (dev_priv->active_display_unit == vmw_du_legacy)
Line 619... Line 447...
619
		return -EINVAL;
447
		return -EINVAL;
Line 620... Line 448...
620
 
448
 
Line 635... Line 463...
635
	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
463
	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
636
		num_clips /= 2;
464
		num_clips /= 2;
637
		inc = 2; /* skip source rects */
465
		inc = 2; /* skip source rects */
638
	}
466
	}
Line -... Line 467...
-
 
467
 
639
 
468
	if (dev_priv->active_display_unit == vmw_du_screen_object)
-
 
469
		ret = vmw_kms_sou_do_surface_dirty(dev_priv, &vfbs->base,
640
	ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base,
470
						   clips, NULL, NULL, 0, 0,
-
 
471
						   num_clips, inc, NULL);
-
 
472
	else
-
 
473
		ret = vmw_kms_stdu_surface_dirty(dev_priv, &vfbs->base,
641
				   flags, color,
474
						 clips, NULL, NULL, 0, 0,
Line -... Line 475...
-
 
475
						 num_clips, inc, NULL);
642
				   clips, num_clips, inc, NULL);
476
 
Line 643... Line 477...
643
 
477
	vmw_fifo_flush(dev_priv, false);
Line 644... Line 478...
644
	ttm_read_unlock(&dev_priv->reservation_sem);
478
	ttm_read_unlock(&dev_priv->reservation_sem);
645
 
479
 
Line -... Line 480...
-
 
480
	drm_modeset_unlock_all(dev_priv->dev);
-
 
481
 
-
 
482
	return 0;
-
 
483
}
-
 
484
 
-
 
485
/**
-
 
486
 * vmw_kms_readback - Perform a readback from the screen system to
-
 
487
 * a dma-buffer backed framebuffer.
-
 
488
 *
-
 
489
 * @dev_priv: Pointer to the device private structure.
-
 
490
 * @file_priv: Pointer to a struct drm_file identifying the caller.
-
 
491
 * Must be set to NULL if @user_fence_rep is NULL.
-
 
492
 * @vfb: Pointer to the dma-buffer backed framebuffer.
-
 
493
 * @user_fence_rep: User-space provided structure for fence information.
-
 
494
 * Must be set to non-NULL if @file_priv is non-NULL.
-
 
495
 * @vclips: Array of clip rects.
-
 
496
 * @num_clips: Number of clip rects in @vclips.
-
 
497
 *
-
 
498
 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
-
 
499
 * interrupted.
-
 
500
 */
-
 
501
int vmw_kms_readback(struct vmw_private *dev_priv,
-
 
502
		     struct drm_file *file_priv,
-
 
503
		     struct vmw_framebuffer *vfb,
-
 
504
		     struct drm_vmw_fence_rep __user *user_fence_rep,
-
 
505
		     struct drm_vmw_rect *vclips,
-
 
506
		     uint32_t num_clips)
-
 
507
{
-
 
508
	switch (dev_priv->active_display_unit) {
-
 
509
	case vmw_du_screen_object:
-
 
510
		return vmw_kms_sou_readback(dev_priv, file_priv, vfb,
-
 
511
					    user_fence_rep, vclips, num_clips);
-
 
512
	case vmw_du_screen_target:
-
 
513
		return vmw_kms_stdu_dma(dev_priv, file_priv, vfb,
-
 
514
					user_fence_rep, NULL, vclips, num_clips,
-
 
515
					1, false, true);
-
 
516
	default:
-
 
517
		WARN_ONCE(true,
-
 
518
			  "Readback called with invalid display system.\n");
-
 
519
}
646
	drm_modeset_unlock_all(dev_priv->dev);
520
 
647
 
521
	return -ENOSYS;
648
	return 0;
522
}
649
}
523
 
Line 650... Line 524...
650
 
524
 
651
static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
-
 
652
   .destroy = vmw_framebuffer_surface_destroy,
525
static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
653
	.dirty = vmw_framebuffer_surface_dirty,
526
	.destroy = vmw_framebuffer_surface_destroy,
654
};
527
	.dirty = vmw_framebuffer_surface_dirty,
655
 
528
};
-
 
529
 
Line 656... Line 530...
656
static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
530
static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
657
					   struct drm_file *file_priv,
531
					   struct vmw_surface *surface,
658
					   struct vmw_surface *surface,
532
					   struct vmw_framebuffer **out,
659
					   struct vmw_framebuffer **out,
533
					   const struct drm_mode_fb_cmd
660
					   const struct drm_mode_fb_cmd
-
 
661
					   *mode_cmd)
534
					   *mode_cmd,
Line 662... Line 535...
662
 
535
					   bool is_dmabuf_proxy)
663
{
536
 
664
	struct drm_device *dev = dev_priv->dev;
537
{
Line 665... Line 538...
665
	struct vmw_framebuffer_surface *vfbs;
538
	struct drm_device *dev = dev_priv->dev;
666
	enum SVGA3dSurfaceFormat format;
539
	struct vmw_framebuffer_surface *vfbs;
667
	struct vmw_master *vmaster = vmw_master(file_priv->master);
540
	enum SVGA3dSurfaceFormat format;
Line 700... Line 573...
700
		format = SVGA3D_R5G6B5;
573
		format = SVGA3D_R5G6B5;
701
		break;
574
		break;
702
	case 15:
575
	case 15:
703
		format = SVGA3D_A1R5G5B5;
576
		format = SVGA3D_A1R5G5B5;
704
		break;
577
		break;
705
	case 8:
-
 
706
		format = SVGA3D_LUMINANCE8;
-
 
707
		break;
-
 
708
	default:
578
	default:
709
		DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth);
579
		DRM_ERROR("Invalid color depth: %d\n", mode_cmd->depth);
710
		return -EINVAL;
580
		return -EINVAL;
711
	}
581
	}
Line -... Line 582...
-
 
582
 
-
 
583
	/*
-
 
584
	 * For DX, surface format validation is done when surface->scanout
-
 
585
	 * is set.
712
 
586
	 */
713
	if (unlikely(format != surface->format)) {
587
	if (!dev_priv->has_dx && format != surface->format) {
714
		DRM_ERROR("Invalid surface format for requested mode.\n");
588
		DRM_ERROR("Invalid surface format for requested mode.\n");
715
		return -EINVAL;
589
		return -EINVAL;
Line 716... Line 590...
716
	}
590
	}
717
 
591
 
718
	vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
592
	vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
719
	if (!vfbs) {
593
	if (!vfbs) {
720
		ret = -ENOMEM;
594
		ret = -ENOMEM;
Line 721... Line -...
721
		goto out_err1;
-
 
722
	}
-
 
723
 
-
 
724
	if (!vmw_surface_reference(surface)) {
-
 
725
		DRM_ERROR("failed to reference surface %p\n", surface);
-
 
726
		ret = -EINVAL;
-
 
727
		goto out_err2;
595
		goto out_err1;
728
	}
596
	}
729
 
597
 
730
	/* XXX get the first 3 from the surface info */
598
	/* XXX get the first 3 from the surface info */
731
	vfbs->base.base.bits_per_pixel = mode_cmd->bpp;
599
	vfbs->base.base.bits_per_pixel = mode_cmd->bpp;
732
	vfbs->base.base.pitches[0] = mode_cmd->pitch;
600
	vfbs->base.base.pitches[0] = mode_cmd->pitch;
733
	vfbs->base.base.depth = mode_cmd->depth;
601
	vfbs->base.base.depth = mode_cmd->depth;
734
	vfbs->base.base.width = mode_cmd->width;
602
	vfbs->base.base.width = mode_cmd->width;
735
	vfbs->base.base.height = mode_cmd->height;
603
	vfbs->base.base.height = mode_cmd->height;
736
	vfbs->surface = surface;
-
 
737
	vfbs->base.user_handle = mode_cmd->handle;
-
 
738
//   vfbs->master = drm_master_get(file_priv->master);
-
 
739
 
-
 
Line 740... Line 604...
740
	mutex_lock(&vmaster->fb_surf_mutex);
604
	vfbs->surface = vmw_surface_reference(surface);
Line 741... Line 605...
741
	list_add_tail(&vfbs->head, &vmaster->fb_surf);
605
	vfbs->base.user_handle = mode_cmd->handle;
742
	mutex_unlock(&vmaster->fb_surf_mutex);
606
	vfbs->is_dmabuf_proxy = is_dmabuf_proxy;
743
 
607
 
744
	*out = &vfbs->base;
608
	*out = &vfbs->base;
Line 745... Line 609...
745
 
609
 
Line 746... Line -...
746
	ret = drm_framebuffer_init(dev, &vfbs->base.base,
-
 
747
				   &vmw_framebuffer_surface_funcs);
-
 
748
	if (ret)
610
	ret = drm_framebuffer_init(dev, &vfbs->base.base,
-
 
611
				   &vmw_framebuffer_surface_funcs);
749
		goto out_err3;
612
	if (ret)
750
 
613
		goto out_err2;
751
	return 0;
614
 
752
 
615
	return 0;
Line 753... Line 616...
753
out_err3:
616
 
754
	vmw_surface_unreference(&surface);
617
out_err2:
755
out_err2:
618
	vmw_surface_unreference(&surface);
Line 756... Line -...
756
	kfree(vfbs);
-
 
757
out_err1:
-
 
758
	return ret;
-
 
759
}
-
 
760
 
-
 
761
/*
-
 
762
 * Dmabuf framebuffer code
-
 
763
 */
-
 
764
 
619
	kfree(vfbs);
765
#define vmw_framebuffer_to_vfbd(x) \
620
out_err1:
766
	container_of(x, struct vmw_framebuffer_dmabuf, base.base)
621
	return ret;
767
 
622
}
Line 768... Line 623...
768
struct vmw_framebuffer_dmabuf {
623
 
769
	struct vmw_framebuffer base;
624
/*
-
 
625
 * Dmabuf framebuffer code
770
	struct vmw_dma_buffer *buffer;
626
 */
Line 771... Line 627...
771
};
627
 
772
 
628
static void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
Line 773... Line -...
773
static void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer)
-
 
774
{
-
 
775
	struct vmw_framebuffer_dmabuf *vfbd =
-
 
776
		vmw_framebuffer_to_vfbd(framebuffer);
-
 
777
 
-
 
778
//   drm_framebuffer_cleanup(framebuffer);
-
 
779
//   vmw_dmabuf_unreference(&vfbd->buffer);
-
 
780
//   ttm_base_object_unref(&vfbd->base.user_obj);
-
 
781
 
-
 
782
	kfree(vfbd);
-
 
783
}
-
 
784
 
-
 
785
static int do_dmabuf_dirty_ldu(struct vmw_private *dev_priv,
-
 
786
			       struct vmw_framebuffer *framebuffer,
-
 
787
			       unsigned flags, unsigned color,
-
 
788
			       struct drm_clip_rect *clips,
-
 
789
			       unsigned num_clips, int increment)
-
 
790
{
-
 
791
	size_t fifo_size;
-
 
792
	int i;
-
 
793
 
-
 
794
	struct {
-
 
795
		uint32_t header;
-
 
796
		SVGAFifoCmdUpdate body;
-
 
797
	} *cmd;
-
 
798
 
-
 
799
	fifo_size = sizeof(*cmd) * num_clips;
-
 
800
	cmd = vmw_fifo_reserve(dev_priv, fifo_size);
-
 
801
	if (unlikely(cmd == NULL)) {
-
 
802
		DRM_ERROR("Fifo reserve failed.\n");
-
 
803
		return -ENOMEM;
-
 
804
	}
-
 
805
 
-
 
806
	memset(cmd, 0, fifo_size);
-
 
807
	for (i = 0; i < num_clips; i++, clips += increment) {
-
 
808
		cmd[i].header = cpu_to_le32(SVGA_CMD_UPDATE);
-
 
809
		cmd[i].body.x = cpu_to_le32(clips->x1);
-
 
810
		cmd[i].body.y = cpu_to_le32(clips->y1);
-
 
811
		cmd[i].body.width = cpu_to_le32(clips->x2 - clips->x1);
-
 
812
		cmd[i].body.height = cpu_to_le32(clips->y2 - clips->y1);
-
 
813
	}
-
 
814
 
-
 
815
	vmw_fifo_commit(dev_priv, fifo_size);
-
 
816
	return 0;
-
 
817
}
-
 
818
 
-
 
819
static int do_dmabuf_define_gmrfb(struct drm_file *file_priv,
-
 
820
				  struct vmw_private *dev_priv,
-
 
821
				  struct vmw_framebuffer *framebuffer)
-
 
822
{
-
 
823
	int depth = framebuffer->base.depth;
-
 
824
	size_t fifo_size;
-
 
825
	int ret;
-
 
826
 
-
 
827
	struct {
-
 
828
		uint32_t header;
-
 
829
		SVGAFifoCmdDefineGMRFB body;
-
 
830
	} *cmd;
-
 
831
 
-
 
832
	/* Emulate RGBA support, contrary to svga_reg.h this is not
-
 
833
	 * supported by hosts. This is only a problem if we are reading
-
 
834
	 * this value later and expecting what we uploaded back.
-
 
835
	 */
-
 
836
	if (depth == 32)
-
 
837
		depth = 24;
-
 
838
 
-
 
839
	fifo_size = sizeof(*cmd);
-
 
840
	cmd = kmalloc(fifo_size, GFP_KERNEL);
-
 
841
	if (unlikely(cmd == NULL)) {
-
 
842
		DRM_ERROR("Failed to allocate temporary cmd buffer.\n");
-
 
843
		return -ENOMEM;
-
 
844
	}
-
 
845
 
-
 
846
	memset(cmd, 0, fifo_size);
-
 
847
	cmd->header = SVGA_CMD_DEFINE_GMRFB;
-
 
848
	cmd->body.format.bitsPerPixel = framebuffer->base.bits_per_pixel;
-
 
849
	cmd->body.format.colorDepth = depth;
-
 
850
	cmd->body.format.reserved = 0;
-
 
851
	cmd->body.bytesPerLine = framebuffer->base.pitches[0];
-
 
852
	cmd->body.ptr.gmrId = framebuffer->user_handle;
-
 
853
	cmd->body.ptr.offset = 0;
-
 
854
 
-
 
855
	ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-
 
856
				  fifo_size, 0, NULL, NULL);
-
 
857
 
-
 
858
	kfree(cmd);
-
 
859
 
-
 
860
	return ret;
-
 
861
}
-
 
862
 
-
 
863
static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
-
 
864
			       struct vmw_private *dev_priv,
-
 
865
			       struct vmw_framebuffer *framebuffer,
-
 
866
			       unsigned flags, unsigned color,
-
 
867
			       struct drm_clip_rect *clips,
-
 
868
			       unsigned num_clips, int increment,
-
 
869
			       struct vmw_fence_obj **out_fence)
-
 
870
{
-
 
871
	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
-
 
872
	struct drm_clip_rect *clips_ptr;
-
 
873
	int i, k, num_units, ret;
-
 
874
	struct drm_crtc *crtc;
-
 
875
	size_t fifo_size;
-
 
876
 
-
 
877
	struct {
-
 
878
		uint32_t header;
-
 
879
		SVGAFifoCmdBlitGMRFBToScreen body;
-
 
880
	} *blits;
-
 
881
 
-
 
882
	ret = do_dmabuf_define_gmrfb(file_priv, dev_priv, framebuffer);
-
 
883
	if (unlikely(ret != 0))
-
 
884
		return ret; /* define_gmrfb prints warnings */
-
 
885
 
-
 
886
	fifo_size = sizeof(*blits) * num_clips;
-
 
887
	blits = kmalloc(fifo_size, GFP_KERNEL);
-
 
888
	if (unlikely(blits == NULL)) {
-
 
889
		DRM_ERROR("Failed to allocate temporary cmd buffer.\n");
-
 
890
		return -ENOMEM;
-
 
891
	}
-
 
892
 
-
 
893
	num_units = 0;
-
 
894
	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
-
 
895
		if (crtc->primary->fb != &framebuffer->base)
-
 
896
			continue;
-
 
897
		units[num_units++] = vmw_crtc_to_du(crtc);
-
 
898
	}
-
 
899
 
-
 
900
	for (k = 0; k < num_units; k++) {
-
 
901
		struct vmw_display_unit *unit = units[k];
-
 
902
		int hit_num = 0;
-
 
903
 
-
 
904
		clips_ptr = clips;
-
 
905
		for (i = 0; i < num_clips; i++, clips_ptr += increment) {
-
 
906
			int clip_x1 = clips_ptr->x1 - unit->crtc.x;
-
 
907
			int clip_y1 = clips_ptr->y1 - unit->crtc.y;
-
 
908
			int clip_x2 = clips_ptr->x2 - unit->crtc.x;
-
 
909
			int clip_y2 = clips_ptr->y2 - unit->crtc.y;
-
 
910
			int move_x, move_y;
-
 
911
 
-
 
912
			/* skip any crtcs that misses the clip region */
-
 
913
			if (clip_x1 >= unit->crtc.mode.hdisplay ||
-
 
914
			    clip_y1 >= unit->crtc.mode.vdisplay ||
-
 
915
			    clip_x2 <= 0 || clip_y2 <= 0)
-
 
916
				continue;
-
 
917
 
-
 
918
			/* clip size to crtc size */
-
 
919
			clip_x2 = min_t(int, clip_x2, unit->crtc.mode.hdisplay);
-
 
920
			clip_y2 = min_t(int, clip_y2, unit->crtc.mode.vdisplay);
-
 
921
 
-
 
922
			/* translate both src and dest to bring clip into screen */
-
 
923
			move_x = min_t(int, clip_x1, 0);
-
 
924
			move_y = min_t(int, clip_y1, 0);
-
 
925
 
-
 
926
			/* actual translate done here */
-
 
927
			blits[hit_num].header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN;
-
 
928
			blits[hit_num].body.destScreenId = unit->unit;
-
 
929
			blits[hit_num].body.srcOrigin.x = clips_ptr->x1 - move_x;
-
 
930
			blits[hit_num].body.srcOrigin.y = clips_ptr->y1 - move_y;
-
 
931
			blits[hit_num].body.destRect.left = clip_x1 - move_x;
-
 
932
			blits[hit_num].body.destRect.top = clip_y1 - move_y;
-
 
933
			blits[hit_num].body.destRect.right = clip_x2;
-
 
934
			blits[hit_num].body.destRect.bottom = clip_y2;
-
 
935
			hit_num++;
-
 
936
		}
-
 
937
 
-
 
938
		/* no clips hit the crtc */
-
 
939
		if (hit_num == 0)
-
 
940
			continue;
-
 
941
 
-
 
942
		/* only return the last fence */
-
 
943
		if (out_fence && *out_fence)
-
 
944
			vmw_fence_obj_unreference(out_fence);
-
 
945
 
-
 
946
		fifo_size = sizeof(*blits) * hit_num;
-
 
947
		ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits,
629
{
948
					  fifo_size, 0, NULL, out_fence);
630
	struct vmw_framebuffer_dmabuf *vfbd =
949
 
631
		vmw_framebuffer_to_vfbd(framebuffer);
950
		if (unlikely(ret != 0))
632
 
951
			break;
633
	drm_framebuffer_cleanup(framebuffer);
Line 985... Line 667...
985
	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
667
	} else if (flags & DRM_MODE_FB_DIRTY_ANNOTATE_COPY) {
986
		num_clips /= 2;
668
		num_clips /= 2;
987
		increment = 2;
669
		increment = 2;
988
	}
670
	}
Line 989... Line 671...
989
 
671
 
-
 
672
	switch (dev_priv->active_display_unit) {
-
 
673
	case vmw_du_screen_target:
-
 
674
		ret = vmw_kms_stdu_dma(dev_priv, NULL, &vfbd->base, NULL,
-
 
675
				       clips, NULL, num_clips, increment,
-
 
676
				       true, true);
-
 
677
		break;
990
	if (dev_priv->ldu_priv) {
678
	case vmw_du_screen_object:
-
 
679
		ret = vmw_kms_sou_do_dmabuf_dirty(dev_priv, &vfbd->base,
991
		ret = do_dmabuf_dirty_ldu(dev_priv, &vfbd->base,
680
						  clips, num_clips, increment,
-
 
681
						  true,
-
 
682
						  NULL);
-
 
683
		break;
-
 
684
	case vmw_du_legacy:
992
					  flags, color,
685
		ret = vmw_kms_ldu_do_dmabuf_dirty(dev_priv, &vfbd->base, 0, 0,
993
					  clips, num_clips, increment);
686
						  clips, num_clips, increment);
994
	} else {
687
		break;
995
		ret = do_dmabuf_dirty_sou(file_priv, dev_priv, &vfbd->base,
688
	default:
996
					  flags, color,
689
		ret = -EINVAL;
-
 
690
		WARN_ONCE(true, "Dirty called with invalid display system.\n");
997
					  clips, num_clips, increment, NULL);
691
		break;
Line -... Line 692...
-
 
692
	}
998
	}
693
 
Line 999... Line 694...
999
 
694
	vmw_fifo_flush(dev_priv, false);
Line 1000... Line 695...
1000
	ttm_read_unlock(&dev_priv->reservation_sem);
695
	ttm_read_unlock(&dev_priv->reservation_sem);
Line 1010... Line 705...
1010
};
705
};
Line 1011... Line 706...
1011
 
706
 
1012
/**
707
/**
1013
 * Pin the dmabuffer to the start of vram.
708
 * Pin the dmabuffer to the start of vram.
1014
 */
709
 */
1015
static int vmw_framebuffer_dmabuf_pin(struct vmw_framebuffer *vfb)
710
static int vmw_framebuffer_pin(struct vmw_framebuffer *vfb)
1016
{
711
{
1017
	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
712
	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
1018
	struct vmw_framebuffer_dmabuf *vfbd =
-
 
1019
		vmw_framebuffer_to_vfbd(&vfb->base);
713
	struct vmw_dma_buffer *buf;
Line 1020... Line 714...
1020
	int ret;
714
	int ret;
1021
 
715
 
Line 1022... Line 716...
1022
	/* This code should not be used with screen objects */
716
	buf = vfb->dmabuf ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
1023
	BUG_ON(dev_priv->sou_priv);
717
		vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
1024
 
-
 
Line -... Line 718...
-
 
718
 
-
 
719
	if (!buf)
-
 
720
		return 0;
-
 
721
 
1025
//   vmw_overlay_pause_all(dev_priv);
722
	switch (dev_priv->active_display_unit) {
-
 
723
	case vmw_du_legacy:
-
 
724
		vmw_overlay_pause_all(dev_priv);
-
 
725
		ret = vmw_dmabuf_pin_in_start_of_vram(dev_priv, buf, false);
-
 
726
		vmw_overlay_resume_all(dev_priv);
-
 
727
		break;
-
 
728
	case vmw_du_screen_object:
Line -... Line 729...
-
 
729
	case vmw_du_screen_target:
-
 
730
		if (vfb->dmabuf)
-
 
731
			return vmw_dmabuf_pin_in_vram_or_gmr(dev_priv, buf,
1026
 
732
							     false);
-
 
733
 
Line 1027... Line 734...
1027
	ret = vmw_dmabuf_to_start_of_vram(dev_priv, vfbd->buffer, true, false);
734
		return vmw_dmabuf_pin_in_placement(dev_priv, buf,
1028
 
735
						   &vmw_mob_placement, false);
Line 1029... Line 736...
1029
//   vmw_overlay_resume_all(dev_priv);
736
	default:
1030
 
737
		return -EINVAL;
1031
	WARN_ON(ret != 0);
738
	}
1032
 
739
 
1033
	return 0;
-
 
Line -... Line 740...
-
 
740
	return ret;
1034
}
741
}
-
 
742
 
1035
 
743
static int vmw_framebuffer_unpin(struct vmw_framebuffer *vfb)
1036
static int vmw_framebuffer_dmabuf_unpin(struct vmw_framebuffer *vfb)
744
{
-
 
745
	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
-
 
746
	struct vmw_dma_buffer *buf;
1037
{
747
 
Line -... Line 748...
-
 
748
	buf = vfb->dmabuf ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
-
 
749
		vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup;
-
 
750
 
-
 
751
	if (WARN_ON(!buf))
-
 
752
		return 0;
-
 
753
 
-
 
754
	return vmw_dmabuf_unpin(dev_priv, buf, false);
-
 
755
}
-
 
756
 
-
 
757
/**
-
 
758
 * vmw_create_dmabuf_proxy - create a proxy surface for the DMA buf
-
 
759
 *
-
 
760
 * @dev: DRM device
-
 
761
 * @mode_cmd: parameters for the new surface
-
 
762
 * @dmabuf_mob: MOB backing the DMA buf
1038
	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
763
 * @srf_out: newly created surface
-
 
764
 *
-
 
765
 * When the content FB is a DMA buf, we create a surface as a proxy to the
-
 
766
 * same buffer.  This way we can do a surface copy rather than a surface DMA.
-
 
767
 * This is a more efficient approach
-
 
768
 *
-
 
769
 * RETURNS:
-
 
770
 * 0 on success, error code otherwise
-
 
771
 */
-
 
772
static int vmw_create_dmabuf_proxy(struct drm_device *dev,
-
 
773
				   const struct drm_mode_fb_cmd *mode_cmd,
-
 
774
				   struct vmw_dma_buffer *dmabuf_mob,
-
 
775
				   struct vmw_surface **srf_out)
-
 
776
{
-
 
777
	uint32_t format;
-
 
778
	struct drm_vmw_size content_base_size;
-
 
779
	struct vmw_resource *res;
-
 
780
	int ret;
-
 
781
 
-
 
782
	switch (mode_cmd->depth) {
-
 
783
	case 32:
-
 
784
	case 24:
-
 
785
		format = SVGA3D_X8R8G8B8;
-
 
786
		break;
-
 
787
 
-
 
788
	case 16:
-
 
789
	case 15:
-
 
790
		format = SVGA3D_R5G6B5;
1039
	struct vmw_framebuffer_dmabuf *vfbd =
791
		break;
Line -... Line 792...
-
 
792
 
-
 
793
	case 8:
-
 
794
		format = SVGA3D_P8;
-
 
795
		break;
-
 
796
 
-
 
797
	default:
-
 
798
		DRM_ERROR("Invalid framebuffer format %d\n", mode_cmd->depth);
-
 
799
		return -EINVAL;
-
 
800
	}
-
 
801
 
-
 
802
	content_base_size.width  = mode_cmd->width;
1040
		vmw_framebuffer_to_vfbd(&vfb->base);
803
	content_base_size.height = mode_cmd->height;
-
 
804
	content_base_size.depth  = 1;
-
 
805
 
-
 
806
	ret = vmw_surface_gb_priv_define(dev,
-
 
807
			0, /* kernel visible only */
-
 
808
			0, /* flags */
-
 
809
			format,
-
 
810
			true, /* can be a scanout buffer */
-
 
811
			1, /* num of mip levels */
-
 
812
			0,
-
 
813
			0,
-
 
814
			content_base_size,
-
 
815
			srf_out);
-
 
816
	if (ret) {
-
 
817
		DRM_ERROR("Failed to allocate proxy content buffer\n");
-
 
818
		return ret;
-
 
819
	}
-
 
820
 
-
 
821
	res = &(*srf_out)->res;
-
 
822
 
-
 
823
	/* Reserve and switch the backing mob. */
-
 
824
	mutex_lock(&res->dev_priv->cmdbuf_mutex);
-
 
825
	(void) vmw_resource_reserve(res, false, true);
-
 
826
	vmw_dmabuf_unreference(&res->backup);
1041
 
827
	res->backup = vmw_dmabuf_reference(dmabuf_mob);
1042
	if (!vfbd->buffer) {
828
	res->backup_offset = 0;
1043
		WARN_ON(!vfbd->buffer);
829
	vmw_resource_unreserve(res, false, NULL, 0);
1044
		return 0;
830
	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
1045
	}
831
 
Line 1066... Line 852...
1066
			  "for requested mode.\n");
852
			  "for requested mode.\n");
1067
		return -EINVAL;
853
		return -EINVAL;
1068
	}
854
	}
Line 1069... Line 855...
1069
 
855
 
1070
	/* Limited framebuffer color depth support for screen objects */
856
	/* Limited framebuffer color depth support for screen objects */
1071
	if (dev_priv->sou_priv) {
857
	if (dev_priv->active_display_unit == vmw_du_screen_object) {
1072
		switch (mode_cmd->depth) {
858
		switch (mode_cmd->depth) {
1073
		case 32:
859
		case 32:
1074
		case 24:
860
		case 24:
1075
			/* Only support 32 bpp for 32 and 24 depth fbs */
861
			/* Only support 32 bpp for 32 and 24 depth fbs */
Line 1098... Line 884...
1098
	if (!vfbd) {
884
	if (!vfbd) {
1099
		ret = -ENOMEM;
885
		ret = -ENOMEM;
1100
		goto out_err1;
886
		goto out_err1;
1101
	}
887
	}
Line 1102... Line -...
1102
 
-
 
1103
	if (!vmw_dmabuf_reference(dmabuf)) {
-
 
1104
		DRM_ERROR("failed to reference dmabuf %p\n", dmabuf);
-
 
1105
		ret = -EINVAL;
-
 
1106
		goto out_err2;
-
 
1107
	}
-
 
1108
 
888
 
1109
	vfbd->base.base.bits_per_pixel = mode_cmd->bpp;
889
	vfbd->base.base.bits_per_pixel = mode_cmd->bpp;
1110
	vfbd->base.base.pitches[0] = mode_cmd->pitch;
890
	vfbd->base.base.pitches[0] = mode_cmd->pitch;
1111
	vfbd->base.base.depth = mode_cmd->depth;
891
	vfbd->base.base.depth = mode_cmd->depth;
1112
	vfbd->base.base.width = mode_cmd->width;
892
	vfbd->base.base.width = mode_cmd->width;
1113
	vfbd->base.base.height = mode_cmd->height;
-
 
1114
	if (!dev_priv->sou_priv) {
-
 
1115
		vfbd->base.pin = vmw_framebuffer_dmabuf_pin;
-
 
1116
		vfbd->base.unpin = vmw_framebuffer_dmabuf_unpin;
-
 
1117
	}
893
	vfbd->base.base.height = mode_cmd->height;
1118
	vfbd->base.dmabuf = true;
894
	vfbd->base.dmabuf = true;
1119
	vfbd->buffer = dmabuf;
895
	vfbd->buffer = vmw_dmabuf_reference(dmabuf);
1120
	vfbd->base.user_handle = mode_cmd->handle;
896
	vfbd->base.user_handle = mode_cmd->handle;
Line 1121... Line 897...
1121
	*out = &vfbd->base;
897
	*out = &vfbd->base;
1122
 
898
 
1123
	ret = drm_framebuffer_init(dev, &vfbd->base.base,
899
	ret = drm_framebuffer_init(dev, &vfbd->base.base,
1124
				   &vmw_framebuffer_dmabuf_funcs);
900
				   &vmw_framebuffer_dmabuf_funcs);
Line 1125... Line 901...
1125
	if (ret)
901
	if (ret)
Line 1126... Line -...
1126
		goto out_err3;
-
 
1127
 
-
 
1128
	return 0;
902
		goto out_err2;
-
 
903
 
1129
 
904
	return 0;
1130
out_err3:
905
 
1131
	vmw_dmabuf_unreference(&dmabuf);
906
out_err2:
1132
out_err2:
907
	vmw_dmabuf_unreference(&dmabuf);
-
 
908
	kfree(vfbd);
-
 
909
out_err1:
-
 
910
	return ret;
-
 
911
}
-
 
912
 
-
 
913
/**
-
 
914
 * vmw_kms_new_framebuffer - Create a new framebuffer.
-
 
915
 *
-
 
916
 * @dev_priv: Pointer to device private struct.
-
 
917
 * @dmabuf: Pointer to dma buffer to wrap the kms framebuffer around.
-
 
918
 * Either @dmabuf or @surface must be NULL.
-
 
919
 * @surface: Pointer to a surface to wrap the kms framebuffer around.
-
 
920
 * Either @dmabuf or @surface must be NULL.
-
 
921
 * @only_2d: No presents will occur to this dma buffer based framebuffer. This
-
 
922
 * Helps the code to do some important optimizations.
-
 
923
 * @mode_cmd: Frame-buffer metadata.
-
 
924
 */
-
 
925
struct vmw_framebuffer *
-
 
926
vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
-
 
927
			struct vmw_dma_buffer *dmabuf,
-
 
928
			struct vmw_surface *surface,
-
 
929
			bool only_2d,
-
 
930
			const struct drm_mode_fb_cmd *mode_cmd)
-
 
931
{
-
 
932
	struct vmw_framebuffer *vfb = NULL;
-
 
933
	bool is_dmabuf_proxy = false;
-
 
934
	int ret;
-
 
935
 
-
 
936
	/*
-
 
937
	 * We cannot use the SurfaceDMA command in an non-accelerated VM,
-
 
938
	 * therefore, wrap the DMA buf in a surface so we can use the
-
 
939
	 * SurfaceCopy command.
-
 
940
	 */
-
 
941
	if (dmabuf && only_2d &&
-
 
942
	    dev_priv->active_display_unit == vmw_du_screen_target) {
-
 
943
		ret = vmw_create_dmabuf_proxy(dev_priv->dev, mode_cmd,
-
 
944
					      dmabuf, &surface);
-
 
945
		if (ret)
-
 
946
			return ERR_PTR(ret);
-
 
947
 
-
 
948
		is_dmabuf_proxy = true;
-
 
949
	}
-
 
950
 
-
 
951
	/* Create the new framebuffer depending one what we have */
-
 
952
	if (surface) {
-
 
953
		ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
-
 
954
						      mode_cmd,
-
 
955
						      is_dmabuf_proxy);
1133
	kfree(vfbd);
956
 
-
 
957
		/*
-
 
958
		 * vmw_create_dmabuf_proxy() adds a reference that is no longer
-
 
959
		 * needed
-
 
960
		 */
-
 
961
		if (is_dmabuf_proxy)
-
 
962
			vmw_surface_unreference(&surface);
-
 
963
	} else if (dmabuf) {
-
 
964
		ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, dmabuf, &vfb,
-
 
965
						     mode_cmd);
-
 
966
	} else {
-
 
967
		BUG();
-
 
968
	}
-
 
969
 
-
 
970
	if (ret)
-
 
971
		return ERR_PTR(ret);
-
 
972
 
-
 
973
	vfb->pin = vmw_framebuffer_pin;
Line 1134... Line 974...
1134
out_err1:
974
	vfb->unpin = vmw_framebuffer_unpin;
1135
	return ret;
975
 
1136
}
976
	return vfb;
Line 1167... Line 1007...
1167
	 */
1007
	 */
Line 1168... Line 1008...
1168
 
1008
 
1169
	if (!vmw_kms_validate_mode_vram(dev_priv,
1009
	if (!vmw_kms_validate_mode_vram(dev_priv,
1170
					mode_cmd.pitch,
1010
					mode_cmd.pitch,
1171
					mode_cmd.height)) {
1011
					mode_cmd.height)) {
1172
		DRM_ERROR("VRAM size is too small for requested mode.\n");
1012
		DRM_ERROR("Requested mode exceed bounding box limit.\n");
1173
		return ERR_PTR(-ENOMEM);
1013
		return ERR_PTR(-ENOMEM);
Line 1174... Line 1014...
1174
	}
1014
	}
1175
 
1015
 
Line 1191... Line 1031...
1191
	/**
1031
	/**
1192
	 * End conditioned code.
1032
	 * End conditioned code.
1193
	 */
1033
	 */
Line 1194... Line 1034...
1194
 
1034
 
1195
	/* returns either a dmabuf or surface */
1035
	/* returns either a dmabuf or surface */
1196
//   ret = vmw_user_lookup_handle(dev_priv, tfile,
1036
	ret = vmw_user_lookup_handle(dev_priv, tfile,
1197
//                    mode_cmd.handle,
1037
				     mode_cmd.handle,
1198
//                    &surface, &bo);
1038
				     &surface, &bo);
1199
//   if (ret)
1039
	if (ret)
1200
//       goto err_out;
1040
		goto err_out;
1201
 
1041
 
1202
	/* Create the new framebuffer depending one what we got back */
-
 
1203
//   if (bo)
1042
	vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
1204
//       ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb,
1043
				      !(dev_priv->capabilities & SVGA_CAP_3D),
1205
//                            &mode_cmd);
1044
				      &mode_cmd);
1206
//   else if (surface)
-
 
1207
		ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv,
1045
	if (IS_ERR(vfb)) {
1208
						      surface, &vfb, &mode_cmd);
1046
		ret = PTR_ERR(vfb);
1209
//   else
1047
		goto err_out;
Line 1210... Line 1048...
1210
//       BUG();
1048
 	}
1211
 
1049
 
1212
err_out:
1050
err_out:
1213
	/* vmw_user_lookup_handle takes one ref so does new_fb */
1051
	/* vmw_user_lookup_handle takes one ref so does new_fb */
1214
//   if (bo)
1052
	if (bo)
1215
//       vmw_dmabuf_unreference(&bo);
1053
		vmw_dmabuf_unreference(&bo);
Line 1216... Line 1054...
1216
//   if (surface)
1054
	if (surface)
1217
//       vmw_surface_unreference(&surface);
1055
		vmw_surface_unreference(&surface);
1218
 
1056
 
1219
	if (ret) {
1057
	if (ret) {
1220
		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
1058
		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
1221
//       ttm_base_object_unref(&user_obj);
1059
		ttm_base_object_unref(&user_obj);
Line 1222... Line 1060...
1222
		return ERR_PTR(ret);
1060
		return ERR_PTR(ret);
Line 1228... Line 1066...
1228
 
1066
 
1229
static const struct drm_mode_config_funcs vmw_kms_funcs = {
1067
static const struct drm_mode_config_funcs vmw_kms_funcs = {
1230
	.fb_create = vmw_kms_fb_create,
1068
	.fb_create = vmw_kms_fb_create,
Line 1231... Line 1069...
1231
};
1069
};
1232
 
1070
 
1233
int vmw_kms_present(struct vmw_private *dev_priv,
1071
static int vmw_kms_generic_present(struct vmw_private *dev_priv,
1234
		    struct drm_file *file_priv,
1072
				   struct drm_file *file_priv,
1235
		    struct vmw_framebuffer *vfb,
1073
				   struct vmw_framebuffer *vfb,
1236
		    struct vmw_surface *surface,
1074
				   struct vmw_surface *surface,
1237
		    uint32_t sid,
1075
				   uint32_t sid,
1238
		    int32_t destX, int32_t destY,
1076
				   int32_t destX, int32_t destY,
1239
		    struct drm_vmw_rect *clips,
1077
				   struct drm_vmw_rect *clips,
1240
		    uint32_t num_clips)
1078
				   uint32_t num_clips)
1241
{
-
 
1242
	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
-
 
1243
	struct drm_clip_rect *tmp;
-
 
1244
	struct drm_crtc *crtc;
-
 
1245
	size_t fifo_size;
-
 
1246
	int i, k, num_units;
-
 
1247
	int ret = 0; /* silence warning */
-
 
1248
	int left, right, top, bottom;
-
 
1249
 
-
 
1250
	struct {
-
 
1251
		SVGA3dCmdHeader header;
-
 
1252
		SVGA3dCmdBlitSurfaceToScreen body;
-
 
1253
	} *cmd;
-
 
1254
	SVGASignedRect *blits;
-
 
1255
 
-
 
1256
	num_units = 0;
1079
{
1257
	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
-
 
1258
		if (crtc->primary->fb != &vfb->base)
-
 
1259
			continue;
-
 
1260
		units[num_units++] = vmw_crtc_to_du(crtc);
-
 
1261
	}
1080
	return vmw_kms_sou_do_surface_dirty(dev_priv, vfb, NULL, clips,
1262
 
-
 
1263
	BUG_ON(surface == NULL);
-
 
1264
	BUG_ON(!clips || !num_clips);
-
 
1265
 
-
 
1266
	tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL);
-
 
1267
	if (unlikely(tmp == NULL)) {
-
 
1268
		DRM_ERROR("Temporary cliprect memory alloc failed.\n");
-
 
1269
		return -ENOMEM;
-
 
1270
	}
-
 
1271
 
-
 
1272
	fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips;
-
 
1273
	cmd = kmalloc(fifo_size, GFP_KERNEL);
-
 
1274
	if (unlikely(cmd == NULL)) {
-
 
1275
		DRM_ERROR("Failed to allocate temporary fifo memory.\n");
-
 
1276
		ret = -ENOMEM;
-
 
1277
		goto out_free_tmp;
-
 
1278
	}
-
 
1279
 
-
 
1280
	left = clips->x;
-
 
1281
	right = clips->x + clips->w;
-
 
1282
	top = clips->y;
-
 
1283
	bottom = clips->y + clips->h;
-
 
1284
 
-
 
1285
	for (i = 1; i < num_clips; i++) {
-
 
1286
		left = min_t(int, left, (int)clips[i].x);
-
 
1287
		right = max_t(int, right, (int)clips[i].x + clips[i].w);
-
 
1288
		top = min_t(int, top, (int)clips[i].y);
1081
					    &surface->res, destX, destY,
Line 1289... Line -...
1289
		bottom = max_t(int, bottom, (int)clips[i].y + clips[i].h);
-
 
1290
	}
-
 
1291
 
-
 
Line 1292... Line -...
1292
	/* only need to do this once */
-
 
1293
	memset(cmd, 0, fifo_size);
-
 
1294
	cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
-
 
1295
 
-
 
1296
	blits = (SVGASignedRect *)&cmd[1];
-
 
1297
 
-
 
1298
	cmd->body.srcRect.left = left;
-
 
1299
	cmd->body.srcRect.right = right;
-
 
1300
	cmd->body.srcRect.top = top;
-
 
1301
	cmd->body.srcRect.bottom = bottom;
-
 
1302
 
-
 
1303
	for (i = 0; i < num_clips; i++) {
-
 
1304
		tmp[i].x1 = clips[i].x - left;
-
 
1305
		tmp[i].x2 = clips[i].x + clips[i].w - left;
-
 
1306
		tmp[i].y1 = clips[i].y - top;
-
 
1307
		tmp[i].y2 = clips[i].y + clips[i].h - top;
-
 
1308
	}
-
 
1309
 
-
 
1310
	for (k = 0; k < num_units; k++) {
-
 
1311
		struct vmw_display_unit *unit = units[k];
-
 
1312
		struct vmw_clip_rect clip;
-
 
1313
		int num;
-
 
1314
 
-
 
1315
		clip.x1 = left + destX - unit->crtc.x;
-
 
1316
		clip.y1 = top + destY - unit->crtc.y;
-
 
1317
		clip.x2 = right + destX - unit->crtc.x;
-
 
1318
		clip.y2 = bottom + destY - unit->crtc.y;
-
 
1319
 
-
 
1320
		/* skip any crtcs that misses the clip region */
-
 
1321
		if (clip.x1 >= unit->crtc.mode.hdisplay ||
-
 
1322
		    clip.y1 >= unit->crtc.mode.vdisplay ||
-
 
1323
		    clip.x2 <= 0 || clip.y2 <= 0)
-
 
1324
			continue;
-
 
1325
 
-
 
1326
		/*
-
 
1327
		 * In order for the clip rects to be correctly scaled
-
 
1328
		 * the src and dest rects needs to be the same size.
-
 
1329
		 */
-
 
1330
		cmd->body.destRect.left = clip.x1;
-
 
1331
		cmd->body.destRect.right = clip.x2;
-
 
1332
		cmd->body.destRect.top = clip.y1;
-
 
1333
		cmd->body.destRect.bottom = clip.y2;
-
 
1334
 
-
 
1335
		/* create a clip rect of the crtc in dest coords */
-
 
1336
		clip.x2 = unit->crtc.mode.hdisplay - clip.x1;
-
 
1337
		clip.y2 = unit->crtc.mode.vdisplay - clip.y1;
-
 
1338
		clip.x1 = 0 - clip.x1;
-
 
1339
		clip.y1 = 0 - clip.y1;
-
 
1340
 
-
 
1341
		/* need to reset sid as it is changed by execbuf */
-
 
1342
		cmd->body.srcImage.sid = sid;
-
 
1343
		cmd->body.destScreenId = unit->unit;
-
 
1344
 
-
 
1345
		/* clip and write blits to cmd stream */
-
 
1346
		vmw_clip_cliprects(tmp, num_clips, clip, blits, &num);
-
 
1347
 
-
 
1348
		/* if no cliprects hit skip this */
-
 
1349
		if (num == 0)
-
 
1350
			continue;
-
 
1351
 
-
 
1352
		/* recalculate package length */
-
 
1353
		fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
-
 
1354
		cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
-
 
1355
		ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
-
 
1356
					  fifo_size, 0, NULL, NULL);
-
 
1357
 
-
 
1358
		if (unlikely(ret != 0))
-
 
1359
			break;
-
 
1360
	}
-
 
1361
 
-
 
1362
	kfree(cmd);
-
 
1363
out_free_tmp:
-
 
1364
	kfree(tmp);
-
 
1365
 
1082
					    num_clips, 1, NULL);
1366
	return ret;
1083
}
1367
}
1084
 
1368
 
1085
 
-
 
1086
int vmw_kms_present(struct vmw_private *dev_priv,
-
 
1087
		    struct drm_file *file_priv,
1369
int vmw_kms_readback(struct vmw_private *dev_priv,
1088
		    struct vmw_framebuffer *vfb,
1370
		     struct drm_file *file_priv,
1089
		    struct vmw_surface *surface,
1371
		     struct vmw_framebuffer *vfb,
1090
		    uint32_t sid,
1372
		     struct drm_vmw_fence_rep __user *user_fence_rep,
-
 
1373
		     struct drm_vmw_rect *clips,
-
 
1374
		     uint32_t num_clips)
-
 
1375
{
-
 
1376
	struct vmw_framebuffer_dmabuf *vfbd =
-
 
1377
		vmw_framebuffer_to_vfbd(&vfb->base);
-
 
1378
	struct vmw_dma_buffer *dmabuf = vfbd->buffer;
-
 
1379
	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
-
 
1380
	struct drm_crtc *crtc;
-
 
1381
	size_t fifo_size;
-
 
1382
	int i, k, ret, num_units, blits_pos;
-
 
1383
 
-
 
1384
	struct {
-
 
1385
		uint32_t header;
-
 
1386
		SVGAFifoCmdDefineGMRFB body;
-
 
1387
	} *cmd;
1091
		    int32_t destX, int32_t destY,
1388
	struct {
-
 
1389
		uint32_t header;
-
 
1390
		SVGAFifoCmdBlitScreenToGMRFB body;
-
 
1391
	} *blits;
-
 
1392
 
-
 
1393
	num_units = 0;
-
 
1394
	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
-
 
1395
		if (crtc->primary->fb != &vfb->base)
-
 
1396
			continue;
-
 
1397
		units[num_units++] = vmw_crtc_to_du(crtc);
-
 
1398
	}
-
 
1399
 
-
 
1400
	BUG_ON(dmabuf == NULL);
-
 
1401
	BUG_ON(!clips || !num_clips);
-
 
1402
 
-
 
1403
	/* take a safe guess at fifo size */
-
 
1404
	fifo_size = sizeof(*cmd) + sizeof(*blits) * num_clips * num_units;
-
 
1405
	cmd = kmalloc(fifo_size, GFP_KERNEL);
-
 
1406
	if (unlikely(cmd == NULL)) {
-
 
1407
		DRM_ERROR("Failed to allocate temporary fifo memory.\n");
-
 
1408
		return -ENOMEM;
-
 
1409
	}
-
 
1410
 
-
 
1411
	memset(cmd, 0, fifo_size);
-
 
1412
	cmd->header = SVGA_CMD_DEFINE_GMRFB;
-
 
1413
	cmd->body.format.bitsPerPixel = vfb->base.bits_per_pixel;
-
 
1414
	cmd->body.format.colorDepth = vfb->base.depth;
-
 
1415
	cmd->body.format.reserved = 0;
-
 
1416
	cmd->body.bytesPerLine = vfb->base.pitches[0];
-
 
1417
	cmd->body.ptr.gmrId = vfb->user_handle;
-
 
1418
	cmd->body.ptr.offset = 0;
-
 
1419
 
-
 
1420
	blits = (void *)&cmd[1];
-
 
1421
	blits_pos = 0;
-
 
1422
	for (i = 0; i < num_units; i++) {
-
 
1423
		struct drm_vmw_rect *c = clips;
-
 
1424
		for (k = 0; k < num_clips; k++, c++) {
-
 
1425
			/* transform clip coords to crtc origin based coords */
-
 
1426
			int clip_x1 = c->x - units[i]->crtc.x;
-
 
1427
			int clip_x2 = c->x - units[i]->crtc.x + c->w;
-
 
1428
			int clip_y1 = c->y - units[i]->crtc.y;
-
 
1429
			int clip_y2 = c->y - units[i]->crtc.y + c->h;
-
 
1430
			int dest_x = c->x;
-
 
1431
			int dest_y = c->y;
-
 
1432
 
-
 
1433
			/* compensate for clipping, we negate
-
 
1434
			 * a negative number and add that.
-
 
1435
			 */
-
 
1436
			if (clip_x1 < 0)
-
 
1437
				dest_x += -clip_x1;
-
 
1438
			if (clip_y1 < 0)
-
 
1439
				dest_y += -clip_y1;
-
 
1440
 
-
 
1441
			/* clip */
-
 
1442
			clip_x1 = max(clip_x1, 0);
-
 
1443
			clip_y1 = max(clip_y1, 0);
-
 
1444
			clip_x2 = min(clip_x2, units[i]->crtc.mode.hdisplay);
-
 
1445
			clip_y2 = min(clip_y2, units[i]->crtc.mode.vdisplay);
-
 
1446
 
-
 
1447
			/* and cull any rects that misses the crtc */
-
 
1448
			if (clip_x1 >= units[i]->crtc.mode.hdisplay ||
-
 
1449
			    clip_y1 >= units[i]->crtc.mode.vdisplay ||
-
 
1450
			    clip_x2 <= 0 || clip_y2 <= 0)
-
 
1451
				continue;
-
 
1452
 
-
 
Line -... Line 1092...
-
 
1092
		    struct drm_vmw_rect *clips,
-
 
1093
		    uint32_t num_clips)
1453
			blits[blits_pos].header = SVGA_CMD_BLIT_SCREEN_TO_GMRFB;
1094
{
1454
			blits[blits_pos].body.srcScreenId = units[i]->unit;
1095
	int ret;
-
 
1096
 
-
 
1097
	switch (dev_priv->active_display_unit) {
-
 
1098
	case vmw_du_screen_target:
-
 
1099
		ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, clips,
1455
			blits[blits_pos].body.destOrigin.x = dest_x;
1100
						 &surface->res, destX, destY,
-
 
1101
						 num_clips, 1, NULL);
-
 
1102
		break;
-
 
1103
	case vmw_du_screen_object:
-
 
1104
		ret = vmw_kms_generic_present(dev_priv, file_priv, vfb, surface,
1456
			blits[blits_pos].body.destOrigin.y = dest_y;
1105
					      sid, destX, destY, clips,
1457
 
1106
					      num_clips);
1458
			blits[blits_pos].body.srcRect.left = clip_x1;
1107
		break;
1459
			blits[blits_pos].body.srcRect.top = clip_y1;
1108
	default:
1460
			blits[blits_pos].body.srcRect.right = clip_x2;
-
 
1461
			blits[blits_pos].body.srcRect.bottom = clip_y2;
1109
		WARN_ONCE(true,
1462
			blits_pos++;
-
 
1463
		}
-
 
1464
	}
1110
			  "Present called with invalid display system.\n");
Line 1465... Line 1111...
1465
	/* reset size here and use calculated exact size from loops */
1111
		ret = -ENOSYS;
Line 1466... Line 1112...
1466
	fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos;
1112
		break;
1467
 
1113
	}
Line 1468... Line 1114...
1468
	ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
1114
	if (ret)
1469
				  0, user_fence_rep, NULL);
1115
		return ret;
1470
 
1116
 
Line 1480... Line 1126...
1480
 
1126
 
1481
	drm_mode_config_init(dev);
1127
	drm_mode_config_init(dev);
1482
	dev->mode_config.funcs = &vmw_kms_funcs;
1128
	dev->mode_config.funcs = &vmw_kms_funcs;
1483
	dev->mode_config.min_width = 1;
1129
	dev->mode_config.min_width = 1;
1484
	dev->mode_config.min_height = 1;
-
 
1485
	/* assumed largest fb size */
1130
	dev->mode_config.min_height = 1;
1486
	dev->mode_config.max_width = 8192;
1131
	dev->mode_config.max_width = dev_priv->texture_max_width;
Line 1487... Line 1132...
1487
	dev->mode_config.max_height = 8192;
1132
	dev->mode_config.max_height = dev_priv->texture_max_height;
-
 
1133
 
-
 
1134
	ret = vmw_kms_stdu_init_display(dev_priv);
-
 
1135
	if (ret) {
-
 
1136
		ret = vmw_kms_sou_init_display(dev_priv);
-
 
1137
		if (ret) /* Fallback */
Line 1488... Line 1138...
1488
 
1138
			ret = vmw_kms_ldu_init_display(dev_priv);
1489
	ret = vmw_kms_init_screen_object_display(dev_priv);
1139
	}
Line 1490... Line 1140...
1490
 
1140
 
1491
	return 0;
1141
	return ret;
-
 
1142
}
-
 
1143
 
1492
}
1144
int vmw_kms_close(struct vmw_private *dev_priv)
1493
 
1145
{
1494
int vmw_kms_close(struct vmw_private *dev_priv)
1146
	int ret;
1495
{
1147
 
1496
	/*
1148
	/*
1497
	 * Docs says we should take the lock before calling this function
1149
	 * Docs says we should take the lock before calling this function
-
 
1150
	 * but since it destroys encoders and our destructor calls
1498
	 * but since it destroys encoders and our destructor calls
1151
	 * drm_encoder_cleanup which takes the lock we deadlock.
-
 
1152
	 */
1499
	 * drm_encoder_cleanup which takes the lock we deadlock.
1153
	drm_mode_config_cleanup(dev_priv->dev);
1500
	 */
1154
	if (dev_priv->active_display_unit == vmw_du_screen_object)
1501
//   drm_mode_config_cleanup(dev_priv->dev);
1155
		ret = vmw_kms_sou_close_display(dev_priv);
-
 
1156
	else if (dev_priv->active_display_unit == vmw_du_screen_target)
1502
//   if (dev_priv->sou_priv)
1157
		ret = vmw_kms_stdu_close_display(dev_priv);
1503
//       vmw_kms_close_screen_object_display(dev_priv);
1158
	else
Line 1504... Line 1159...
1504
//   else
1159
		ret = vmw_kms_ldu_close_display(dev_priv);
1505
//       vmw_kms_close_legacy_display_system(dev_priv);
1160
 
1506
	return 0;
1161
	return ret;
Line 1552... Line 1207...
1552
			unsigned bpp, unsigned depth)
1207
			unsigned bpp, unsigned depth)
1553
{
1208
{
1554
	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1209
	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1555
		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
1210
		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK, pitch);
1556
	else if (vmw_fifo_have_pitchlock(vmw_priv))
1211
	else if (vmw_fifo_have_pitchlock(vmw_priv))
1557
		iowrite32(pitch, vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
1212
		vmw_mmio_write(pitch, vmw_priv->mmio_virt +
-
 
1213
			       SVGA_FIFO_PITCHLOCK);
1558
	vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
1214
	vmw_write(vmw_priv, SVGA_REG_WIDTH, width);
1559
	vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
1215
	vmw_write(vmw_priv, SVGA_REG_HEIGHT, height);
1560
	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bpp);
1216
	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, bpp);
Line 1561... Line 1217...
1561
 
1217
 
Line 1578... Line 1234...
1578
	vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
1234
	vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
1579
	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1235
	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1580
		vmw_priv->vga_pitchlock =
1236
		vmw_priv->vga_pitchlock =
1581
		  vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
1237
		  vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
1582
	else if (vmw_fifo_have_pitchlock(vmw_priv))
1238
	else if (vmw_fifo_have_pitchlock(vmw_priv))
1583
		vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt +
1239
		vmw_priv->vga_pitchlock = vmw_mmio_read(vmw_priv->mmio_virt +
1584
						       SVGA_FIFO_PITCHLOCK);
1240
							SVGA_FIFO_PITCHLOCK);
Line 1585... Line 1241...
1585
 
1241
 
1586
	if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
1242
	if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
Line 1627... Line 1283...
1627
	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
1283
	vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
1628
	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1284
	if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
1629
		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
1285
		vmw_write(vmw_priv, SVGA_REG_PITCHLOCK,
1630
			  vmw_priv->vga_pitchlock);
1286
			  vmw_priv->vga_pitchlock);
1631
	else if (vmw_fifo_have_pitchlock(vmw_priv))
1287
	else if (vmw_fifo_have_pitchlock(vmw_priv))
1632
		iowrite32(vmw_priv->vga_pitchlock,
1288
		vmw_mmio_write(vmw_priv->vga_pitchlock,
1633
			  vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
1289
			       vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
Line 1634... Line 1290...
1634
 
1290
 
1635
	if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
1291
	if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
Line 1651... Line 1307...
1651
 
1307
 
1652
bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
1308
bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
1653
				uint32_t pitch,
1309
				uint32_t pitch,
1654
				uint32_t height)
1310
				uint32_t height)
1655
{
1311
{
-
 
1312
	return ((u64) pitch * (u64) height) < (u64)
-
 
1313
		((dev_priv->active_display_unit == vmw_du_screen_target) ?
1656
	return ((u64) pitch * (u64) height) < (u64) dev_priv->prim_bb_mem;
1314
		 dev_priv->prim_bb_mem : dev_priv->vram_size);
Line 1657... Line 1315...
1657
}
1315
}
1658
 
1316
 
1659
 
1317
 
1660
/**
1318
/**
1661
 * Function called by DRM code called with vbl_lock held.
1319
 * Function called by DRM code called with vbl_lock held.
1662
 */
1320
 */
1663
u32 vmw_get_vblank_counter(struct drm_device *dev, int crtc)
1321
u32 vmw_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
Line 1664... Line 1322...
1664
{
1322
{
1665
	return 0;
1323
	return 0;
1666
}
1324
}
1667
 
1325
 
1668
/**
1326
/**
1669
 * Function called by DRM code called with vbl_lock held.
1327
 * Function called by DRM code called with vbl_lock held.
1670
 */
1328
 */
Line 1671... Line 1329...
1671
int vmw_enable_vblank(struct drm_device *dev, int crtc)
1329
int vmw_enable_vblank(struct drm_device *dev, unsigned int pipe)
1672
{
1330
{
1673
	return -ENOSYS;
1331
	return -ENOSYS;
1674
}
1332
}
1675
 
1333
 
1676
/**
1334
/**
Line 1677... Line 1335...
1677
 * Function called by DRM code called with vbl_lock held.
1335
 * Function called by DRM code called with vbl_lock held.
Line 1725... Line 1383...
1725
	mutex_unlock(&dev->mode_config.mutex);
1383
	mutex_unlock(&dev->mode_config.mutex);
Line 1726... Line 1384...
1726
 
1384
 
1727
	return 0;
1385
	return 0;
Line 1728... Line -...
1728
}
-
 
1729
 
-
 
1730
#if 0
-
 
1731
int vmw_du_page_flip(struct drm_crtc *crtc,
-
 
1732
		     struct drm_framebuffer *fb,
-
 
1733
		     struct drm_pending_vblank_event *event,
-
 
1734
		     uint32_t page_flip_flags)
-
 
1735
{
-
 
1736
	struct vmw_private *dev_priv = vmw_priv(crtc->dev);
-
 
1737
	struct drm_framebuffer *old_fb = crtc->primary->fb;
-
 
1738
	struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
-
 
1739
	struct drm_file *file_priv ;
-
 
1740
	struct vmw_fence_obj *fence = NULL;
-
 
1741
	struct drm_clip_rect clips;
-
 
1742
	int ret;
-
 
1743
 
-
 
1744
	if (event == NULL)
-
 
1745
		return -EINVAL;
-
 
1746
 
-
 
1747
	/* require ScreenObject support for page flipping */
-
 
1748
	if (!dev_priv->sou_priv)
-
 
1749
		return -ENOSYS;
-
 
1750
 
-
 
1751
	file_priv = event->base.file_priv;
-
 
1752
	if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
-
 
1753
		return -EINVAL;
-
 
1754
 
-
 
1755
	crtc->primary->fb = fb;
-
 
1756
 
-
 
1757
	/* do a full screen dirty update */
-
 
1758
	clips.x1 = clips.y1 = 0;
-
 
1759
	clips.x2 = fb->width;
-
 
1760
	clips.y2 = fb->height;
-
 
1761
 
-
 
1762
	if (vfb->dmabuf)
-
 
1763
		ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb,
-
 
1764
					  0, 0, &clips, 1, 1, &fence);
-
 
1765
	else
-
 
1766
		ret = do_surface_dirty_sou(dev_priv, file_priv, vfb,
-
 
1767
					   0, 0, &clips, 1, 1, &fence);
-
 
1768
 
-
 
1769
 
-
 
1770
	if (ret != 0)
-
 
1771
		goto out_no_fence;
-
 
1772
	if (!fence) {
-
 
1773
		ret = -EINVAL;
-
 
1774
		goto out_no_fence;
-
 
1775
	}
-
 
1776
 
-
 
1777
	ret = vmw_event_fence_action_queue(file_priv, fence,
-
 
1778
					   &event->base,
-
 
1779
					   &event->event.tv_sec,
-
 
1780
					   &event->event.tv_usec,
-
 
1781
					   true);
-
 
1782
 
-
 
1783
	/*
-
 
1784
	 * No need to hold on to this now. The only cleanup
-
 
1785
	 * we need to do if we fail is unref the fence.
-
 
1786
	 */
-
 
1787
	vmw_fence_obj_unreference(&fence);
-
 
1788
 
-
 
1789
	if (vmw_crtc_to_du(crtc)->is_implicit)
-
 
1790
		vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc);
-
 
1791
 
-
 
1792
	return ret;
-
 
1793
 
-
 
1794
out_no_fence:
-
 
1795
	crtc->primary->fb = old_fb;
-
 
1796
	return ret;
-
 
1797
}
-
 
1798
#endif
1386
}
1799
 
1387
 
1800
void vmw_du_crtc_save(struct drm_crtc *crtc)
1388
void vmw_du_crtc_save(struct drm_crtc *crtc)
Line 1801... Line 1389...
1801
{
1389
{
Line 1819... Line 1407...
1819
		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
1407
		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
1820
		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
1408
		vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
1821
	}
1409
	}
1822
}
1410
}
Line 1823... Line 1411...
1823
 
1411
 
1824
void vmw_du_connector_dpms(struct drm_connector *connector, int mode)
1412
int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
-
 
1413
{
1825
{
1414
	return 0;
Line 1826... Line 1415...
1826
}
1415
}
1827
 
1416
 
1828
void vmw_du_connector_save(struct drm_connector *connector)
1417
void vmw_du_connector_save(struct drm_connector *connector)
Line 1839... Line 1428...
1839
	uint32_t num_displays;
1428
	uint32_t num_displays;
1840
	struct drm_device *dev = connector->dev;
1429
	struct drm_device *dev = connector->dev;
1841
	struct vmw_private *dev_priv = vmw_priv(dev);
1430
	struct vmw_private *dev_priv = vmw_priv(dev);
1842
	struct vmw_display_unit *du = vmw_connector_to_du(connector);
1431
	struct vmw_display_unit *du = vmw_connector_to_du(connector);
Line 1843... Line -...
1843
 
-
 
1844
	mutex_lock(&dev_priv->hw_mutex);
1432
 
1845
	num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
-
 
Line 1846... Line 1433...
1846
	mutex_unlock(&dev_priv->hw_mutex);
1433
	num_displays = vmw_read(dev_priv, SVGA_REG_NUM_DISPLAYS);
1847
 
1434
 
1848
	return ((vmw_connector_to_du(connector)->unit < num_displays &&
1435
	return ((vmw_connector_to_du(connector)->unit < num_displays &&
1849
		 du->pref_active) ?
1436
		 du->pref_active) ?
Line 1936... Line 1523...
1936
 * 60Hz vrefresh mode.
1523
 * 60Hz vrefresh mode.
1937
 *
1524
 *
1938
 * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay
1525
 * @mode - Pointer to a struct drm_display_mode with hdisplay and vdisplay
1939
 * members filled in.
1526
 * members filled in.
1940
 */
1527
 */
1941
static void vmw_guess_mode_timing(struct drm_display_mode *mode)
1528
void vmw_guess_mode_timing(struct drm_display_mode *mode)
1942
{
1529
{
1943
	mode->hsync_start = mode->hdisplay + 50;
1530
	mode->hsync_start = mode->hdisplay + 50;
1944
	mode->hsync_end = mode->hsync_start + 50;
1531
	mode->hsync_end = mode->hsync_start + 50;
1945
	mode->htotal = mode->hsync_end + 50;
1532
	mode->htotal = mode->hsync_end + 50;
Line 1965... Line 1552...
1965
		DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
1552
		DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
1966
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1553
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1967
		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
1554
		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
1968
	};
1555
	};
1969
	int i;
1556
	int i;
-
 
1557
	u32 assumed_bpp = 2;
-
 
1558
 
-
 
1559
	/*
-
 
1560
	 * If using screen objects, then assume 32-bpp because that's what the
-
 
1561
	 * SVGA device is assuming
-
 
1562
	 */
-
 
1563
	if (dev_priv->active_display_unit == vmw_du_screen_object)
-
 
1564
		assumed_bpp = 4;
-
 
1565
 
-
 
1566
	if (dev_priv->active_display_unit == vmw_du_screen_target) {
-
 
1567
		max_width  = min(max_width,  dev_priv->stdu_max_width);
-
 
1568
		max_height = min(max_height, dev_priv->stdu_max_height);
-
 
1569
	}
Line 1970... Line 1570...
1970
 
1570
 
1971
	/* Add preferred mode */
-
 
1972
	{
1571
	/* Add preferred mode */
1973
		mode = drm_mode_duplicate(dev, &prefmode);
1572
	mode = drm_mode_duplicate(dev, &prefmode);
1974
		if (!mode)
1573
	if (!mode)
1975
			return 0;
1574
		return 0;
1976
		mode->hdisplay = du->pref_width;
1575
	mode->hdisplay = du->pref_width;
1977
		mode->vdisplay = du->pref_height;
1576
	mode->vdisplay = du->pref_height;
Line 1978... Line 1577...
1978
		vmw_guess_mode_timing(mode);
1577
	vmw_guess_mode_timing(mode);
-
 
1578
 
1979
 
1579
	if (vmw_kms_validate_mode_vram(dev_priv,
1980
		if (vmw_kms_validate_mode_vram(dev_priv, mode->hdisplay * 2,
1580
					mode->hdisplay * assumed_bpp,
1981
					       mode->vdisplay)) {
1581
					mode->vdisplay)) {
1982
			drm_mode_probed_add(connector, mode);
1582
		drm_mode_probed_add(connector, mode);
1983
		} else {
1583
	} else {
Line 1990... Line 1590...
1990
			drm_mode_destroy(dev, du->pref_mode);
1590
		drm_mode_destroy(dev, du->pref_mode);
1991
		}
1591
	}
Line 1992... Line 1592...
1992
 
1592
 
1993
		/* mode might be null here, this is intended */
1593
	/* mode might be null here, this is intended */
1994
		du->pref_mode = mode;
-
 
Line 1995... Line 1594...
1995
	}
1594
	du->pref_mode = mode;
1996
 
1595
 
1997
	for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
1596
	for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
1998
		bmode = &vmw_kms_connector_builtin[i];
1597
		bmode = &vmw_kms_connector_builtin[i];
1999
		if (bmode->hdisplay > max_width ||
1598
		if (bmode->hdisplay > max_width ||
Line 2000... Line 1599...
2000
		    bmode->vdisplay > max_height)
1599
		    bmode->vdisplay > max_height)
-
 
1600
			continue;
2001
			continue;
1601
 
2002
 
1602
		if (!vmw_kms_validate_mode_vram(dev_priv,
Line 2003... Line 1603...
2003
		if (!vmw_kms_validate_mode_vram(dev_priv, bmode->hdisplay * 2,
1603
						bmode->hdisplay * assumed_bpp,
2004
						bmode->vdisplay))
1604
						bmode->vdisplay))
Line 2010... Line 1610...
2010
		mode->vrefresh = drm_mode_vrefresh(mode);
1610
		mode->vrefresh = drm_mode_vrefresh(mode);
Line 2011... Line 1611...
2011
 
1611
 
2012
		drm_mode_probed_add(connector, mode);
1612
		drm_mode_probed_add(connector, mode);
Line 2013... Line -...
2013
	}
-
 
2014
 
-
 
2015
	/* Move the prefered mode first, help apps pick the right mode. */
-
 
2016
	if (du->pref_mode)
-
 
2017
		list_move(&du->pref_mode->head, &connector->probed_modes);
1613
	}
-
 
1614
 
-
 
1615
	drm_mode_connector_list_update(connector, true);
Line 2018... Line 1616...
2018
 
1616
	/* Move the prefered mode first, help apps pick the right mode. */
2019
	drm_mode_connector_list_update(connector, true);
1617
	drm_mode_sort(&connector->modes);
Line 2020... Line 1618...
2020
 
1618
 
Line 2038... Line 1636...
2038
	void __user *user_rects;
1636
	void __user *user_rects;
2039
	struct drm_vmw_rect *rects;
1637
	struct drm_vmw_rect *rects;
2040
	unsigned rects_size;
1638
	unsigned rects_size;
2041
	int ret;
1639
	int ret;
2042
	int i;
1640
	int i;
-
 
1641
	u64 total_pixels = 0;
2043
	struct drm_mode_config *mode_config = &dev->mode_config;
1642
	struct drm_mode_config *mode_config = &dev->mode_config;
2044
 
-
 
2045
	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
1643
	struct drm_vmw_rect bounding_box = {0};
2046
	if (unlikely(ret != 0))
-
 
2047
		return ret;
-
 
Line 2048... Line 1644...
2048
 
1644
 
2049
	if (!arg->num_outputs) {
1645
	if (!arg->num_outputs) {
2050
		struct drm_vmw_rect def_rect = {0, 0, 800, 600};
1646
		struct drm_vmw_rect def_rect = {0, 0, 800, 600};
2051
		vmw_du_update_layout(dev_priv, 1, &def_rect);
1647
		vmw_du_update_layout(dev_priv, 1, &def_rect);
2052
		goto out_unlock;
1648
		return 0;
Line 2053... Line 1649...
2053
	}
1649
	}
2054
 
1650
 
2055
	rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
1651
	rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
2056
	rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
1652
	rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect),
2057
			GFP_KERNEL);
1653
			GFP_KERNEL);
2058
	if (unlikely(!rects)) {
-
 
2059
		ret = -ENOMEM;
-
 
Line 2060... Line 1654...
2060
		goto out_unlock;
1654
	if (unlikely(!rects))
2061
	}
1655
		return -ENOMEM;
2062
 
1656
 
2063
	user_rects = (void __user *)(unsigned long)arg->rects;
1657
	user_rects = (void __user *)(unsigned long)arg->rects;
Line 2075... Line 1669...
2075
		    rects[i].y + rects[i].h > mode_config->max_height) {
1669
		    rects[i].y + rects[i].h > mode_config->max_height) {
2076
			DRM_ERROR("Invalid GUI layout.\n");
1670
			DRM_ERROR("Invalid GUI layout.\n");
2077
			ret = -EINVAL;
1671
			ret = -EINVAL;
2078
			goto out_free;
1672
			goto out_free;
2079
		}
1673
		}
-
 
1674
 
-
 
1675
		/*
-
 
1676
		 * bounding_box.w and bunding_box.h are used as
-
 
1677
		 * lower-right coordinates
-
 
1678
		 */
-
 
1679
		if (rects[i].x + rects[i].w > bounding_box.w)
-
 
1680
			bounding_box.w = rects[i].x + rects[i].w;
-
 
1681
 
-
 
1682
		if (rects[i].y + rects[i].h > bounding_box.h)
-
 
1683
			bounding_box.h = rects[i].y + rects[i].h;
-
 
1684
 
-
 
1685
		total_pixels += (u64) rects[i].w * (u64) rects[i].h;
-
 
1686
	}
-
 
1687
 
-
 
1688
	if (dev_priv->active_display_unit == vmw_du_screen_target) {
-
 
1689
		/*
-
 
1690
		 * For Screen Targets, the limits for a toplogy are:
-
 
1691
		 *	1. Bounding box (assuming 32bpp) must be < prim_bb_mem
-
 
1692
		 *      2. Total pixels (assuming 32bpp) must be < prim_bb_mem
-
 
1693
		 */
-
 
1694
		u64 bb_mem    = bounding_box.w * bounding_box.h * 4;
-
 
1695
		u64 pixel_mem = total_pixels * 4;
-
 
1696
 
-
 
1697
		if (bb_mem > dev_priv->prim_bb_mem) {
-
 
1698
			DRM_ERROR("Topology is beyond supported limits.\n");
-
 
1699
			ret = -EINVAL;
-
 
1700
			goto out_free;
-
 
1701
		}
-
 
1702
 
-
 
1703
		if (pixel_mem > dev_priv->prim_bb_mem) {
-
 
1704
			DRM_ERROR("Combined output size too large\n");
-
 
1705
			ret = -EINVAL;
-
 
1706
			goto out_free;
-
 
1707
		}
2080
	}
1708
	}
Line 2081... Line 1709...
2081
 
1709
 
Line 2082... Line 1710...
2082
	vmw_du_update_layout(dev_priv, arg->num_outputs, rects);
1710
	vmw_du_update_layout(dev_priv, arg->num_outputs, rects);
2083
 
1711
 
2084
out_free:
-
 
2085
	kfree(rects);
-
 
2086
out_unlock:
1712
out_free:
2087
	ttm_read_unlock(&dev_priv->reservation_sem);
1713
	kfree(rects);
2088
	return ret;
1714
	return ret;
-
 
1715
}
-
 
1716
#endif
-
 
1717
/**
-
 
1718
 * vmw_kms_helper_dirty - Helper to build commands and perform actions based
-
 
1719
 * on a set of cliprects and a set of display units.
-
 
1720
 *
-
 
1721
 * @dev_priv: Pointer to a device private structure.
-
 
1722
 * @framebuffer: Pointer to the framebuffer on which to perform the actions.
-
 
1723
 * @clips: A set of struct drm_clip_rect. Either this os @vclips must be NULL.
-
 
1724
 * Cliprects are given in framebuffer coordinates.
-
 
1725
 * @vclips: A set of struct drm_vmw_rect cliprects. Either this or @clips must
-
 
1726
 * be NULL. Cliprects are given in source coordinates.
-
 
1727
 * @dest_x: X coordinate offset for the crtc / destination clip rects.
-
 
1728
 * @dest_y: Y coordinate offset for the crtc / destination clip rects.
-
 
1729
 * @num_clips: Number of cliprects in the @clips or @vclips array.
-
 
1730
 * @increment: Integer with which to increment the clip counter when looping.
-
 
1731
 * Used to skip a predetermined number of clip rects.
-
 
1732
 * @dirty: Closure structure. See the description of struct vmw_kms_dirty.
-
 
1733
 */
-
 
1734
int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
-
 
1735
			 struct vmw_framebuffer *framebuffer,
-
 
1736
			 const struct drm_clip_rect *clips,
-
 
1737
			 const struct drm_vmw_rect *vclips,
-
 
1738
			 s32 dest_x, s32 dest_y,
-
 
1739
			 int num_clips,
-
 
1740
			 int increment,
-
 
1741
			 struct vmw_kms_dirty *dirty)
-
 
1742
{
-
 
1743
	struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
-
 
1744
	struct drm_crtc *crtc;
-
 
1745
	u32 num_units = 0;
-
 
1746
	u32 i, k;
-
 
1747
 
-
 
1748
	dirty->dev_priv = dev_priv;
-
 
1749
 
-
 
1750
	list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) {
-
 
1751
		if (crtc->primary->fb != &framebuffer->base)
-
 
1752
			continue;
-
 
1753
		units[num_units++] = vmw_crtc_to_du(crtc);
-
 
1754
	}
-
 
1755
 
-
 
1756
	for (k = 0; k < num_units; k++) {
-
 
1757
		struct vmw_display_unit *unit = units[k];
-
 
1758
		s32 crtc_x = unit->crtc.x;
-
 
1759
		s32 crtc_y = unit->crtc.y;
-
 
1760
		s32 crtc_width = unit->crtc.mode.hdisplay;
-
 
1761
		s32 crtc_height = unit->crtc.mode.vdisplay;
-
 
1762
		const struct drm_clip_rect *clips_ptr = clips;
-
 
1763
		const struct drm_vmw_rect *vclips_ptr = vclips;
-
 
1764
 
-
 
1765
		dirty->unit = unit;
-
 
1766
		if (dirty->fifo_reserve_size > 0) {
-
 
1767
			dirty->cmd = vmw_fifo_reserve(dev_priv,
-
 
1768
						      dirty->fifo_reserve_size);
-
 
1769
			if (!dirty->cmd) {
-
 
1770
				DRM_ERROR("Couldn't reserve fifo space "
-
 
1771
					  "for dirty blits.\n");
-
 
1772
				return -ENOMEM;
-
 
1773
			}
-
 
1774
			memset(dirty->cmd, 0, dirty->fifo_reserve_size);
-
 
1775
		}
-
 
1776
		dirty->num_hits = 0;
-
 
1777
		for (i = 0; i < num_clips; i++, clips_ptr += increment,
-
 
1778
		       vclips_ptr += increment) {
-
 
1779
			s32 clip_left;
-
 
1780
			s32 clip_top;
-
 
1781
 
-
 
1782
			/*
-
 
1783
			 * Select clip array type. Note that integer type
-
 
1784
			 * in @clips is unsigned short, whereas in @vclips
-
 
1785
			 * it's 32-bit.
-
 
1786
			 */
-
 
1787
			if (clips) {
-
 
1788
				dirty->fb_x = (s32) clips_ptr->x1;
-
 
1789
				dirty->fb_y = (s32) clips_ptr->y1;
-
 
1790
				dirty->unit_x2 = (s32) clips_ptr->x2 + dest_x -
-
 
1791
					crtc_x;
-
 
1792
				dirty->unit_y2 = (s32) clips_ptr->y2 + dest_y -
-
 
1793
					crtc_y;
-
 
1794
			} else {
-
 
1795
				dirty->fb_x = vclips_ptr->x;
-
 
1796
				dirty->fb_y = vclips_ptr->y;
-
 
1797
				dirty->unit_x2 = dirty->fb_x + vclips_ptr->w +
-
 
1798
					dest_x - crtc_x;
-
 
1799
				dirty->unit_y2 = dirty->fb_y + vclips_ptr->h +
-
 
1800
					dest_y - crtc_y;
-
 
1801
			}
-
 
1802
 
-
 
1803
			dirty->unit_x1 = dirty->fb_x + dest_x - crtc_x;
-
 
1804
			dirty->unit_y1 = dirty->fb_y + dest_y - crtc_y;
-
 
1805
 
-
 
1806
			/* Skip this clip if it's outside the crtc region */
-
 
1807
			if (dirty->unit_x1 >= crtc_width ||
-
 
1808
			    dirty->unit_y1 >= crtc_height ||
-
 
1809
			    dirty->unit_x2 <= 0 || dirty->unit_y2 <= 0)
-
 
1810
				continue;
-
 
1811
 
-
 
1812
			/* Clip right and bottom to crtc limits */
-
 
1813
			dirty->unit_x2 = min_t(s32, dirty->unit_x2,
-
 
1814
					       crtc_width);
-
 
1815
			dirty->unit_y2 = min_t(s32, dirty->unit_y2,
-
 
1816
					       crtc_height);
-
 
1817
 
-
 
1818
			/* Clip left and top to crtc limits */
-
 
1819
			clip_left = min_t(s32, dirty->unit_x1, 0);
-
 
1820
			clip_top = min_t(s32, dirty->unit_y1, 0);
-
 
1821
			dirty->unit_x1 -= clip_left;
-
 
1822
			dirty->unit_y1 -= clip_top;
-
 
1823
			dirty->fb_x -= clip_left;
-
 
1824
			dirty->fb_y -= clip_top;
-
 
1825
 
-
 
1826
			dirty->clip(dirty);
-
 
1827
		}
-
 
1828
 
-
 
1829
		dirty->fifo_commit(dirty);
-
 
1830
	}
-
 
1831
 
-
 
1832
	return 0;
-
 
1833
}
-
 
1834
 
-
 
1835
/**
-
 
1836
 * vmw_kms_helper_buffer_prepare - Reserve and validate a buffer object before
-
 
1837
 * command submission.
-
 
1838
 *
-
 
1839
 * @dev_priv. Pointer to a device private structure.
-
 
1840
 * @buf: The buffer object
-
 
1841
 * @interruptible: Whether to perform waits as interruptible.
-
 
1842
 * @validate_as_mob: Whether the buffer should be validated as a MOB. If false,
-
 
1843
 * The buffer will be validated as a GMR. Already pinned buffers will not be
-
 
1844
 * validated.
-
 
1845
 *
-
 
1846
 * Returns 0 on success, negative error code on failure, -ERESTARTSYS if
-
 
1847
 * interrupted by a signal.
-
 
1848
 */
-
 
1849
int vmw_kms_helper_buffer_prepare(struct vmw_private *dev_priv,
-
 
1850
				  struct vmw_dma_buffer *buf,
-
 
1851
				  bool interruptible,
-
 
1852
				  bool validate_as_mob)
-
 
1853
{
-
 
1854
	struct ttm_buffer_object *bo = &buf->base;
-
 
1855
	int ret;
-
 
1856
 
-
 
1857
	ttm_bo_reserve(bo, false, false, interruptible, NULL);
-
 
1858
	ret = vmw_validate_single_buffer(dev_priv, bo, interruptible,
-
 
1859
					 validate_as_mob);
-
 
1860
	if (ret)
-
 
1861
		ttm_bo_unreserve(bo);
-
 
1862
 
-
 
1863
	return ret;
-
 
1864
}
-
 
1865
 
-
 
1866
/**
-
 
1867
 * vmw_kms_helper_buffer_revert - Undo the actions of
-
 
1868
 * vmw_kms_helper_buffer_prepare.
-
 
1869
 *
-
 
1870
 * @res: Pointer to the buffer object.
-
 
1871
 *
-
 
1872
 * Helper to be used if an error forces the caller to undo the actions of
-
 
1873
 * vmw_kms_helper_buffer_prepare.
-
 
1874
 */
-
 
1875
void vmw_kms_helper_buffer_revert(struct vmw_dma_buffer *buf)
-
 
1876
{
-
 
1877
	if (buf)
-
 
1878
		ttm_bo_unreserve(&buf->base);
-
 
1879
}
-
 
1880
 
-
 
1881
/**
-
 
1882
 * vmw_kms_helper_buffer_finish - Unreserve and fence a buffer object after
-
 
1883
 * kms command submission.
-
 
1884
 *
-
 
1885
 * @dev_priv: Pointer to a device private structure.
-
 
1886
 * @file_priv: Pointer to a struct drm_file representing the caller's
-
 
1887
 * connection. Must be set to NULL if @user_fence_rep is NULL, and conversely
-
 
1888
 * if non-NULL, @user_fence_rep must be non-NULL.
-
 
1889
 * @buf: The buffer object.
-
 
1890
 * @out_fence:  Optional pointer to a fence pointer. If non-NULL, a
-
 
1891
 * ref-counted fence pointer is returned here.
-
 
1892
 * @user_fence_rep: Optional pointer to a user-space provided struct
-
 
1893
 * drm_vmw_fence_rep. If provided, @file_priv must also be provided and the
-
 
1894
 * function copies fence data to user-space in a fail-safe manner.
-
 
1895
 */
-
 
1896
void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
-
 
1897
				  struct drm_file *file_priv,
-
 
1898
				  struct vmw_dma_buffer *buf,
-
 
1899
				  struct vmw_fence_obj **out_fence,
-
 
1900
				  struct drm_vmw_fence_rep __user *
-
 
1901
				  user_fence_rep)
-
 
1902
{
-
 
1903
	struct vmw_fence_obj *fence;
-
 
1904
	uint32_t handle;
-
 
1905
	int ret;
-
 
1906
 
-
 
1907
	ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
-
 
1908
					 file_priv ? &handle : NULL);
-
 
1909
	if (buf)
-
 
1910
		vmw_fence_single_bo(&buf->base, fence);
-
 
1911
	if (file_priv)
-
 
1912
		vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv),
-
 
1913
					    ret, user_fence_rep, fence,
-
 
1914
					    handle);
-
 
1915
	if (out_fence)
-
 
1916
		*out_fence = fence;
-
 
1917
	else
-
 
1918
		vmw_fence_obj_unreference(&fence);
-
 
1919
 
-
 
1920
	vmw_kms_helper_buffer_revert(buf);
-
 
1921
}
-
 
1922
 
-
 
1923
 
-
 
1924
/**
-
 
1925
 * vmw_kms_helper_resource_revert - Undo the actions of
-
 
1926
 * vmw_kms_helper_resource_prepare.
-
 
1927
 *
-
 
1928
 * @res: Pointer to the resource. Typically a surface.
-
 
1929
 *
-
 
1930
 * Helper to be used if an error forces the caller to undo the actions of
-
 
1931
 * vmw_kms_helper_resource_prepare.
-
 
1932
 */
-
 
1933
void vmw_kms_helper_resource_revert(struct vmw_resource *res)
-
 
1934
{
-
 
1935
	vmw_kms_helper_buffer_revert(res->backup);
-
 
1936
	vmw_resource_unreserve(res, false, NULL, 0);
-
 
1937
	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
-
 
1938
}
-
 
1939
 
-
 
1940
/**
-
 
1941
 * vmw_kms_helper_resource_prepare - Reserve and validate a resource before
-
 
1942
 * command submission.
-
 
1943
 *
-
 
1944
 * @res: Pointer to the resource. Typically a surface.
-
 
1945
 * @interruptible: Whether to perform waits as interruptible.
-
 
1946
 *
-
 
1947
 * Reserves and validates also the backup buffer if a guest-backed resource.
-
 
1948
 * Returns 0 on success, negative error code on failure. -ERESTARTSYS if
-
 
1949
 * interrupted by a signal.
-
 
1950
 */
-
 
1951
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
-
 
1952
				    bool interruptible)
-
 
1953
{
-
 
1954
	int ret = 0;
-
 
1955
 
-
 
1956
	if (interruptible)
-
 
1957
		ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
-
 
1958
	else
-
 
1959
		mutex_lock(&res->dev_priv->cmdbuf_mutex);
-
 
1960
 
-
 
1961
	if (unlikely(ret != 0))
-
 
1962
		return -ERESTARTSYS;
-
 
1963
 
-
 
1964
	ret = vmw_resource_reserve(res, interruptible, false);
-
 
1965
	if (ret)
-
 
1966
		goto out_unlock;
-
 
1967
 
-
 
1968
	if (res->backup) {
-
 
1969
		ret = vmw_kms_helper_buffer_prepare(res->dev_priv, res->backup,
-
 
1970
						    interruptible,
-
 
1971
						    res->dev_priv->has_mob);
-
 
1972
		if (ret)
-
 
1973
			goto out_unreserve;
-
 
1974
	}
-
 
1975
	ret = vmw_resource_validate(res);
-
 
1976
	if (ret)
-
 
1977
		goto out_revert;
-
 
1978
	return 0;
-
 
1979
 
-
 
1980
out_revert:
-
 
1981
	vmw_kms_helper_buffer_revert(res->backup);
-
 
1982
out_unreserve:
-
 
1983
	vmw_resource_unreserve(res, false, NULL, 0);
-
 
1984
out_unlock:
-
 
1985
	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
-
 
1986
	return ret;
-
 
1987
}
-
 
1988
 
-
 
1989
/**
-
 
1990
 * vmw_kms_helper_resource_finish - Unreserve and fence a resource after
-
 
1991
 * kms command submission.
-
 
1992
 *
-
 
1993
 * @res: Pointer to the resource. Typically a surface.
-
 
1994
 * @out_fence: Optional pointer to a fence pointer. If non-NULL, a
-
 
1995
 * ref-counted fence pointer is returned here.
-
 
1996
 */
-
 
1997
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
-
 
1998
			     struct vmw_fence_obj **out_fence)
-
 
1999
{
-
 
2000
	if (res->backup || out_fence)
-
 
2001
		vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup,
-
 
2002
					     out_fence, NULL);
-
 
2003
 
-
 
2004
	vmw_resource_unreserve(res, false, NULL, 0);
-
 
2005
	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
-
 
2006
}
-
 
2007
 
-
 
2008
/**
-
 
2009
 * vmw_kms_update_proxy - Helper function to update a proxy surface from
-
 
2010
 * its backing MOB.
-
 
2011
 *
-
 
2012
 * @res: Pointer to the surface resource
-
 
2013
 * @clips: Clip rects in framebuffer (surface) space.
-
 
2014
 * @num_clips: Number of clips in @clips.
-
 
2015
 * @increment: Integer with which to increment the clip counter when looping.
-
 
2016
 * Used to skip a predetermined number of clip rects.
-
 
2017
 *
-
 
2018
 * This function makes sure the proxy surface is updated from its backing MOB
-
 
2019
 * using the region given by @clips. The surface resource @res and its backing
-
 
2020
 * MOB needs to be reserved and validated on call.
-
 
2021
 */
-
 
2022
int vmw_kms_update_proxy(struct vmw_resource *res,
-
 
2023
			 const struct drm_clip_rect *clips,
-
 
2024
			 unsigned num_clips,
-
 
2025
			 int increment)
-
 
2026
{
-
 
2027
	struct vmw_private *dev_priv = res->dev_priv;
-
 
2028
	struct drm_vmw_size *size = &vmw_res_to_srf(res)->base_size;
-
 
2029
	struct {
-
 
2030
		SVGA3dCmdHeader header;
-
 
2031
		SVGA3dCmdUpdateGBImage body;
-
 
2032
	} *cmd;
-
 
2033
	SVGA3dBox *box;
-
 
2034
	size_t copy_size = 0;
-
 
2035
	int i;
-
 
2036
 
-
 
2037
	if (!clips)
-
 
2038
		return 0;
-
 
2039
 
-
 
2040
	cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips);
-
 
2041
	if (!cmd) {
-
 
2042
		DRM_ERROR("Couldn't reserve fifo space for proxy surface "
-
 
2043
			  "update.\n");
-
 
2044
		return -ENOMEM;
-
 
2045
	}
-
 
2046
 
-
 
2047
	for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
-
 
2048
		box = &cmd->body.box;
-
 
2049
 
-
 
2050
		cmd->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
-
 
2051
		cmd->header.size = sizeof(cmd->body);
-
 
2052
		cmd->body.image.sid = res->id;
-
 
2053
		cmd->body.image.face = 0;
-
 
2054
		cmd->body.image.mipmap = 0;
-
 
2055
 
-
 
2056
		if (clips->x1 > size->width || clips->x2 > size->width ||
-
 
2057
		    clips->y1 > size->height || clips->y2 > size->height) {
-
 
2058
			DRM_ERROR("Invalid clips outsize of framebuffer.\n");
-
 
2059
			return -EINVAL;
-
 
2060
		}
-
 
2061
 
-
 
2062
		box->x = clips->x1;
-
 
2063
		box->y = clips->y1;
-
 
2064
		box->z = 0;
-
 
2065
		box->w = clips->x2 - clips->x1;
-
 
2066
		box->h = clips->y2 - clips->y1;
-
 
2067
		box->d = 1;
-
 
2068
 
-
 
2069
		copy_size += sizeof(*cmd);
-
 
2070
	}
-
 
2071
 
-
 
2072
	vmw_fifo_commit(dev_priv, copy_size);
-
 
2073
 
-
 
2074
	return 0;
-
 
2075
}
-
 
2076
 
-
 
2077
int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
-
 
2078
			    unsigned unit,
-
 
2079
			    u32 max_width,
-
 
2080
			    u32 max_height,
-
 
2081
			    struct drm_connector **p_con,
-
 
2082
			    struct drm_crtc **p_crtc,
-
 
2083
			    struct drm_display_mode **p_mode)
-
 
2084
{
-
 
2085
	struct drm_connector *con;
-
 
2086
	struct vmw_display_unit *du;
-
 
2087
	struct drm_display_mode *mode;
-
 
2088
	int i = 0;
-
 
2089
 
-
 
2090
	list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list,
-
 
2091
			    head) {
-
 
2092
		if (i == unit)
-
 
2093
			break;
-
 
2094
 
-
 
2095
		++i;
-
 
2096
	}
-
 
2097
 
-
 
2098
	if (i != unit) {
-
 
2099
		DRM_ERROR("Could not find initial display unit.\n");
-
 
2100
		return -EINVAL;
-
 
2101
	}
-
 
2102
 
-
 
2103
	if (list_empty(&con->modes))
-
 
2104
		(void) vmw_du_connector_fill_modes(con, max_width, max_height);
-
 
2105
 
-
 
2106
	if (list_empty(&con->modes)) {
-
 
2107
		DRM_ERROR("Could not find initial display mode.\n");
-
 
2108
		return -EINVAL;
-
 
2109
	}
-
 
2110
 
-
 
2111
	du = vmw_connector_to_du(con);
-
 
2112
	*p_con = con;
-
 
2113
	*p_crtc = &du->crtc;
-
 
2114
 
-
 
2115
	list_for_each_entry(mode, &con->modes, head) {
-
 
2116
		if (mode->type & DRM_MODE_TYPE_PREFERRED)
-
 
2117
			break;
-
 
2118
	}
-
 
2119
 
-
 
2120
	if (mode->type & DRM_MODE_TYPE_PREFERRED)
-
 
2121
		*p_mode = mode;
-
 
2122
	else {
-
 
2123
		WARN_ONCE(true, "Could not find initial preferred mode.\n");
-
 
2124
		*p_mode = list_first_entry(&con->modes,
-
 
2125
					   struct drm_display_mode,
-
 
2126
					   head);
-
 
2127
	}
-
 
2128