Sat Jan 30 09:48:59 2021 UTC ()
Don't print undefined interrupt value


(skrll)
diff -r1.3 -r1.4 src/sys/arch/arm/nxp/imx6_usb.c

cvs diff -r1.3 -r1.4 src/sys/arch/arm/nxp/imx6_usb.c (switch to unified diff)

--- src/sys/arch/arm/nxp/imx6_usb.c 2021/01/27 03:10:20 1.3
+++ src/sys/arch/arm/nxp/imx6_usb.c 2021/01/30 09:48:59 1.4
@@ -1,279 +1,279 @@ @@ -1,279 +1,279 @@
1/* $NetBSD: imx6_usb.c,v 1.3 2021/01/27 03:10:20 thorpej Exp $ */ 1/* $NetBSD: imx6_usb.c,v 1.4 2021/01/30 09:48:59 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Genetec Corporation. All rights reserved. 4 * Copyright (c) 2019 Genetec Corporation. All rights reserved.
5 * Written by Hashimoto Kenichi for Genetec Corporation. 5 * Written by Hashimoto Kenichi for Genetec Corporation.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: imx6_usb.c,v 1.3 2021/01/27 03:10:20 thorpej Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: imx6_usb.c,v 1.4 2021/01/30 09:48:59 skrll Exp $");
31 31
32#include "opt_fdt.h" 32#include "opt_fdt.h"
33 33
34#include <locators.h> 34#include <locators.h>
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/conf.h> 38#include <sys/conf.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/intr.h> 41#include <sys/intr.h>
42#include <sys/bus.h> 42#include <sys/bus.h>
43 43
44#include <dev/usb/usb.h> 44#include <dev/usb/usb.h>
45#include <dev/usb/usbdi.h> 45#include <dev/usb/usbdi.h>
46#include <dev/usb/usbdivar.h> 46#include <dev/usb/usbdivar.h>
47#include <dev/usb/usb_mem.h> 47#include <dev/usb/usb_mem.h>
48 48
49#include <dev/usb/ehcireg.h> 49#include <dev/usb/ehcireg.h>
50#include <dev/usb/ehcivar.h> 50#include <dev/usb/ehcivar.h>
51 51
52#include <arm/nxp/imx6_usbreg.h> 52#include <arm/nxp/imx6_usbreg.h>
53#include <arm/imx/imxusbvar.h> 53#include <arm/imx/imxusbvar.h>
54 54
55#include <dev/fdt/fdtvar.h> 55#include <dev/fdt/fdtvar.h>
56 56
57struct imxusbc_fdt_softc { 57struct imxusbc_fdt_softc {
58 struct imxusbc_softc sc_imxusbc; /* Must be first */ 58 struct imxusbc_softc sc_imxusbc; /* Must be first */
59 59
60 int sc_phandle; 60 int sc_phandle;
61}; 61};
62 62
63static int imx6_usb_match(device_t, struct cfdata *, void *); 63static int imx6_usb_match(device_t, struct cfdata *, void *);
64static void imx6_usb_attach(device_t, device_t, void *); 64static void imx6_usb_attach(device_t, device_t, void *);
65static int imx6_usb_init_clocks(struct imxusbc_softc *); 65static int imx6_usb_init_clocks(struct imxusbc_softc *);
66static void imx6_usb_init(struct imxehci_softc *); 66static void imx6_usb_init(struct imxehci_softc *);
67static void init_otg(struct imxehci_softc *); 67static void init_otg(struct imxehci_softc *);
68static void init_h1(struct imxehci_softc *); 68static void init_h1(struct imxehci_softc *);
69static int imxusbc_print(void *, const char *); 69static int imxusbc_print(void *, const char *);
70static void *imx6_usb_intr_establish(struct imxehci_softc *); 70static void *imx6_usb_intr_establish(struct imxehci_softc *);
71 71
72/* attach structures */ 72/* attach structures */
73CFATTACH_DECL_NEW(imxusbc_fdt, sizeof(struct imxusbc_fdt_softc), 73CFATTACH_DECL_NEW(imxusbc_fdt, sizeof(struct imxusbc_fdt_softc),
74 imx6_usb_match, imx6_usb_attach, NULL, NULL); 74 imx6_usb_match, imx6_usb_attach, NULL, NULL);
75 75
76static const struct device_compatible_entry compat_data[] = { 76static const struct device_compatible_entry compat_data[] = {
77 { .compat = "fsl,imx6q-usb" }, 77 { .compat = "fsl,imx6q-usb" },
78 { .compat = "fsl,imx7d-usb" }, 78 { .compat = "fsl,imx7d-usb" },
79 DEVICE_COMPAT_EOL 79 DEVICE_COMPAT_EOL
80}; 80};
81 81
82static int 82static int
83imx6_usb_match(device_t parent, cfdata_t cf, void *aux) 83imx6_usb_match(device_t parent, cfdata_t cf, void *aux)
84{ 84{
85 struct fdt_attach_args * const faa = aux; 85 struct fdt_attach_args * const faa = aux;
86 86
87 return of_compatible_match(faa->faa_phandle, compat_data); 87 return of_compatible_match(faa->faa_phandle, compat_data);
88} 88}
89 89
90static void 90static void
91imx6_usb_attach(device_t parent, device_t self, void *aux) 91imx6_usb_attach(device_t parent, device_t self, void *aux)
92{ 92{
93 struct imxusbc_fdt_softc *ifsc = device_private(self); 93 struct imxusbc_fdt_softc *ifsc = device_private(self);
94 struct imxusbc_softc *sc = &ifsc->sc_imxusbc; 94 struct imxusbc_softc *sc = &ifsc->sc_imxusbc;
95 struct fdt_attach_args * const faa = aux; 95 struct fdt_attach_args * const faa = aux;
96 const int phandle = faa->faa_phandle; 96 const int phandle = faa->faa_phandle;
97 bus_space_tag_t bst = faa->faa_bst; 97 bus_space_tag_t bst = faa->faa_bst;
98 bus_space_handle_t bsh; 98 bus_space_handle_t bsh;
99 bus_addr_t addr; 99 bus_addr_t addr;
100 bus_size_t size; 100 bus_size_t size;
101 int error; 101 int error;
102 102
103 aprint_naive("\n"); 103 aprint_naive("\n");
104 aprint_normal("\n"); 104 aprint_normal("\n");
105 105
106 ifsc->sc_phandle = phandle; 106 ifsc->sc_phandle = phandle;
107 107
108 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 108 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
109 aprint_error(": couldn't get imxusbc registers\n"); 109 aprint_error(": couldn't get imxusbc registers\n");
110 return; 110 return;
111 } 111 }
112 112
113 error = bus_space_map(bst, addr, size, 0, &bsh); 113 error = bus_space_map(bst, addr, size, 0, &bsh);
114 if (error) { 114 if (error) {
115 aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", addr, error); 115 aprint_error(": couldn't map %#" PRIxBUSADDR ": %d", addr, error);
116 return; 116 return;
117 } 117 }
118 118
119 sc->sc_clk = fdtbus_clock_get_index(phandle, 0); 119 sc->sc_clk = fdtbus_clock_get_index(phandle, 0);
120 if (sc->sc_clk == NULL) { 120 if (sc->sc_clk == NULL) {
121 aprint_error(": couldn't get clock\n"); 121 aprint_error(": couldn't get clock\n");
122 return; 122 return;
123 } 123 }
124 124
125 sc->sc_init_md_hook = imx6_usb_init; 125 sc->sc_init_md_hook = imx6_usb_init;
126 sc->sc_intr_establish_md_hook = imx6_usb_intr_establish; 126 sc->sc_intr_establish_md_hook = imx6_usb_intr_establish;
127 sc->sc_setup_md_hook = NULL; 127 sc->sc_setup_md_hook = NULL;
128 128
129 sc->sc_dev = self; 129 sc->sc_dev = self;
130 sc->sc_iot = bst; 130 sc->sc_iot = bst;
131 sc->sc_ioh = bsh; 131 sc->sc_ioh = bsh;
132 sc->sc_ehci_size = size; 132 sc->sc_ehci_size = size;
133 sc->sc_ehci_offset = 0; 133 sc->sc_ehci_offset = 0;
134 134
135 struct fdt_phandle_data data; 135 struct fdt_phandle_data data;
136 error = fdtbus_get_phandle_with_data(phandle, "fsl,usbmisc", 136 error = fdtbus_get_phandle_with_data(phandle, "fsl,usbmisc",
137 "#index-cells", 0, &data); 137 "#index-cells", 0, &data);
138 if (error) { 138 if (error) {
139 aprint_error(": couldn't get usbmisc property\n"); 139 aprint_error(": couldn't get usbmisc property\n");
140 return; 140 return;
141 } 141 }
142 int unit = be32toh(data.values[0]); 142 int unit = be32toh(data.values[0]);
143 143
144 if (fdtbus_get_reg(data.phandle, 0, &addr, &size) != 0) { 144 if (fdtbus_get_reg(data.phandle, 0, &addr, &size) != 0) {
145 aprint_error(": couldn't get usbmisc registers\n"); 145 aprint_error(": couldn't get usbmisc registers\n");
146 return; 146 return;
147 } 147 }
148 error = bus_space_map(bst, addr, size, 0, &bsh); 148 error = bus_space_map(bst, addr, size, 0, &bsh);
149 if (error) { 149 if (error) {
150 aprint_error(": couldn't map usbmisc registers: %d\n", error); 150 aprint_error(": couldn't map usbmisc registers: %d\n", error);
151 return; 151 return;
152 } 152 }
153 sc->sc_ioh_usbnc = bsh; 153 sc->sc_ioh_usbnc = bsh;
154 154
155 if (imx6_usb_init_clocks(sc) != 0) { 155 if (imx6_usb_init_clocks(sc) != 0) {
156 aprint_error_dev(self, "couldn't init clocks\n"); 156 aprint_error_dev(self, "couldn't init clocks\n");
157 return; 157 return;
158 } 158 }
159 159
160 /* attach OTG/EHCI host controllers */ 160 /* attach OTG/EHCI host controllers */
161 struct imxusbc_attach_args iaa; 161 struct imxusbc_attach_args iaa;
162 iaa.aa_iot = sc->sc_iot; 162 iaa.aa_iot = sc->sc_iot;
163 iaa.aa_ioh = sc->sc_ioh; 163 iaa.aa_ioh = sc->sc_ioh;
164 iaa.aa_dmat = faa->faa_dmat; 164 iaa.aa_dmat = faa->faa_dmat;
165 iaa.aa_unit = unit; 165 iaa.aa_unit = unit;
166 iaa.aa_irq = IMXUSBCCF_IRQ_DEFAULT; 166 iaa.aa_irq = IMXUSBCCF_IRQ_DEFAULT;
167 config_found_sm_loc(self, "imxusbc", NULL, &iaa, imxusbc_print, NULL); 167 config_found_sm_loc(self, "imxusbc", NULL, &iaa, imxusbc_print, NULL);
168 168
169 return; 169 return;
170} 170}
171 171
172static int 172static int
173imxusbc_print(void *aux, const char *name __unused) 173imxusbc_print(void *aux, const char *name __unused)
174{ 174{
175 struct imxusbc_attach_args *iaa; 175 struct imxusbc_attach_args *iaa;
176 176
177 iaa = (struct imxusbc_attach_args *)aux; 177 iaa = (struct imxusbc_attach_args *)aux;
178 178
179 aprint_normal(" unit %d intr %d", iaa->aa_unit, iaa->aa_irq); 179 aprint_normal(" unit %d", iaa->aa_unit);
180 return UNCONF; 180 return UNCONF;
181} 181}
182 182
183 183
184static int 184static int
185imx6_usb_init_clocks(struct imxusbc_softc *sc) 185imx6_usb_init_clocks(struct imxusbc_softc *sc)
186{ 186{
187 int error; 187 int error;
188 188
189 error = clk_enable(sc->sc_clk); 189 error = clk_enable(sc->sc_clk);
190 if (error) { 190 if (error) {
191 aprint_error_dev(sc->sc_dev, "couldn't enable: %d\n", error); 191 aprint_error_dev(sc->sc_dev, "couldn't enable: %d\n", error);
192 return error; 192 return error;
193 } 193 }
194 194
195 return 0; 195 return 0;
196} 196}
197 197
198static void 198static void
199imx6_usb_init(struct imxehci_softc *sc) 199imx6_usb_init(struct imxehci_softc *sc)
200{ 200{
201 switch (sc->sc_unit) { 201 switch (sc->sc_unit) {
202 case 0: /* OTG controller */ 202 case 0: /* OTG controller */
203 init_otg(sc); 203 init_otg(sc);
204 break; 204 break;
205 case 1: /* EHCI Host 1 */ 205 case 1: /* EHCI Host 1 */
206 init_h1(sc); 206 init_h1(sc);
207 break; 207 break;
208 case 2: /* EHCI Host 2 */ 208 case 2: /* EHCI Host 2 */
209 case 3: /* EHCI Host 3 */ 209 case 3: /* EHCI Host 3 */
210 default: 210 default:
211 aprint_error_dev(sc->sc_dev, "unit %d not supported\n", 211 aprint_error_dev(sc->sc_dev, "unit %d not supported\n",
212 sc->sc_unit); 212 sc->sc_unit);
213 } 213 }
214} 214}
215 215
216static void 216static void
217init_otg(struct imxehci_softc *sc) 217init_otg(struct imxehci_softc *sc)
218{ 218{
219 struct imxusbc_softc *usbc = sc->sc_usbc; 219 struct imxusbc_softc *usbc = sc->sc_usbc;
220 uint32_t v; 220 uint32_t v;
221 221
222 sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE; 222 sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE;
223 223
224 imxehci_reset(sc); 224 imxehci_reset(sc);
225 225
226 v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_OTG_CTRL); 226 v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_OTG_CTRL);
227 v |= USBNC_USB_OTG_CTRL_WKUP_VBUS_EN; 227 v |= USBNC_USB_OTG_CTRL_WKUP_VBUS_EN;
228 v |= USBNC_USB_OTG_CTRL_OVER_CUR_DIS; 228 v |= USBNC_USB_OTG_CTRL_OVER_CUR_DIS;
229 v |= USBNC_USB_OTG_CTRL_PWR_POL; 229 v |= USBNC_USB_OTG_CTRL_PWR_POL;
230 v &= ~USBNC_USB_OTG_CTRL_UTMI_ON_CLOCK; 230 v &= ~USBNC_USB_OTG_CTRL_UTMI_ON_CLOCK;
231 bus_space_write_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_OTG_CTRL, v); 231 bus_space_write_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_OTG_CTRL, v);
232} 232}
233 233
234static void 234static void
235init_h1(struct imxehci_softc *sc) 235init_h1(struct imxehci_softc *sc)
236{ 236{
237 struct imxusbc_softc *usbc = sc->sc_usbc; 237 struct imxusbc_softc *usbc = sc->sc_usbc;
238 uint32_t v; 238 uint32_t v;
239 239
240 sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE; 240 sc->sc_iftype = IMXUSBC_IF_UTMI_WIDE;
241 241
242 v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_UH1_CTRL); 242 v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_UH1_CTRL);
243 v |= USBNC_USB_UH1_CTRL_OVER_CUR_POL; 243 v |= USBNC_USB_UH1_CTRL_OVER_CUR_POL;
244 v |= USBNC_USB_UH1_CTRL_OVER_CUR_DIS; 244 v |= USBNC_USB_UH1_CTRL_OVER_CUR_DIS;
245 bus_space_write_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_UH1_CTRL, v); 245 bus_space_write_4(usbc->sc_iot, usbc->sc_ioh_usbnc, USBNC_USB_UH1_CTRL, v);
246 246
247 /* do reset */ 247 /* do reset */
248 imxehci_reset(sc); 248 imxehci_reset(sc);
249 249
250 /* set mode */ 250 /* set mode */
251 v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh, USBC_UH1_USBMODE); 251 v = bus_space_read_4(usbc->sc_iot, usbc->sc_ioh, USBC_UH1_USBMODE);
252 v &= ~USBC_UH_USBMODE_CM; 252 v &= ~USBC_UH_USBMODE_CM;
253 v |= __SHIFTIN(USBC_UH_USBMODE_CM, USBC_UH_USBMODE_CM_HOST_CONTROLLER); 253 v |= __SHIFTIN(USBC_UH_USBMODE_CM, USBC_UH_USBMODE_CM_HOST_CONTROLLER);
254 bus_space_write_4(usbc->sc_iot, usbc->sc_ioh, USBC_UH1_USBMODE, v); 254 bus_space_write_4(usbc->sc_iot, usbc->sc_ioh, USBC_UH1_USBMODE, v);
255} 255}
256 256
257static void * 257static void *
258imx6_usb_intr_establish(struct imxehci_softc *sc) 258imx6_usb_intr_establish(struct imxehci_softc *sc)
259{ 259{
260 struct imxusbc_fdt_softc *ifsc = (struct imxusbc_fdt_softc *)sc->sc_usbc; 260 struct imxusbc_fdt_softc *ifsc = (struct imxusbc_fdt_softc *)sc->sc_usbc;
261 ehci_softc_t *hsc = &sc->sc_hsc; 261 ehci_softc_t *hsc = &sc->sc_hsc;
262 void *ih; 262 void *ih;
263 263
264 char intrstr[128]; 264 char intrstr[128];
265 if (!fdtbus_intr_str(ifsc->sc_phandle, 0, intrstr, sizeof(intrstr))) { 265 if (!fdtbus_intr_str(ifsc->sc_phandle, 0, intrstr, sizeof(intrstr))) {
266 aprint_error_dev(sc->sc_dev, "failed to decode interrupt\n"); 266 aprint_error_dev(sc->sc_dev, "failed to decode interrupt\n");
267 return NULL; 267 return NULL;
268 } 268 }
269 ih = fdtbus_intr_establish_xname(ifsc->sc_phandle, 0, IPL_USB, 269 ih = fdtbus_intr_establish_xname(ifsc->sc_phandle, 0, IPL_USB,
270 FDT_INTR_MPSAFE, ehci_intr, hsc, device_xname(sc->sc_dev)); 270 FDT_INTR_MPSAFE, ehci_intr, hsc, device_xname(sc->sc_dev));
271 if (ih == NULL) { 271 if (ih == NULL) {
272 aprint_error_dev(sc->sc_dev, "failed to establish interrupt on %s\n", 272 aprint_error_dev(sc->sc_dev, "failed to establish interrupt on %s\n",
273 intrstr); 273 intrstr);
274 return NULL; 274 return NULL;
275 } 275 }
276 aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr); 276 aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr);
277 277
278 return ih; 278 return ih;
279} 279}