diff options
| author | Haiyang Zhang <haiyangz@microsoft.com> | 2013-04-29 18:05:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-29 18:54:26 -0400 |
| commit | 68a2d20b79b105f02dcbc52c211d7e62f98996b7 (patch) | |
| tree | 7068bd5a37c0d85e92ff20ed079df1e74b676c61 | |
| parent | 6cd472d3d2a9cace26eae924fe95ec21dc4a0502 (diff) | |
drivers/video: add Hyper-V Synthetic Video Frame Buffer Driver
This is the driver for the Hyper-V Synthetic Video, which supports
screen resolution up to Full HD 1920x1080 on Windows Server 2012 host,
and 1600x1200 on Windows Server 2008 R2 or earlier. It also solves the
double mouse cursor issue of the emulated video mode.
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Cc: Olaf Hering <olaf@aepfle.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | drivers/video/Kconfig | 9 | ||||
| -rw-r--r-- | drivers/video/Makefile | 1 | ||||
| -rw-r--r-- | drivers/video/hyperv_fb.c | 829 | ||||
| -rw-r--r-- | include/linux/hyperv.h | 11 |
4 files changed, 850 insertions, 0 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 981c1c08c727..76be61701c97 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
| @@ -2440,6 +2440,15 @@ config FB_PUV3_UNIGFX | |||
| 2440 | Choose this option if you want to use the Unigfx device as a | 2440 | Choose this option if you want to use the Unigfx device as a |
| 2441 | framebuffer device. Without the support of PCI & AGP. | 2441 | framebuffer device. Without the support of PCI & AGP. |
| 2442 | 2442 | ||
| 2443 | config FB_HYPERV | ||
| 2444 | tristate "Microsoft Hyper-V Synthetic Video support" | ||
| 2445 | depends on FB && HYPERV | ||
| 2446 | select FB_CFB_FILLRECT | ||
| 2447 | select FB_CFB_COPYAREA | ||
| 2448 | select FB_CFB_IMAGEBLIT | ||
| 2449 | help | ||
| 2450 | This framebuffer driver supports Microsoft Hyper-V Synthetic Video. | ||
| 2451 | |||
| 2443 | source "drivers/video/omap/Kconfig" | 2452 | source "drivers/video/omap/Kconfig" |
| 2444 | source "drivers/video/omap2/Kconfig" | 2453 | source "drivers/video/omap2/Kconfig" |
| 2445 | source "drivers/video/exynos/Kconfig" | 2454 | source "drivers/video/exynos/Kconfig" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index e414378d6a51..7234e4a959e8 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
| @@ -149,6 +149,7 @@ obj-$(CONFIG_FB_MSM) += msm/ | |||
| 149 | obj-$(CONFIG_FB_NUC900) += nuc900fb.o | 149 | obj-$(CONFIG_FB_NUC900) += nuc900fb.o |
| 150 | obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o | 150 | obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o |
| 151 | obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o | 151 | obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o |
| 152 | obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o | ||
| 152 | 153 | ||
| 153 | # Platform or fallback drivers go here | 154 | # Platform or fallback drivers go here |
| 154 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 155 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c new file mode 100644 index 000000000000..d4d2c5fe2488 --- /dev/null +++ b/drivers/video/hyperv_fb.c | |||
| @@ -0,0 +1,829 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2012, Microsoft Corporation. | ||
| 3 | * | ||
| 4 | * Author: | ||
| 5 | * Haiyang Zhang <haiyangz@microsoft.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but | ||
| 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
| 14 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
| 15 | * details. | ||
| 16 | */ | ||
| 17 | |||
| 18 | /* | ||
| 19 | * Hyper-V Synthetic Video Frame Buffer Driver | ||
| 20 | * | ||
| 21 | * This is the driver for the Hyper-V Synthetic Video, which supports | ||
| 22 | * screen resolution up to Full HD 1920x1080 with 32 bit color on Windows | ||
| 23 | * Server 2012, and 1600x1200 with 16 bit color on Windows Server 2008 R2 | ||
| 24 | * or earlier. | ||
| 25 | * | ||
| 26 | * It also solves the double mouse cursor issue of the emulated video mode. | ||
| 27 | * | ||
| 28 | * The default screen resolution is 1152x864, which may be changed by a | ||
| 29 | * kernel parameter: | ||
| 30 | * video=hyperv_fb:<width>x<height> | ||
| 31 | * For example: video=hyperv_fb:1280x1024 | ||
| 32 | * | ||
| 33 | * Portrait orientation is also supported: | ||
| 34 | * For example: video=hyperv_fb:864x1152 | ||
| 35 | */ | ||
| 36 | |||
| 37 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 38 | |||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/kernel.h> | ||
| 41 | #include <linux/init.h> | ||
| 42 | #include <linux/completion.h> | ||
| 43 | #include <linux/fb.h> | ||
| 44 | #include <linux/pci.h> | ||
| 45 | |||
| 46 | #include <linux/hyperv.h> | ||
| 47 | |||
| 48 | |||
| 49 | /* Hyper-V Synthetic Video Protocol definitions and structures */ | ||
| 50 | #define MAX_VMBUS_PKT_SIZE 0x4000 | ||
| 51 | |||
| 52 | #define SYNTHVID_VERSION(major, minor) ((minor) << 16 | (major)) | ||
| 53 | #define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0) | ||
| 54 | #define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2) | ||
| 55 | |||
| 56 | #define SYNTHVID_DEPTH_WIN7 16 | ||
| 57 | #define SYNTHVID_DEPTH_WIN8 32 | ||
| 58 | |||
| 59 | #define SYNTHVID_FB_SIZE_WIN7 (4 * 1024 * 1024) | ||
| 60 | #define SYNTHVID_WIDTH_MAX_WIN7 1600 | ||
| 61 | #define SYNTHVID_HEIGHT_MAX_WIN7 1200 | ||
| 62 | |||
| 63 | #define SYNTHVID_FB_SIZE_WIN8 (8 * 1024 * 1024) | ||
| 64 | |||
| 65 | #define PCI_VENDOR_ID_MICROSOFT 0x1414 | ||
| 66 | #define PCI_DEVICE_ID_HYPERV_VIDEO 0x5353 | ||
| 67 | |||
| 68 | |||
| 69 | enum pipe_msg_type { | ||
| 70 | PIPE_MSG_INVALID, | ||
| 71 | PIPE_MSG_DATA, | ||
| 72 | PIPE_MSG_MAX | ||
| 73 | }; | ||
| 74 | |||
| 75 | struct pipe_msg_hdr { | ||
| 76 | u32 type; | ||
| 77 | u32 size; /* size of message after this field */ | ||
| 78 | } __packed; | ||
| 79 | |||
| 80 | |||
| 81 | enum synthvid_msg_type { | ||
| 82 | SYNTHVID_ERROR = 0, | ||
| 83 | SYNTHVID_VERSION_REQUEST = 1, | ||
| 84 | SYNTHVID_VERSION_RESPONSE = 2, | ||
| 85 | SYNTHVID_VRAM_LOCATION = 3, | ||
| 86 | SYNTHVID_VRAM_LOCATION_ACK = 4, | ||
| 87 | SYNTHVID_SITUATION_UPDATE = 5, | ||
| 88 | SYNTHVID_SITUATION_UPDATE_ACK = 6, | ||
| 89 | SYNTHVID_POINTER_POSITION = 7, | ||
| 90 | SYNTHVID_POINTER_SHAPE = 8, | ||
| 91 | SYNTHVID_FEATURE_CHANGE = 9, | ||
| 92 | SYNTHVID_DIRT = 10, | ||
| 93 | |||
| 94 | SYNTHVID_MAX = 11 | ||
| 95 | }; | ||
| 96 | |||
| 97 | struct synthvid_msg_hdr { | ||
| 98 | u32 type; | ||
| 99 | u32 size; /* size of this header + payload after this field*/ | ||
| 100 | } __packed; | ||
| 101 | |||
| 102 | |||
| 103 | struct synthvid_version_req { | ||
| 104 | u32 version; | ||
| 105 | } __packed; | ||
| 106 | |||
| 107 | struct synthvid_version_resp { | ||
| 108 | u32 version; | ||
| 109 | u8 is_accepted; | ||
| 110 | u8 max_video_outputs; | ||
| 111 | } __packed; | ||
| 112 | |||
| 113 | struct synthvid_vram_location { | ||
| 114 | u64 user_ctx; | ||
| 115 | u8 is_vram_gpa_specified; | ||
| 116 | u64 vram_gpa; | ||
| 117 | } __packed; | ||
| 118 | |||
| 119 | struct synthvid_vram_location_ack { | ||
| 120 | u64 user_ctx; | ||
| 121 | } __packed; | ||
| 122 | |||
| 123 | struct video_output_situation { | ||
| 124 | u8 active; | ||
| 125 | u32 vram_offset; | ||
| 126 | u8 depth_bits; | ||
| 127 | u32 width_pixels; | ||
| 128 | u32 height_pixels; | ||
| 129 | u32 pitch_bytes; | ||
| 130 | } __packed; | ||
| 131 | |||
| 132 | struct synthvid_situation_update { | ||
| 133 | u64 user_ctx; | ||
| 134 | u8 video_output_count; | ||
| 135 | struct video_output_situation video_output[1]; | ||
| 136 | } __packed; | ||
| 137 | |||
| 138 | struct synthvid_situation_update_ack { | ||
| 139 | u64 user_ctx; | ||
| 140 | } __packed; | ||
| 141 | |||
| 142 | struct synthvid_pointer_position { | ||
| 143 | u8 is_visible; | ||
| 144 | u8 video_output; | ||
| 145 | s32 image_x; | ||
| 146 | s32 image_y; | ||
| 147 | } __packed; | ||
| 148 | |||
| 149 | |||
| 150 | #define CURSOR_MAX_X 96 | ||
| 151 | #define CURSOR_MAX_Y 96 | ||
| 152 | #define CURSOR_ARGB_PIXEL_SIZE 4 | ||
| 153 | #define CURSOR_MAX_SIZE (CURSOR_MAX_X * CURSOR_MAX_Y * CURSOR_ARGB_PIXEL_SIZE) | ||
| 154 | #define CURSOR_COMPLETE (-1) | ||
| 155 | |||
| 156 | struct synthvid_pointer_shape { | ||
| 157 | u8 part_idx; | ||
| 158 | u8 is_argb; | ||
| 159 | u32 width; /* CURSOR_MAX_X at most */ | ||
| 160 | u32 height; /* CURSOR_MAX_Y at most */ | ||
| 161 | u32 hot_x; /* hotspot relative to upper-left of pointer image */ | ||
| 162 | u32 hot_y; | ||
