Sun Mar 8 09:28:04 2020 UTC ()
Pull up following revision(s) (requested by mrg in ticket #1512):

	sys/external/bsd/drm2/nouveau/nouveau_pci.c: revision 1.24,1.25
	(via patch)

Improve nouveau pci attachment code so it waits for the availability of /
before trying to load firmware.
Fixes my PR 54274.

LGTM mrg

list the PCI ID range for new nvidia TU117 and TU116.

adjust the check to simply be >= 0x1580, which is the
first pciid not support.

should fix PR#54600.


(martin)
diff -r1.8.10.2 -r1.8.10.3 src/sys/external/bsd/drm2/nouveau/nouveau_pci.c

cvs diff -r1.8.10.2 -r1.8.10.3 src/sys/external/bsd/drm2/nouveau/nouveau_pci.c (expand / switch to unified diff)

--- src/sys/external/bsd/drm2/nouveau/nouveau_pci.c 2018/12/25 11:25:00 1.8.10.2
+++ src/sys/external/bsd/drm2/nouveau/nouveau_pci.c 2020/03/08 09:28:04 1.8.10.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nouveau_pci.c,v 1.8.10.2 2018/12/25 11:25:00 martin Exp $ */ 1/* $NetBSD: nouveau_pci.c,v 1.8.10.3 2020/03/08 09:28:04 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell. 8 * by Taylor R. Campbell.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,147 +20,160 @@ @@ -20,147 +20,160 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.8.10.2 2018/12/25 11:25:00 martin Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: nouveau_pci.c,v 1.8.10.3 2020/03/08 09:28:04 martin Exp $");
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/device.h> 36#include <sys/device.h>
37#include <sys/queue.h> 37#include <sys/queue.h>
38#include <sys/workqueue.h> 38#include <sys/workqueue.h>
39#include <sys/module.h> 39#include <sys/module.h>
40 40
41#include <drm/drmP.h> 41#include <drm/drmP.h>
42 42
43#include <engine/device.h> 43#include <engine/device.h>
44 44
45#include "nouveau_drm.h" 45#include "nouveau_drm.h"
46#include "nouveau_pci.h" 46#include "nouveau_pci.h"
47 47
48MODULE(MODULE_CLASS_DRIVER, nouveau_pci, "nouveau,drmkms_pci"); 48MODULE(MODULE_CLASS_DRIVER, nouveau_pci, "nouveau,drmkms_pci");
49 49
50SIMPLEQ_HEAD(nouveau_pci_task_head, nouveau_pci_task); 50SIMPLEQ_HEAD(nouveau_pci_task_head, nouveau_pci_task);
51 51
52struct nouveau_pci_softc { 52struct nouveau_pci_softc {
53 device_t sc_dev; 53 device_t sc_dev;
 54 struct pci_attach_args sc_pa;
54 enum { 55 enum {
55 NOUVEAU_TASK_ATTACH, 56 NOUVEAU_TASK_ATTACH,
56 NOUVEAU_TASK_WORKQUEUE, 57 NOUVEAU_TASK_WORKQUEUE,
57 } sc_task_state; 58 } sc_task_state;
58 union { 59 union {
59 struct workqueue *workqueue; 60 struct workqueue *workqueue;
60 struct nouveau_pci_task_head attach; 61 struct nouveau_pci_task_head attach;
61 } sc_task_u; 62 } sc_task_u;
62 struct drm_device *sc_drm_dev; 63 struct drm_device *sc_drm_dev;
63 struct pci_dev sc_pci_dev; 64 struct pci_dev sc_pci_dev;
64 struct nouveau_device *sc_nv_dev; 65 struct nouveau_device *sc_nv_dev;
65}; 66};
66 67
67static int nouveau_pci_match(device_t, cfdata_t, void *); 68static int nouveau_pci_match(device_t, cfdata_t, void *);
68static void nouveau_pci_attach(device_t, device_t, void *); 69static void nouveau_pci_attach(device_t, device_t, void *);
 70static void nouveau_pci_attach_real(device_t);
69static int nouveau_pci_detach(device_t, int); 71static int nouveau_pci_detach(device_t, int);
70 72
71static bool nouveau_pci_suspend(device_t, const pmf_qual_t *); 73static bool nouveau_pci_suspend(device_t, const pmf_qual_t *);
72static bool nouveau_pci_resume(device_t, const pmf_qual_t *); 74static bool nouveau_pci_resume(device_t, const pmf_qual_t *);
73 75
74static void nouveau_pci_task_work(struct work *, void *); 76static void nouveau_pci_task_work(struct work *, void *);
75 77
76CFATTACH_DECL_NEW(nouveau_pci, sizeof(struct nouveau_pci_softc), 78CFATTACH_DECL_NEW(nouveau_pci, sizeof(struct nouveau_pci_softc),
77 nouveau_pci_match, nouveau_pci_attach, nouveau_pci_detach, NULL); 79 nouveau_pci_match, nouveau_pci_attach, nouveau_pci_detach, NULL);
78 80
79/* Kludge to get this from nouveau_drm.c. */ 81/* Kludge to get this from nouveau_drm.c. */
80extern struct drm_driver *const nouveau_drm_driver; 82extern struct drm_driver *const nouveau_drm_driver;
81 83
82static int 84static int
83nouveau_pci_match(device_t parent, cfdata_t match, void *aux) 85nouveau_pci_match(device_t parent, cfdata_t match, void *aux)
84{ 86{
85 const struct pci_attach_args *const pa = aux; 87 const struct pci_attach_args *const pa = aux;
86 88
87 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA && 89 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA &&
88 PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS) 90 PCI_VENDOR(pa->pa_id) != PCI_VENDOR_NVIDIA_SGS)
89 return 0; 91 return 0;
90 92
91 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) 93 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
92 return 0; 94 return 0;
93 95
94#define IS_BETWEEN(x,y) \ 
95 (PCI_PRODUCT(pa->pa_id) >= (x) && PCI_PRODUCT(pa->pa_id) <= (y)) 
96 /* 96 /*
97 * NetBSD drm2 needs missing-so-far firmware for Maxwell-based cards: 97 * NetBSD 8.x drm2 doesn't support Maxwell, Pascal, Volta or Turing
98 * 0x1380-0x13bf GM107 98 * based cards:
99 */ 99 * 0x1340-0x137f GM108 [1]
100 if (IS_BETWEEN(0x1380, 0x13bf)) 100 * 0x1380-0x13bf GM107 [1]
101 return 0; 101 * 0x13c0-0x13ff GM204
102 102 * 0x1400-0x147f GM206
103 /* 
104 * NetBSD drm2 doesn't support Pascal, Volta or Turing based cards: 
105 * 0x1580-0x15ff GP100 103 * 0x1580-0x15ff GP100
106 * 0x1b00-0x1b7f GP102 104 * 0x1b00-0x1b7f GP102
107 * 0x1b80-0x1bff GP104 105 * 0x1b80-0x1bff GP104
108 * 0x1c00-0x1c7f GP106 106 * 0x1c00-0x1c7f GP106
109 * 0x1c80-0x1cff GP107 107 * 0x1c80-0x1cff GP107
110 * 0x1d00-0x1d7f GP108 108 * 0x1d00-0x1d7f GP108
111 * 0x1d80-0x1dff GV100 109 * 0x1d80-0x1dff GV100
112 * 0x1e00-0x1e7f TU102 110 * 0x1e00-0x1e7f TU102
113 * 0x1e80-0x1eff TU104 111 * 0x1e80-0x1eff TU104
114 * 0x1f00-0x1f7f TU106 112 * 0x1f00-0x1f7f TU106
 113 * 0x1f80-0x1fff TU117
 114 * 0x2180-0x21ff TU116
 115 *
 116 * [1] GM107/GM108 may work if firmware files are provided.
 117 * There are Windows and Linux methods to extract them, but they
 118 * are not readily available. NetBSD-9 drm works.
 119 *
 120 * reduce this to >= 1300, so that new chipsets not explictly
 121 * listed above will be picked up.
 122 *
 123 * XXX perhaps switch this to explicitly match known list.
115 */ 124 */
116  125 if (PCI_PRODUCT(pa->pa_id) >= 0x1300)
117 if (IS_BETWEEN(0x1580, 0x15ff) || 
118 IS_BETWEEN(0x1b00, 0x1b7f) || 
119 IS_BETWEEN(0x1b80, 0x1bff) || 
120 IS_BETWEEN(0x1c00, 0x1c7f) || 
121 IS_BETWEEN(0x1c80, 0x1cff) || 
122 IS_BETWEEN(0x1d00, 0x1d7f) || 
123 IS_BETWEEN(0x1d80, 0x1dff) || 
124 IS_BETWEEN(0x1e00, 0x1e7f) || 
125 IS_BETWEEN(0x1e80, 0x1eff) || 
126 IS_BETWEEN(0x1f00, 0x1f7f)) 
127 return 0; 126 return 0;
128#undef IS_BETWEEN 
129 127
130 return 6; /* XXX Beat genfb_pci... */ 128 return 6; /* XXX Beat genfb_pci... */
131} 129}
132 130
133extern char *nouveau_config; 131extern char *nouveau_config;
134extern char *nouveau_debug; 132extern char *nouveau_debug;
135 133
136static void 134static void
137nouveau_pci_attach(device_t parent, device_t self, void *aux) 135nouveau_pci_attach(device_t parent, device_t self, void *aux)
138{ 136{
139 struct nouveau_pci_softc *const sc = device_private(self); 137 struct nouveau_pci_softc *const sc = device_private(self);
140 const struct pci_attach_args *const pa = aux; 138 const struct pci_attach_args *const pa = aux;
141 uint64_t devname; 
142 int error; 
143 139
144 pci_aprint_devinfo(pa, NULL); 140 pci_aprint_devinfo(pa, NULL);
145 141
146 sc->sc_dev = self; 142 if (!pmf_device_register(self, &nouveau_pci_suspend, &nouveau_pci_resume))
147 
148 if (!pmf_device_register(self, &nouveau_pci_suspend, 
149 &nouveau_pci_resume)) 
150 aprint_error_dev(self, "unable to establish power handler\n"); 143 aprint_error_dev(self, "unable to establish power handler\n");
151 144
152 sc->sc_task_state = NOUVEAU_TASK_ATTACH; 145 /*
153 SIMPLEQ_INIT(&sc->sc_task_u.attach); 146 * Trivial initialization first; the rest will come after we
 147 * have mounted the root file system and can load firmware
 148 * images.
 149 */
 150 sc->sc_dev = NULL;
 151 sc->sc_pa = *pa;
 152
 153 config_mountroot(self, &nouveau_pci_attach_real);
 154}
 155
 156static void
 157nouveau_pci_attach_real(device_t self)
 158{
 159 struct nouveau_pci_softc *const sc = device_private(self);
 160 const struct pci_attach_args *const pa = &sc->sc_pa;
 161 uint64_t devname;
 162 int error;
 163
 164 sc->sc_dev = self;
 165 sc->sc_task_state = NOUVEAU_TASK_ATTACH;
 166 SIMPLEQ_INIT(&sc->sc_task_u.attach);
154 167
155 devname = (uint64_t)device_unit(device_parent(self)) << 32; 168 devname = (uint64_t)device_unit(device_parent(self)) << 32;
156 devname |= pa->pa_bus << 16; 169 devname |= pa->pa_bus << 16;
157 /* XXX errno Linux->NetBSD */ 170 /* XXX errno Linux->NetBSD */
158 error = -nouveau_device_create(&sc->sc_pci_dev, NOUVEAU_BUS_PCI, 171 error = -nouveau_device_create(&sc->sc_pci_dev, NOUVEAU_BUS_PCI,
159 devname, device_xname(self), nouveau_config, nouveau_debug, 172 devname, device_xname(self), nouveau_config, nouveau_debug,
160 &sc->sc_nv_dev); 173 &sc->sc_nv_dev);
161 if (error) { 174 if (error) {
162 aprint_error_dev(self, "unable to create nouveau device: %d\n", 175 aprint_error_dev(self, "unable to create nouveau device: %d\n",
163 error); 176 error);
164 return; 177 return;
165 } 178 }
166 179
@@ -187,26 +200,30 @@ nouveau_pci_attach(device_t parent, devi @@ -187,26 +200,30 @@ nouveau_pci_attach(device_t parent, devi
187 aprint_error_dev(self, "unable to create workqueue: %d\n", 200 aprint_error_dev(self, "unable to create workqueue: %d\n",
188 error); 201 error);
189 sc->sc_task_u.workqueue = NULL; 202 sc->sc_task_u.workqueue = NULL;
190 return; 203 return;
191 } 204 }
192} 205}
193 206
194static int 207static int
195nouveau_pci_detach(device_t self, int flags) 208nouveau_pci_detach(device_t self, int flags)
196{ 209{
197 struct nouveau_pci_softc *const sc = device_private(self); 210 struct nouveau_pci_softc *const sc = device_private(self);
198 int error; 211 int error;
199 212
 213 if (sc->sc_dev == NULL)
 214 /* Not done attaching. */
 215 return EBUSY;
 216
200 /* XXX Check for in-use before tearing it all down... */ 217 /* XXX Check for in-use before tearing it all down... */
201 error = config_detach_children(self, flags); 218 error = config_detach_children(self, flags);
202 if (error) 219 if (error)
203 return error; 220 return error;
204 221
205 if (sc->sc_task_state == NOUVEAU_TASK_ATTACH) 222 if (sc->sc_task_state == NOUVEAU_TASK_ATTACH)
206 goto out0; 223 goto out0;
207 if (sc->sc_task_u.workqueue != NULL) { 224 if (sc->sc_task_u.workqueue != NULL) {
208 workqueue_destroy(sc->sc_task_u.workqueue); 225 workqueue_destroy(sc->sc_task_u.workqueue);
209 sc->sc_task_u.workqueue = NULL; 226 sc->sc_task_u.workqueue = NULL;
210 } 227 }
211 228
212 if (sc->sc_nv_dev == NULL) 229 if (sc->sc_nv_dev == NULL)