Subversion Repositories Kolibri OS

Rev

Rev 4111 | Rev 5078 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4075 Serge 1
/**************************************************************************
2
 *
3
 * Copyright © 2011 VMware, Inc., Palo Alto, CA., USA
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 **************************************************************************/
27
 
28
#include "vmwgfx_kms.h"
29
 
30
 
31
#define vmw_crtc_to_sou(x) \
32
	container_of(x, struct vmw_screen_object_unit, base.crtc)
33
#define vmw_encoder_to_sou(x) \
34
	container_of(x, struct vmw_screen_object_unit, base.encoder)
35
#define vmw_connector_to_sou(x) \
36
	container_of(x, struct vmw_screen_object_unit, base.connector)
37
 
38
struct vmw_screen_object_display {
39
	unsigned num_implicit;
40
 
41
	struct vmw_framebuffer *implicit_fb;
42
};
43
 
44
/**
45
 * Display unit using screen objects.
46
 */
47
struct vmw_screen_object_unit {
48
	struct vmw_display_unit base;
49
 
50
	unsigned long buffer_size; /**< Size of allocated buffer */
51
	struct vmw_dma_buffer *buffer; /**< Backing store buffer */
52
 
53
	bool defined;
54
	bool active_implicit;
55
};
56
 
57
static void vmw_sou_destroy(struct vmw_screen_object_unit *sou)
58
{
59
//   vmw_display_unit_cleanup(&sou->base);
60
	kfree(sou);
61
}
62
 
63
 
64
/*
65
 * Screen Object Display Unit CRTC functions
66
 */
67
 
68
static void vmw_sou_crtc_destroy(struct drm_crtc *crtc)
69
{
70
	vmw_sou_destroy(vmw_crtc_to_sou(crtc));
71
}
72
 
73
static void vmw_sou_del_active(struct vmw_private *vmw_priv,
74
			      struct vmw_screen_object_unit *sou)
75
{
76
	struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
77
 
78
	if (sou->active_implicit) {
79
		if (--(ld->num_implicit) == 0)
80
			ld->implicit_fb = NULL;
81
		sou->active_implicit = false;
82
	}
83
}
84
 
85
static void vmw_sou_add_active(struct vmw_private *vmw_priv,
86
			      struct vmw_screen_object_unit *sou,
87
			      struct vmw_framebuffer *vfb)
88
{
89
	struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
90
 
91
	BUG_ON(!ld->num_implicit && ld->implicit_fb);
92
 
93
	if (!sou->active_implicit && sou->base.is_implicit) {
94
		ld->implicit_fb = vfb;
95
		sou->active_implicit = true;
96
		ld->num_implicit++;
97
	}
98
}
99
 
100
/**
101
 * Send the fifo command to create a screen.
102
 */
4080 Serge 103
int vmw_sou_fifo_create(struct vmw_private *dev_priv,
4075 Serge 104
			       struct vmw_screen_object_unit *sou,
105
			       uint32_t x, uint32_t y,
106
			       struct drm_display_mode *mode)
107
{
108
	size_t fifo_size;
109
 
110
	struct {
111
		struct {
112
			uint32_t cmdType;
113
		} header;
114
		SVGAScreenObject obj;
115
	} *cmd;
116
 
4080 Serge 117
//   BUG_ON(!sou->buffer);
4075 Serge 118
 
4080 Serge 119
    ENTER();
120
 
4075 Serge 121
	fifo_size = sizeof(*cmd);
122
	cmd = vmw_fifo_reserve(dev_priv, fifo_size);
123
	/* The hardware has hung, nothing we can do about it here. */
124
	if (unlikely(cmd == NULL)) {
125
		DRM_ERROR("Fifo reserve failed.\n");
126
		return -ENOMEM;
127
	}
128
 
129
	memset(cmd, 0, fifo_size);
130
	cmd->header.cmdType = SVGA_CMD_DEFINE_SCREEN;
131
	cmd->obj.structSize = sizeof(SVGAScreenObject);
132
	cmd->obj.id = sou->base.unit;
133
	cmd->obj.flags = SVGA_SCREEN_HAS_ROOT |
134
		(sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0);
135
	cmd->obj.size.width = mode->hdisplay;
136
	cmd->obj.size.height = mode->vdisplay;
137
	if (sou->base.is_implicit) {
138
		cmd->obj.root.x = x;
139
		cmd->obj.root.y = y;
140
	} else {
141
		cmd->obj.root.x = sou->base.gui_x;
142
		cmd->obj.root.y = sou->base.gui_y;
143
	}
144
 
145
	/* Ok to assume that buffer is pinned in vram */
4080 Serge 146
//   vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
147
 
148
    cmd->obj.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER;
149
    cmd->obj.backingStore.ptr.offset = 0;
4075 Serge 150
	cmd->obj.backingStore.pitch = mode->hdisplay * 4;
151
 
152
	vmw_fifo_commit(dev_priv, fifo_size);
153
 
154
	sou->defined = true;
155
 
4080 Serge 156
    LEAVE();
157
 
4075 Serge 158
	return 0;
159
}
160
 
