> Date: Wed, 30 Dec 2015 10:58:53 +0200 (EET)
> From: [email protected]
> 
> pci0 at mainbus0 bus 0
> pchb0 at pci0 dev 0 function 0 "Intel Core 2G Host" rev 0x09
> ppb0 at pci0 dev 1 function 0 "Intel Core 2G PCIE" rev 0x09: msi
> pci1 at ppb0 bus 1
> vga1 at pci1 dev 0 function 0 "ATI Radeon HD 6950" rev 0x00
> wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
> wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
> azalia0 at pci1 dev 0 function 1 vendor "ATI", unknown product 0xaa80 rev 
> 0x00: msi
> azalia0: no supported codecs
> "Intel HD Graphics 3000" rev 0x09 at pci0 dev 2 function 0 not configured

Does the diff below help?

Index: drm_drv.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_drv.c,v
retrieving revision 1.141
diff -u -p -r1.141 drm_drv.c
--- drm_drv.c   20 Dec 2015 13:10:09 -0000      1.141
+++ drm_drv.c   30 Dec 2015 11:41:25 -0000
@@ -383,6 +383,7 @@ drm_attach(struct device *parent, struct
        dev->pdev->pc = da->pc;
        dev->bridgetag = da->bridgetag;
        dev->pdev->tag = da->tag;
+       dev->pdev->pci = (struct pci_softc *)parent->dv_parent;
 
        rw_init(&dev->struct_mutex, "drmdevlk");
        mtx_init(&dev->event_lock, IPL_TTY);
Index: drm_linux.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_linux.c,v
retrieving revision 1.5
diff -u -p -r1.5 drm_linux.c
--- drm_linux.c 26 Sep 2015 11:17:15 -0000      1.5
+++ drm_linux.c 30 Dec 2015 11:41:25 -0000
@@ -16,6 +16,7 @@
  */
 
 #include <dev/pci/drm/drmP.h>
+#include <dev/pci/ppbreg.h>
 
 struct timespec
 ns_to_timespec(const int64_t nsec)
@@ -207,3 +208,68 @@ vunmap(void *addr, size_t size)
        uvm_km_free(kernel_map, va, size);
 }
 
+#if defined(__amd64__) || defined(__i386__)
+
+extern int pci_enumerate_bus(struct pci_softc *,
+    int (*)(struct pci_attach_args *), struct pci_attach_args *);
+
+pcitag_t vga_bridge_tag;
+int vga_bridge_disabled;
+
+int
+vga_disable_bridge(struct pci_attach_args *pa)
+{
+       pcireg_t bhlc, bc;
+
+       if (pa->pa_domain != 0)
+               return 0;
+
+       bhlc = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
+       if (PCI_HDRTYPE_TYPE(bhlc) != 1)
+               return 0;
+
+       bc = pci_conf_read(pa->pa_pc, pa->pa_tag, PPB_REG_BRIDGECONTROL);
+       if ((bc & PPB_BC_VGA_ENABLE) == 0)
+               return 0;
+       bc &= ~PPB_BC_VGA_ENABLE;
+       pci_conf_write(pa->pa_pc, pa->pa_tag, PPB_REG_BRIDGECONTROL, bc);
+
+       vga_bridge_tag = pa->pa_tag;
+       vga_bridge_disabled = 1;
+
+       return 1;
+}
+
+int
+vga_enable_bridge(struct pci_attach_args *pa)
+{
+       pcireg_t bc;
+
+       if (!vga_bridge_disabled)
+               return 0;
+
+       if (pa->pa_tag != vga_bridge_tag)
+               return 0;
+
+       bc = pci_conf_read(pa->pa_pc, pa->pa_tag, PPB_REG_BRIDGECONTROL);
+       bc |= PPB_BC_VGA_ENABLE;
+       pci_conf_write(pa->pa_pc, pa->pa_tag, PPB_REG_BRIDGECONTROL, bc);
+
+       return 1;
+}
+
+void
+vga_get_uninterruptible(struct pci_dev *pdev, int rsrc)
+{
+       KASSERT(pdev->pci->sc_bridgetag == NULL);
+       pci_enumerate_bus(pdev->pci, vga_disable_bridge, NULL);
+}
+
+void
+vga_put(struct pci_dev *pdev, int rsrc)
+{
+       KASSERT(pdev->pci->sc_bridgetag == NULL);
+       pci_enumerate_bus(pdev->pci, vga_enable_bridge, NULL);
+}
+
+#endif
Index: drm_linux.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/drm_linux.h,v
retrieving revision 1.42
diff -u -p -r1.42 drm_linux.h
--- drm_linux.h 17 Oct 2015 21:41:12 -0000      1.42
+++ drm_linux.h 30 Dec 2015 11:41:25 -0000
@@ -982,6 +982,7 @@ struct pci_dev {
        uint16_t        subsystem_device;
        pci_chipset_tag_t pc;
        pcitag_t        tag;
+       struct pci_softc *pci;
 };
 #define PCI_ANY_ID (uint16_t) (~0U)
 
@@ -1078,6 +1079,11 @@ pci_dma_mapping_error(struct pci_dev *pd
 {
        return 0;
 }
+
+#define VGA_RSRC_LEGACY_IO     0x01
+
+void vga_get_uninterruptible(struct pci_dev *, int);
+void vga_put(struct pci_dev *, int);
 
 #endif
 
Index: i915/intel_display.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_display.c,v
retrieving revision 1.56
diff -u -p -r1.56 intel_display.c
--- i915/intel_display.c        25 Sep 2015 09:42:14 -0000      1.56
+++ i915/intel_display.c        30 Dec 2015 11:41:26 -0000
@@ -10904,19 +10904,19 @@ static void i915_disable_vga(struct drm_
        u8 sr1;
        u32 vga_reg = i915_vgacntrl_reg(dev);
 
-#ifdef __linux__
        vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+#ifdef __linux__
        outb(SR01, VGA_SR_INDEX);
 #else
-       outb(VGA_SR_INDEX,SR01);
+       outb(VGA_SR_INDEX, SR01);
 #endif
        sr1 = inb(VGA_SR_DATA);
 #ifdef __linux__
        outb(sr1 | 1<<5, VGA_SR_DATA);
-       vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 #else
        outb(VGA_SR_DATA, sr1 | 1<<5);
 #endif
+       vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
        udelay(300);
 
        I915_WRITE(vga_reg, VGA_DISP_DISABLE);
Index: i915/intel_pm.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/intel_pm.c,v
retrieving revision 1.39
diff -u -p -r1.39 intel_pm.c
--- i915/intel_pm.c     26 Sep 2015 19:52:16 -0000      1.39
+++ i915/intel_pm.c     30 Dec 2015 11:41:26 -0000
@@ -5216,13 +5216,13 @@ static void hsw_power_well_post_enable(s
         * sure vgacon can keep working normally without triggering interrupts
         * and error messages.
         */
-#ifdef __linux__
        vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
+#ifdef __linux__
        outb(inb(VGA_MSR_READ), VGA_MSR_WRITE);
-       vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 #else
        outb(VGA_MSR_WRITE, inb(VGA_MSR_READ));
 #endif
+       vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 
        if (IS_BROADWELL(dev)) {
                spin_lock_irqsave(&dev_priv->irq_lock, irqflags);

Reply via email to