summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2019-05-04 11:34:49 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2019-05-04 11:34:49 +0000
commitf5574b4a644211fe7709234b1b9ed715099e02a7 (patch)
tree01d4f0baa026101a4c304df9a928193d69293bdd /sys/dev/pci
parent4ed7a9910f2e75595c48e6cff73d3964a8de4c77 (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.c14
-rw-r--r--sys/dev/pci/drm/files.drm4
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.c47
-rw-r--r--sys/dev/pci/drm/i915/i915_drv.h1
-rw-r--r--sys/dev/pci/drm/include/drm/drmP.h11
-rw-r--r--sys/dev/pci/drm/radeon/radeon.h1
-rw-r--r--sys/dev/pci/drm/radeon/radeon_kms.c29
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;