161
/**
162
 * Send the fifo command to destroy a screen.
163
 */
164
static int vmw_sou_fifo_destroy(struct vmw_private *dev_priv,
165
				struct vmw_screen_object_unit *sou)
166
{
167
	size_t fifo_size;
168
	int ret;
169
 
170
	struct {
171
		struct {
172
			uint32_t cmdType;
173
		} header;
174
		SVGAFifoCmdDestroyScreen body;
175
	} *cmd;
176
 
177
	/* no need to do anything */
178
	if (unlikely(!sou->defined))
179
		return 0;
180
 
181
	fifo_size = sizeof(*cmd);
182
	cmd = vmw_fifo_reserve(dev_priv, fifo_size);
183
	/* the hardware has hung, nothing we can do about it here */
184
	if (unlikely(cmd == NULL)) {
185
		DRM_ERROR("Fifo reserve failed.\n");
186
		return -ENOMEM;
187
	}
188
 
189
	memset(cmd, 0, fifo_size);
190
	cmd->header.cmdType = SVGA_CMD_DESTROY_SCREEN;
191
	cmd->body.screenId = sou->base.unit;
192
 
193
	vmw_fifo_commit(dev_priv, fifo_size);
194
 
195
	/* Force sync */
196
	ret = vmw_fallback_wait(dev_priv, false, true, 0, false, 3*HZ);
197
	if (unlikely(ret != 0))
198
		DRM_ERROR("Failed to sync with HW");
199
	else
200
		sou->defined = false;
201
 
202
	return ret;
203
}
204
 
205
/**
206
 * Free the backing store.
207
 */
208
static void vmw_sou_backing_free(struct vmw_private *dev_priv,
209
				 struct vmw_screen_object_unit *sou)
210
{
211
	struct ttm_buffer_object *bo;
212
 
213
	if (unlikely(sou->buffer == NULL))
214
		return;
215
 
216
	bo = &sou->buffer->base;
217
	ttm_bo_unref(&bo);
218
	sou->buffer = NULL;
219
	sou->buffer_size = 0;
220
}
221
 
222
/**
223
 * Allocate the backing store for the buffer.
224
 */
225
static int vmw_sou_backing_alloc(struct vmw_private *dev_priv,
226
				 struct vmw_screen_object_unit *sou,
227
				 unsigned long size)
228
{
229
	int ret;
230
 
231
	if (sou->buffer_size == size)
232
		return 0;
233
 
234
	if (sou->buffer)
235
		vmw_sou_backing_free(dev_priv, sou);
236
 
237
	sou->buffer = kzalloc(sizeof(*sou->buffer), GFP_KERNEL);
238
	if (unlikely(sou->buffer == NULL))
239
		return -ENOMEM;
240
 
241
	/* After we have alloced the backing store might not be able to
242
	 * resume the overlays, this is preferred to failing to alloc.
243
	 */
244
//    vmw_overlay_pause_all(dev_priv);
245
	ret = vmw_dmabuf_init(dev_priv, sou->buffer, size,
246
			      &vmw_vram_ne_placement,
247
			      false, &vmw_dmabuf_bo_free);
248
//   vmw_overlay_resume_all(dev_priv);
249
 
250
	if (unlikely(ret != 0))
251
		sou->buffer = NULL; /* vmw_dmabuf_init frees on error */
252
	else
253
		sou->buffer_size = size;
254
 
255
	return ret;
256
}
257
 
