> Date: Sun, 25 Oct 2015 15:51:54 +1100 > From: Jonathan Gray <j...@jsg.id.au> > > 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;