xref: /openbmc/linux/drivers/gpu/drm/vboxvideo/modesetting.c (revision 762f99f4f3cb41a775b5157dd761217beba65873)
1131abc56SHans de Goede // SPDX-License-Identifier: MIT
2131abc56SHans de Goede /* Copyright (C) 2006-2017 Oracle Corporation */
3131abc56SHans de Goede 
4131abc56SHans de Goede #include <linux/vbox_err.h>
5131abc56SHans de Goede #include "vbox_drv.h"
6131abc56SHans de Goede #include "vboxvideo_guest.h"
7131abc56SHans de Goede #include "vboxvideo_vbe.h"
8131abc56SHans de Goede #include "hgsmi_channels.h"
9131abc56SHans de Goede 
10131abc56SHans de Goede /**
11*8fd54b2cSLee Jones  * hgsmi_process_display_info - Set a video mode via an HGSMI request.
12*8fd54b2cSLee Jones  *                              The views must have been initialised first
13*8fd54b2cSLee Jones  *                              using @a VBoxHGSMISendViewInfo and if the mode
14*8fd54b2cSLee Jones  *                              is being set on the first display then it must
15*8fd54b2cSLee Jones  *                              be set first using registers.
16131abc56SHans de Goede  * @ctx:           The context containing the heap to use.
17131abc56SHans de Goede  * @display:       The screen number.
18131abc56SHans de Goede  * @origin_x:      The horizontal displacement relative to the first scrn.
19131abc56SHans de Goede  * @origin_y:      The vertical displacement relative to the first screen.
20131abc56SHans de Goede  * @start_offset:  The offset of the visible area of the framebuffer
21131abc56SHans de Goede  *                 relative to the framebuffer start.
22131abc56SHans de Goede  * @pitch:         The offset in bytes between the starts of two adjecent
23131abc56SHans de Goede  *                 scan lines in video RAM.
24131abc56SHans de Goede  * @width:         The mode width.
25131abc56SHans de Goede  * @height:        The mode height.
26131abc56SHans de Goede  * @bpp:           The colour depth of the mode.
27131abc56SHans de Goede  * @flags:         Flags.
28131abc56SHans de Goede  */
hgsmi_process_display_info(struct gen_pool * ctx,u32 display,s32 origin_x,s32 origin_y,u32 start_offset,u32 pitch,u32 width,u32 height,u16 bpp,u16 flags)29131abc56SHans de Goede void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
30131abc56SHans de Goede 				s32 origin_x, s32 origin_y, u32 start_offset,
31131abc56SHans de Goede 				u32 pitch, u32 width, u32 height,
32131abc56SHans de Goede 				u16 bpp, u16 flags)
33131abc56SHans de Goede {
34131abc56SHans de Goede 	struct vbva_infoscreen *p;
35131abc56SHans de Goede 
36131abc56SHans de Goede 	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
37131abc56SHans de Goede 			       VBVA_INFO_SCREEN);
38131abc56SHans de Goede 	if (!p)
39131abc56SHans de Goede 		return;
40131abc56SHans de Goede 
41131abc56SHans de Goede 	p->view_index = display;
42131abc56SHans de Goede 	p->origin_x = origin_x;
43131abc56SHans de Goede 	p->origin_y = origin_y;
44131abc56SHans de Goede 	p->start_offset = start_offset;
45131abc56SHans de Goede 	p->line_size = pitch;
46131abc56SHans de Goede 	p->width = width;
47131abc56SHans de Goede 	p->height = height;
48131abc56SHans de Goede 	p->bits_per_pixel = bpp;
49131abc56SHans de Goede 	p->flags = flags;
50131abc56SHans de Goede 
51131abc56SHans de Goede 	hgsmi_buffer_submit(ctx, p);
52131abc56SHans de Goede 	hgsmi_buffer_free(ctx, p);
53131abc56SHans de Goede }
54131abc56SHans de Goede 
55131abc56SHans de Goede /**
56*8fd54b2cSLee Jones  * hgsmi_update_input_mapping - Report the rectangle relative to which absolute
57*8fd54b2cSLee Jones  *                              pointer events should be expressed.  This
58*8fd54b2cSLee Jones  *                              information remains valid until the next VBVA
59*8fd54b2cSLee Jones  *                              resize event for any screen, at which time it is
60*8fd54b2cSLee Jones  *                              reset to the bounding rectangle of all virtual
61*8fd54b2cSLee Jones  *                              screens.
62131abc56SHans de Goede  * Return: 0 or negative errno value.
63131abc56SHans de Goede  * @ctx:       The context containing the heap to use.
64131abc56SHans de Goede  * @origin_x:  Upper left X co-ordinate relative to the first screen.
65131abc56SHans de Goede  * @origin_y:  Upper left Y co-ordinate relative to the first screen.
66131abc56SHans de Goede  * @width:     Rectangle width.
67131abc56SHans de Goede  * @height:    Rectangle height.
68131abc56SHans de Goede  */
hgsmi_update_input_mapping(struct gen_pool * ctx,s32 origin_x,s32 origin_y,u32 width,u32 height)69131abc56SHans de Goede int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
70131abc56SHans de Goede 			       u32 width, u32 height)
71131abc56SHans de Goede {
72131abc56SHans de Goede 	struct vbva_report_input_mapping *p;
73131abc56SHans de Goede 
74131abc56SHans de Goede 	p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
75131abc56SHans de Goede 			       VBVA_REPORT_INPUT_MAPPING);
76131abc56SHans de Goede 	if (!p)
77131abc56SHans de Goede 		return -ENOMEM;
78131abc56SHans de Goede 
79131abc56SHans de Goede 	p->x = origin_x;
80131abc56SHans de Goede 	p->y = origin_y;
81131abc56SHans de Goede 	p->cx = width;
82131abc56SHans de Goede 	p->cy = height;
83131abc56SHans de Goede 
84131abc56SHans de Goede 	hgsmi_buffer_submit(ctx, p);
85131abc56SHans de Goede 	hgsmi_buffer_free(ctx, p);
86131abc56SHans de Goede 
87131abc56SHans de Goede 	return 0;
88131abc56SHans de Goede }
89131abc56SHans de Goede 
90131abc56SHans de Goede /**
91*8fd54b2cSLee Jones  * hgsmi_get_mode_hints - Get most recent video mode hints.
92131abc56SHans de Goede  * Return: 0 or negative errno value.
93131abc56SHans de Goede  * @ctx:      The context containing the heap to use.
94131abc56SHans de Goede  * @screens:  The number of screens to query hints for, starting at 0.
95131abc56SHans de Goede  * @hints:    Array of vbva_modehint structures for receiving the hints.
96131abc56SHans de Goede  */
hgsmi_get_mode_hints(struct gen_pool * ctx,unsigned int screens,struct vbva_modehint * hints)97131abc56SHans de Goede int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
98131abc56SHans de Goede 			 struct vbva_modehint *hints)
99131abc56SHans de Goede {
100131abc56SHans de Goede 	struct vbva_query_mode_hints *p;
101131abc56SHans de Goede 	size_t size;
102131abc56SHans de Goede 
103131abc56SHans de Goede 	if (WARN_ON(!hints))
104131abc56SHans de Goede 		return -EINVAL;
105131abc56SHans de Goede 
106131abc56SHans de Goede 	size = screens * sizeof(struct vbva_modehint);
107131abc56SHans de Goede 	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA,
108131abc56SHans de Goede 			       VBVA_QUERY_MODE_HINTS);
109131abc56SHans de Goede 	if (!p)
110131abc56SHans de Goede 		return -ENOMEM;
111131abc56SHans de Goede 
112131abc56SHans de Goede 	p->hints_queried_count = screens;
113131abc56SHans de Goede 	p->hint_structure_guest_size = sizeof(struct vbva_modehint);
114131abc56SHans de Goede 	p->rc = VERR_NOT_SUPPORTED;
115131abc56SHans de Goede 
116131abc56SHans de Goede 	hgsmi_buffer_submit(ctx, p);
117131abc56SHans de Goede 
118131abc56SHans de Goede 	if (p->rc < 0) {
119131abc56SHans de Goede 		hgsmi_buffer_free(ctx, p);
120131abc56SHans de Goede 		return -EIO;
121131abc56SHans de Goede 	}
122131abc56SHans de Goede 
123131abc56SHans de Goede 	memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size);
124131abc56SHans de Goede 	hgsmi_buffer_free(ctx, p);
125131abc56SHans de Goede 
126131abc56SHans de Goede 	return 0;
127131abc56SHans de Goede }
128