258
static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
259
{
260
	struct vmw_private *dev_priv;
261
	struct vmw_screen_object_unit *sou;
262
	struct drm_connector *connector;
263
	struct drm_display_mode *mode;
264
	struct drm_encoder *encoder;
265
	struct vmw_framebuffer *vfb;
266
	struct drm_framebuffer *fb;
267
	struct drm_crtc *crtc;
268
	int ret = 0;
269
 
270
	if (!set)
271
		return -EINVAL;
272
 
273
	if (!set->crtc)
274
		return -EINVAL;
275
 
276
	/* get the sou */
277
	crtc = set->crtc;
278
	sou = vmw_crtc_to_sou(crtc);
279
	vfb = set->fb ? vmw_framebuffer_to_vfb(set->fb) : NULL;
280
	dev_priv = vmw_priv(crtc->dev);
281
 
282
	if (set->num_connectors > 1) {
283
		DRM_ERROR("to many connectors\n");
284
		return -EINVAL;
285
	}
286
 
287
	if (set->num_connectors == 1 &&
288
	    set->connectors[0] != &sou->base.connector) {
289
		DRM_ERROR("connector doesn't match %p %p\n",
290
			set->connectors[0], &sou->base.connector);
291
		return -EINVAL;
292
	}
293
 
294
	/* sou only supports one fb active at the time */
295
	if (sou->base.is_implicit &&
296
	    dev_priv->sou_priv->implicit_fb && vfb &&
297
	    !(dev_priv->sou_priv->num_implicit == 1 &&
298
	      sou->active_implicit) &&
299
	    dev_priv->sou_priv->implicit_fb != vfb) {
300
		DRM_ERROR("Multiple framebuffers not supported\n");
301
		return -EINVAL;
302
	}
303
 
304
	/* since they always map one to one these are safe */
305
	connector = &sou->base.connector;
306
	encoder = &sou->base.encoder;
307
 
308
	/* should we turn the crtc off */
309
	if (set->num_connectors == 0 || !set->mode || !set->fb) {
310
		ret = vmw_sou_fifo_destroy(dev_priv, sou);
311
		/* the hardware has hung don't do anything more */
312
		if (unlikely(ret != 0))
313
			return ret;
314
 
315
		connector->encoder = NULL;
316
		encoder->crtc = NULL;
317
		crtc->fb = NULL;
318
		crtc->x = 0;
319
		crtc->y = 0;
4569 Serge 320
		crtc->enabled = false;
4075 Serge 321
 
322
		vmw_sou_del_active(dev_priv, sou);
323
 
324
		vmw_sou_backing_free(dev_priv, sou);
325
 
326
		return 0;
327
	}
328
 
329
 
330
	/* we now know we want to set a mode */
331
	mode = set->mode;
332
	fb = set->fb;
333
 
334
	if (set->x + mode->hdisplay > fb->width ||
335
	    set->y + mode->vdisplay > fb->height) {
336
		DRM_ERROR("set outside of framebuffer\n");
337
		return -EINVAL;
338
	}
339
 
340
//   vmw_fb_off(dev_priv);
341
 
342
	if (mode->hdisplay != crtc->mode.hdisplay ||
343
	    mode->vdisplay != crtc->mode.vdisplay) {
344
		/* no need to check if depth is different, because backing
345
		 * store depth is forced to 4 by the device.
346
		 */
347
 
348
		ret = vmw_sou_fifo_destroy(dev_priv, sou);
349
		/* the hardware has hung don't do anything more */
350
		if (unlikely(ret != 0))
351
			return ret;
352
 
353
		vmw_sou_backing_free(dev_priv, sou);
354
	}
355
 
356
	if (!sou->buffer) {
357
		/* forced to depth 4 by the device */
358
		size_t size = mode->hdisplay * mode->vdisplay * 4;
359
		ret = vmw_sou_backing_alloc(dev_priv, sou, size);
360
		if (unlikely(ret != 0))
361
			return ret;
362
	}
363
 
364
	ret = vmw_sou_fifo_create(dev_priv, sou, set->x, set->y, mode);
365
	if (unlikely(ret != 0)) {
366
		/*
367
		 * We are in a bit of a situation here, the hardware has
368
		 * hung and we may or may not have a buffer hanging of
369
		 * the screen object, best thing to do is not do anything
370
		 * if we where defined, if not just turn the crtc of.
371
		 * Not what userspace wants but it needs to htfu.
372
		 */
373
		if (sou->defined)
374
			return ret;
375
 
376
		connector->encoder = NULL;
377
		encoder->crtc = NULL;
378
		crtc->fb = NULL;
379
		crtc->x = 0;
380
		crtc->y = 0;
4569 Serge 381
		crtc->enabled = false;
4075 Serge 382
 
383
		return ret;
384
	}
385
 
386
	vmw_sou_add_active(dev_priv, sou, vfb);
387
 
388
	connector->encoder = encoder;
389
	encoder->crtc = crtc;
390
	crtc->mode = *mode;
391
	crtc->fb = fb;
392
	crtc->x = set->x;
393
	crtc->y = set->y;
4569 Serge 394
	crtc->enabled = true;
4075 Serge 395
 
396
	return 0;
397
}
398
 
