Fri Jul 17 08:06:02 2020 UTC ()
Don't use a reserved value for the USB endian CSR selects and
enable octxhci_uctl_init().  Between these, USB works without
needing a "usb start" from u-boot.

XXX: Note the port power enable goop is still disabled until
we get a GPIO driver.


(simonb)
diff -r1.1 -r1.2 src/sys/arch/mips/cavium/dev/octeon_xhci.c
diff -r1.1 -r1.2 src/sys/arch/mips/cavium/dev/octeon_xhcireg.h

cvs diff -r1.1 -r1.2 src/sys/arch/mips/cavium/dev/octeon_xhci.c (switch to unified diff)

--- src/sys/arch/mips/cavium/dev/octeon_xhci.c 2020/07/16 21:34:52 1.1
+++ src/sys/arch/mips/cavium/dev/octeon_xhci.c 2020/07/17 08:06:02 1.2
@@ -1,391 +1,390 @@ @@ -1,391 +1,390 @@
1/* $NetBSD: octeon_xhci.c,v 1.1 2020/07/16 21:34:52 jmcneill Exp $ */ 1/* $NetBSD: octeon_xhci.c,v 1.2 2020/07/17 08:06:02 simonb Exp $ */
2/* $OpenBSD: octxhci.c,v 1.4 2019/09/29 04:32:23 visa Exp $ */ 2/* $OpenBSD: octxhci.c,v 1.4 2019/09/29 04:32:23 visa Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2017 Visa Hankala 5 * Copyright (c) 2017 Visa Hankala
6 * Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca> 6 * Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca>
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies. 10 * copyright notice and this permission notice appear in all copies.
11 * 11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */ 19 */
20 20
21/* 21/*
22 * Driver for OCTEON USB3 controller bridge. 22 * Driver for OCTEON USB3 controller bridge.
23 */ 23 */
24 24
25#include <sys/param.h> 25#include <sys/param.h>
26#include <sys/systm.h> 26#include <sys/systm.h>
27#include <sys/device.h> 27#include <sys/device.h>
28#include <sys/malloc.h> 28#include <sys/malloc.h>
29 29
30#include <mips/cavium/octeonvar.h> 30#include <mips/cavium/octeonvar.h>
31 31
32#include <mips/cavium/dev/octeon_xhcireg.h> 32#include <mips/cavium/dev/octeon_xhcireg.h>
33 33
34#include <dev/usb/usb.h> 34#include <dev/usb/usb.h>
35#include <dev/usb/usbdi.h> 35#include <dev/usb/usbdi.h>
36#include <dev/usb/usbdivar.h> 36#include <dev/usb/usbdivar.h>
37#include <dev/usb/usb_mem.h> 37#include <dev/usb/usb_mem.h>
38#include <dev/usb/xhcireg.h> 38#include <dev/usb/xhcireg.h>
39#include <dev/usb/xhcivar.h> 39#include <dev/usb/xhcivar.h>
40 40
41#include <dev/fdt/fdtvar.h> 41#include <dev/fdt/fdtvar.h>
42 42
43#define XCTL_RD_8(sc, reg) \ 43#define XCTL_RD_8(sc, reg) \
44 bus_space_read_8((sc)->sc_iot, (sc)->sc_ioh, (reg)) 44 bus_space_read_8((sc)->sc_iot, (sc)->sc_ioh, (reg))
45#define XCTL_WR_8(sc, reg, val) \ 45#define XCTL_WR_8(sc, reg, val) \
46 bus_space_write_8((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 46 bus_space_write_8((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
47 47
48struct octxhci_softc { 48struct octxhci_softc {
49 struct xhci_softc sc_xhci; 49 struct xhci_softc sc_xhci;
50 bus_space_tag_t sc_iot; 50 bus_space_tag_t sc_iot;
51 bus_space_handle_t sc_ioh; 51 bus_space_handle_t sc_ioh;
52 struct fdtbus_gpio_pin *sc_power_gpio; 52 struct fdtbus_gpio_pin *sc_power_gpio;
53 int sc_unit; 53 int sc_unit;
54}; 54};
55 55
56static int octxhci_match(device_t, cfdata_t, void *); 56static int octxhci_match(device_t, cfdata_t, void *);
57static void octxhci_attach(device_t, device_t, void *); 57static void octxhci_attach(device_t, device_t, void *);
58 58
59static int octxhci_dwc3_init(struct xhci_softc *); 59static int octxhci_dwc3_init(struct xhci_softc *);
60static void octxhci_uctl_init(struct octxhci_softc *, uint64_t, uint64_t); 60static void octxhci_uctl_init(struct octxhci_softc *, uint64_t, uint64_t);
61 61
62static void octxhci_bus_io_init(bus_space_tag_t, void *); 62static void octxhci_bus_io_init(bus_space_tag_t, void *);
63 63
64static struct mips_bus_space octxhci_bus_tag; 64static struct mips_bus_space octxhci_bus_tag;
65 65
66CFATTACH_DECL_NEW(octxhci, sizeof(struct octxhci_softc), 66CFATTACH_DECL_NEW(octxhci, sizeof(struct octxhci_softc),
67 octxhci_match, octxhci_attach, NULL, NULL); 67 octxhci_match, octxhci_attach, NULL, NULL);
68 68
69static const char * compatible[] = { 69static const char * compatible[] = {
70 "cavium,octeon-7130-usb-uctl", 70 "cavium,octeon-7130-usb-uctl",
71 NULL 71 NULL
72}; 72};
73 73
74int 74int
75octxhci_match(device_t parent, cfdata_t cf, void *aux) 75octxhci_match(device_t parent, cfdata_t cf, void *aux)
76{ 76{
77 struct fdt_attach_args * const faa = aux; 77 struct fdt_attach_args * const faa = aux;
78 78
79 return of_match_compatible(faa->faa_phandle, compatible); 79 return of_match_compatible(faa->faa_phandle, compatible);
80} 80}
81 81
82void 82void
83octxhci_attach(device_t parent, device_t self, void *aux) 83octxhci_attach(device_t parent, device_t self, void *aux)
84{ 84{
85 struct octxhci_softc *osc = device_private(self); 85 struct octxhci_softc *osc = device_private(self);
86 struct xhci_softc *sc = &osc->sc_xhci; 86 struct xhci_softc *sc = &osc->sc_xhci;
87 struct fdt_attach_args * const faa = aux; 87 struct fdt_attach_args * const faa = aux;
88 const int phandle = faa->faa_phandle; 88 const int phandle = faa->faa_phandle;
89 const char *clock_type_hs; 89 const char *clock_type_hs;
90 const char *clock_type_ss; 90 const char *clock_type_ss;
91 u_int clock_freq, clock_sel; 91 u_int clock_freq, clock_sel;
92 char intrstr[128]; 92 char intrstr[128];
93 int child, error; 93 int child, error;
94 bus_addr_t addr; 94 bus_addr_t addr;
95 bus_size_t size; 95 bus_size_t size;
96 void *ih; 96 void *ih;
97 97
98 osc->sc_iot = faa->faa_bst; 98 osc->sc_iot = faa->faa_bst;
99 99
100 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 100 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
101 aprint_error(": couldn't get bridge registers\n"); 101 aprint_error(": couldn't get bridge registers\n");
102 return; 102 return;
103 } 103 }
104 if (bus_space_map(osc->sc_iot, addr, size, 0, &osc->sc_ioh) != 0) { 104 if (bus_space_map(osc->sc_iot, addr, size, 0, &osc->sc_ioh) != 0) {
105 aprint_error(": couldn't map bridge registers\n"); 105 aprint_error(": couldn't map bridge registers\n");
106 return; 106 return;
107 } 107 }
108 osc->sc_power_gpio = fdtbus_gpio_acquire(phandle, "power", 108 osc->sc_power_gpio = fdtbus_gpio_acquire(phandle, "power",
109 GPIO_PIN_OUTPUT); 109 GPIO_PIN_OUTPUT);
110 osc->sc_unit = (addr >> 24) & 0x1; 110 osc->sc_unit = (addr >> 24) & 0x1;
111 111
112 octxhci_bus_io_init(&octxhci_bus_tag, NULL); 112 octxhci_bus_io_init(&octxhci_bus_tag, NULL);
113 113
114 sc->sc_dev = self; 114 sc->sc_dev = self;
115 sc->sc_bus.ub_hcpriv = sc; 115 sc->sc_bus.ub_hcpriv = sc;
116 sc->sc_bus.ub_dmatag = faa->faa_dmat; 116 sc->sc_bus.ub_dmatag = faa->faa_dmat;
117 sc->sc_iot = &octxhci_bus_tag; 117 sc->sc_iot = &octxhci_bus_tag;
118 118
119 child = of_find_bycompat(phandle, "synopsys,dwc3"); 119 child = of_find_bycompat(phandle, "synopsys,dwc3");
120 if (child == -1) { 120 if (child == -1) {
121 aprint_error(": couldn't find dwc3 child node\n"); 121 aprint_error(": couldn't find dwc3 child node\n");
122 return; 122 return;
123 } 123 }
124 if (fdtbus_get_reg(child, 0, &addr, &size) != 0) { 124 if (fdtbus_get_reg(child, 0, &addr, &size) != 0) {
125 aprint_error(": couldn't get xhci registers\n"); 125 aprint_error(": couldn't get xhci registers\n");
126 return; 126 return;
127 } 127 }
128 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) { 128 if (bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh) != 0) {
129 aprint_error(": couldn't map xhci registers\n"); 129 aprint_error(": couldn't map xhci registers\n");
130 return; 130 return;
131 } 131 }
132 132
133 if (of_getprop_uint32(phandle, "refclk-frequency", &clock_freq) != 0) { 133 if (of_getprop_uint32(phandle, "refclk-frequency", &clock_freq) != 0) {
134 aprint_error(": couldn't get refclk-frequency property\n"); 134 aprint_error(": couldn't get refclk-frequency property\n");
135 return; 135 return;
136 } 136 }
137 clock_type_hs = fdtbus_get_string(phandle, "refclk-type-hs"); 137 clock_type_hs = fdtbus_get_string(phandle, "refclk-type-hs");
138 if (clock_type_hs == NULL) { 138 if (clock_type_hs == NULL) {
139 aprint_error(": couldn't get refclk-type-hs property\n"); 139 aprint_error(": couldn't get refclk-type-hs property\n");
140 return; 140 return;
141 } 141 }
142 clock_type_ss = fdtbus_get_string(phandle, "refclk-type-ss"); 142 clock_type_ss = fdtbus_get_string(phandle, "refclk-type-ss");
143 if (clock_type_ss == NULL) { 143 if (clock_type_ss == NULL) {
144 aprint_error(": couldn't get refclk-type-ss property\n"); 144 aprint_error(": couldn't get refclk-type-ss property\n");
145 return; 145 return;
146 } 146 }
147 147
148 clock_sel = 0; 148 clock_sel = 0;
149 if (strcmp(clock_type_ss, "dlmc_ref_clk1") == 0) 149 if (strcmp(clock_type_ss, "dlmc_ref_clk1") == 0)
150 clock_sel |= 1; 150 clock_sel |= 1;
151 if (strcmp(clock_type_hs, "pll_ref_clk") == 0) 151 if (strcmp(clock_type_hs, "pll_ref_clk") == 0)
152 clock_sel |= 2; 152 clock_sel |= 2;
153 153
154 if (0) 
155 octxhci_uctl_init(osc, clock_freq, clock_sel); 154 octxhci_uctl_init(osc, clock_freq, clock_sel);
156 155
157 if (octxhci_dwc3_init(sc) != 0) { 156 if (octxhci_dwc3_init(sc) != 0) {
158 /* Error message has been printed already. */ 157 /* Error message has been printed already. */
159 return; 158 return;
160 } 159 }
161 160
162 if (!fdtbus_intr_str(child, 0, intrstr, sizeof(intrstr))) { 161 if (!fdtbus_intr_str(child, 0, intrstr, sizeof(intrstr))) {
163 aprint_error_dev(self, "failed to decode interrupt\n"); 162 aprint_error_dev(self, "failed to decode interrupt\n");
164 return; 163 return;
165 } 164 }
166 165
167 ih = fdtbus_intr_establish(child, 0, IPL_USB, FDT_INTR_MPSAFE, 166 ih = fdtbus_intr_establish(child, 0, IPL_USB, FDT_INTR_MPSAFE,
168 xhci_intr, sc); 167 xhci_intr, sc);
169 if (ih == NULL) { 168 if (ih == NULL) {
170 aprint_error_dev(self, "couldn't establish interrupt on %s\n", 169 aprint_error_dev(self, "couldn't establish interrupt on %s\n",
171 intrstr); 170 intrstr);
172 return; 171 return;
173 } 172 }
174 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 173 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
175 174
176 sc->sc_bus.ub_revision = USBREV_3_0; 175 sc->sc_bus.ub_revision = USBREV_3_0;
177 error = xhci_init(sc); 176 error = xhci_init(sc);
178 if (error != 0) { 177 if (error != 0) {
179 aprint_error_dev(self, "init failed, error = %d\n", error); 178 aprint_error_dev(self, "init failed, error = %d\n", error);
180 return; 179 return;
181 } 180 }
182 181
183 sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); 182 sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
184 sc->sc_child2 = config_found(self, &sc->sc_bus2, usbctlprint); 183 sc->sc_child2 = config_found(self, &sc->sc_bus2, usbctlprint);
185} 184}
186 185
187void 186void
188octxhci_uctl_init(struct octxhci_softc *sc, uint64_t clock_freq, 187octxhci_uctl_init(struct octxhci_softc *sc, uint64_t clock_freq,
189 uint64_t clock_sel) 188 uint64_t clock_sel)
190{ 189{
191 static const uint32_t clock_divs[] = { 1, 2, 4, 6, 8, 16, 24, 32 }; 190 static const uint32_t clock_divs[] = { 1, 2, 4, 6, 8, 16, 24, 32 };
192 uint64_t i, val; 191 uint64_t i, val;
193 uint64_t ioclock = octeon_ioclock_speed(); 192 uint64_t ioclock = octeon_ioclock_speed();
194 uint64_t mpll_mult; 193 uint64_t mpll_mult;
195 uint64_t refclk_fsel; 194 uint64_t refclk_fsel;
196#if notyet 195#if notyet
197 int output_sel; 196 int output_sel;
198#endif 197#endif
199 198
200 /* 199 /*
201 * Put the bridge controller, USB core, PHY, and clock divider 200 * Put the bridge controller, USB core, PHY, and clock divider
202 * into reset. 201 * into reset.
203 */ 202 */
204 val = XCTL_RD_8(sc, XCTL_CTL); 203 val = XCTL_RD_8(sc, XCTL_CTL);
205 val |= XCTL_CTL_UCTL_RST; 204 val |= XCTL_CTL_UCTL_RST;
206 val |= XCTL_CTL_UAHC_RST; 205 val |= XCTL_CTL_UAHC_RST;
207 val |= XCTL_CTL_UPHY_RST; 206 val |= XCTL_CTL_UPHY_RST;
208 XCTL_WR_8(sc, XCTL_CTL, val); 207 XCTL_WR_8(sc, XCTL_CTL, val);
209 val = XCTL_RD_8(sc, XCTL_CTL); 208 val = XCTL_RD_8(sc, XCTL_CTL);
210 val |= XCTL_CTL_CLKDIV_RST; 209 val |= XCTL_CTL_CLKDIV_RST;
211 XCTL_WR_8(sc, XCTL_CTL, val); 210 XCTL_WR_8(sc, XCTL_CTL, val);
212 211
213 /* Select IO clock divisor. */ 212 /* Select IO clock divisor. */
214 for (i = 0; i < __arraycount(clock_divs); i++) { 213 for (i = 0; i < __arraycount(clock_divs); i++) {
215 if (ioclock / clock_divs[i] < 300000000) 214 if (ioclock / clock_divs[i] < 300000000)
216 break; 215 break;
217 } 216 }
218 217
219 /* Update the divisor and enable the clock. */ 218 /* Update the divisor and enable the clock. */
220 val = XCTL_RD_8(sc, XCTL_CTL); 219 val = XCTL_RD_8(sc, XCTL_CTL);
221 val &= ~XCTL_CTL_CLKDIV_SEL; 220 val &= ~XCTL_CTL_CLKDIV_SEL;
222 val |= (i << XCTL_CTL_CLKDIV_SEL_SHIFT) & XCTL_CTL_CLKDIV_SEL; 221 val |= (i << XCTL_CTL_CLKDIV_SEL_SHIFT) & XCTL_CTL_CLKDIV_SEL;
223 val |= XCTL_CTL_CLK_EN; 222 val |= XCTL_CTL_CLK_EN;
224 XCTL_WR_8(sc, XCTL_CTL, val); 223 XCTL_WR_8(sc, XCTL_CTL, val);
225 224
226 /* Take the clock divider out of reset. */ 225 /* Take the clock divider out of reset. */
227 val = XCTL_RD_8(sc, XCTL_CTL); 226 val = XCTL_RD_8(sc, XCTL_CTL);
228 val &= ~XCTL_CTL_CLKDIV_RST; 227 val &= ~XCTL_CTL_CLKDIV_RST;
229 XCTL_WR_8(sc, XCTL_CTL, val); 228 XCTL_WR_8(sc, XCTL_CTL, val);
230 229
231 /* Select the reference clock. */ 230 /* Select the reference clock. */
232 switch (clock_freq) { 231 switch (clock_freq) {
233 case 50000000: 232 case 50000000:
234 refclk_fsel = 0x07; 233 refclk_fsel = 0x07;
235 mpll_mult = 0x32; 234 mpll_mult = 0x32;
236 break; 235 break;
237 case 125000000: 236 case 125000000:
238 refclk_fsel = 0x07; 237 refclk_fsel = 0x07;
239 mpll_mult = 0x28; 238 mpll_mult = 0x28;
240 break; 239 break;
241 case 100000000: 240 case 100000000:
242 default: 241 default:
243 if (clock_sel < 2) 242 if (clock_sel < 2)
244 refclk_fsel = 0x27; 243 refclk_fsel = 0x27;
245 else 244 else
246 refclk_fsel = 0x07; 245 refclk_fsel = 0x07;
247 mpll_mult = 0x19; 246 mpll_mult = 0x19;
248 break; 247 break;
249 } 248 }
250 249
251 /* Set the clock and power up PHYs. */ 250 /* Set the clock and power up PHYs. */
252 val = XCTL_RD_8(sc, XCTL_CTL); 251 val = XCTL_RD_8(sc, XCTL_CTL);
253 val &= ~XCTL_CTL_REFCLK_SEL; 252 val &= ~XCTL_CTL_REFCLK_SEL;
254 val |= clock_sel << XCTL_CTL_REFCLK_SEL_SHIFT; 253 val |= clock_sel << XCTL_CTL_REFCLK_SEL_SHIFT;
255 val &= ~XCTL_CTL_REFCLK_DIV2; 254 val &= ~XCTL_CTL_REFCLK_DIV2;
256 val &= ~XCTL_CTL_REFCLK_FSEL; 255 val &= ~XCTL_CTL_REFCLK_FSEL;
257 val |= refclk_fsel << XCTL_CTL_REFCLK_FSEL_SHIFT; 256 val |= refclk_fsel << XCTL_CTL_REFCLK_FSEL_SHIFT;
258 val &= ~XCTL_CTL_MPLL_MULT; 257 val &= ~XCTL_CTL_MPLL_MULT;
259 val |= mpll_mult << XCTL_CTL_MPLL_MULT_SHIFT; 258 val |= mpll_mult << XCTL_CTL_MPLL_MULT_SHIFT;
260 val |= XCTL_CTL_SSC_EN; 259 val |= XCTL_CTL_SSC_EN;
261 val |= XCTL_CTL_REFCLK_SSP_EN; 260 val |= XCTL_CTL_REFCLK_SSP_EN;
262 val |= XCTL_CTL_SSPOWER_EN; 261 val |= XCTL_CTL_SSPOWER_EN;
263 val |= XCTL_CTL_HSPOWER_EN; 262 val |= XCTL_CTL_HSPOWER_EN;
264 XCTL_WR_8(sc, XCTL_CTL, val); 263 XCTL_WR_8(sc, XCTL_CTL, val);
265 264
266 delay(100); 265 delay(100);
267 266
268 /* Take the bridge out of reset. */ 267 /* Take the bridge out of reset. */
269 val = XCTL_RD_8(sc, XCTL_CTL); 268 val = XCTL_RD_8(sc, XCTL_CTL);
270 val &= ~XCTL_CTL_UCTL_RST; 269 val &= ~XCTL_CTL_UCTL_RST;
271 XCTL_WR_8(sc, XCTL_CTL, val); 270 XCTL_WR_8(sc, XCTL_CTL, val);
272 271
273 delay(100); 272 delay(100);
274 273
275#if notyet 274#if notyet
276 if (sc->sc_power_gpio[0] != 0) { 275 if (sc->sc_power_gpio[0] != 0) {
277 if (sc->sc_unit == 0) 276 if (sc->sc_unit == 0)
278 output_sel = GPIO_CONFIG_MD_USB0_VBUS_CTRL; 277 output_sel = GPIO_CONFIG_MD_USB0_VBUS_CTRL;
279 else 278 else
280 output_sel = GPIO_CONFIG_MD_USB1_VBUS_CTRL; 279 output_sel = GPIO_CONFIG_MD_USB1_VBUS_CTRL;
281 gpio_controller_config_pin(sc->sc_power_gpio, 280 gpio_controller_config_pin(sc->sc_power_gpio,
282 GPIO_CONFIG_OUTPUT | output_sel); 281 GPIO_CONFIG_OUTPUT | output_sel);
283 282
284 /* Enable port power control. */ 283 /* Enable port power control. */
285 val = XCTL_RD_8(sc, XCTL_HOST_CFG); 284 val = XCTL_RD_8(sc, XCTL_HOST_CFG);
286 val |= XCTL_HOST_CFG_PPC_EN; 285 val |= XCTL_HOST_CFG_PPC_EN;
287 if (sc->sc_power_gpio[2] & GPIO_ACTIVE_LOW) 286 if (sc->sc_power_gpio[2] & GPIO_ACTIVE_LOW)
288 val &= ~XCTL_HOST_CFG_PPC_ACTIVE_HIGH_EN; 287 val &= ~XCTL_HOST_CFG_PPC_ACTIVE_HIGH_EN;
289 else 288 else
290 val |= XCTL_HOST_CFG_PPC_ACTIVE_HIGH_EN; 289 val |= XCTL_HOST_CFG_PPC_ACTIVE_HIGH_EN;
291 XCTL_WR_8(sc, XCTL_HOST_CFG, val); 290 XCTL_WR_8(sc, XCTL_HOST_CFG, val);
292 } else { 291 } else {
293 /* Disable port power control. */ 292 /* Disable port power control. */
294 val = XCTL_RD_8(sc, XCTL_HOST_CFG); 293 val = XCTL_RD_8(sc, XCTL_HOST_CFG);
295 val &= ~XCTL_HOST_CFG_PPC_EN; 294 val &= ~XCTL_HOST_CFG_PPC_EN;
296 XCTL_WR_8(sc, XCTL_HOST_CFG, val); 295 XCTL_WR_8(sc, XCTL_HOST_CFG, val);
297 } 296 }
298#else 297#else
299 /* Disable port power control. */ 298 /* Disable port power control. */
300 val = XCTL_RD_8(sc, XCTL_HOST_CFG); 299 val = XCTL_RD_8(sc, XCTL_HOST_CFG);
301 val &= ~XCTL_HOST_CFG_PPC_EN; 300 val &= ~XCTL_HOST_CFG_PPC_EN;
302 XCTL_WR_8(sc, XCTL_HOST_CFG, val); 301 XCTL_WR_8(sc, XCTL_HOST_CFG, val);
303#endif 302#endif
304 303
305 /* Enable host-only mode. */ 304 /* Enable host-only mode. */
306 val = XCTL_RD_8(sc, XCTL_CTL); 305 val = XCTL_RD_8(sc, XCTL_CTL);
307 val &= ~XCTL_CTL_DRD_MODE; 306 val &= ~XCTL_CTL_DRD_MODE;
308 XCTL_WR_8(sc, XCTL_CTL, val); 307 XCTL_WR_8(sc, XCTL_CTL, val);
309 308
310 delay(100); 309 delay(100);
311 310
312 /* Take the USB core out of reset. */ 311 /* Take the USB core out of reset. */
313 val = XCTL_RD_8(sc, XCTL_CTL); 312 val = XCTL_RD_8(sc, XCTL_CTL);
314 val &= ~XCTL_CTL_UAHC_RST; 313 val &= ~XCTL_CTL_UAHC_RST;
315 XCTL_WR_8(sc, XCTL_CTL, val); 314 XCTL_WR_8(sc, XCTL_CTL, val);
316 315
317 delay(100); 316 delay(100);
318 317
319 val = XCTL_RD_8(sc, XCTL_CTL); 318 val = XCTL_RD_8(sc, XCTL_CTL);
320 val |= XCTL_CTL_CSCLK_EN; 319 val |= XCTL_CTL_CSCLK_EN;
321 XCTL_WR_8(sc, XCTL_CTL, val); 320 XCTL_WR_8(sc, XCTL_CTL, val);
322 321
323 /* Take the PHY out of reset. */ 322 /* Take the PHY out of reset. */
324 val = XCTL_RD_8(sc, XCTL_CTL); 323 val = XCTL_RD_8(sc, XCTL_CTL);
325 val &= ~XCTL_CTL_UPHY_RST; 324 val &= ~XCTL_CTL_UPHY_RST;
326 XCTL_WR_8(sc, XCTL_CTL, val); 325 XCTL_WR_8(sc, XCTL_CTL, val);
327 (void)XCTL_RD_8(sc, XCTL_CTL); 326 (void)XCTL_RD_8(sc, XCTL_CTL);
328 327
329 /* Fix endianess. */ 328 /* Fix endianess. */
330 val = XCTL_RD_8(sc, XCTL_SHIM_CFG); 329 val = XCTL_RD_8(sc, XCTL_SHIM_CFG);
331 val &= ~XCTL_SHIM_CFG_CSR_BYTE_SWAP; 330 val &= ~XCTL_SHIM_CFG_CSR_BYTE_SWAP;
332 val &= ~XCTL_SHIM_CFG_DMA_BYTE_SWAP; 331 val &= ~XCTL_SHIM_CFG_DMA_BYTE_SWAP;
333 val |= 3ull << XCTL_SHIM_CFG_CSR_BYTE_SWAP_SHIFT; 332 val |= __SHIFTIN(XCTL_SHIM_ENDIAN_BIG, XCTL_SHIM_CFG_DMA_BYTE_SWAP);
334 val |= 1ull << XCTL_SHIM_CFG_DMA_BYTE_SWAP_SHIFT; 333 val |= __SHIFTIN(XCTL_SHIM_ENDIAN_BIG, XCTL_SHIM_CFG_CSR_BYTE_SWAP);
335 XCTL_WR_8(sc, XCTL_SHIM_CFG, val); 334 XCTL_WR_8(sc, XCTL_SHIM_CFG, val);
336 (void)XCTL_RD_8(sc, XCTL_SHIM_CFG); 335 (void)XCTL_RD_8(sc, XCTL_SHIM_CFG);
337} 336}
338 337
339int 338int
340octxhci_dwc3_init(struct xhci_softc *sc) 339octxhci_dwc3_init(struct xhci_softc *sc)
341{ 340{
342 bus_space_handle_t ioh = sc->sc_ioh; 341 bus_space_handle_t ioh = sc->sc_ioh;
343 uint32_t rev; 342 uint32_t rev;
344 uint32_t val; 343 uint32_t val;
345 344
346 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GSNPSID); 345 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GSNPSID);
347 if ((val & 0xffff0000u) != 0x55330000u) { 346 if ((val & 0xffff0000u) != 0x55330000u) {
348 aprint_error(": no DWC3 core (DWC3_GSNPSID=%08x)\n", val); 347 aprint_error(": no DWC3 core (DWC3_GSNPSID=%08x)\n", val);
349 return EIO; 348 return EIO;
350 } 349 }
351 rev = val & 0xffffu; 350 rev = val & 0xffffu;
352 aprint_normal(": DWC3 rev 0x%04x\n", rev); 351 aprint_normal(": DWC3 rev 0x%04x\n", rev);
353 352
354 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GUSB3PIPECTL(0)); 353 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GUSB3PIPECTL(0));
355 val &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX; 354 val &= ~DWC3_GUSB3PIPECTL_UX_EXIT_PX;
356 val |= DWC3_GUSB3PIPECTL_SUSPHY; 355 val |= DWC3_GUSB3PIPECTL_SUSPHY;
357 bus_space_write_4(sc->sc_iot, ioh, DWC3_GUSB3PIPECTL(0), val); 356 bus_space_write_4(sc->sc_iot, ioh, DWC3_GUSB3PIPECTL(0), val);
358 357
359 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GUSB2PHYCFG(0)); 358 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GUSB2PHYCFG(0));
360 val |= DWC3_GUSB2PHYCFG_SUSPHY; 359 val |= DWC3_GUSB2PHYCFG_SUSPHY;
361 bus_space_write_4(sc->sc_iot, ioh, DWC3_GUSB2PHYCFG(0), val); 360 bus_space_write_4(sc->sc_iot, ioh, DWC3_GUSB2PHYCFG(0), val);
362 361
363 /* Set the controller into host mode. */ 362 /* Set the controller into host mode. */
364 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GCTL); 363 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GCTL);
365 val &= ~DWC3_GCTL_PRTCAP_MASK; 364 val &= ~DWC3_GCTL_PRTCAP_MASK;
366 val |= DWC3_GCTL_PRTCAP_HOST; 365 val |= DWC3_GCTL_PRTCAP_HOST;
367 bus_space_write_4(sc->sc_iot, ioh, DWC3_GCTL, val); 366 bus_space_write_4(sc->sc_iot, ioh, DWC3_GCTL, val);
368 367
369 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GCTL); 368 val = bus_space_read_4(sc->sc_iot, ioh, DWC3_GCTL);
370 val &= ~DWC3_GCTL_SCALEDOWN_MASK; 369 val &= ~DWC3_GCTL_SCALEDOWN_MASK;
371 val &= ~DWC3_GCTL_DISSCRAMBLE; 370 val &= ~DWC3_GCTL_DISSCRAMBLE;
372 if (rev >= DWC3_REV_210A && rev <= DWC3_REV_250A) 371 if (rev >= DWC3_REV_210A && rev <= DWC3_REV_250A)
373 val |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; 372 val |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC;
374 else 373 else
375 val &= ~DWC3_GCTL_DSBLCLKGTNG; 374 val &= ~DWC3_GCTL_DSBLCLKGTNG;
376 bus_space_write_4(sc->sc_iot, ioh, DWC3_GCTL, val); 375 bus_space_write_4(sc->sc_iot, ioh, DWC3_GCTL, val);
377 376
378 return 0; 377 return 0;
379} 378}
380 379
381/* ---- bus_space(9) */ 380/* ---- bus_space(9) */
382#define CHIP octxhci  381#define CHIP octxhci
383#define CHIP_IO 382#define CHIP_IO
384#define CHIP_LITTLE_ENDIAN 383#define CHIP_LITTLE_ENDIAN
385 384
386#define CHIP_W1_BUS_START(v) 0x0000000000000000ULL 385#define CHIP_W1_BUS_START(v) 0x0000000000000000ULL
387#define CHIP_W1_BUS_END(v) 0x7fffffffffffffffULL 386#define CHIP_W1_BUS_END(v) 0x7fffffffffffffffULL
388#define CHIP_W1_SYS_START(v) 0x8000000000000000ULL 387#define CHIP_W1_SYS_START(v) 0x8000000000000000ULL
389#define CHIP_W1_SYS_END(v) 0xffffffffffffffffULL 388#define CHIP_W1_SYS_END(v) 0xffffffffffffffffULL
390 389
391#include <mips/mips/bus_space_alignstride_chipdep.c> 390#include <mips/mips/bus_space_alignstride_chipdep.c>

