xref: /openbmc/linux/drivers/gpu/drm/vboxvideo/modesetting.c (revision 131abc56e1bacef23cb7b340519d36e2f5adb2a9)
1*131abc56SHans de Goede // SPDX-License-Identifier: MIT
2*131abc56SHans de Goede /* Copyright (C) 2006-2017 Oracle Corporation */
3*131abc56SHans de Goede 
4*131abc56SHans de Goede #include <linux/vbox_err.h>
5*131abc56SHans de Goede #include "vbox_drv.h"
6*131abc56SHans de Goede #include "vboxvideo_guest.h"
7*131abc56SHans de Goede #include "vboxvideo_vbe.h"
8*131abc56SHans de Goede #include "hgsmi_channels.h"
9*131abc56SHans de Goede 
10*131abc56SHans de Goede /**
11*131abc56SHans de Goede  * Set a video mode via an HGSMI request.  The views must have been
12*131abc56SHans de Goede  * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
13*131abc56SHans de Goede  * set on the first display then it must be set first using registers.
14*131abc56SHans de Goede  * @ctx:           The context containing the heap to use.
15*131abc56SHans de Goede  * @display:       The screen number.
16*131abc56SHans de Goede  * @origin_x:      The horizontal displacement relative to the first scrn.
17*131abc56SHans de Goede  * @origin_y:      The vertical displacement relative to the first screen.
18*131abc56SHans de Goede  * @start_offset:  The offset of the visible area of the framebuffer
19*131abc56SHans de Goede  *                 relative to the framebuffer start.
20*131abc56SHans de Goede  * @pitch:         The offset in bytes between the starts of two adjecent
21*131abc56SHans de Goede  *                 scan lines in video RAM.
22*131abc56SHans de Goede  * @width:         The mode width.
23*131abc56SHans de Goede  * @height:        The mode height.
24*131abc56SHans de Goede  * @bpp:           The colour depth of the mode.
25*131abc56SHans de Goede  * @flags:         Flags.
26*131abc56SHans de Goede  */
27*131abc56SHans de Goede void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
28*131abc56SHans de Goede 				s32 origin_x, s32 origin_y, u32 start_offset,
29*131abc56SHans de Goede 				u32 pitch, u32 width, u32 height,
30*131abc56SHans de Goede 				u16 bpp, u16 flags)
31*131abc56SHans de Goede {
32*131abc56SHans de Goede 	struct vbva_infoscreen *p;
33*131abc56SHans de Goede 
34*131abc56SHans de Goede 	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
35*131abc56SHans de Goede 			       VBVA_INFO_SCREEN);
36*131abc56SHans de Goede 	if (!p)
37*131abc56SHans de Goede 		return;
38*131abc56SHans de Goede 
39*131abc56SHans de Goede 	p->view_index = display;
40*131abc56SHans de Goede 	p->origin_x = origin_x;
41*131abc56SHans de Goede 	p->origin_y = origin_y;
42*131abc56SHans de Goede 	p->start_offset = start_offset;
43*131abc56SHans de Goede 	p->line_size = pitch;
44*131abc56SHans de Goede 	p->width = width;
45*131abc56SHans de Goede 	p->height = height;
46*131abc56SHans de Goede 	p->bits_per_pixel = bpp;
47*131abc56SHans de Goede 	p->flags = flags;
48*131abc56SHans de Goede 
49*131abc56SHans de Goede 	hgsmi_buffer_submit(ctx, p);
50*131abc56SHans de Goede 	hgsmi_buffer_free(ctx, p);
51*131abc56SHans de Goede }
52*131abc56SHans de Goede 
53*131abc56SHans de Goede /**
54*131abc56SHans de Goede  * Report the rectangle relative to which absolute pointer events should be
55*131abc56SHans de Goede  * expressed.  This information remains valid until the next VBVA resize event
56*131abc56SHans de Goede  * for any screen, at which time it is reset to the bounding rectangle of all
57*131abc56SHans de Goede  * virtual screens.
58*131abc56SHans de Goede  * Return: 0 or negative errno value.
59*131abc56SHans de Goede  * @ctx:       The context containing the heap to use.
60*131abc56SHans de Goede  * @origin_x:  Upper left X co-ordinate relative to the first screen.
61*131abc56SHans de Goede  * @origin_y:  Upper left Y co-ordinate relative to the first screen.
62*131abc56SHans de Goede  * @width:     Rectangle width.
63*131abc56SHans de Goede  * @height:    Rectangle height.
64*131abc56SHans de Goede  */
65*131abc56SHans de Goede int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
66*131abc56SHans de Goede 			       u32 width, u32 height)
67*131abc56SHans de Goede {
68*131abc56SHans de Goede 	struct vbva_report_input_mapping *p;
69*131abc56SHans de Goede 
70*131abc56SHans de Goede 	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
71*131abc56SHans de Goede 			       VBVA_REPORT_INPUT_MAPPING);
72*131abc56SHans de Goede 	if (!p)
73*131abc56SHans de Goede 		return -ENOMEM;
74*131abc56SHans de Goede 
75*131abc56SHans de Goede 	p->x = origin_x;
76*131abc56SHans de Goede 	p->y = origin_y;
77*131abc56SHans de Goede 	p->cx = width;
78*131abc56SHans de Goede 	p->cy = height;
79*131abc56SHans de Goede 
80*131abc56SHans de Goede 	hgsmi_buffer_submit(ctx, p);
81*131abc56SHans de Goede 	hgsmi_buffer_free(ctx, p);
82*131abc56SHans de Goede 
83*131abc56SHans de Goede 	return 0;
84*131abc56SHans de Goede }
85*131abc56SHans de Goede 
86*131abc56SHans de Goede /**
87*131abc56SHans de Goede  * Get most recent video mode hints.
88*131abc56SHans de Goede  * Return: 0 or negative errno value.
89*131abc56SHans de Goede  * @ctx:      The context containing the heap to use.
90*131abc56SHans de Goede  * @screens:  The number of screens to query hints for, starting at 0.
91*131abc56SHans de Goede  * @hints:    Array of vbva_modehint structures for receiving the hints.
92*131abc56SHans de Goede  */
93*131abc56SHans de Goede int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
94*131abc56SHans de Goede 			 struct vbva_modehint *hints)
95*131abc56SHans de Goede {
96*131abc56SHans de Goede 	struct vbva_query_mode_hints *p;
97*131abc56SHans de Goede 	size_t size;
98*131abc56SHans de Goede 
99*131abc56SHans de Goede 	if (WARN_ON(!hints))
100*131abc56SHans de Goede 		return -EINVAL;
101*131abc56SHans de Goede 
102*131abc56SHans de Goede 	size = screens * sizeof(struct vbva_modehint);
103*131abc56SHans de Goede 	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA,
104*131abc56SHans de Goede 			       VBVA_QUERY_MODE_HINTS);
105*131abc56SHans de Goede 	if (!p)
106*131abc56SHans de Goede 		return -ENOMEM;
107*131abc56SHans de Goede 
108*131abc56SHans de Goede 	p->hints_queried_count = screens;
109*131abc56SHans de Goede 	p->hint_structure_guest_size = sizeof(struct vbva_modehint);
110*131abc56SHans de Goede 	p->rc = VERR_NOT_SUPPORTED;
111*131abc56SHans de Goede 
112*131abc56SHans de Goede 	hgsmi_buffer_submit(ctx, p);
113*131abc56SHans de Goede 
114*131abc56SHans de Goede 	if (p->rc < 0) {
115*131abc56SHans de Goede 		hgsmi_buffer_free(ctx, p);
116*131abc56SHans de Goede 		return -EIO;
117*131abc56SHans de Goede 	}
118*131abc56SHans de Goede 
119*131abc56SHans de Goede 	memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size);
120*131abc56SHans de Goede 	hgsmi_buffer_free(ctx, p);
121*131abc56SHans de Goede 
122*131abc56SHans de Goede 	return 0;
123*131abc56SHans de Goede }
124