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 */ 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 */ 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 */ 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