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