RE: [PATCH v3 3/4] hyperv-fb: add support for generation 2 virtual machines.
> -Original Message- > From: Gerd Hoffmann [mailto:kra...@redhat.com] > Sent: Monday, February 24, 2014 8:17 AM > To: linux-fb...@vger.kernel.org > Cc: linux-kernel@vger.kernel.org; gre...@linuxfoundation.org; KY Srinivasan; > Abhishek Gupta (LIS); Haiyang Zhang; jasow...@redhat.com; > tomi.valkei...@ti.com; de...@linuxdriverproject.org; Gerd Hoffmann; Jean- > Christophe Plagniol-Villard > Subject: [PATCH v3 3/4] hyperv-fb: add support for generation 2 virtual > machines. > > UEFI-based generation 2 virtual machines support vmbus devices only. > There is no pci bus. Thus they use a different mechanism for the graphics > framebuffer: Instead of using the vga pci bar a chunk of memory muct be > allocated from the hyperv mmio region declared using APCI. This patch > implements support for it. > > Based on a patch by Haiyang Zhang > > Signed-off-by: Gerd Hoffmann > --- > drivers/video/hyperv_fb.c | 86 +- > - > 1 file changed, 60 insertions(+), 26 deletions(-) > > diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c index > 130708f..135d8cd 100644 > --- a/drivers/video/hyperv_fb.c > +++ b/drivers/video/hyperv_fb.c > @@ -42,6 +42,7 @@ > #include > #include > #include > +#include > > #include > > @@ -212,6 +213,7 @@ struct synthvid_msg { > > struct hvfb_par { > struct fb_info *info; > + struct resource mem; > bool fb_ready; /* fb device is ready */ > struct completion wait; > u32 synthvid_version; > @@ -460,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; > > @@ -627,26 +629,46 @@ 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; > - ulong fb_phys; > + struct hvfb_par *par = info->par; > + struct pci_dev *pdev = NULL; > void __iomem *fb_virt; > + int gen2vm = efi_enabled(EFI_BOOT); > + int ret; > > - pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, > + par->mem.name = "hyperv_fb"; Please use KBUILD_MODNAME, so that the naming is consistent. Thanks, - Haiyang > + par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY; > + if (gen2vm) { > + ret = allocate_resource(_mmio, >mem, > + screen_fb_size, > + 0, -1, > + screen_fb_size, > + NULL, NULL); > + if (ret != 0) { > + pr_err("Unable to allocate framebuffer memory\n"); > + return -ENODEV; > + } > + } 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; > - if (!request_mem_region(fb_phys, screen_fb_size, > KBUILD_MODNAME)) > - goto err1; > + par->mem.end = pci_resource_end(pdev, 0); > + par->mem.start = par->mem.end - screen_fb_size + 1; > + ret = request_resource(>resource[0], >mem); > + if (ret != 0) { > + pr_err("Unable to request framebuffer memory\n"); > + goto err1; > + } > + } > > - fb_virt = ioremap(fb_phys, screen_fb_size); > + fb_virt = ioremap(par->mem.start, screen_fb_size); > if (!fb_virt) > goto err2; > > @@ -654,30 +676,42 @@ 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); > -
RE: [PATCH v3 3/4] hyperv-fb: add support for generation 2 virtual machines.
-Original Message- From: Gerd Hoffmann [mailto:kra...@redhat.com] Sent: Monday, February 24, 2014 8:17 AM To: linux-fb...@vger.kernel.org Cc: linux-kernel@vger.kernel.org; gre...@linuxfoundation.org; KY Srinivasan; Abhishek Gupta (LIS); Haiyang Zhang; jasow...@redhat.com; tomi.valkei...@ti.com; de...@linuxdriverproject.org; Gerd Hoffmann; Jean- Christophe Plagniol-Villard Subject: [PATCH v3 3/4] hyperv-fb: add support for generation 2 virtual machines. UEFI-based generation 2 virtual machines support vmbus devices only. There is no pci bus. Thus they use a different mechanism for the graphics framebuffer: Instead of using the vga pci bar a chunk of memory muct be allocated from the hyperv mmio region declared using APCI. This patch implements support for it. Based on a patch by Haiyang Zhang haiya...@microsoft.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- drivers/video/hyperv_fb.c | 86 +- - 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c index 130708f..135d8cd 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 @@ -212,6 +213,7 @@ struct synthvid_msg { struct hvfb_par { struct fb_info *info; + struct resource mem; bool fb_ready; /* fb device is ready */ struct completion wait; u32 synthvid_version; @@ -460,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; @@ -627,26 +629,46 @@ 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; - ulong fb_phys; + struct hvfb_par *par = info-par; + struct pci_dev *pdev = NULL; void __iomem *fb_virt; + int gen2vm = efi_enabled(EFI_BOOT); + int ret; - pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, + par-mem.name = hyperv_fb; Please use KBUILD_MODNAME, so that the naming is consistent. Thanks, - Haiyang + par-mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (gen2vm) { + ret = allocate_resource(hyperv_mmio, par-mem, + screen_fb_size, + 0, -1, + screen_fb_size, + NULL, NULL); + if (ret != 0) { + pr_err(Unable to allocate framebuffer memory\n); + return -ENODEV; + } + } 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; - if (!request_mem_region(fb_phys, screen_fb_size, KBUILD_MODNAME)) - goto err1; + par-mem.end = pci_resource_end(pdev, 0); + par-mem.start = par-mem.end - screen_fb_size + 1; + ret = request_resource(pdev-resource[0], par-mem); + if (ret != 0) { + pr_err(Unable to request framebuffer memory\n); + goto err1; + } + } - fb_virt = ioremap(fb_phys, screen_fb_size); + fb_virt = ioremap(par-mem.start, screen_fb_size); if (!fb_virt) goto err2; @@ -654,30 +676,42 @@ 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); - info-fix.smem_start = fb_phys; + if