> 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);