diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-05-04 11:34:49 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-05-04 11:34:49 +0000 |
commit | f5574b4a644211fe7709234b1b9ed715099e02a7 (patch) | |
tree | 01d4f0baa026101a4c304df9a928193d69293bdd /sys/dev/pci | |
parent | 4ed7a9910f2e75595c48e6cff73d3964a8de4c77 (diff) |
Improve the interaction between efifb(4), inteldrm(4) and radeondrm(4)
when we have a serial console by introducing the notion of a "primary"
graphics device. The primary graphics device is the one set up and
used by firmware (BIOS, UEFI).
The goal is to make sure that wsdisplay0 and drm0 reliably attach to
the primary graphics device such that X works out of the box even
if you have multiple cards or if you are using a serial console.
This also fixes the situation where inteldrm(4) or radeondrm(4) would
take over the console on UEFI systems even if the kernel was booted
with a serial console.
ok jsg@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 14 | ||||
-rw-r--r-- | sys/dev/pci/drm/files.drm | 4 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.c | 47 | ||||
-rw-r--r-- | sys/dev/pci/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/include/drm/drmP.h | 11 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon.h | 1 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_kms.c | 29 |
7 files changed, 74 insertions, 33 deletions
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index aed8d64de7c..0a2211ac1c3 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_drv.c,v 1.161 2019/05/02 09:47:16 kettenis Exp $ */ +/* $OpenBSD: drm_drv.c,v 1.162 2019/05/04 11:34:47 kettenis Exp $ */ /*- * Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org> * Copyright © 2008 Intel Corporation @@ -98,7 +98,7 @@ SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp); */ struct drm_device * drm_attach_pci(struct drm_driver *driver, struct pci_attach_args *pa, - int is_agp, int console, struct device *dev, struct drm_device *drm) + int is_agp, int primary, struct device *dev, struct drm_device *drm) { struct drm_attach_args arg; struct drm_softc *sc; @@ -109,7 +109,7 @@ drm_attach_pci(struct drm_driver *driver, struct pci_attach_args *pa, arg.dmat = pa->pa_dmat; arg.bst = pa->pa_memt; arg.is_agp = is_agp; - arg.console = console; + arg.primary = primary; arg.pci_vendor = PCI_VENDOR(pa->pa_id); arg.pci_device = PCI_PRODUCT(pa->pa_id); @@ -180,18 +180,18 @@ drm_probe(struct device *parent, void *match, void *aux) struct cfdata *cf = match; struct drm_attach_args *da = aux; - if (cf->drmdevcf_console != DRMDEVCF_CONSOLE_UNK) { + if (cf->drmdevcf_primary != DRMDEVCF_PRIMARY_UNK) { /* - * If console-ness of device specified, either match + * If primary-ness of device specified, either match * exactly (at high priority), or fail. */ - if (cf->drmdevcf_console != 0 && da->console != 0) + if (cf->drmdevcf_primary != 0 && da->primary != 0) return (10); else return (0); } - /* If console-ness unspecified, it wins. */ + /* If primary-ness unspecified, it wins. */ return (1); } diff --git a/sys/dev/pci/drm/files.drm b/sys/dev/pci/drm/files.drm index 3538bcd9d3d..4128ae94672 100644 --- a/sys/dev/pci/drm/files.drm +++ b/sys/dev/pci/drm/files.drm @@ -1,8 +1,8 @@ # $NetBSD: files.drm,v 1.2 2007/03/28 11:29:37 jmcneill Exp $ -# $OpenBSD: files.drm,v 1.43 2019/04/14 10:14:51 jsg Exp $ +# $OpenBSD: files.drm,v 1.44 2019/05/04 11:34:47 kettenis Exp $ # direct rendering modules -define drmbase {[console = -1]} +define drmbase {[primary = -1]} device drm: drmbase attach drm at drmbase file dev/pci/drm/drm_agpsupport.c drm & agp diff --git a/sys/dev/pci/drm/i915/i915_drv.c b/sys/dev/pci/drm/i915/i915_drv.c index 67f9b15ba09..94328f76178 100644 --- a/sys/dev/pci/drm/i915/i915_drv.c +++ b/sys/dev/pci/drm/i915/i915_drv.c @@ -3106,6 +3106,7 @@ static struct drm_driver driver = { #ifdef __amd64__ #include "efifb.h" +#include <machine/biosvar.h> #endif #if NEFIFB > 0 @@ -3432,11 +3433,18 @@ struct cfdriver inteldrm_cd = { void inteldrm_init_backlight(struct inteldrm_softc *); int inteldrm_intr(void *); +/* + * Set if the mountroot hook has a fatal error. + */ +int inteldrm_fatal_error; + int inteldrm_match(struct device *parent, void *match, void *aux) { struct pci_attach_args *pa = aux; + if (inteldrm_fatal_error) + return 0; if (drm_pciprobe(aux, pciidlist) && pa->pa_function == 0) return 20; return 0; @@ -3468,20 +3476,22 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) (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)) { + dev_priv->primary = 1; + dev_priv->console = vga_is_console(pa->pa_iot, -1);; vga_console_attached = 1; - dev_priv->console = 1; } #if NEFIFB > 0 - if (efifb_is_console(pa)) { - dev_priv->console = 1; - efifb_cndetach(); + if (efifb_is_primary(pa)) { + dev_priv->primary = 1; + dev_priv->console = efifb_is_console(pa); + efifb_detach(); } #endif printf("\n"); - dev = drm_attach_pci(&driver, pa, 0, dev_priv->console, + dev = drm_attach_pci(&driver, pa, 0, dev_priv->primary, self, &dev_priv->drm); id = drm_find_description(PCI_VENDOR(pa->pa_id), @@ -3561,6 +3571,24 @@ inteldrm_attach(struct device *parent, struct device *self, void *aux) } void +inteldrm_forcedetach(struct inteldrm_softc *dev_priv) +{ + struct pci_softc *psc = (struct pci_softc *)dev_priv->sc_dev.dv_parent; + pcitag_t tag = dev_priv->tag; + extern int vga_console_attached; + + if (dev_priv->primary) { + vga_console_attached = 0; +#if NEFIFB > 0 + efifb_reattach(); +#endif + } + + config_detach(&dev_priv->sc_dev, 0); + pci_probe_device(psc, tag, NULL, NULL); +} + +void inteldrm_attachhook(struct device *self) { struct inteldrm_softc *dev_priv = (struct inteldrm_softc *)self; @@ -3570,10 +3598,10 @@ inteldrm_attachhook(struct device *self) struct drm_device *dev = &dev_priv->drm; if (i915_driver_load(dev_priv, id)) - return; + goto fail; if (ri->ri_bits == NULL) - return; + goto fail; printf("%s: %dx%d, %dbpp\n", dev_priv->sc_dev.dv_xname, ri->ri_width, ri->ri_height, ri->ri_depth); @@ -3615,6 +3643,7 @@ inteldrm_attachhook(struct device *self) inteldrm_stdscreen.fontheight = ri->ri_font->fontheight; aa.console = dev_priv->console; + aa.primary = dev_priv->primary; aa.scrdata = &inteldrm_screenlist; aa.accessops = &inteldrm_accessops; aa.accesscookie = dev_priv; @@ -3638,6 +3667,10 @@ inteldrm_attachhook(struct device *self) config_found_sm(self, &aa, wsemuldisplaydevprint, wsemuldisplaydevsubmatch); return; + +fail: + inteldrm_fatal_error = 1; + inteldrm_forcedetach(dev_priv); } int diff --git a/sys/dev/pci/drm/i915/i915_drv.h b/sys/dev/pci/drm/i915/i915_drv.h index 3e0aac63a02..3e4606d04f6 100644 --- a/sys/dev/pci/drm/i915/i915_drv.h +++ b/sys/dev/pci/drm/i915/i915_drv.h @@ -1721,6 +1721,7 @@ struct inteldrm_softc { struct drm_pcidev *id; int console; + int primary; int nscreens; void (*switchcb)(void *, int, int); void *switchcbarg; diff --git a/sys/dev/pci/drm/include/drm/drmP.h b/sys/dev/pci/drm/include/drm/drmP.h index 080f74426e0..3e388f34bae 100644 --- a/sys/dev/pci/drm/include/drm/drmP.h +++ b/sys/dev/pci/drm/include/drm/drmP.h @@ -1,4 +1,4 @@ -/* $OpenBSD: drmP.h,v 1.1 2019/04/14 10:14:52 jsg Exp $ */ +/* $OpenBSD: drmP.h,v 1.2 2019/05/04 11:34:48 kettenis Exp $ */ /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com */ @@ -239,13 +239,12 @@ struct drm_attach_args { pci_chipset_tag_t pc; pcitag_t tag; pcitag_t *bridgetag; - int console; + int primary; }; -#define DRMDEVCF_CONSOLE 0 -#define drmdevcf_console cf_loc[DRMDEVCF_CONSOLE] -/* spec'd as console? */ -#define DRMDEVCF_CONSOLE_UNK -1 +#define DRMDEVCF_PRIMARY 0 +#define drmdevcf_primary cf_loc[DRMDEVCF_PRIMARY] /* spec'd as primary? */ +#define DRMDEVCF_PRIMARY_UNK -1 extern int drm_debug_flag; diff --git a/sys/dev/pci/drm/radeon/radeon.h b/sys/dev/pci/drm/radeon/radeon.h index 595543c4fbe..fe098d02de3 100644 --- a/sys/dev/pci/drm/radeon/radeon.h +++ b/sys/dev/pci/drm/radeon/radeon.h @@ -2341,6 +2341,7 @@ struct radeon_device { struct task switchtask; struct rasops_info ro; int console; + int primary; struct task burner_task; int burner_fblank; diff --git a/sys/dev/pci/drm/radeon/radeon_kms.c b/sys/dev/pci/drm/radeon/radeon_kms.c index 3fb81fa4222..a12106fcbbe 100644 --- a/sys/dev/pci/drm/radeon/radeon_kms.c +++ b/sys/dev/pci/drm/radeon/radeon_kms.c @@ -45,6 +45,11 @@ static inline bool radeon_has_atpx(void) { return false; } #include "vga.h" #if NVGA > 0 +#include <dev/ic/mc6845reg.h> +#include <dev/ic/pcdisplayvar.h> +#include <dev/ic/vgareg.h> +#include <dev/ic/vgavar.h> + extern int vga_console_attached; #endif @@ -484,22 +489,25 @@ radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) #if defined(__sparc64__) || defined(__macppc__) if (fbnode == PCITAG_NODE(rdev->pa_tag)) - rdev->console = 1; + rdev->console = rdev->primary = 1; #else 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)) { - rdev->console = 1; + rdev->primary = 1; #if NVGA > 0 + rdev->console = vga_is_console(pa->pa_iot, -1); vga_console_attached = 1; #endif } + #if NEFIFB > 0 - if (efifb_is_console(pa)) { - rdev->console = 1; - efifb_cndetach(); + if (efifb_is_primary(pa)) { + rdev->primary = 1; + rdev->console = efifb_is_console(pa); + efifb_detach(); } #endif #endif @@ -628,7 +636,7 @@ radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) kms_driver.num_ioctls = radeon_max_kms_ioctl; kms_driver.driver_features |= DRIVER_MODESET; - dev = drm_attach_pci(&kms_driver, pa, is_agp, rdev->console, + dev = drm_attach_pci(&kms_driver, pa, is_agp, rdev->primary, self, NULL); rdev->ddev = dev; rdev->pdev = dev->pdev; @@ -696,8 +704,6 @@ radeondrm_attach_kms(struct device *parent, struct device *self, void *aux) config_mountroot(self, radeondrm_attachhook); } -extern void mainbus_efifb_reattach(void); - int radeondrm_forcedetach(struct radeon_device *rdev) { @@ -705,7 +711,7 @@ radeondrm_forcedetach(struct radeon_device *rdev) pcitag_t tag = rdev->pa_tag; #if NVGA > 0 - if (rdev->console) + if (rdev->primary) vga_console_attached = 0; #endif @@ -716,8 +722,8 @@ radeondrm_forcedetach(struct radeon_device *rdev) config_detach(&rdev->self, 0); return pci_probe_device(sc, tag, NULL, NULL); #if NEFIFB > 0 - } else if (rdev->console) { - mainbus_efifb_reattach(); + } else if (rdev->primary) { + efifb_reattach(); } #endif @@ -807,6 +813,7 @@ radeondrm_attachhook(struct device *self) radeondrm_stdscreen.fontheight = ri->ri_font->fontheight; aa.console = rdev->console; + aa.primary = rdev->primary; aa.scrdata = &radeondrm_screenlist; aa.accessops = &radeondrm_accessops; aa.accesscookie = ri; |