399
static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
400
	.save = vmw_du_crtc_save,
401
	.restore = vmw_du_crtc_restore,
402
//   .cursor_set = vmw_du_crtc_cursor_set,
403
//   .cursor_move = vmw_du_crtc_cursor_move,
404
	.gamma_set = vmw_du_crtc_gamma_set,
405
	.destroy = vmw_sou_crtc_destroy,
406
	.set_config = vmw_sou_crtc_set_config,
407
//   .page_flip = vmw_du_page_flip,
408
};
409
 
410
/*
411
 * Screen Object Display Unit encoder functions
412
 */
413
 
414
static void vmw_sou_encoder_destroy(struct drm_encoder *encoder)
415
{
416
	vmw_sou_destroy(vmw_encoder_to_sou(encoder));
417
}
418
 
419
static struct drm_encoder_funcs vmw_screen_object_encoder_funcs = {
420
	.destroy = vmw_sou_encoder_destroy,
421
};
422
 
423
/*
424
 * Screen Object Display Unit connector functions
425
 */
426
 
427
static void vmw_sou_connector_destroy(struct drm_connector *connector)
428
{
429
	vmw_sou_destroy(vmw_connector_to_sou(connector));
430
}
431
 
432
static struct drm_connector_funcs vmw_legacy_connector_funcs = {
433
	.dpms = vmw_du_connector_dpms,
434
	.save = vmw_du_connector_save,
435
	.restore = vmw_du_connector_restore,
436
	.detect = vmw_du_connector_detect,
437
	.fill_modes = vmw_du_connector_fill_modes,
438
	.set_property = vmw_du_connector_set_property,
439
	.destroy = vmw_sou_connector_destroy,
440
};
441
 
442
static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
443
{
444
	struct vmw_screen_object_unit *sou;
445
	struct drm_device *dev = dev_priv->dev;
446
	struct drm_connector *connector;
447
	struct drm_encoder *encoder;
448
	struct drm_crtc *crtc;
449
 
4080 Serge 450
    ENTER();
451
 
4075 Serge 452
	sou = kzalloc(sizeof(*sou), GFP_KERNEL);
453
	if (!sou)
454
		return -ENOMEM;
455
 
456
	sou->base.unit = unit;
457
	crtc = &sou->base.crtc;
458
	encoder = &sou->base.encoder;
459
	connector = &sou->base.connector;
460
 
461
	sou->active_implicit = false;
462
 
463
	sou->base.pref_active = (unit == 0);
464
	sou->base.pref_width = dev_priv->initial_width;
465
	sou->base.pref_height = dev_priv->initial_height;
466
	sou->base.pref_mode = NULL;
467
	sou->base.is_implicit = true;
468
 
469
	drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
470
			   DRM_MODE_CONNECTOR_VIRTUAL);
471
	connector->status = vmw_du_connector_detect(connector, true);
472
 
473
	drm_encoder_init(dev, encoder, &vmw_screen_object_encoder_funcs,
474
			 DRM_MODE_ENCODER_VIRTUAL);
475
	drm_mode_connector_attach_encoder(connector, encoder);
476
	encoder->possible_crtcs = (1 << unit);
