162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT 262306a36Sopenharmony_ci/* Copyright (C) 2006-2017 Oracle Corporation */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/vbox_err.h> 562306a36Sopenharmony_ci#include "vbox_drv.h" 662306a36Sopenharmony_ci#include "vboxvideo_guest.h" 762306a36Sopenharmony_ci#include "vboxvideo_vbe.h" 862306a36Sopenharmony_ci#include "hgsmi_channels.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/** 1162306a36Sopenharmony_ci * hgsmi_process_display_info - Set a video mode via an HGSMI request. 1262306a36Sopenharmony_ci * The views must have been initialised first 1362306a36Sopenharmony_ci * using @a VBoxHGSMISendViewInfo and if the mode 1462306a36Sopenharmony_ci * is being set on the first display then it must 1562306a36Sopenharmony_ci * be set first using registers. 1662306a36Sopenharmony_ci * @ctx: The context containing the heap to use. 1762306a36Sopenharmony_ci * @display: The screen number. 1862306a36Sopenharmony_ci * @origin_x: The horizontal displacement relative to the first scrn. 1962306a36Sopenharmony_ci * @origin_y: The vertical displacement relative to the first screen. 2062306a36Sopenharmony_ci * @start_offset: The offset of the visible area of the framebuffer 2162306a36Sopenharmony_ci * relative to the framebuffer start. 2262306a36Sopenharmony_ci * @pitch: The offset in bytes between the starts of two adjecent 2362306a36Sopenharmony_ci * scan lines in video RAM. 2462306a36Sopenharmony_ci * @width: The mode width. 2562306a36Sopenharmony_ci * @height: The mode height. 2662306a36Sopenharmony_ci * @bpp: The colour depth of the mode. 2762306a36Sopenharmony_ci * @flags: Flags. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_civoid hgsmi_process_display_info(struct gen_pool *ctx, u32 display, 3062306a36Sopenharmony_ci s32 origin_x, s32 origin_y, u32 start_offset, 3162306a36Sopenharmony_ci u32 pitch, u32 width, u32 height, 3262306a36Sopenharmony_ci u16 bpp, u16 flags) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci struct vbva_infoscreen *p; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, 3762306a36Sopenharmony_ci VBVA_INFO_SCREEN); 3862306a36Sopenharmony_ci if (!p) 3962306a36Sopenharmony_ci return; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci p->view_index = display; 4262306a36Sopenharmony_ci p->origin_x = origin_x; 4362306a36Sopenharmony_ci p->origin_y = origin_y; 4462306a36Sopenharmony_ci p->start_offset = start_offset; 4562306a36Sopenharmony_ci p->line_size = pitch; 4662306a36Sopenharmony_ci p->width = width; 4762306a36Sopenharmony_ci p->height = height; 4862306a36Sopenharmony_ci p->bits_per_pixel = bpp; 4962306a36Sopenharmony_ci p->flags = flags; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci hgsmi_buffer_submit(ctx, p); 5262306a36Sopenharmony_ci hgsmi_buffer_free(ctx, p); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/** 5662306a36Sopenharmony_ci * hgsmi_update_input_mapping - Report the rectangle relative to which absolute 5762306a36Sopenharmony_ci * pointer events should be expressed. This 5862306a36Sopenharmony_ci * information remains valid until the next VBVA 5962306a36Sopenharmony_ci * resize event for any screen, at which time it is 6062306a36Sopenharmony_ci * reset to the bounding rectangle of all virtual 6162306a36Sopenharmony_ci * screens. 6262306a36Sopenharmony_ci * Return: 0 or negative errno value. 6362306a36Sopenharmony_ci * @ctx: The context containing the heap to use. 6462306a36Sopenharmony_ci * @origin_x: Upper left X co-ordinate relative to the first screen. 6562306a36Sopenharmony_ci * @origin_y: Upper left Y co-ordinate relative to the first screen. 6662306a36Sopenharmony_ci * @width: Rectangle width. 6762306a36Sopenharmony_ci * @height: Rectangle height. 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_ciint hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y, 7062306a36Sopenharmony_ci u32 width, u32 height) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci struct vbva_report_input_mapping *p; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, 7562306a36Sopenharmony_ci VBVA_REPORT_INPUT_MAPPING); 7662306a36Sopenharmony_ci if (!p) 7762306a36Sopenharmony_ci return -ENOMEM; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci p->x = origin_x; 8062306a36Sopenharmony_ci p->y = origin_y; 8162306a36Sopenharmony_ci p->cx = width; 8262306a36Sopenharmony_ci p->cy = height; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci hgsmi_buffer_submit(ctx, p); 8562306a36Sopenharmony_ci hgsmi_buffer_free(ctx, p); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci return 0; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/** 9162306a36Sopenharmony_ci * hgsmi_get_mode_hints - Get most recent video mode hints. 9262306a36Sopenharmony_ci * Return: 0 or negative errno value. 9362306a36Sopenharmony_ci * @ctx: The context containing the heap to use. 9462306a36Sopenharmony_ci * @screens: The number of screens to query hints for, starting at 0. 9562306a36Sopenharmony_ci * @hints: Array of vbva_modehint structures for receiving the hints. 9662306a36Sopenharmony_ci */ 9762306a36Sopenharmony_ciint hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens, 9862306a36Sopenharmony_ci struct vbva_modehint *hints) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci struct vbva_query_mode_hints *p; 10162306a36Sopenharmony_ci size_t size; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci if (WARN_ON(!hints)) 10462306a36Sopenharmony_ci return -EINVAL; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci size = screens * sizeof(struct vbva_modehint); 10762306a36Sopenharmony_ci p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA, 10862306a36Sopenharmony_ci VBVA_QUERY_MODE_HINTS); 10962306a36Sopenharmony_ci if (!p) 11062306a36Sopenharmony_ci return -ENOMEM; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci p->hints_queried_count = screens; 11362306a36Sopenharmony_ci p->hint_structure_guest_size = sizeof(struct vbva_modehint); 11462306a36Sopenharmony_ci p->rc = VERR_NOT_SUPPORTED; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci hgsmi_buffer_submit(ctx, p); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (p->rc < 0) { 11962306a36Sopenharmony_ci hgsmi_buffer_free(ctx, p); 12062306a36Sopenharmony_ci return -EIO; 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size); 12462306a36Sopenharmony_ci hgsmi_buffer_free(ctx, p); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci return 0; 12762306a36Sopenharmony_ci} 128