2014-02-21 04:58:51

by Haiyang Zhang

[permalink] [raw]
Subject: [PATCH v2,0/2] Re-sending two patches for hyperv_fb

They were sent out during tree closing, I'm re-sending them now.
---
v2:
Updated the variable type gen2vm to int, because efi_enabled() returns int.

Haiyang Zhang (2):
hyperv_fb: Add screen refresh after pause/resume operation
hyperv_fb: Add support for Gen2 VM

drivers/video/hyperv_fb.c | 70 ++++++++++++++++++++++++++++++++-------------
1 files changed, 50 insertions(+), 20 deletions(-)

--
1.7.4.1


2014-02-21 04:58:59

by Haiyang Zhang

[permalink] [raw]
Subject: [PATCH v2,1/2] hyperv_fb: Add screen refresh after pause/resume operation

This is necessary because after VM is pause/resumed, some portion of
the screen may need refresh.

Signed-off-by: Haiyang Zhang <[email protected]>
Reviewed-by: K. Y. Srinivasan <[email protected]>
---
drivers/video/hyperv_fb.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c
index 130708f..bbcc8c0 100644
--- a/drivers/video/hyperv_fb.c
+++ b/drivers/video/hyperv_fb.c
@@ -218,6 +218,7 @@ struct hvfb_par {

struct delayed_work dwork;
bool update;
+ bool xrefresh;

u32 pseudo_palette[16];
u8 init_buf[MAX_VMBUS_PKT_SIZE];
@@ -369,7 +370,7 @@ static void synthvid_recv_sub(struct hv_device *hdev)
synthvid_send_situ(hdev);
}

- par->update = msg->feature_chg.is_dirt_needed;
+ par->xrefresh = par->update = msg->feature_chg.is_dirt_needed;
if (par->update)
schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
}
@@ -522,6 +523,13 @@ static void hvfb_update_work(struct work_struct *w)
{
struct hvfb_par *par = container_of(w, struct hvfb_par, dwork.work);
struct fb_info *info = par->info;
+ char *argv[] = {"/usr/bin/xrefresh", "-display", ":0.0", NULL};
+ char *envp[] = {"HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
+
+ if (par->xrefresh) {
+ par->xrefresh = false;
+ call_usermodehelper(argv[0], argv, envp, UMH_NO_WAIT);
+ }

if (par->fb_ready)
synthvid_update(info);
--
1.7.4.1

2014-02-21 04:59:19

by Haiyang Zhang

[permalink] [raw]
Subject: [PATCH v2,2/2] hyperv_fb: Add support for Gen2 VM

This patch enables Hyper-V FB driver to run on Gen2 VM.

The Gen2 VM provides MMIO area for synthetic video from ACPI module,
which is exported by vmbus. The generic video is provided by UEFI. PCI
video in Gen1 is no longer available.

To support synthetic video on Hyper-V Gen2 VM, this patch updated
code related to the changes above.

Signed-off-by: Haiyang Zhang <[email protected]>
Reviewed-by: K. Y. Srinivasan <[email protected]>
---
drivers/video/hyperv_fb.c | 60 ++++++++++++++++++++++++++++++--------------
1 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c
index bbcc8c0..5db1f20 100644
--- a/drivers/video/hyperv_fb.c
+++ b/drivers/video/hyperv_fb.c
@@ -42,6 +42,7 @@
#include <linux/completion.h>
#include <linux/fb.h>
#include <linux/pci.h>
+#include <linux/efi.h>

#include <linux/hyperv.h>

@@ -461,13 +462,13 @@ static int synthvid_connect_vsp(struct hv_device *hdev)
goto error;
}

- if (par->synthvid_version == SYNTHVID_VERSION_WIN7) {
+ if (par->synthvid_version == SYNTHVID_VERSION_WIN7)
screen_depth = SYNTHVID_DEPTH_WIN7;
- screen_fb_size = SYNTHVID_FB_SIZE_WIN7;
- } else {
+ else
screen_depth = SYNTHVID_DEPTH_WIN8;
- screen_fb_size = SYNTHVID_FB_SIZE_WIN8;
- }
+
+ screen_fb_size = hdev->channel->offermsg.offer.
+ mmio_megabytes * 1024 * 1024;

return 0;

@@ -635,22 +636,33 @@ static void hvfb_get_option(struct fb_info *info)
/* Get framebuffer memory from Hyper-V video pci space */
static int hvfb_getmem(struct fb_info *info)
{
- struct pci_dev *pdev;
+ struct pci_dev *pdev = NULL;
ulong fb_phys;
void __iomem *fb_virt;
+ int gen2vm = efi_enabled(EFI_BOOT);

- pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
+ if (gen2vm) {
+ if (!hyperv_mmio_start || hyperv_mmio_size < screen_fb_size) {
+ pr_err("Unable to find ACPI MMIO area\n");
+ return -ENODEV;
+ }
+
+ fb_phys = hyperv_mmio_start;
+ } else {
+ pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
- if (!pdev) {
- pr_err("Unable to find PCI Hyper-V video\n");
- return -ENODEV;
- }
+ if (!pdev) {
+ pr_err("Unable to find PCI Hyper-V video\n");
+ return -ENODEV;
+ }

- if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
- pci_resource_len(pdev, 0) < screen_fb_size)
- goto err1;
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
+ pci_resource_len(pdev, 0) < screen_fb_size)
+ goto err1;
+
+ fb_phys = pci_resource_end(pdev, 0) - screen_fb_size + 1;
+ }

- fb_phys = pci_resource_end(pdev, 0) - screen_fb_size + 1;
if (!request_mem_region(fb_phys, screen_fb_size, KBUILD_MODNAME))
goto err1;

@@ -662,14 +674,22 @@ static int hvfb_getmem(struct fb_info *info)
if (!info->apertures)
goto err3;

- info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
- info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
+ if (gen2vm) {
+ info->apertures->ranges[0].base = screen_info.lfb_base;
+ info->apertures->ranges[0].size = screen_info.lfb_size;
+ } else {
+ info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
+ info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
+ }
+
info->fix.smem_start = fb_phys;
info->fix.smem_len = screen_fb_size;
info->screen_base = fb_virt;
info->screen_size = screen_fb_size;

- pci_dev_put(pdev);
+ if (!gen2vm)
+ pci_dev_put(pdev);
+
return 0;

err3:
@@ -677,7 +697,9 @@ err3:
err2:
release_mem_region(fb_phys, screen_fb_size);
err1:
- pci_dev_put(pdev);
+ if (!gen2vm)
+ pci_dev_put(pdev);
+
return -ENOMEM;
}

--
1.7.4.1