477
	encoder->possible_clones = 0;
478
 
479
	drm_crtc_init(dev, crtc, &vmw_screen_object_crtc_funcs);
480
 
481
	drm_mode_crtc_set_gamma_size(crtc, 256);
482
 
483
	drm_object_attach_property(&connector->base,
484
				      dev->mode_config.dirty_info_property,
485
				      1);
4080 Serge 486
    LEAVE();
4075 Serge 487
	return 0;
488
}
489
 
490
int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv)
491
{
492
	struct drm_device *dev = dev_priv->dev;
493
	int i, ret;
494
 
495
    ENTER();
496
 
497
	if (dev_priv->sou_priv) {
498
		DRM_INFO("sou system already on\n");
499
		return -EINVAL;
500
	}
501
 
502
	if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) {
503
		DRM_INFO("Not using screen objects,"
504
			 " missing cap SCREEN_OBJECT_2\n");
505
		return -ENOSYS;
506
	}
507
 
508
	ret = -ENOMEM;
509
	dev_priv->sou_priv = kmalloc(sizeof(*dev_priv->sou_priv), GFP_KERNEL);
510
	if (unlikely(!dev_priv->sou_priv))
511
		goto err_no_mem;
512
 
513
	dev_priv->sou_priv->num_implicit = 0;
514
	dev_priv->sou_priv->implicit_fb = NULL;
515
 
516
 
517
	ret = drm_mode_create_dirty_info_property(dev);
518
	if (unlikely(ret != 0))
519
		goto err_vblank_cleanup;
520
 
521
	for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i)
522
		vmw_sou_init(dev_priv, i);
523
 
524
	DRM_INFO("Screen objects system initialized\n");
525
 
526
    LEAVE();
527
	return 0;
528
 
529
err_vblank_cleanup:
530
//   drm_vblank_cleanup(dev);
531
err_free:
532
	kfree(dev_priv->sou_priv);
533
	dev_priv->sou_priv = NULL;
534
err_no_mem:
535
	return ret;
536
}
537
 
538
int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
539
{
540
	struct drm_device *dev = dev_priv->dev;
541
 
542
	if (!dev_priv->sou_priv)
543
		return -ENOSYS;
544
 
545
//   drm_vblank_cleanup(dev);
546
 
547
	kfree(dev_priv->sou_priv);
548
 
549
	return 0;
550
}
551
 
552
/**
553
 * Returns if this unit can be page flipped.
554
 * Must be called with the mode_config mutex held.
555
 */
556
bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
557
				     struct drm_crtc *crtc)
558
{
559
	struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
560
 
561
	if (!sou->base.is_implicit)
562
		return true;
563
 
564
	if (dev_priv->sou_priv->num_implicit != 1)
565
		return false;
566
 
567
	return true;
568
}
569
 
570
/**
571
 * Update the implicit fb to the current fb of this crtc.
572
 * Must be called with the mode_config mutex held.
573
 */
574
void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
575
					      struct drm_crtc *crtc)
576
{
577
	struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
578
 
579
	BUG_ON(!sou->base.is_implicit);
580
 
581
	dev_priv->sou_priv->implicit_fb =
582
		vmw_framebuffer_to_vfb(sou->base.crtc.fb);
583
}
4080 Serge 584
 
585
#include "bitmap.h"
586
 
587
typedef struct
588
{
589
    kobj_t     header;
590
 
591
    uint32_t  *data;
592
    uint32_t   hot_x;
593
    uint32_t   hot_y;
594
 
595
    struct list_head   list;
596
//    struct drm_i915_gem_object  *cobj;
597
}cursor_t;
598
 
599
 
600
struct tag_display
601
{
602
    int  x;
603
    int  y;
604
    int  width;
605
    int  height;
606
    int  bpp;
607
    int  vrefresh;
608
    int  pitch;
609
    int  lfb;
610
 
611
    int  supported_modes;
612
    struct drm_device    *ddev;
613
    struct drm_connector *connector;
614
    struct drm_crtc      *crtc;
615
 
616
    struct list_head   cursors;
617
 
618
    cursor_t   *cursor;
619
    int       (*init_cursor)(cursor_t*);
620
    cursor_t* (__stdcall *select_cursor)(cursor_t*);
621
    void      (*show_cursor)(int show);
622
    void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
623
    void      (__stdcall *restore_cursor)(int x, int y);
624
    void      (*disable_mouse)(void);
625
    u32  mask_seqno;
626
    u32  check_mouse;
627
    u32  check_m_pixel;
628
    u32  dirty;
629
    void (*update)(void);
630
};
631
 
