tech-x11 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Fix for kern/54274: firmware loading issue in nouveau driver



Hi!

I've remodeled the nouveau attach routine to match the one used by the
radeon driver, to address PR 54274.

The attached diff changes the dmesg output like this (and moves all
the nouveau lines around because most of the attachment happens much
later):

--- before      2019-07-03 09:41:04.000000000 +0200
+++ after       2019-07-03 09:41:28.000000000 +0200
@@ -1,11 +1,10 @@
 nouveau0: info: NVIDIA GM206 (126010a1)
 nouveau0: info: bios: version 84.06.14.00.ff
 nouveau0: info: gr: using external firmware
-firmware_open(nouveau/nvidia/gm206/fecs_inst.bin) called too early.
 nouveau0: autoconfiguration error: error: gr: failed to load fecs_inst
 nouveau0: notice: disp: dcb 15 type 8 unknown
 nouveau0: info: fb: 4096 MiB GDDR5
-Zone  kernel: Available graphics memory: 46177220 kiB
+Zone  kernel: Available graphics memory: 46167654 kiB
 Zone   dma32: Available graphics memory: 2097152 kiB
 nouveau0: info: DRM: VRAM: 4096 MiB
 nouveau0: info: DRM: GART: 1048576 MiB
@@ -35,6 +34,6 @@
 kern info: [drm] Driver supports precise vblank timestamp query.
 nouveau0: info: DRM: MM: using COPY for buffer copies
 nouveaufb0 at nouveau0
-nouveaufb0: framebuffer at 0xffff870908ef4000, size 1920x1080, depth 32, stride 7680
-wsdisplay0 at nouveaufb0 kbdmux 1: console (default, vt100 emulation)
+nouveaufb0: framebuffer at 0xffffcf0909fb2000, size 1920x1080, depth 32, stride 7680
+wsdisplay0 at nouveaufb0 kbdmux 1: console (default, vt100 emulation), using wskbd0
 wsmux1: connecting to wsdisplay0

Before you ask: All of the line reordering changes are because the
radeon driver (radeon_pci.c) does it in that order, and I didn't
change style stuff I found weird to make the two drivers match up as
closely as possible.

Ok to commit?
 Thomas
Index: nouveau_pci.c
===================================================================
RCS file: /cvsroot/src/sys/external/bsd/drm2/nouveau/nouveau_pci.c,v
retrieving revision 1.23
diff -u -r1.23 nouveau_pci.c
--- nouveau_pci.c	24 Dec 2018 08:40:33 -0000	1.23
+++ nouveau_pci.c	3 Jul 2019 07:39:18 -0000
@@ -52,6 +52,7 @@
 
 struct nouveau_pci_softc {
 	device_t		sc_dev;
+	struct pci_attach_args	sc_pa;
 	enum {
 		NOUVEAU_TASK_ATTACH,
 		NOUVEAU_TASK_WORKQUEUE,
@@ -67,6 +68,7 @@
 
 static int	nouveau_pci_match(device_t, cfdata_t, void *);
 static void	nouveau_pci_attach(device_t, device_t, void *);
+static void	nouveau_pci_attach_real(device_t);
 static int	nouveau_pci_detach(device_t, int);
 
 static bool	nouveau_pci_suspend(device_t, const pmf_qual_t *);
@@ -110,7 +112,7 @@
 	 *   0x1e80-0x1eff 	TU104
 	 *   0x1f00-0x1f7f 	TU106
 	 */
-	
+
 	if (IS_BETWEEN(0x1580, 0x15ff) ||
 	    IS_BETWEEN(0x1b00, 0x1b7f) ||
 	    IS_BETWEEN(0x1b80, 0x1bff) ||
@@ -144,22 +146,36 @@
 {
 	struct nouveau_pci_softc *const sc = device_private(self);
 	const struct pci_attach_args *const pa = aux;
-	int error;
 
 	pci_aprint_devinfo(pa, NULL);
 
-	sc->sc_dev = self;
+	if (!pmf_device_register(self, &nouveau_pci_suspend, &nouveau_pci_resume))
+		aprint_error_dev(self, "unable to establish power handler\n");
 
-	/* Initialize the Linux PCI device descriptor.  */
-	linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0);
+	/*
+	 * Trivial initialization first; the rest will come after we
+	 * have mounted the root file system and can load firmware
+	 * images.
+	 */
+	sc->sc_dev = NULL;
+	sc->sc_pa = *pa;
 
-	if (!pmf_device_register(self, &nouveau_pci_suspend,
-		&nouveau_pci_resume))
-		aprint_error_dev(self, "unable to establish power handler\n");
+	config_mountroot(self, &nouveau_pci_attach_real);
+}
+
+static void
+nouveau_pci_attach_real(device_t self)
+{
+	struct nouveau_pci_softc *const sc = device_private(self);
+	const struct pci_attach_args *const pa = &sc->sc_pa;
+	int error;
 
 	sc->sc_task_state = NOUVEAU_TASK_ATTACH;
 	SIMPLEQ_INIT(&sc->sc_task_u.attach);
 
+	/* Initialize the Linux PCI device descriptor.  */
+	linux_pci_dev_init(&sc->sc_pci_dev, self, device_parent(self), pa, 0);
+
 	/* XXX errno Linux->NetBSD */
 	error = -nvkm_device_pci_new(&sc->sc_pci_dev,
 	    nouveau_config, nouveau_debug,
@@ -168,7 +184,7 @@
 	if (error) {
 		aprint_error_dev(self, "unable to create nouveau device: %d\n",
 		    error);
-		return;
+		goto out;
 	}
 
 	/* XXX errno Linux->NetBSD */
@@ -176,7 +192,7 @@
 	    nouveau_drm_driver_pci, 0, &sc->sc_drm_dev);
 	if (error) {
 		aprint_error_dev(self, "unable to attach drm: %d\n", error);
-		return;
+		goto out;
 	}
 
 	while (!SIMPLEQ_EMPTY(&sc->sc_task_u.attach)) {
@@ -194,8 +210,10 @@
 		aprint_error_dev(self, "unable to create workqueue: %d\n",
 		    error);
 		sc->sc_task_u.workqueue = NULL;
-		return;
+		goto out;
 	}
+
+out:	sc->sc_dev = self;
 }
 
 static int
@@ -204,6 +222,10 @@
 	struct nouveau_pci_softc *const sc = device_private(self);
 	int error;
 
+	if (sc->sc_dev == NULL)
+		/* Not done attaching.  */
+		return EBUSY;
+
 	/* XXX Check for in-use before tearing it all down...  */
 	error = config_detach_children(self, flags);
 	if (error)


Home | Main Index | Thread Index | Old Index