Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright (c) 2012, Microsoft Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Author:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *   Haiyang Zhang <haiyangz@microsoft.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Hyper-V Synthetic Video Frame Buffer Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * This is the driver for the Hyper-V Synthetic Video, which supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * screen resolution up to Full HD 1920x1080 with 32 bit color on Windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * Server 2012, and 1600x1200 with 16 bit color on Windows Server 2008 R2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * or earlier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * It also solves the double mouse cursor issue of the emulated video mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * The default screen resolution is 1152x864, which may be changed by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * kernel parameter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  *     video=hyperv_fb:<width>x<height>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *     For example: video=hyperv_fb:1280x1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * Portrait orientation is also supported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  *     For example: video=hyperv_fb:864x1152
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  * When a Windows 10 RS5+ host is used, the virtual machine screen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * resolution is obtained from the host. The "video=hyperv_fb" option is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  * not needed, but still can be used to overwrite what the host specifies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * The VM resolution on the host could be set by executing the powershell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * "set-vmvideo" command. For example
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  *     set-vmvideo -vmname name -horizontalresolution:1920 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * -verticalresolution:1200 -resolutiontype single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  * Gen 1 VMs also support direct using VM's physical memory for framebuffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  * It could improve the efficiency and performance for framebuffer and VM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * This requires to allocate contiguous physical memory from Linux kernel's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * CMA memory allocator. To enable this, supply a kernel parameter to give
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  * enough memory space to CMA allocator for framebuffer. For example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  *    cma=130m
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * This gives 130MB memory to CMA allocator that can be allocated to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  * framebuffer. For reference, 8K resolution (7680x4320) takes about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)  * 127MB memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/hyperv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) /* Hyper-V Synthetic Video Protocol definitions and structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define MAX_VMBUS_PKT_SIZE 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define SYNTHVID_VERSION(major, minor) ((minor) << 16 | (major))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define SYNTHVID_VERSION_WIN10 SYNTHVID_VERSION(3, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define SYNTHVID_VER_GET_MAJOR(ver) (ver & 0x0000ffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define SYNTHVID_VER_GET_MINOR(ver) ((ver & 0xffff0000) >> 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define SYNTHVID_DEPTH_WIN7 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define SYNTHVID_DEPTH_WIN8 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define SYNTHVID_FB_SIZE_WIN7 (4 * 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define SYNTHVID_WIDTH_MAX_WIN7 1600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define SYNTHVID_HEIGHT_MAX_WIN7 1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define SYNTHVID_FB_SIZE_WIN8 (8 * 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define PCI_VENDOR_ID_MICROSOFT 0x1414
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define PCI_DEVICE_ID_HYPERV_VIDEO 0x5353
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) enum pipe_msg_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	PIPE_MSG_INVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	PIPE_MSG_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	PIPE_MSG_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) struct pipe_msg_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	u32 size; /* size of message after this field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) enum synthvid_msg_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	SYNTHVID_ERROR			= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	SYNTHVID_VERSION_REQUEST	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	SYNTHVID_VERSION_RESPONSE	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	SYNTHVID_VRAM_LOCATION		= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	SYNTHVID_VRAM_LOCATION_ACK	= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	SYNTHVID_SITUATION_UPDATE	= 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	SYNTHVID_SITUATION_UPDATE_ACK	= 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	SYNTHVID_POINTER_POSITION	= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	SYNTHVID_POINTER_SHAPE		= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	SYNTHVID_FEATURE_CHANGE		= 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	SYNTHVID_DIRT			= 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	SYNTHVID_RESOLUTION_REQUEST	= 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	SYNTHVID_RESOLUTION_RESPONSE	= 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	SYNTHVID_MAX			= 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define		SYNTHVID_EDID_BLOCK_SIZE	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define		SYNTHVID_MAX_RESOLUTION_COUNT	64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) struct hvd_screen_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	u16 width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	u16 height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) struct synthvid_msg_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	u32 size;  /* size of this header + payload after this field*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) struct synthvid_version_req {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) struct synthvid_version_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	u8 is_accepted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	u8 max_video_outputs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) struct synthvid_supported_resolution_req {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	u8 maximum_resolution_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) struct synthvid_supported_resolution_resp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	u8 edid_block[SYNTHVID_EDID_BLOCK_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	u8 resolution_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	u8 default_resolution_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	u8 is_standard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	struct hvd_screen_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		supported_resolution[SYNTHVID_MAX_RESOLUTION_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) struct synthvid_vram_location {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	u64 user_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	u8 is_vram_gpa_specified;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	u64 vram_gpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) struct synthvid_vram_location_ack {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	u64 user_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) struct video_output_situation {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	u8 active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	u32 vram_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	u8 depth_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	u32 width_pixels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	u32 height_pixels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	u32 pitch_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) struct synthvid_situation_update {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	u64 user_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	u8 video_output_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	struct video_output_situation video_output[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) struct synthvid_situation_update_ack {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	u64 user_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) struct synthvid_pointer_position {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	u8 is_visible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	u8 video_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	s32 image_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	s32 image_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #define CURSOR_MAX_X 96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) #define CURSOR_MAX_Y 96
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) #define CURSOR_ARGB_PIXEL_SIZE 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) #define CURSOR_MAX_SIZE (CURSOR_MAX_X * CURSOR_MAX_Y * CURSOR_ARGB_PIXEL_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) #define CURSOR_COMPLETE (-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) struct synthvid_pointer_shape {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	u8 part_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	u8 is_argb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	u32 width; /* CURSOR_MAX_X at most */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	u32 height; /* CURSOR_MAX_Y at most */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	u32 hot_x; /* hotspot relative to upper-left of pointer image */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	u32 hot_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	u8 data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) struct synthvid_feature_change {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	u8 is_dirt_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	u8 is_ptr_pos_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	u8 is_ptr_shape_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	u8 is_situ_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) struct rect {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	s32 x1, y1; /* top left corner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	s32 x2, y2; /* bottom right corner, exclusive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) struct synthvid_dirt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	u8 video_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	u8 dirt_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	struct rect rect[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) struct synthvid_msg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	struct pipe_msg_hdr pipe_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	struct synthvid_msg_hdr vid_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		struct synthvid_version_req ver_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		struct synthvid_version_resp ver_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		struct synthvid_vram_location vram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		struct synthvid_vram_location_ack vram_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		struct synthvid_situation_update situ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		struct synthvid_situation_update_ack situ_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		struct synthvid_pointer_position ptr_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		struct synthvid_pointer_shape ptr_shape;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		struct synthvid_feature_change feature_chg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		struct synthvid_dirt dirt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		struct synthvid_supported_resolution_req resolution_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		struct synthvid_supported_resolution_resp resolution_resp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) /* FB driver definitions and structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) #define HVFB_WIDTH 1152 /* default screen width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) #define HVFB_HEIGHT 864 /* default screen height */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) #define HVFB_WIDTH_MIN 640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) #define HVFB_HEIGHT_MIN 480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) #define RING_BUFSIZE (256 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) #define VSP_TIMEOUT (10 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) #define HVFB_UPDATE_DELAY (HZ / 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) #define HVFB_ONDEMAND_THROTTLE (HZ / 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) struct hvfb_par {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	struct resource *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	bool fb_ready; /* fb device is ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	struct completion wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	u32 synthvid_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	struct delayed_work dwork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	bool update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	bool update_saved; /* The value of 'update' before hibernation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	u32 pseudo_palette[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	u8 init_buf[MAX_VMBUS_PKT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	u8 recv_buf[MAX_VMBUS_PKT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	/* If true, the VSC notifies the VSP on every framebuffer change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	bool synchronous_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	/* If true, need to copy from deferred IO mem to framebuffer mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	bool need_docopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	struct notifier_block hvfb_panic_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	/* Memory for deferred IO and frame buffer itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	unsigned char *dio_vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	unsigned char *mmio_vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	phys_addr_t mmio_pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	/* Dirty rectangle, protected by delayed_refresh_lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	int x1, y1, x2, y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	bool delayed_refresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	spinlock_t delayed_refresh_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) static uint screen_width = HVFB_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static uint screen_height = HVFB_HEIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) static uint screen_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) static uint screen_fb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) static uint dio_fb_size; /* FB size for deferred IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) /* Send message to Hyper-V host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) static inline int synthvid_send(struct hv_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 				struct synthvid_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	static atomic64_t request_id = ATOMIC64_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	msg->pipe_hdr.type = PIPE_MSG_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	msg->pipe_hdr.size = msg->vid_hdr.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	ret = vmbus_sendpacket(hdev->channel, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 			       msg->vid_hdr.size + sizeof(struct pipe_msg_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 			       atomic64_inc_return(&request_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			       VM_PKT_DATA_INBAND, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		pr_err("Unable to send packet via vmbus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) /* Send screen resolution info to host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) static int synthvid_send_situ(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	struct synthvid_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	memset(&msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	msg.vid_hdr.type = SYNTHVID_SITUATION_UPDATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		sizeof(struct synthvid_situation_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	msg.situ.user_ctx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	msg.situ.video_output_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	msg.situ.video_output[0].active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	msg.situ.video_output[0].vram_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	msg.situ.video_output[0].depth_bits = info->var.bits_per_pixel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	msg.situ.video_output[0].width_pixels = info->var.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	msg.situ.video_output[0].height_pixels = info->var.yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	msg.situ.video_output[0].pitch_bytes = info->fix.line_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	synthvid_send(hdev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) /* Send mouse pointer info to host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) static int synthvid_send_ptr(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	struct synthvid_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	memset(&msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	msg.vid_hdr.type = SYNTHVID_POINTER_POSITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		sizeof(struct synthvid_pointer_position);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	msg.ptr_pos.is_visible = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	msg.ptr_pos.video_output = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	msg.ptr_pos.image_x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	msg.ptr_pos.image_y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	synthvid_send(hdev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	memset(&msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	msg.vid_hdr.type = SYNTHVID_POINTER_SHAPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		sizeof(struct synthvid_pointer_shape);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	msg.ptr_shape.part_idx = CURSOR_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	msg.ptr_shape.is_argb = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	msg.ptr_shape.width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	msg.ptr_shape.height = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	msg.ptr_shape.hot_x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	msg.ptr_shape.hot_y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	msg.ptr_shape.data[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	msg.ptr_shape.data[1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	msg.ptr_shape.data[2] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	msg.ptr_shape.data[3] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	synthvid_send(hdev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) /* Send updated screen area (dirty rectangle) location to host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) synthvid_update(struct fb_info *info, int x1, int y1, int x2, int y2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	struct hv_device *hdev = device_to_hv_device(info->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	struct synthvid_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	memset(&msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	if (x2 == INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		x2 = info->var.xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	if (y2 == INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		y2 = info->var.yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	msg.vid_hdr.type = SYNTHVID_DIRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		sizeof(struct synthvid_dirt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	msg.dirt.video_output = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	msg.dirt.dirt_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	msg.dirt.rect[0].x1 = (x1 > x2) ? 0 : x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	msg.dirt.rect[0].y1 = (y1 > y2) ? 0 : y1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	msg.dirt.rect[0].x2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		(x2 < x1 || x2 > info->var.xres) ? info->var.xres : x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	msg.dirt.rect[0].y2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		(y2 < y1 || y2 > info->var.yres) ? info->var.yres : y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	synthvid_send(hdev, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) static void hvfb_docopy(struct hvfb_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			unsigned long offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	if (!par || !par->mmio_vp || !par->dio_vp || !par->fb_ready ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	    size == 0 || offset >= dio_fb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	if (offset + size > dio_fb_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		size = dio_fb_size - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	memcpy(par->mmio_vp + offset, par->dio_vp + offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) /* Deferred IO callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) static void synthvid_deferred_io(struct fb_info *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				 struct list_head *pagelist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	struct hvfb_par *par = p->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	struct page *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	unsigned long start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	int y1, y2, miny, maxy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	miny = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	maxy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	 * Merge dirty pages. It is possible that last page cross
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	 * over the end of frame buffer row yres. This is taken care of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	 * in synthvid_update function by clamping the y2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	 * value to yres.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	list_for_each_entry(page, pagelist, lru) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		start = page->index << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		end = start + PAGE_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		y1 = start / p->fix.line_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		y2 = end / p->fix.line_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		miny = min_t(int, miny, y1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		maxy = max_t(int, maxy, y2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		/* Copy from dio space to mmio address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		if (par->fb_ready && par->need_docopy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			hvfb_docopy(par, start, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	if (par->fb_ready && par->update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		synthvid_update(p, 0, miny, p->var.xres, maxy + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) static struct fb_deferred_io synthvid_defio = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	.delay		= HZ / 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	.deferred_io	= synthvid_deferred_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  * Actions on received messages from host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  * Complete the wait event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464)  * Or, reply with screen and cursor info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) static void synthvid_recv_sub(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	struct hvfb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	struct synthvid_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	msg = (struct synthvid_msg *)par->recv_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	/* Complete the wait event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	if (msg->vid_hdr.type == SYNTHVID_VERSION_RESPONSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	    msg->vid_hdr.type == SYNTHVID_RESOLUTION_RESPONSE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	    msg->vid_hdr.type == SYNTHVID_VRAM_LOCATION_ACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		memcpy(par->init_buf, msg, MAX_VMBUS_PKT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		complete(&par->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	/* Reply with screen and cursor info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		if (par->fb_ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			synthvid_send_ptr(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			synthvid_send_situ(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		par->update = msg->feature_chg.is_dirt_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		if (par->update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) /* Receive callback for messages from the host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) static void synthvid_receive(void *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	struct hv_device *hdev = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	struct hvfb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	struct synthvid_msg *recv_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	u32 bytes_recvd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	u64 req_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	recv_buf = (struct synthvid_msg *)par->recv_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		ret = vmbus_recvpacket(hdev->channel, recv_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 				       MAX_VMBUS_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 				       &bytes_recvd, &req_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		if (bytes_recvd > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		    recv_buf->pipe_hdr.type == PIPE_MSG_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 			synthvid_recv_sub(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	} while (bytes_recvd > 0 && ret == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) /* Check if the ver1 version is equal or greater than ver2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) static inline bool synthvid_ver_ge(u32 ver1, u32 ver2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	if (SYNTHVID_VER_GET_MAJOR(ver1) > SYNTHVID_VER_GET_MAJOR(ver2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	    (SYNTHVID_VER_GET_MAJOR(ver1) == SYNTHVID_VER_GET_MAJOR(ver2) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	     SYNTHVID_VER_GET_MINOR(ver1) >= SYNTHVID_VER_GET_MINOR(ver2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) /* Check synthetic video protocol version with the host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	memset(msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		sizeof(struct synthvid_version_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	msg->ver_req.version = ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	synthvid_send(hdev, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	if (!t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		pr_err("Time out on waiting version response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	if (!msg->ver_resp.is_accepted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	par->synthvid_version = ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	pr_info("Synthvid Version major %d, minor %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		SYNTHVID_VER_GET_MAJOR(ver), SYNTHVID_VER_GET_MINOR(ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) /* Get current resolution from the host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) static int synthvid_get_supported_resolution(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	memset(msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	msg->vid_hdr.type = SYNTHVID_RESOLUTION_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		sizeof(struct synthvid_supported_resolution_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	msg->resolution_req.maximum_resolution_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		SYNTHVID_MAX_RESOLUTION_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	synthvid_send(hdev, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	if (!t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		pr_err("Time out on waiting resolution response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	if (msg->resolution_resp.resolution_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		pr_err("No supported resolutions\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	index = msg->resolution_resp.default_resolution_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	if (index >= msg->resolution_resp.resolution_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		pr_err("Invalid resolution index: %d\n", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	screen_width =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		msg->resolution_resp.supported_resolution[index].width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	screen_height =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		msg->resolution_resp.supported_resolution[index].height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) /* Connect to VSP (Virtual Service Provider) on host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) static int synthvid_connect_vsp(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	ret = vmbus_open(hdev->channel, RING_BUFSIZE, RING_BUFSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			 NULL, 0, synthvid_receive, hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		pr_err("Unable to open vmbus channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	/* Negotiate the protocol version with host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	switch (vmbus_proto_version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	case VERSION_WIN10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	case VERSION_WIN10_V5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	case VERSION_WIN8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	case VERSION_WIN8_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	case VERSION_WS2008:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	case VERSION_WIN7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		pr_err("Synthetic video device version not accepted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	if (par->synthvid_version == SYNTHVID_VERSION_WIN7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		screen_depth = SYNTHVID_DEPTH_WIN7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		screen_depth = SYNTHVID_DEPTH_WIN8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	if (synthvid_ver_ge(par->synthvid_version, SYNTHVID_VERSION_WIN10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		ret = synthvid_get_supported_resolution(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			pr_info("Failed to get supported resolution from host, use default\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	screen_fb_size = hdev->channel->offermsg.offer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 				mmio_megabytes * 1024 * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	vmbus_close(hdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) /* Send VRAM and Situation messages to the host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) static int synthvid_send_config(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	/* Send VRAM location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	memset(msg, 0, sizeof(struct synthvid_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	msg->vid_hdr.type = SYNTHVID_VRAM_LOCATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		sizeof(struct synthvid_vram_location);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	msg->vram.user_ctx = msg->vram.vram_gpa = par->mmio_pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	msg->vram.is_vram_gpa_specified = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	synthvid_send(hdev, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	if (!t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		pr_err("Time out on waiting vram location ack\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	if (msg->vram_ack.user_ctx != par->mmio_pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		pr_err("Unable to set VRAM location\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	/* Send pointer and situation update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	synthvid_send_ptr(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	synthvid_send_situ(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724)  * Delayed work callback:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)  * It is scheduled to call whenever update request is received and it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)  * not been called in last HVFB_ONDEMAND_THROTTLE time interval.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) static void hvfb_update_work(struct work_struct *w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	struct hvfb_par *par = container_of(w, struct hvfb_par, dwork.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	struct fb_info *info = par->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	int x1, x2, y1, y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	spin_lock_irqsave(&par->delayed_refresh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	/* Reset the request flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	par->delayed_refresh = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	/* Store the dirty rectangle to local variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	x1 = par->x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	x2 = par->x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	y1 = par->y1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	y2 = par->y2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	/* Clear dirty rectangle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	par->x1 = par->y1 = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	par->x2 = par->y2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	spin_unlock_irqrestore(&par->delayed_refresh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (x1 > info->var.xres || x2 > info->var.xres ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	    y1 > info->var.yres || y2 > info->var.yres || x2 <= x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	/* Copy the dirty rectangle to frame buffer memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if (par->need_docopy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		for (j = y1; j < y2; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			hvfb_docopy(par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 				    j * info->fix.line_length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 				    (x1 * screen_depth / 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 				    (x2 - x1) * screen_depth / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	/* Refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (par->fb_ready && par->update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		synthvid_update(info, x1, y1, x2, y2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770)  * Control the on-demand refresh frequency. It schedules a delayed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771)  * screen update if it has not yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) static void hvfb_ondemand_refresh_throttle(struct hvfb_par *par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 					   int x1, int y1, int w, int h)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	int x2 = x1 + w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	int y2 = y1 + h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	spin_lock_irqsave(&par->delayed_refresh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	/* Merge dirty rectangle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	par->x1 = min_t(int, par->x1, x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	par->y1 = min_t(int, par->y1, y1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	par->x2 = max_t(int, par->x2, x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	par->y2 = max_t(int, par->y2, y2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	/* Schedule a delayed screen update if not yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	if (par->delayed_refresh == false) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		schedule_delayed_work(&par->dwork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 				      HVFB_ONDEMAND_THROTTLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		par->delayed_refresh = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	spin_unlock_irqrestore(&par->delayed_refresh_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) static int hvfb_on_panic(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			 unsigned long e, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	struct hvfb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	par->synchronous_fb = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	info = par->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	if (par->need_docopy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		hvfb_docopy(par, 0, dio_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) /* Framebuffer operation handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) static int hvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	if (var->xres < HVFB_WIDTH_MIN || var->yres < HVFB_HEIGHT_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	    var->xres > screen_width || var->yres >  screen_height ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	    var->bits_per_pixel != screen_depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	var->xres_virtual = var->xres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	var->yres_virtual = var->yres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) static int hvfb_set_par(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	struct hv_device *hdev = device_to_hv_device(info->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	return synthvid_send_situ(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) static inline u32 chan_to_field(u32 chan, struct fb_bitfield *bf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) static int hvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			  unsigned blue, unsigned transp, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	u32 *pal = info->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	if (regno > 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	pal[regno] = chan_to_field(red, &info->var.red)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		| chan_to_field(green, &info->var.green)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		| chan_to_field(blue, &info->var.blue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		| chan_to_field(transp, &info->var.transp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) static int hvfb_blank(int blank, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	return 1;	/* get fb_blank to set the colormap to all black */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) static void hvfb_cfb_fillrect(struct fb_info *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			      const struct fb_fillrect *rect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	struct hvfb_par *par = p->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	cfb_fillrect(p, rect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	if (par->synchronous_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		hvfb_ondemand_refresh_throttle(par, rect->dx, rect->dy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 					       rect->width, rect->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) static void hvfb_cfb_copyarea(struct fb_info *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 			      const struct fb_copyarea *area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	struct hvfb_par *par = p->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	cfb_copyarea(p, area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (par->synchronous_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		hvfb_ondemand_refresh_throttle(par, area->dx, area->dy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 					       area->width, area->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) static void hvfb_cfb_imageblit(struct fb_info *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			       const struct fb_image *image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	struct hvfb_par *par = p->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	cfb_imageblit(p, image);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	if (par->synchronous_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		synthvid_update(p, 0, 0, INT_MAX, INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		hvfb_ondemand_refresh_throttle(par, image->dx, image->dy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 					       image->width, image->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) static const struct fb_ops hvfb_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	.fb_check_var = hvfb_check_var,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	.fb_set_par = hvfb_set_par,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	.fb_setcolreg = hvfb_setcolreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	.fb_fillrect = hvfb_cfb_fillrect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	.fb_copyarea = hvfb_cfb_copyarea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	.fb_imageblit = hvfb_cfb_imageblit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	.fb_blank = hvfb_blank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) /* Get options from kernel paramenter "video=" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) static void hvfb_get_option(struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	char *opt = NULL, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	uint x = 0, y = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (fb_get_options(KBUILD_MODNAME, &opt) || !opt || !*opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	p = strsep(&opt, "x");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	if (!*p || kstrtouint(p, 0, &x) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	    !opt || !*opt || kstrtouint(opt, 0, &y)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		pr_err("Screen option is invalid: skipped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	    (synthvid_ver_ge(par->synthvid_version, SYNTHVID_VERSION_WIN10) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	    (x * y * screen_depth / 8 > screen_fb_size)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	    (par->synthvid_version == SYNTHVID_VERSION_WIN8 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	     x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	    (par->synthvid_version == SYNTHVID_VERSION_WIN7 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	     (x > SYNTHVID_WIDTH_MAX_WIN7 || y > SYNTHVID_HEIGHT_MAX_WIN7))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		pr_err("Screen resolution option is out of range: skipped\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	screen_width = x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	screen_height = y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948)  * Allocate enough contiguous physical memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949)  * Return physical address if succeeded or -1 if failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 				   unsigned int request_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct page *page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	dma_addr_t dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	void *vmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	phys_addr_t paddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	unsigned int order = get_order(request_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	if (request_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (order < MAX_ORDER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		/* Call alloc_pages if the size is less than 2^MAX_ORDER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		paddr = (page_to_pfn(page) << PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		/* Allocate from CMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		hdev->device.coherent_dma_mask = DMA_BIT_MASK(64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		vmem = dma_alloc_coherent(&hdev->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 					  round_up(request_size, PAGE_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 					  &dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 					  GFP_KERNEL | __GFP_NOWARN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		if (!vmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		paddr = virt_to_phys(vmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	return paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) /* Release contiguous physical memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) static void hvfb_release_phymem(struct hv_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 				phys_addr_t paddr, unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	unsigned int order = get_order(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	if (order < MAX_ORDER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		__free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		dma_free_coherent(&hdev->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 				  round_up(size, PAGE_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 				  phys_to_virt(paddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 				  paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* Get framebuffer memory from Hyper-V video pci space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	struct pci_dev *pdev  = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	void __iomem *fb_virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	int gen2vm = efi_enabled(EFI_BOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	resource_size_t pot_start, pot_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	phys_addr_t paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	info->apertures = alloc_apertures(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	if (!info->apertures)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (!gen2vm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 			PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 			pr_err("Unable to find PCI Hyper-V video\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		 * For Gen 1 VM, we can directly use the contiguous memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		 * from VM. If we succeed, deferred IO happens directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		 * on this allocated framebuffer memory, avoiding extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		 * memory copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		paddr = hvfb_get_phymem(hdev, screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 		if (paddr != (phys_addr_t) -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			par->mmio_pp = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			par->mmio_vp = par->dio_vp = __va(paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			info->fix.smem_start = paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			info->fix.smem_len = screen_fb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			info->screen_base = par->mmio_vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			info->screen_size = screen_fb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			par->need_docopy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			goto getmem_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		info->apertures->ranges[0].base = screen_info.lfb_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		info->apertures->ranges[0].size = screen_info.lfb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	 * Cannot use the contiguous physical memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	 * Allocate mmio space for framebuffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	dio_fb_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		screen_width * screen_height * screen_depth / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	if (gen2vm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		pot_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		pot_end = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		    pci_resource_len(pdev, 0) < screen_fb_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			pr_err("Resource not available or (0x%lx < 0x%lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			       (unsigned long) pci_resource_len(pdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			       (unsigned long) screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		pot_end = pci_resource_end(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		pot_start = pot_end - screen_fb_size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	ret = vmbus_allocate_mmio(&par->mem, hdev, pot_start, pot_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				  screen_fb_size, 0x100000, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		pr_err("Unable to allocate framebuffer memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	 * Map the VRAM cacheable for performance. This is also required for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	 * VM Connect to display properly for ARM64 Linux VM, as the host also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	 * maps the VRAM cacheable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	fb_virt = ioremap_cache(par->mem->start, screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	if (!fb_virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	/* Allocate memory for deferred IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	par->dio_vp = vzalloc(round_up(dio_fb_size, PAGE_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	if (par->dio_vp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		goto err3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	/* Physical address of FB device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	par->mmio_pp = par->mem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	/* Virtual address of FB device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	par->mmio_vp = (unsigned char *) fb_virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	info->fix.smem_start = par->mem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	info->fix.smem_len = dio_fb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	info->screen_base = par->dio_vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	info->screen_size = dio_fb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) getmem_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	remove_conflicting_framebuffers(info->apertures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 					KBUILD_MODNAME, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	if (gen2vm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		/* framebuffer is reallocated, clear screen_info to avoid misuse from kexec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		screen_info.lfb_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		screen_info.lfb_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		screen_info.orig_video_isVGA = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) err3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	iounmap(fb_virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	vmbus_free_mmio(par->mem->start, screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	par->mem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	if (!gen2vm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		pci_dev_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /* Release the framebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	if (par->need_docopy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		vfree(par->dio_vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		iounmap(info->screen_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		vmbus_free_mmio(par->mem->start, screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		hvfb_release_phymem(hdev, info->fix.smem_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 				    screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	par->mem = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static int hvfb_probe(struct hv_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		      const struct hv_vmbus_device_id *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	struct fb_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	struct hvfb_par *par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	par->info = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	par->fb_ready = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	par->need_docopy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	init_completion(&par->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	par->delayed_refresh = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	spin_lock_init(&par->delayed_refresh_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	par->x1 = par->y1 = INT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	par->x2 = par->y2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	/* Connect to VSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	hv_set_drvdata(hdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	ret = synthvid_connect_vsp(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		pr_err("Unable to connect to VSP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		goto error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	hvfb_get_option(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	pr_info("Screen resolution: %dx%d, Color depth: %d, Frame buffer size: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		screen_width, screen_height, screen_depth, screen_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	ret = hvfb_getmem(hdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		pr_err("No memory for framebuffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		goto error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	/* Set up fb_info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	info->flags = FBINFO_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	info->var.xres_virtual = info->var.xres = screen_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	info->var.yres_virtual = info->var.yres = screen_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	info->var.bits_per_pixel = screen_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	if (info->var.bits_per_pixel == 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		info->var.red = (struct fb_bitfield){11, 5, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		info->var.green = (struct fb_bitfield){5, 6, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		info->var.blue = (struct fb_bitfield){0, 5, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		info->var.transp = (struct fb_bitfield){0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		info->var.red = (struct fb_bitfield){16, 8, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		info->var.green = (struct fb_bitfield){8, 8, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		info->var.blue = (struct fb_bitfield){0, 8, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		info->var.transp = (struct fb_bitfield){24, 8, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	info->var.activate = FB_ACTIVATE_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	info->var.height = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	info->var.width = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	info->var.vmode = FB_VMODE_NONINTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	strcpy(info->fix.id, KBUILD_MODNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	info->fix.type = FB_TYPE_PACKED_PIXELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	info->fix.visual = FB_VISUAL_TRUECOLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	info->fix.line_length = screen_width * screen_depth / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	info->fix.accel = FB_ACCEL_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	info->fbops = &hvfb_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	info->pseudo_palette = par->pseudo_palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	/* Initialize deferred IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	info->fbdefio = &synthvid_defio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	fb_deferred_io_init(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	/* Send config to host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	ret = synthvid_send_config(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	ret = register_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		pr_err("Unable to register framebuffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	par->fb_ready = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	par->synchronous_fb = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	atomic_notifier_chain_register(&panic_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 				       &par->hvfb_panic_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	fb_deferred_io_cleanup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	hvfb_putmem(hdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) error2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	vmbus_close(hdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) error1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	cancel_delayed_work_sync(&par->dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	hv_set_drvdata(hdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int hvfb_remove(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	atomic_notifier_chain_unregister(&panic_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 					 &par->hvfb_panic_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	par->update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	par->fb_ready = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	fb_deferred_io_cleanup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	unregister_framebuffer(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	cancel_delayed_work_sync(&par->dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	vmbus_close(hdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	hv_set_drvdata(hdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	hvfb_putmem(hdev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	framebuffer_release(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) static int hvfb_suspend(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	/* 1 means do suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	fb_set_suspend(info, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	cancel_delayed_work_sync(&par->dwork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	cancel_delayed_work_sync(&info->deferred_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	par->update_saved = par->update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	par->update = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	par->fb_ready = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	vmbus_close(hdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) static int hvfb_resume(struct hv_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	struct fb_info *info = hv_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	struct hvfb_par *par = info->par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	console_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	ret = synthvid_connect_vsp(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	ret = synthvid_send_config(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		vmbus_close(hdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	par->fb_ready = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	par->update = par->update_saved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	schedule_delayed_work(&info->deferred_work, info->fbdefio->delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	/* 0 means do resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	fb_set_suspend(info, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	console_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) static const struct pci_device_id pci_stub_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		.vendor      = PCI_VENDOR_ID_MICROSOFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 		.device      = PCI_DEVICE_ID_HYPERV_VIDEO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	{ /* end of list */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static const struct hv_vmbus_device_id id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	/* Synthetic Video Device GUID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	{HV_SYNTHVID_GUID},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) MODULE_DEVICE_TABLE(pci, pci_stub_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) MODULE_DEVICE_TABLE(vmbus, id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) static struct hv_driver hvfb_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	.name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	.id_table = id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	.probe = hvfb_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	.remove = hvfb_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	.suspend = hvfb_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	.resume = hvfb_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) static int hvfb_pci_stub_probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 			       const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static void hvfb_pci_stub_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static struct pci_driver hvfb_pci_stub_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	.name =		KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	.id_table =	pci_stub_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	.probe =	hvfb_pci_stub_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	.remove =	hvfb_pci_stub_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) static int __init hvfb_drv_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	ret = vmbus_driver_register(&hvfb_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	ret = pci_register_driver(&hvfb_pci_stub_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		vmbus_driver_unregister(&hvfb_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static void __exit hvfb_drv_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	pci_unregister_driver(&hvfb_pci_stub_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	vmbus_driver_unregister(&hvfb_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) module_init(hvfb_drv_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) module_exit(hvfb_drv_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");