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