cvs diff -r1.1 -r1.2 src/sys/arch/mips/cavium/dev/octeon_xhcireg.h (switch to unified diff)

--- src/sys/arch/mips/cavium/dev/octeon_xhcireg.h 2020/07/16 21:34:52 1.1
+++ src/sys/arch/mips/cavium/dev/octeon_xhcireg.h 2020/07/17 08:06:02 1.2
@@ -1,89 +1,93 @@ @@ -1,89 +1,93 @@
1/* $OpenBSD: octxctlreg.h,v 1.2 2018/01/16 15:50:28 visa Exp $ */ 1/* $OpenBSD: octxctlreg.h,v 1.2 2018/01/16 15:50:28 visa Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2017 Visa Hankala 4 * Copyright (c) 2017 Visa Hankala
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies. 8 * copyright notice and this permission notice appear in all copies.
9 * 9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19#ifndef _OCTXCTLREG_H_ 19#ifndef _OCTXCTLREG_H_
20#define _OCTXCTLREG_H_ 20#define _OCTXCTLREG_H_
21 21
22#define XCTL_CTL 0x00 22#define XCTL_CTL 0x00
23#define XCTL_CTL_CLEAR_BIST 0x8000000000000000ull 23#define XCTL_CTL_CLEAR_BIST 0x8000000000000000ull
24#define XCTL_CTL_START_BIST 0x4000000000000000ull 24#define XCTL_CTL_START_BIST 0x4000000000000000ull
25#define XCTL_CTL_REFCLK_SEL 0x3000000000000000ull 25#define XCTL_CTL_REFCLK_SEL 0x3000000000000000ull
26#define XCTL_CTL_REFCLK_SEL_SHIFT 60 26#define XCTL_CTL_REFCLK_SEL_SHIFT 60
27#define XCTL_CTL_SSC_EN 0x0800000000000000ull 27#define XCTL_CTL_SSC_EN 0x0800000000000000ull
28#define XCTL_CTL_SSC_RANG 0x0700000000000000ull 28#define XCTL_CTL_SSC_RANG 0x0700000000000000ull
29#define XCTL_CTL_SSC_REFCLK_SEL 0x00ff800000000000ull 29#define XCTL_CTL_SSC_REFCLK_SEL 0x00ff800000000000ull
30#define XCTL_CTL_MPLL_MULT 0x00007f0000000000ull 30#define XCTL_CTL_MPLL_MULT 0x00007f0000000000ull
31#define XCTL_CTL_MPLL_MULT_SHIFT 40 31#define XCTL_CTL_MPLL_MULT_SHIFT 40
32#define XCTL_CTL_REFCLK_SSP_EN 0x0000008000000000ull 32#define XCTL_CTL_REFCLK_SSP_EN 0x0000008000000000ull
33#define XCTL_CTL_REFCLK_DIV2 0x0000004000000000ull 33#define XCTL_CTL_REFCLK_DIV2 0x0000004000000000ull
34#define XCTL_CTL_REFCLK_FSEL 0x0000003f00000000ull 34#define XCTL_CTL_REFCLK_FSEL 0x0000003f00000000ull
35#define XCTL_CTL_REFCLK_FSEL_SHIFT 32 35#define XCTL_CTL_REFCLK_FSEL_SHIFT 32
36#define XCTL_CTL_CLK_EN 0x0000000040000000ull 36#define XCTL_CTL_CLK_EN 0x0000000040000000ull
37#define XCTL_CTL_CLK_BYP_SEL 0x0000000020000000ull 37#define XCTL_CTL_CLK_BYP_SEL 0x0000000020000000ull
38#define XCTL_CTL_CLKDIV_RST 0x0000000010000000ull 38#define XCTL_CTL_CLKDIV_RST 0x0000000010000000ull
39#define XCTL_CTL_CLKDIV_SEL 0x0000000007000000ull 39#define XCTL_CTL_CLKDIV_SEL 0x0000000007000000ull
40#define XCTL_CTL_CLKDIV_SEL_SHIFT 24 40#define XCTL_CTL_CLKDIV_SEL_SHIFT 24
41#define XCTL_CTL_USB3_PORT_PERM_ATTACH 0x0000000000200000ull 41#define XCTL_CTL_USB3_PORT_PERM_ATTACH 0x0000000000200000ull
42#define XCTL_CTL_USB2_PORT_PERM_ATTACH 0x0000000000100000ull 42#define XCTL_CTL_USB2_PORT_PERM_ATTACH 0x0000000000100000ull
43#define XCTL_CTL_USB3_PORT_DIS 0x0000000000040000ull 43#define XCTL_CTL_USB3_PORT_DIS 0x0000000000040000ull
44#define XCTL_CTL_USB2_PORT_DIS 0x0000000000010000ull 44#define XCTL_CTL_USB2_PORT_DIS 0x0000000000010000ull
45#define XCTL_CTL_SSPOWER_EN 0x0000000000004000ull 45#define XCTL_CTL_SSPOWER_EN 0x0000000000004000ull
46#define XCTL_CTL_HSPOWER_EN 0x0000000000001000ull 46#define XCTL_CTL_HSPOWER_EN 0x0000000000001000ull
47#define XCTL_CTL_CSCLK_EN 0x0000000000000010ull 47#define XCTL_CTL_CSCLK_EN 0x0000000000000010ull
48#define XCTL_CTL_DRD_MODE 0x0000000000000008ull 48#define XCTL_CTL_DRD_MODE 0x0000000000000008ull
49#define XCTL_CTL_UPHY_RST 0x0000000000000004ull 49#define XCTL_CTL_UPHY_RST 0x0000000000000004ull
50#define XCTL_CTL_UAHC_RST 0x0000000000000002ull 50#define XCTL_CTL_UAHC_RST 0x0000000000000002ull
51#define XCTL_CTL_UCTL_RST 0x0000000000000001ull 51#define XCTL_CTL_UCTL_RST 0x0000000000000001ull
52 52
53#define XCTL_HOST_CFG 0xe0 53#define XCTL_HOST_CFG 0xe0
54#define XCTL_HOST_CFG_PPC_EN 0x0000000002000000ull 54#define XCTL_HOST_CFG_PPC_EN 0x0000000002000000ull
55#define XCTL_HOST_CFG_PPC_ACTIVE_HIGH_EN 0x0000000001000000ull 55#define XCTL_HOST_CFG_PPC_ACTIVE_HIGH_EN 0x0000000001000000ull
56 56
57#define XCTL_SHIM_CFG 0xe8 57#define XCTL_SHIM_CFG 0xe8
58#define XCTL_SHIM_CFG_DMA_BYTE_SWAP 0x0000000000000300ull 58#define XCTL_SHIM_CFG_DMA_BYTE_SWAP 0x0000000000000300ull
59#define XCTL_SHIM_CFG_DMA_BYTE_SWAP_SHIFT 8 59#define XCTL_SHIM_CFG_DMA_BYTE_SWAP_SHIFT 8
60#define XCTL_SHIM_CFG_CSR_BYTE_SWAP 0x0000000000000003ull 60#define XCTL_SHIM_CFG_CSR_BYTE_SWAP 0x0000000000000003ull
61#define XCTL_SHIM_CFG_CSR_BYTE_SWAP_SHIFT 0 61#define XCTL_SHIM_CFG_CSR_BYTE_SWAP_SHIFT 0
 62#define XCTL_SHIM_ENDIAN_LITTLE 0 /* A-B-C-D-E-F-G-H -> A-B-C-D-E-F-G-H */
 63#define XCTL_SHIM_ENDIAN_BIG 1 /* A-B-C-D-E-F-G-H -> H-G-F-E-D-C-B-A */
 64#define XCTL_SHIM_ENDIAN_RSVD2 2 /* A-B-C-D-E-F-G-H -> D-C-B-A-H-G-F-E */
 65#define XCTL_SHIM_ENDIAN_RSVD3 3 /* A-B-C-D-E-F-G-H -> E-F-G-H-A-B-C-D */
