> Date: Sun, 25 Oct 2015 15:51:54 +1100
> From: Jonathan Gray <[email protected]>
>
> On Sat, Oct 24, 2015 at 11:48:01PM +0200, Mark Kettenis wrote:
> > The diff below makes inteldrm(4) attach directly to pci(4) instead of
> > vga(1). Because inteldrm(4) depends on intagp(4), this also make
> > intagp(4) a child of inteldrm(4). Ultimately I'd like to integrate
> > intagp(4) into inteldrm(4), but that's going to be a bit more work.
> >
> > This diff is needed to make inteldrm(4) work when OpenBSD gets booted
> > by UEFI firmware. It will also make inteldrm(4) work on machines with
> > discrete graphics.
> >
> > This diff needs to be tested on a wide range of hardware. So if you
> > have a machine with inteldrm(4), please give it a shot. I'm
> > particularly interested in testing on an x40.
>
> after with serial console:
>
> inteldrm0 at pci0 dev 2 function 0 "Intel 82855GM Video" rev 0x02
> intagp0 at inteldrm0
> agp0 at intagp0: aperture at 0xe0000000, size 0x8000000
> drm0 at inteldrm0
> inteldrm0: can't map mmio space
> inteldrm1 at pci0 dev 2 function 1 "Intel 82855GM Video" rev 0x02
> intagp at inteldrm1 not configured
> drm1 at inteldrm1
> inteldrm1: couldn't map interrupt
> Memory manager not clean. Delaying takedown
The diff below should fix the issue on the x40 and similar machines
with 2nd generation Intel graphics.
Index: arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.398
diff -u -p -r1.398 GENERIC
--- arch/amd64/conf/GENERIC 30 Sep 2015 12:24:44 -0000 1.398
+++ arch/amd64/conf/GENERIC 9 Oct 2015 20:40:52 -0000
@@ -300,15 +300,16 @@ wsdisplay0 at vga? console 1
wskbd* at pckbd? mux 1
wsmouse* at pms? mux 0
-intagp* at vga? # intel integrated graphics
#mmuagp* at pchb? # amd64 mmu agp.
-
-agp* at intagp?
#agp* at mmuagp?
-inteldrm* at vga? # Intel i915, i945 DRM driver
+inteldrm* at pci? # Intel i915, i945 DRM driver
+intagp* at inteldrm?
+agp* at intagp?
drm0 at inteldrm? console 1
drm* at inteldrm?
+wsdisplay0 at inteldrm? console 1
+wsdisplay* at inteldrm?
radeondrm* at pci? # ATI Radeon DRM driver
drm0 at radeondrm? console 1
drm* at radeondrm?
Index: arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.81
diff -u -p -r1.81 files.amd64
--- arch/amd64/conf/files.amd64 4 Sep 2015 23:22:56 -0000 1.81
+++ arch/amd64/conf/files.amd64 9 Oct 2015 16:36:41 -0000
@@ -133,7 +133,7 @@ attach amas at pci
file dev/pci/amas.c amas
# AGP bridge support. most attach at pchb
-file arch/amd64/pci/agp_machdep.c agp
+file arch/amd64/pci/agp_machdep.c agp | inteldrm
#
# CARDBUS
Index: arch/i386/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/i386/conf/GENERIC,v
retrieving revision 1.807
diff -u -p -r1.807 GENERIC
--- arch/i386/conf/GENERIC 25 Oct 2015 19:32:33 -0000 1.807
+++ arch/i386/conf/GENERIC 25 Oct 2015 20:21:06 -0000
@@ -358,7 +358,6 @@ wsdisplay0 at pcdisplay? console 1
wskbd* at pckbd? mux 1
wsmouse* at pms? mux 0
-intagp* at vga? # intel integrated graphics agp
aliagp* at pchb?
amdagp* at pchb?
intelagp* at pchb?
@@ -366,7 +365,6 @@ sisagp* at pchb?
viaagp* at pchb?
#mmuagp* at pchb?
-agp* at intagp? # AGP bridges
agp* at aliagp? # AGP bridges
agp* at amdagp? # AGP bridges
agp* at intelagp? # AGP bridges
@@ -374,9 +372,13 @@ agp* at sisagp? # AGP bridges
agp* at viaagp? # AGP bridges
#agp* at mmuagp?
-inteldrm* at vga? # Intel i915, i945 DRM driver
+inteldrm* at pci? # Intel i915, i945 DRM driver
+intagp* at inteldrm?
+agp* at intagp?
drm0 at inteldrm? console 1
drm* at inteldrm?
+wsdisplay0 at inteldrm? console 1
+wsdisplay* at inteldrm?
radeondrm* at pci? # ATI Radeon DRM driver
drm0 at radeondrm? console 1
drm* at radeondrm?
Index: arch/i386/conf/files.i386
===================================================================
RCS file: /cvs/src/sys/arch/i386/conf/files.i386,v
retrieving revision 1.226
diff -u -p -r1.226 files.i386
--- arch/i386/conf/files.i386 20 Aug 2015 04:41:46 -0000 1.226
+++ arch/i386/conf/files.i386 24 Oct 2015 21:28:00 -0000
@@ -113,7 +113,7 @@ attach amas at pci
file dev/pci/amas.c amas
# AGP bridge support. most attach at pchb
-file arch/i386/pci/agp_machdep.c agp
+file arch/i386/pci/agp_machdep.c agp | inteldrm
# AMD Elan SC520 System Controller (PCI-Host bridge)
device elansc: gpiobus
Index: dev/pci/agp_i810.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/agp_i810.c,v
retrieving revision 1.91
diff -u -p -r1.91 agp_i810.c
--- dev/pci/agp_i810.c 9 Oct 2015 13:22:54 -0000 1.91
+++ dev/pci/agp_i810.c 24 Oct 2015 21:17:05 -0000
@@ -43,11 +43,7 @@
#include <dev/pci/pcidevs.h>
#include <dev/pci/agpvar.h>
#include <dev/pci/agpreg.h>
-#include <dev/ic/mc6845reg.h>
-#include <dev/ic/pcdisplayvar.h>
-#include <dev/ic/vgareg.h>
-#include <dev/ic/vgavar.h>
-#include <dev/pci/vga_pcivar.h>
+#include <dev/pci/drm/i915/i915_drv.h>
#include <machine/bus.h>
@@ -84,7 +80,9 @@ struct agp_i810_softc {
struct agp_softc *agpdev;
struct agp_gatt *gatt;
struct vga_pci_bar *map;
- struct vga_pci_bar *gtt_map;
+ bus_space_tag_t gtt_bst;
+ bus_space_handle_t gtt_bsh;
+ bus_size_t gtt_size;
bus_dmamap_t scrib_dmamap;
bus_addr_t isc_apaddr;
bus_size_t isc_apsize; /* current aperture size */
@@ -241,8 +239,9 @@ agp_i810_attach(struct device *parent, s
struct agp_i810_softc *isc = (struct agp_i810_softc *)self;
struct agp_gatt *gatt;
struct pci_attach_args *pa = aux, bpa;
- struct vga_pci_softc *vga = (struct vga_pci_softc *)parent;
+ struct inteldrm_softc *psc = (struct inteldrm_softc *)parent;
bus_addr_t mmaddr, gmaddr, tmp;
+ bus_size_t gtt_off = 0;
pcireg_t memtype, reg;
u_int32_t stolen;
u_int16_t gcc1;
@@ -263,11 +262,16 @@ agp_i810_attach(struct device *parent, s
gmaddr = AGP_I965_GMADR;
mmaddr = AGP_I965_MMADR;
memtype = PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT;
+ if (isc->chiptype == CHIP_I965)
+ gtt_off = AGP_I965_GTT;
+ else
+ gtt_off = AGP_G4X_GTT;
break;
default:
gmaddr = AGP_APBASE;
mmaddr = AGP_I810_MMADR;
memtype = PCI_MAPREG_TYPE_MEM;
+ gtt_off = AGP_I810_GTT;
break;
}
@@ -277,20 +281,31 @@ agp_i810_attach(struct device *parent, s
return;
}
- isc->map = vga_pci_bar_map(vga, mmaddr, 0, BUS_SPACE_MAP_LINEAR);
- if (isc->map == NULL) {
+ isc->map = psc->regs;
+ if (pci_mapreg_map(pa, mmaddr, memtype, BUS_SPACE_MAP_LINEAR,
+ &isc->map->bst, &isc->map->bsh, &isc->map->base,
+ &isc->map->size, gtt_off)) {
printf("can't map mmadr registers\n");
return;
}
if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33 ||
isc->chiptype == CHIP_PINEVIEW) {
- isc->gtt_map = vga_pci_bar_map(vga, AGP_I915_GTTADR, 0,
- BUS_SPACE_MAP_LINEAR);
- if (isc->gtt_map == NULL) {
+ if (pci_mapreg_map(pa, AGP_I915_GTTADR, memtype,
+ BUS_SPACE_MAP_LINEAR, &isc->gtt_bst, &isc->gtt_bsh,
+ NULL, &isc->gtt_size, 0)) {
printf("can't map gatt registers\n");
goto out;
}
+ } else {
+ isc->gtt_bst = isc->map->bst;
+ isc->gtt_size = (isc->isc_apsize >> AGP_PAGE_SHIFT) * 4;
+ if (bus_space_map(isc->gtt_bst, isc->map->base + gtt_off,
+ isc->gtt_size, BUS_SPACE_MAP_LINEAR, &isc->gtt_bsh)) {
+ printf("can't map gatt registers\n");
+ isc->gtt_size = 0;
+ goto out;
+ }
}
gatt = malloc(sizeof(*gatt), M_AGP, M_NOWAIT | M_ZERO);
@@ -512,6 +527,7 @@ agp_i810_attach(struct device *parent, s
isc->agpdev = (struct agp_softc *)agp_attach_bus(pa, &agp_i810_methods,
isc->isc_apaddr, isc->isc_apsize, &isc->dev);
isc->agpdev->sc_stolen_entries = isc->stolen;
+ bus_space_unmap(isc->map->bst, isc->map->bsh, isc->map->size);
return;
out:
@@ -521,10 +537,10 @@ out:
isc->gatt->ag_dmamap, &isc->gatt->ag_dmaseg);
free(isc->gatt, M_AGP, sizeof (*isc->gatt));
}
- if (isc->gtt_map != NULL)
- vga_pci_bar_unmap(isc->gtt_map);
- if (isc->map != NULL)
- vga_pci_bar_unmap(isc->map);
+ if (isc->gtt_size != 0)
+ bus_space_unmap(isc->gtt_bst, isc->gtt_bsh, isc->gtt_size);
+ if (isc->map->size != 0)
+ bus_space_unmap(isc->map->bst, isc->map->bsh, isc->map->size);
}
int
@@ -777,7 +793,7 @@ void
intagp_write_gtt(struct agp_i810_softc *isc, bus_size_t off, paddr_t v)
{
u_int32_t pte = 0;
- bus_size_t baseoff, wroff;
+ bus_size_t wroff;
if (isc->chiptype != CHIP_I810 &&
(off >> AGP_PAGE_SHIFT) < isc->stolen) {
@@ -800,25 +816,5 @@ intagp_write_gtt(struct agp_i810_softc *
}
wroff = (off >> AGP_PAGE_SHIFT) * 4;
-
- switch(isc->chiptype) {
- case CHIP_I915:
- /* FALLTHROUGH */
- case CHIP_G33:
- case CHIP_PINEVIEW:
- bus_space_write_4(isc->gtt_map->bst, isc->gtt_map->bsh,
- wroff, pte);
- return;
- case CHIP_I965:
- baseoff = AGP_I965_GTT;
- break;
- case CHIP_G4X:
- case CHIP_IRONLAKE:
- baseoff = AGP_G4X_GTT;
- break;
- default:
- baseoff = AGP_I810_GTT;
- break;
- }
- bus_space_write_4(isc->map->bst, isc->map->bsh, baseoff + wroff, pte);
+ bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, wroff, pte);
}
Index: dev/pci/drm/files.drm
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/files.drm,v
retrieving revision 1.33
diff -u -p -r1.33 files.drm
--- dev/pci/drm/files.drm 23 Sep 2015 23:12:11 -0000 1.33
+++ dev/pci/drm/files.drm 9 Oct 2015 20:43:10 -0000
@@ -35,8 +35,8 @@ file dev/pci/drm/ttm/ttm_object.c ttm
file dev/pci/drm/ttm/ttm_page_alloc.c ttm
file dev/pci/drm/ttm/ttm_tt.c ttm
-device inteldrm: drmbase, wsemuldisplaydev, rasops32, i2cbus, i2c_bitbang
-attach inteldrm at drmdev
+device inteldrm: agpint, drmbase, wsemuldisplaydev, rasops32, i2cbus,
i2c_bitbang
+attach inteldrm at pci
file dev/pci/drm/i915/i915_dma.c inteldrm
file dev/pci/drm/i915/i915_drv.c inteldrm
file dev/pci/drm/i915/i915_gem.c inteldrm
Index: dev/pci/drm/i915/i915_drv.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.c,v
retrieving revision 1.94
diff -u -p -r1.94 i915_drv.c
--- dev/pci/drm/i915/i915_drv.c 17 Oct 2015 21:41:12 -0000 1.94
+++ dev/pci/drm/i915/i915_drv.c 25 Oct 2015 19:51:02 -0000
@@ -497,7 +497,11 @@ i915_get_device_id(int device)
int
inteldrm_probe(struct device *parent, void *match, void *aux)
{
- return (drm_pciprobe((struct pci_attach_args *)aux, pciidlist));
+ struct pci_attach_args *pa = aux;
+
+ if (drm_pciprobe(aux, pciidlist) && pa->pa_function == 0)
+ return 20;
+ return 0;
}
static int
@@ -954,6 +958,12 @@ int i915_reset(struct drm_device *dev)
return 0;
}
+#include "intagp.h"
+
+#if NINTAGP > 0
+int intagpsubmatch(struct device *, void *, void *);
+int intagp_print(void *, const char *);
+#endif
int inteldrm_wsioctl(void *, u_long, caddr_t, int, struct proc *);
paddr_t inteldrm_wsmmap(void *, off_t, int);
@@ -1183,18 +1193,27 @@ void
inteldrm_attach(struct device *parent, struct device *self, void *aux)
{
struct inteldrm_softc *dev_priv = (struct inteldrm_softc *)self;
- struct vga_pci_softc *vga_sc = (struct vga_pci_softc *)parent;
struct pci_attach_args *pa = aux;
struct rasops_info *ri = &dev_priv->ro;
struct wsemuldisplaydev_attach_args aa;
- extern int wsdisplay_console_initted;
- struct vga_pci_bar *bar;
+ extern int vga_console_attached;
struct drm_device *dev;
const struct intel_device_info *info;
int ret = 0, mmio_bar, mmio_size;
+ pcireg_t mmio_type;
uint32_t aperture_size;
+ int console = 0;
int i;
+ if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
+ PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA &&
+ (pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG)
+ & (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE))
+ == (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) {
+ console = 1;
+ vga_console_attached = 1;
+ }
+
info = i915_get_device_id(PCI_PRODUCT(pa->pa_id));
KASSERT(info->gen != 0);
@@ -1205,17 +1224,23 @@ inteldrm_attach(struct device *parent, s
dev_priv->dmat = pa->pa_dmat;
dev_priv->bst = pa->pa_memt;
dev_priv->memex = pa->pa_memex;
+ dev_priv->regs = &dev_priv->bar;
printf("\n");
if (dev_priv->info->gen >= 6)
inteldrm_driver.flags &= ~(DRIVER_AGP | DRIVER_AGP_REQUIRE);
+#if NINTAGP > 0
+ else {
+ config_found_sm(self, aux, intagp_print, intagpsubmatch);
+ }
+#endif
inteldrm_driver.num_ioctls = i915_max_ioctl;
/* All intel chipsets need to be treated as agp, so just pass one */
dev = dev_priv->dev = (struct drm_device *)
- drm_attach_pci(&inteldrm_driver, pa, 1, 1, self);
+ drm_attach_pci(&inteldrm_driver, pa, 1, console, self);
intel_gtt_chipset_setup(dev);
mtx_init(&mchdev_lock, IPL_TTY);
@@ -1262,16 +1287,15 @@ inteldrm_attach(struct device *parent, s
else
mmio_size = 2*1024*1024;
- /* we need to use this api for now due to sharing with intagp */
- bar = vga_pci_bar_info(vga_sc, mmio_bar);
- if (bar == NULL) {
- printf("%s: can't get BAR info\n",
- dev_priv->sc_dev.dv_xname);
- goto free_priv;
- }
-
- dev_priv->regs = vga_pci_bar_map(vga_sc, bar->addr, mmio_size, 0);
- if (dev_priv->regs == NULL) {
+ /* XXX */
+ if (info->gen < 3)
+ mmio_size = 64*1024;
+
+ mmio_bar = 0x10 + mmio_bar * 0x04;
+ mmio_type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, mmio_bar);
+ if (pci_mapreg_map(pa, mmio_bar, mmio_type, 0, &dev_priv->regs->bst,
+ &dev_priv->regs->bsh, &dev_priv->regs->base,
+ &dev_priv->regs->size, mmio_size)) {
printf("%s: can't map mmio space\n",
dev_priv->sc_dev.dv_xname);
goto free_priv;
@@ -1473,23 +1497,22 @@ inteldrm_attach(struct device *parent, s
inteldrm_stdscreen.fontwidth = ri->ri_font->fontwidth;
inteldrm_stdscreen.fontheight = ri->ri_font->fontheight;
- aa.console = 0;
+ aa.console = console;
aa.scrdata = &inteldrm_screenlist;
aa.accessops = &inteldrm_accessops;
aa.accesscookie = dev_priv;
aa.defaultscreens = 0;
- if (wsdisplay_console_initted) {
+ if (console) {
long defattr;
ri->ri_ops.alloc_attr(ri->ri_active, 0, 0, 0, &defattr);
wsdisplay_cnattach(&inteldrm_stdscreen, ri->ri_active,
0, 0, defattr);
- aa.console = 1;
}
- vga_sc->sc_type = -1;
- config_found(parent, &aa, wsemuldisplaydevprint);
+ config_found_sm(self, &aa, wsemuldisplaydevprint,
+ wsemuldisplaydevsubmatch);
return;
out_power_well:
@@ -1524,7 +1547,8 @@ out_regs:
#ifdef __linux__
pci_iounmap(dev->pdev, dev_priv->regs);
#else
- vga_pci_bar_unmap(dev_priv->regs);
+ bus_space_unmap(dev_priv->regs->bst, dev_priv->regs->bsh,
+ dev_priv->regs->size);
#endif
free_priv:
dev->dev_private = NULL;
@@ -1556,7 +1580,8 @@ inteldrm_detach(struct device *self, int
pci_intr_disestablish(dev_priv->pc, dev_priv->irqh);
if (dev_priv->regs != NULL)
- vga_pci_bar_unmap(dev_priv->regs);
+ bus_space_unmap(dev_priv->regs->bst, dev_priv->regs->bsh,
+ dev_priv->regs->size);
return (0);
}
Index: dev/pci/drm/i915/i915_drv.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.h,v
retrieving revision 1.70
diff -u -p -r1.70 i915_drv.h
--- dev/pci/drm/i915/i915_drv.h 17 Oct 2015 21:41:12 -0000 1.70
+++ dev/pci/drm/i915/i915_drv.h 24 Oct 2015 20:42:44 -0000
@@ -1457,6 +1457,7 @@ typedef struct inteldrm_softc {
pci_intr_handle_t ih;
void *irqh;
+ struct vga_pci_bar bar;
struct vga_pci_bar *regs;
int nscreens;