1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include <linux/export.h>
35#include <drm/drm_crtc_helper.h>
36#include <drm/drm_plane_helper.h>
37
38#include "vbox_drv.h"
39#include "vboxvideo.h"
40#include "hgsmi_channels.h"
41
42static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
43 u32 handle, u32 width, u32 height,
44 s32 hot_x, s32 hot_y);
45static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y);
46
47
48
49
50
51static void vbox_do_modeset(struct drm_crtc *crtc,
52 const struct drm_display_mode *mode)
53{
54 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
55 struct vbox_private *vbox;
56 int width, height, bpp, pitch;
57 u16 flags;
58 s32 x_offset, y_offset;
59
60 vbox = crtc->dev->dev_private;
61 width = mode->hdisplay ? mode->hdisplay : 640;
62 height = mode->vdisplay ? mode->vdisplay : 480;
63 bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
64 pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
65 x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
66 y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint;
67
68
69
70
71
72
73
74 if (vbox_crtc->crtc_id == 0 && crtc->enabled &&
75 vbox_crtc->fb_offset / pitch < 0xffff - crtc->y &&
76 vbox_crtc->fb_offset % (bpp / 8) == 0) {
77 vbox_write_ioport(VBE_DISPI_INDEX_XRES, width);
78 vbox_write_ioport(VBE_DISPI_INDEX_YRES, height);
79 vbox_write_ioport(VBE_DISPI_INDEX_VIRT_WIDTH, pitch * 8 / bpp);
80 vbox_write_ioport(VBE_DISPI_INDEX_BPP,
81 CRTC_FB(crtc)->format->cpp[0] * 8);
82 vbox_write_ioport(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
83 vbox_write_ioport(
84 VBE_DISPI_INDEX_X_OFFSET,
85 vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x);
86 vbox_write_ioport(VBE_DISPI_INDEX_Y_OFFSET,
87 vbox_crtc->fb_offset / pitch + crtc->y);
88 }
89
90 flags = VBVA_SCREEN_F_ACTIVE;
91 flags |= (crtc->enabled && !vbox_crtc->blanked) ?
92 0 : VBVA_SCREEN_F_BLANK;
93 flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
94 hgsmi_process_display_info(vbox->guest_pool, vbox_crtc->crtc_id,
95 x_offset, y_offset,
96 crtc->x * bpp / 8 + crtc->y * pitch,
97 pitch, width, height,
98 vbox_crtc->blanked ? 0 : bpp, flags);
99}
100
101static int vbox_set_view(struct drm_crtc *crtc)
102{
103 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
104 struct vbox_private *vbox = crtc->dev->dev_private;
105 struct vbva_infoview *p;
106
107
108
109
110
111
112
113
114
115
116
117
118 p = hgsmi_buffer_alloc(vbox->guest_pool, sizeof(*p),
119 HGSMI_CH_VBVA, VBVA_INFO_VIEW);
120 if (!p)
121 return -ENOMEM;
122
123 p->view_index = vbox_crtc->crtc_id;
124 p->view_offset = vbox_crtc->fb_offset;
125 p->view_size = vbox->available_vram_size - vbox_crtc->fb_offset +
126 vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
127 p->max_screen_size = vbox->available_vram_size - vbox_crtc->fb_offset;
128
129 hgsmi_buffer_submit(vbox->guest_pool, p);
130 hgsmi_buffer_free(vbox->guest_pool, p);
131
132 return 0;
133}
134
135static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
136{
137 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
138 struct vbox_private *vbox = crtc->dev->dev_private;
139
140 switch (mode) {
141 case DRM_MODE_DPMS_ON:
142 vbox_crtc->blanked = false;
143 break;
144 case DRM_MODE_DPMS_STANDBY:
145 case DRM_MODE_DPMS_SUSPEND:
146 case DRM_MODE_DPMS_OFF:
147 vbox_crtc->blanked = true;
148 break;
149 }
150
151 mutex_lock(&vbox->hw_mutex);
152 vbox_do_modeset(crtc, &crtc->hwmode);
153 mutex_unlock(&vbox->hw_mutex);
154}
155
156static bool vbox_crtc_mode_fixup(struct drm_crtc *crtc,
157 const struct drm_display_mode *mode,
158 struct drm_display_mode *adjusted_mode)
159{
160 return true;
161}
162
163
164
165
166
167
168static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
169{
170 struct drm_crtc *crtci;
171 struct drm_connector *connectori;
172 struct drm_framebuffer *fb1 = NULL;
173 bool single_framebuffer = true;
174 bool old_single_framebuffer = vbox->single_framebuffer;
175 u16 width = 0, height = 0;
176
177
178
179
180
181
182 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
183 if (!fb1) {
184 fb1 = CRTC_FB(crtci);
185 if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb)
186 break;
187 } else if (CRTC_FB(crtci) && fb1 != CRTC_FB(crtci)) {
188 single_framebuffer = false;
189 }
190 }
191 if (single_framebuffer) {
192 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
193 head) {
194 if (to_vbox_crtc(crtci)->crtc_id != 0)
195 continue;
196
197 vbox->single_framebuffer = true;
198 vbox->input_mapping_width = CRTC_FB(crtci)->width;
199 vbox->input_mapping_height = CRTC_FB(crtci)->height;
200 return old_single_framebuffer !=
201 vbox->single_framebuffer;
202 }
203 }
204
205 list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list,
206 head) {
207 struct vbox_connector *vbox_connector =
208 to_vbox_connector(connectori);
209 struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc;
210
211 width = max_t(u16, width, vbox_crtc->x_hint +
212 vbox_connector->mode_hint.width);
213 height = max_t(u16, height, vbox_crtc->y_hint +
214 vbox_connector->mode_hint.height);
215 }
216
217 vbox->single_framebuffer = false;
218 vbox->input_mapping_width = width;
219 vbox->input_mapping_height = height;
220
221 return old_single_framebuffer != vbox->single_framebuffer;
222}
223
224static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
225 struct drm_framebuffer *old_fb, int x, int y)
226{
227 struct vbox_private *vbox = crtc->dev->dev_private;
228 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
229 struct drm_gem_object *obj;
230 struct vbox_framebuffer *vbox_fb;
231 struct vbox_bo *bo;
232 int ret;
233 u64 gpu_addr;
234
235
236 if (old_fb) {
237 vbox_fb = to_vbox_framebuffer(old_fb);
238 obj = vbox_fb->obj;
239 bo = gem_to_vbox_bo(obj);
240 ret = vbox_bo_reserve(bo, false);
241 if (ret)
242 return ret;
243
244 vbox_bo_unpin(bo);
245 vbox_bo_unreserve(bo);
246 }
247
248 vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc));
249 obj = vbox_fb->obj;
250 bo = gem_to_vbox_bo(obj);
251
252 ret = vbox_bo_reserve(bo, false);
253 if (ret)
254 return ret;
255
256 ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
257 if (ret) {
258 vbox_bo_unreserve(bo);
259 return ret;
260 }
261
262 if (&vbox->fbdev->afb == vbox_fb)
263 vbox_fbdev_set_base(vbox, gpu_addr);
264 vbox_bo_unreserve(bo);
265
266
267 vbox_crtc->fb_offset = gpu_addr;
268 if (vbox_set_up_input_mapping(vbox)) {
269 struct drm_crtc *crtci;
270
271 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
272 head) {
273 vbox_set_view(crtc);
274 vbox_do_modeset(crtci, &crtci->mode);
275 }
276 }
277
278 return 0;
279}
280
281static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
282 struct drm_framebuffer *old_fb)
283{
284 return vbox_crtc_do_set_base(crtc, old_fb, x, y);
285}
286
287static int vbox_crtc_mode_set(struct drm_crtc *crtc,
288 struct drm_display_mode *mode,
289 struct drm_display_mode *adjusted_mode,
290 int x, int y, struct drm_framebuffer *old_fb)
291{
292 struct vbox_private *vbox = crtc->dev->dev_private;
293 int ret;
294
295 vbox_crtc_mode_set_base(crtc, x, y, old_fb);
296
297 mutex_lock(&vbox->hw_mutex);
298 ret = vbox_set_view(crtc);
299 if (!ret)
300 vbox_do_modeset(crtc, mode);
301 hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
302 vbox->input_mapping_width,
303 vbox->input_mapping_height);
304 mutex_unlock(&vbox->hw_mutex);
305
306 return ret;
307}
308
309static void vbox_crtc_disable(struct drm_crtc *crtc)
310{
311}
312
313static void vbox_crtc_prepare(struct drm_crtc *crtc)
314{
315}
316
317static void vbox_crtc_commit(struct drm_crtc *crtc)
318{
319}
320
321static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
322 .dpms = vbox_crtc_dpms,
323 .mode_fixup = vbox_crtc_mode_fixup,
324 .mode_set = vbox_crtc_mode_set,
325
326 .disable = vbox_crtc_disable,
327 .prepare = vbox_crtc_prepare,
328 .commit = vbox_crtc_commit,
329};
330
331static void vbox_crtc_reset(struct drm_crtc *crtc)
332{
333}
334
335static void vbox_crtc_destroy(struct drm_crtc *crtc)
336{
337 drm_crtc_cleanup(crtc);
338 kfree(crtc);
339}
340
341static const struct drm_crtc_funcs vbox_crtc_funcs = {
342 .cursor_move = vbox_cursor_move,
343 .cursor_set2 = vbox_cursor_set2,
344 .reset = vbox_crtc_reset,
345 .set_config = drm_crtc_helper_set_config,
346
347 .destroy = vbox_crtc_destroy,
348};
349
350static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i)
351{
352 struct vbox_crtc *vbox_crtc;
353
354 vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL);
355 if (!vbox_crtc)
356 return NULL;
357
358 vbox_crtc->crtc_id = i;
359
360 drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
361 drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
362 drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
363
364 return vbox_crtc;
365}
366
367static void vbox_encoder_destroy(struct drm_encoder *encoder)
368{
369 drm_encoder_cleanup(encoder);
370 kfree(encoder);
371}
372
373static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
374 *connector)
375{
376 int enc_id = connector->encoder_ids[0];
377
378
379 if (enc_id)
380 return drm_encoder_find(connector->dev, NULL, enc_id);
381
382 return NULL;
383}
384
385static const struct drm_encoder_funcs vbox_enc_funcs = {
386 .destroy = vbox_encoder_destroy,
387};
388
389static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
390{
391}
392
393static bool vbox_mode_fixup(struct drm_encoder *encoder,
394 const struct drm_display_mode *mode,
395 struct drm_display_mode *adjusted_mode)
396{
397 return true;
398}
399
400static void vbox_encoder_mode_set(struct drm_encoder *encoder,
401 struct drm_display_mode *mode,
402 struct drm_display_mode *adjusted_mode)
403{
404}
405
406static void vbox_encoder_prepare(struct drm_encoder *encoder)
407{
408}
409
410static void vbox_encoder_commit(struct drm_encoder *encoder)
411{
412}
413
414static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
415 .dpms = vbox_encoder_dpms,
416 .mode_fixup = vbox_mode_fixup,
417 .prepare = vbox_encoder_prepare,
418 .commit = vbox_encoder_commit,
419 .mode_set = vbox_encoder_mode_set,
420};
421
422static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
423 unsigned int i)
424{
425 struct vbox_encoder *vbox_encoder;
426
427 vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL);
428 if (!vbox_encoder)
429 return NULL;
430
431 drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
432 DRM_MODE_ENCODER_DAC, NULL);
433 drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
434
435 vbox_encoder->base.possible_crtcs = 1 << i;
436 return &vbox_encoder->base;
437}
438
439
440
441
442
443
444
445static void vbox_set_edid(struct drm_connector *connector, int width,
446 int height)
447{
448 enum { EDID_SIZE = 128 };
449 unsigned char edid[EDID_SIZE] = {
450 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
451 0x58, 0x58,
452 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00,
454 0x01,
455 0x00,
456 0x01, 0x03,
457 0x80,
458 0x00,
459 0x00,
460 0x78,
461 0xEE,
462
463 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
464
465 0x00, 0x00, 0x00,
466 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
467 0x01, 0x01,
468 0x01, 0x01, 0x01, 0x01,
469 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02,
470 0x02, 0x02,
471
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473
474 0x00, 0x00, 0x00, 0xFD, 0x00,
475 0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20,
476 0x20, 0x20,
477
478 0x20,
479
480 0x00, 0x00, 0x00, 0xFC, 0x00,
481 'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r',
482 '\n',
483
484 0x00, 0x00, 0x00, 0x10, 0x00,
485 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
486 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
487 0x20,
488 0x00,
489 0x00
490 };
491 int clock = (width + 6) * (height + 6) * 60 / 10000;
492 unsigned int i, sum = 0;
493
494 edid[12] = width & 0xff;
495 edid[13] = width >> 8;
496 edid[14] = height & 0xff;
497 edid[15] = height >> 8;
498 edid[54] = clock & 0xff;
499 edid[55] = clock >> 8;
500 edid[56] = width & 0xff;
501 edid[58] = (width >> 4) & 0xf0;
502 edid[59] = height & 0xff;
503 edid[61] = (height >> 4) & 0xf0;
504 for (i = 0; i < EDID_SIZE - 1; ++i)
505 sum += edid[i];
506 edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
507 drm_mode_connector_update_edid_property(connector, (struct edid *)edid);
508}
509
510static int vbox_get_modes(struct drm_connector *connector)
511{
512 struct vbox_connector *vbox_connector = NULL;
513 struct drm_display_mode *mode = NULL;
514 struct vbox_private *vbox = NULL;
515 unsigned int num_modes = 0;
516 int preferred_width, preferred_height;
517
518 vbox_connector = to_vbox_connector(connector);
519 vbox = connector->dev->dev_private;
520
521
522
523
524
525
526
527
528
529
530
531
532 hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
533 HOST_FLAGS_OFFSET);
534 if (vbox_connector->vbox_crtc->crtc_id == 0)
535 vbox_report_caps(vbox);
536 if (!vbox->initial_mode_queried) {
537 if (vbox_connector->vbox_crtc->crtc_id == 0) {
538 vbox->initial_mode_queried = true;
539 vbox_report_hotplug(vbox);
540 }
541 return drm_add_modes_noedid(connector, 800, 600);
542 }
543 num_modes = drm_add_modes_noedid(connector, 2560, 1600);
544 preferred_width = vbox_connector->mode_hint.width ?
545 vbox_connector->mode_hint.width : 1024;
546 preferred_height = vbox_connector->mode_hint.height ?
547 vbox_connector->mode_hint.height : 768;
548 mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height,
549 60, false, false, false);
550 if (mode) {
551 mode->type |= DRM_MODE_TYPE_PREFERRED;
552 drm_mode_probed_add(connector, mode);
553 ++num_modes;
554 }
555 vbox_set_edid(connector, preferred_width, preferred_height);
556
557 if (vbox_connector->vbox_crtc->x_hint != -1)
558 drm_object_property_set_value(&connector->base,
559 vbox->dev->mode_config.suggested_x_property,
560 vbox_connector->vbox_crtc->x_hint);
561 else
562 drm_object_property_set_value(&connector->base,
563 vbox->dev->mode_config.suggested_x_property, 0);
564
565 if (vbox_connector->vbox_crtc->y_hint != -1)
566 drm_object_property_set_value(&connector->base,
567 vbox->dev->mode_config.suggested_y_property,
568 vbox_connector->vbox_crtc->y_hint);
569 else
570 drm_object_property_set_value(&connector->base,
571 vbox->dev->mode_config.suggested_y_property, 0);
572
573 return num_modes;
574}
575
576static int vbox_mode_valid(struct drm_connector *connector,
577 struct drm_display_mode *mode)
578{
579 return MODE_OK;
580}
581
582static void vbox_connector_destroy(struct drm_connector *connector)
583{
584 drm_connector_unregister(connector);
585 drm_connector_cleanup(connector);
586 kfree(connector);
587}
588
589static enum drm_connector_status
590vbox_connector_detect(struct drm_connector *connector, bool force)
591{
592 struct vbox_connector *vbox_connector;
593
594 vbox_connector = to_vbox_connector(connector);
595
596 return vbox_connector->mode_hint.disconnected ?
597 connector_status_disconnected : connector_status_connected;
598}
599
600static int vbox_fill_modes(struct drm_connector *connector, u32 max_x,
601 u32 max_y)
602{
603 struct vbox_connector *vbox_connector;
604 struct drm_device *dev;
605 struct drm_display_mode *mode, *iterator;
606
607 vbox_connector = to_vbox_connector(connector);
608 dev = vbox_connector->base.dev;
609 list_for_each_entry_safe(mode, iterator, &connector->modes, head) {
610 list_del(&mode->head);
611 drm_mode_destroy(dev, mode);
612 }
613
614 return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
615}
616
617static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
618 .mode_valid = vbox_mode_valid,
619 .get_modes = vbox_get_modes,
620 .best_encoder = vbox_best_single_encoder,
621};
622
623static const struct drm_connector_funcs vbox_connector_funcs = {
624 .dpms = drm_helper_connector_dpms,
625 .detect = vbox_connector_detect,
626 .fill_modes = vbox_fill_modes,
627 .destroy = vbox_connector_destroy,
628};
629
630static int vbox_connector_init(struct drm_device *dev,
631 struct vbox_crtc *vbox_crtc,
632 struct drm_encoder *encoder)
633{
634 struct vbox_connector *vbox_connector;
635 struct drm_connector *connector;
636
637 vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL);
638 if (!vbox_connector)
639 return -ENOMEM;
640
641 connector = &vbox_connector->base;
642 vbox_connector->vbox_crtc = vbox_crtc;
643
644 drm_connector_init(dev, connector, &vbox_connector_funcs,
645 DRM_MODE_CONNECTOR_VGA);
646 drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
647
648 connector->interlace_allowed = 0;
649 connector->doublescan_allowed = 0;
650
651 drm_mode_create_suggested_offset_properties(dev);
652 drm_object_attach_property(&connector->base,
653 dev->mode_config.suggested_x_property, 0);
654 drm_object_attach_property(&connector->base,
655 dev->mode_config.suggested_y_property, 0);
656 drm_connector_register(connector);
657
658 drm_mode_connector_attach_encoder(connector, encoder);
659
660 return 0;
661}
662
663int vbox_mode_init(struct drm_device *dev)
664{
665 struct vbox_private *vbox = dev->dev_private;
666 struct drm_encoder *encoder;
667 struct vbox_crtc *vbox_crtc;
668 unsigned int i;
669 int ret;
670
671
672 for (i = 0; i < vbox->num_crtcs; ++i) {
673 vbox_crtc = vbox_crtc_init(dev, i);
674 if (!vbox_crtc)
675 return -ENOMEM;
676 encoder = vbox_encoder_init(dev, i);
677 if (!encoder)
678 return -ENOMEM;
679 ret = vbox_connector_init(dev, vbox_crtc, encoder);
680 if (ret)
681 return ret;
682 }
683
684 return 0;
685}
686
687void vbox_mode_fini(struct drm_device *dev)
688{
689
690}
691
692
693
694
695
696
697static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
698 size_t mask_size)
699{
700 size_t line_size = (width + 7) / 8;
701 u32 i, j;
702
703 memcpy(dst + mask_size, src, width * height * 4);
704 for (i = 0; i < height; ++i)
705 for (j = 0; j < width; ++j)
706 if (((u32 *)src)[i * width + j] > 0xf0000000)
707 dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
708}
709
710static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
711 u32 handle, u32 width, u32 height,
712 s32 hot_x, s32 hot_y)
713{
714 struct vbox_private *vbox = crtc->dev->dev_private;
715 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
716 struct ttm_bo_kmap_obj uobj_map;
717 size_t data_size, mask_size;
718 struct drm_gem_object *obj;
719 u32 flags, caps = 0;
720 struct vbox_bo *bo;
721 bool src_isiomem;
722 u8 *dst = NULL;
723 u8 *src;
724 int ret;
725
726
727
728
729
730 hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
731 vbox->input_mapping_width,
732 vbox->input_mapping_height);
733 if (!handle) {
734 bool cursor_enabled = false;
735 struct drm_crtc *crtci;
736
737
738 vbox_crtc->cursor_enabled = false;
739 list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
740 head) {
741 if (to_vbox_crtc(crtci)->cursor_enabled)
742 cursor_enabled = true;
743 }
744
745 if (!cursor_enabled)
746 hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0,
747 0, 0, NULL, 0);
748 return 0;
749 }
750
751 vbox_crtc->cursor_enabled = true;
752
753 if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
754 width == 0 || height == 0)
755 return -EINVAL;
756
757 ret = hgsmi_query_conf(vbox->guest_pool,
758 VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
759 if (ret)
760 return ret;
761
762 if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
763
764
765
766
767 return -EBUSY;
768 }
769
770 obj = drm_gem_object_lookup(file_priv, handle);
771 if (!obj) {
772 DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
773 return -ENOENT;
774 }
775
776 bo = gem_to_vbox_bo(obj);
777 ret = vbox_bo_reserve(bo, false);
778 if (ret)
779 goto out_unref_obj;
780
781
782
783
784
785
786 mask_size = ((width + 7) / 8 * height + 3) & ~3;
787 data_size = width * height * 4 + mask_size;
788 vbox->cursor_hot_x = min_t(u32, max(hot_x, 0), width);
789 vbox->cursor_hot_y = min_t(u32, max(hot_y, 0), height);
790 vbox->cursor_width = width;
791 vbox->cursor_height = height;
792 vbox->cursor_data_size = data_size;
793 dst = vbox->cursor_data;
794
795 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
796 if (ret) {
797 vbox->cursor_data_size = 0;
798 goto out_unreserve_bo;
799 }
800
801 src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
802 if (src_isiomem) {
803 DRM_ERROR("src cursor bo not in main memory\n");
804 ret = -EIO;
805 goto out_unmap_bo;
806 }
807
808 copy_cursor_image(src, dst, width, height, mask_size);
809
810 flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
811 VBOX_MOUSE_POINTER_ALPHA;
812 ret = hgsmi_update_pointer_shape(vbox->guest_pool, flags,
813 vbox->cursor_hot_x, vbox->cursor_hot_y,
814 width, height, dst, data_size);
815out_unmap_bo:
816 ttm_bo_kunmap(&uobj_map);
817out_unreserve_bo:
818 vbox_bo_unreserve(bo);
819out_unref_obj:
820 drm_gem_object_put_unlocked(obj);
821
822 return ret;
823}
824
825static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y)
826{
827 struct vbox_private *vbox = crtc->dev->dev_private;
828 u32 flags = VBOX_MOUSE_POINTER_VISIBLE |
829 VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
830 s32 crtc_x =
831 vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
832 s32 crtc_y =
833 vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
834 u32 host_x, host_y;
835 u32 hot_x = 0;
836 u32 hot_y = 0;
837 int ret;
838
839
840
841
842
843 if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
844 return 0;
845
846 ret = hgsmi_cursor_position(vbox->guest_pool, true, x + crtc_x,
847 y + crtc_y, &host_x, &host_y);
848
849
850
851
852
853
854
855
856
857
858
859
860 if (ret || (host_x == 0 && host_y == 0))
861 return ret;
862
863 if (x + crtc_x < host_x)
864 hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
865 if (y + crtc_y < host_y)
866 hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
867
868 if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
869 return 0;
870
871 vbox->cursor_hot_x = hot_x;
872 vbox->cursor_hot_y = hot_y;
873
874 return hgsmi_update_pointer_shape(vbox->guest_pool, flags,
875 hot_x, hot_y, vbox->cursor_width, vbox->cursor_height,
876 vbox->cursor_data, vbox->cursor_data_size);
877}
878