62 66
63/* 67/*
64 * DWC3 core control registers. 68 * DWC3 core control registers.
65 * These are relative to the xHCI register space. 69 * These are relative to the xHCI register space.
66 */ 70 */
67 71
68#define DWC3_GCTL 0xc110 72#define DWC3_GCTL 0xc110
69#define DWC3_GCTL_PRTCAP_MASK 0x00003000u 73#define DWC3_GCTL_PRTCAP_MASK 0x00003000u
70#define DWC3_GCTL_PRTCAP_HOST 0x00001000u 74#define DWC3_GCTL_PRTCAP_HOST 0x00001000u
71#define DWC3_GCTL_SOFITPSYNC 0x00000400u 75#define DWC3_GCTL_SOFITPSYNC 0x00000400u
72#define DWC3_GCTL_SCALEDOWN_MASK 0x00000030u 76#define DWC3_GCTL_SCALEDOWN_MASK 0x00000030u
73#define DWC3_GCTL_DISSCRAMBLE 0x00000004u 77#define DWC3_GCTL_DISSCRAMBLE 0x00000004u
74#define DWC3_GCTL_DSBLCLKGTNG 0x00000001u 78#define DWC3_GCTL_DSBLCLKGTNG 0x00000001u
75 79
76#define DWC3_GSNPSID 0xc120 80#define DWC3_GSNPSID 0xc120
77 81
78#define DWC3_GUSB2PHYCFG(n) (0xc200 + ((n) * 0x04)) 82#define DWC3_GUSB2PHYCFG(n) (0xc200 + ((n) * 0x04))
79#define DWC3_GUSB2PHYCFG_SUSPHY 0x00000040u 83#define DWC3_GUSB2PHYCFG_SUSPHY 0x00000040u
80 84
81#define DWC3_GUSB3PIPECTL(n) (0xc2c0 + ((n) * 0x04)) 85#define DWC3_GUSB3PIPECTL(n) (0xc2c0 + ((n) * 0x04))
82#define DWC3_GUSB3PIPECTL_UX_EXIT_PX 0x08000000u 86#define DWC3_GUSB3PIPECTL_UX_EXIT_PX 0x08000000u
83#define DWC3_GUSB3PIPECTL_SUSPHY 0x00020000u 87#define DWC3_GUSB3PIPECTL_SUSPHY 0x00020000u
84 88
85/* DWC3 revision numbers. */ 89/* DWC3 revision numbers. */
86#define DWC3_REV_210A 0x210a 90#define DWC3_REV_210A 0x210a
87#define DWC3_REV_250A 0x250a 91#define DWC3_REV_250A 0x250a
88 92
89#endif /* !_OCTXCTLREG_H_ */ 93#endif /* !_OCTXCTLREG_H_ */