xref: /openbsd/sys/arch/octeon/dev/octdwctwo.c (revision 4cfece93)
1 /*	$OpenBSD: octdwctwo.c,v 1.12 2019/07/28 12:57:09 visa Exp $	*/
2 
3 /*
4  * Copyright (c) 2015 Masao Uebayashi <uebayasi@tombiinc.com>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
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
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 
23 #include <machine/intr.h>
24 #include <machine/bus.h>
25 #include <machine/octeonreg.h>
26 #include <machine/octeonvar.h>
27 #include <machine/octeon_model.h>
28 
29 #include <octeon/dev/iobusvar.h>
30 #include <octeon/dev/octhcireg.h>
31 
32 #include <dev/usb/usb.h>
33 #include <dev/usb/usbdi.h>
34 #include <dev/usb/usbdivar.h>
35 
36 #include <dev/usb/dwc2/dwc2var.h>
37 #include <dev/usb/dwc2/dwc2.h>
38 #include <dev/usb/dwc2/dwc2_core.h>
39 
40 struct octdwctwo_softc {
41 	struct dwc2_softc	sc_dwc2;
42 
43 	/* USBN bus space */
44 	bus_space_tag_t		sc_bust;
45 	bus_space_handle_t	sc_regh;
46 	bus_space_handle_t	sc_regh2;
47 
48 	void			*sc_ih;
49 };
50 
51 int			octdwctwo_match(struct device *, void *, void *);
52 void			octdwctwo_attach(struct device *, struct device *,
53 			    void *);
54 int			octdwctwo_activate(struct device *, int);
55 int			octdwctwo_set_dma_addr(void *, dma_addr_t, int);
56 u_int64_t		octdwctwo_reg2_rd(struct octdwctwo_softc *, bus_size_t);
57 void			octdwctwo_reg2_wr(struct octdwctwo_softc *, bus_size_t,
58 			    u_int64_t);
59 void			octdwctwo_reg_set(struct octdwctwo_softc *, bus_size_t,
60 			    u_int64_t);
61 void			octdwctwo_reg_clear(struct octdwctwo_softc *,
62 			    bus_size_t, u_int64_t);
63 u_int32_t		octdwctwo_read_4(bus_space_tag_t, bus_space_handle_t,
64 			    bus_size_t);
65 void			octdwctwo_write_4(bus_space_tag_t, bus_space_handle_t,
66 			    bus_size_t, u_int32_t);
67 
68 
69 const struct cfattach octdwctwo_ca = {
70 	sizeof(struct octdwctwo_softc), octdwctwo_match, octdwctwo_attach,
71 	NULL, octdwctwo_activate
72 };
73 
74 struct cfdriver dwctwo_cd = {
75 	NULL, "dwctwo", DV_DULL
76 };
77 
78 static struct dwc2_core_params octdwctwo_params = {
79 	.otg_cap = 2,
80 	.otg_ver = 0,
81 	.dma_enable = 1,
82 	.dma_desc_enable = 0,
83 	.speed = 0,
84 	.enable_dynamic_fifo = 1,
85 	.en_multiple_tx_fifo = 0,
86 	.host_rx_fifo_size = 456,
87 	.host_nperio_tx_fifo_size = 912,
88 	.host_perio_tx_fifo_size = 256,
89 	.max_transfer_size = 65535,
90 	.max_packet_count = 511,
91 	.host_channels = 8,
92 	.phy_type = 1,
93 	.phy_utmi_width = 16,
94 	.phy_ulpi_ddr = 0,
95 	.phy_ulpi_ext_vbus = 0,
96 	.i2c_enable = 0,
97 	.ulpi_fs_ls = 0,
98 	.host_support_fs_ls_low_power = 0,
99 	.host_ls_low_power_phy_clk = 0,
100 	.ts_dline = 0,
101 	.reload_ctl = 0,
102 	.ahbcfg = 0x7,
103 	.uframe_sched = 1,
104 };
105 
106 static struct dwc2_core_dma_config octdwctwo_dma_config = {
107 	.set_dma_addr = octdwctwo_set_dma_addr,
108 };
109 
110 /*
111  * This bus space tag adjusts register addresses to account for
112  * dwc2 using little endian addressing.  dwc2 only does 32bit reads
113  * and writes, so only those functions are provided.
114  */
115 bus_space_t octdwctwo_tag = {
116 	.bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
117 	.bus_private = NULL,
118 	._space_read_4 =	octdwctwo_read_4,
119 	._space_write_4 =	octdwctwo_write_4,
120 	._space_map =		iobus_space_map,
121 	._space_unmap =		iobus_space_unmap,
122 	._space_subregion =	generic_space_region,
123 	._space_vaddr =		generic_space_vaddr
124 };
125 
126 int
127 octdwctwo_match(struct device *parent, void *match, void *aux)
128 {
129 	int id;
130 
131 	id = octeon_get_chipid();
132 	switch (octeon_model_family(id)) {
133 	case OCTEON_MODEL_FAMILY_CN30XX:
134 	case OCTEON_MODEL_FAMILY_CN31XX:
135 	case OCTEON_MODEL_FAMILY_CN50XX:
136 		return (1);
137 	default:
138 		return (0);
139 	}
140 }
141 
142 void
143 octdwctwo_attach(struct device *parent, struct device *self, void *aux)
144 {
145 	struct octdwctwo_softc *sc = (struct octdwctwo_softc *)self;
146 	struct iobus_attach_args *aa = aux;
147 	uint64_t clk;
148 	int rc;
149 
150 	sc->sc_dwc2.sc_iot = &octdwctwo_tag;
151 	sc->sc_dwc2.sc_bus.pipe_size = sizeof(struct usbd_pipe);
152 	sc->sc_dwc2.sc_bus.dmatag = aa->aa_dmat;
153 	sc->sc_dwc2.sc_params = &octdwctwo_params;
154 
155 	rc = bus_space_map(sc->sc_dwc2.sc_iot, USBC_BASE, USBC_SIZE,
156 	    0, &sc->sc_dwc2.sc_ioh);
157 	KASSERT(rc == 0);
158 
159 	sc->sc_bust = aa->aa_bust;
160 	rc = bus_space_map(sc->sc_bust, USBN_BASE, USBN_SIZE,
161 	    0, &sc->sc_regh);
162 	KASSERT(rc == 0);
163 	rc = bus_space_map(sc->sc_bust, USBN_2_BASE, USBN_2_SIZE,
164 	    0, &sc->sc_regh2);
165 	KASSERT(rc == 0);
166 
167 	/*
168 	 * Clock setup.
169 	 */
170 	clk = bus_space_read_8(sc->sc_bust, sc->sc_regh, USBN_CLK_CTL_OFFSET);
171 	clk |= USBN_CLK_CTL_POR;
172 	clk &= ~(USBN_CLK_CTL_HRST | USBN_CLK_CTL_PRST | USBN_CLK_CTL_HCLK_RST |
173 	    USBN_CLK_CTL_ENABLE | USBN_CLK_CTL_P_C_SEL | USBN_CLK_CTL_P_RTYPE);
174 	clk |= SET_USBN_CLK_CTL_DIVIDE(0x4ULL)
175 	    | SET_USBN_CLK_CTL_DIVIDE2(0x0ULL);
176 
177 	bus_space_write_8(sc->sc_bust, sc->sc_regh, USBN_CLK_CTL_OFFSET, clk);
178 	bus_space_read_8(sc->sc_bust, sc->sc_regh, USBN_CLK_CTL_OFFSET);
179 
180 	/*
181 	 * Reset HCLK and wait for it to stabilize.
182 	 */
183 	octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_HCLK_RST);
184 	delay(64);
185 
186 	octdwctwo_reg_clear(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_POR);
187 
188 	/*
189 	 * Wait for the PHY clock to start.
190 	 */
191 	delay(1000);
192 
193 	octdwctwo_reg_set(sc, USBN_USBP_CTL_STATUS_OFFSET,
194 	    USBN_USBP_CTL_STATUS_ATE_RESET);
195 	delay(10);
196 
197 	octdwctwo_reg_clear(sc, USBN_USBP_CTL_STATUS_OFFSET,
198 			USBN_USBP_CTL_STATUS_ATE_RESET);
199 	octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_PRST);
200 
201 	/*
202 	 * Select host mode.
203 	 */
204 	octdwctwo_reg_clear(sc, USBN_USBP_CTL_STATUS_OFFSET,
205 	    USBN_USBP_CTL_STATUS_HST_MODE);
206 	delay(1);
207 
208 	octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_HRST);
209 
210 	/*
211 	 * Enable clock.
212 	 */
213 	octdwctwo_reg_set(sc, USBN_CLK_CTL_OFFSET, USBN_CLK_CTL_ENABLE);
214 	delay(1);
215 
216 	strlcpy(sc->sc_dwc2.sc_vendor, "Octeon", sizeof(sc->sc_dwc2.sc_vendor));
217 
218 	rc = dwc2_init(&sc->sc_dwc2);
219 	if (rc != 0)
220 		return;
221 	octdwctwo_dma_config.set_dma_addr_data = sc;
222 	rc = dwc2_dma_config(&sc->sc_dwc2, &octdwctwo_dma_config);
223 	if (rc != 0)
224 		return;
225 
226 	printf("\n");
227 
228 	sc->sc_dwc2.sc_child = config_found(&sc->sc_dwc2.sc_bus.bdev,
229 	    &sc->sc_dwc2.sc_bus, usbctlprint);
230 
231 	sc->sc_ih = octeon_intr_establish(CIU_INT_USB, IPL_USB | IPL_MPSAFE,
232 	    dwc2_intr, (void *)&sc->sc_dwc2, sc->sc_dwc2.sc_bus.bdev.dv_xname);
233 	KASSERT(sc->sc_ih != NULL);
234 }
235 
236 int
237 octdwctwo_activate(struct device *self, int act)
238 {
239 	struct octdwctwo_softc *sc = (struct octdwctwo_softc *)self;
240 	uint64_t clk;
241 	int rv = 0;
242 
243 	switch (act) {
244 	case DVACT_POWERDOWN:
245 		/*
246 		 * Put the controller into reset mode.
247 		 * It appears necessary to hold this state for a moment.
248 		 * Otherwise subsequent attempts to reinitialize the controller
249 		 * may fail because of hanging or trapping access
250 		 * of DWC2 core registers.
251 		 */
252 		clk = bus_space_read_8(sc->sc_bust, sc->sc_regh,
253 		    USBN_CLK_CTL_OFFSET);
254 		clk |= USBN_CLK_CTL_POR;
255 		clk |= USBN_CLK_CTL_HCLK_RST;
256 		clk |= USBN_CLK_CTL_ENABLE;
257 		clk &= ~USBN_CLK_CTL_HRST;
258 		clk &= ~USBN_CLK_CTL_PRST;
259 		bus_space_write_8(sc->sc_bust, sc->sc_regh,
260 		    USBN_CLK_CTL_OFFSET, clk);
261 		(void)bus_space_read_8(sc->sc_bust, sc->sc_regh,
262 		    USBN_CLK_CTL_OFFSET);
263 		delay(50000);
264 		break;
265 	default:
266 		break;
267 	}
268 	return rv;
269 }
270 
271 int
272 octdwctwo_set_dma_addr(void *data, dma_addr_t dma_addr, int ch)
273 {
274 	struct octdwctwo_softc *sc = data;
275 
276 	octdwctwo_reg2_wr(sc,
277 	    USBN_DMA0_INB_CHN0_OFFSET + ch * 0x8, dma_addr);
278 	octdwctwo_reg2_wr(sc,
279 	    USBN_DMA0_OUTB_CHN0_OFFSET + ch * 0x8, dma_addr);
280 	return 0;
281 }
282 
283 u_int64_t
284 octdwctwo_reg2_rd(struct octdwctwo_softc *sc, bus_size_t offset)
285 {
286 	u_int64_t value;
287 
288 	value = bus_space_read_8(sc->sc_bust, sc->sc_regh2, offset);
289 	return value;
290 }
291 
292 void
293 octdwctwo_reg2_wr(struct octdwctwo_softc *sc, bus_size_t offset, u_int64_t value)
294 {
295 	bus_space_write_8(sc->sc_bust, sc->sc_regh2, offset, value);
296 	/* guarantee completion of the store operation on RSL registers*/
297 	bus_space_read_8(sc->sc_bust, sc->sc_regh2, offset);
298 }
299 
300 void
301 octdwctwo_reg_set(struct octdwctwo_softc *sc, bus_size_t offset,
302     u_int64_t bits)
303 {
304 	u_int64_t value;
305 	value = bus_space_read_8(sc->sc_bust, sc->sc_regh, offset);
306 	value |= bits;
307 
308 	bus_space_write_8(sc->sc_bust, sc->sc_regh, offset, value);
309 	bus_space_read_8(sc->sc_bust, sc->sc_regh, offset);
310 }
311 
312 void
313 octdwctwo_reg_clear(struct octdwctwo_softc *sc, bus_size_t offset,
314     u_int64_t bits)
315 {
316 	u_int64_t value;
317 	value = bus_space_read_8(sc->sc_bust, sc->sc_regh, offset);
318 	value &= ~bits;
319 
320 	bus_space_write_8(sc->sc_bust, sc->sc_regh, offset, value);
321 	bus_space_read_8(sc->sc_bust, sc->sc_regh, offset);
322 }
323 
324 u_int32_t
325 octdwctwo_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
326 {
327 	return *(volatile u_int32_t *)(h + (o^4));
328 }
329 
330 void
331 octdwctwo_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
332     u_int32_t v)
333 {
334 	*(volatile u_int32_t *)(h + (o^4)) = v;
335 }
336