632
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
633
              videomode_t *reqmode, bool strict)
634
{
635
    struct drm_display_mode  *mode = NULL, *tmpmode;
4111 Serge 636
    struct vmw_private *dev_priv = vmw_priv(dev);
4080 Serge 637
    struct vmw_screen_object_unit *sou;
638
    display_t *os_display;
639
 
640
    bool ret = false;
641
 
642
    ENTER();
643
 
644
//    dbgprintf("width %d height %d vrefresh %d\n",
645
//               reqmode->width, reqmode->height, reqmode->freq);
646
 
647
    list_for_each_entry(tmpmode, &connector->modes, head)
648
    {
649
        if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
650
            (drm_mode_height(tmpmode)   == reqmode->height) &&
651
            (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
652
        {
653
            mode = tmpmode;
654
            goto do_set;
655
        }
656
    };
657
 
658
    if( (mode == NULL) && (strict == false) )
659
    {
660
        list_for_each_entry(tmpmode, &connector->modes, head)
661
        {
662
            if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
663
                (drm_mode_height(tmpmode) == reqmode->height) )
664
            {
665
                mode = tmpmode;
666
                goto do_set;
667
            }
668
        };
669
    };
670
 
671
do_set:
672
 
673
    if( mode != NULL )
674
    {
675
        struct drm_framebuffer   *fb;
676
        struct drm_encoder       *encoder;
677
        struct drm_crtc          *crtc;
678
 
679
//        char  con_edid[128];
680
        const char *con_name;
681
        const char *enc_name;
682
 
683
        encoder = connector->encoder;
684
        crtc = encoder->crtc;
685
 
686
 
687
//        fb = list_first_entry(&dev->mode_config.fb_kernel_list,
688
//                              struct drm_framebuffer, filp_head);
689
 
690
//        memcpy(con_edid, connector->edid_blob_ptr->data, 128);
691
 
692
//        dbgprintf("Manufacturer: %s Model %x Serial Number %u\n",
693
//        manufacturer_name(con_edid + 0x08),
694
//        (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
695
//        (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
696
//            + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
697
 
698
        con_name = drm_get_connector_name(connector);
699
        enc_name = drm_get_encoder_name(encoder);
700
 
701
        dbgprintf("set mode %d %d connector %s encoder %s\n",
702
                   mode->hdisplay, mode->vdisplay, con_name, enc_name);
703
 
704
        os_display = GetDisplay();
705
 
706
#if 0
707
        sou = vmw_crtc_to_sou(crtc);
708
        sou->defined = true;
709
 
710
        ret = vmw_sou_fifo_destroy(dev_priv, sou);
711
        if (unlikely(ret != 0))
712
            return ret;
713
 
714
        ret = vmw_sou_fifo_create(dev_priv, sou, 0, 0, mode);
715
 
716
#else   /*   sledgehammer  */
717
 
718
        vmw_write(dev_priv,SVGA_REG_WIDTH,  mode->hdisplay);
719
        vmw_write(dev_priv,SVGA_REG_HEIGHT, mode->vdisplay);
720
        vmw_write(dev_priv,SVGA_REG_BITS_PER_PIXEL, 32);
721
        ret = 0;
722
#endif
723
        if (ret == 0)
724
        {
725
            os_display->width    = mode->hdisplay;
726
            os_display->height   = mode->vdisplay;
727
            os_display->pitch    = mode->hdisplay*4;
728
            os_display->vrefresh = drm_mode_vrefresh(mode);
729
 
730
            sysSetScreen(os_display->width, os_display->height, os_display->pitch);
731
 
732
            dbgprintf("new mode %d x %d pitch %d\n",
733
                       os_display->width, os_display->height, os_display->pitch);
734
        }
735
        else
736
            DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
737
                       os_display->width, os_display->height, crtc);
738
    }
739
 
740
    LEAVE();
741
    return ret;
742
};