xref: /rk3399_rockchip-uboot/drivers/usb/musb/musb_core.c (revision 95de1e2f26b562156210833ff667be6d071de019)
12731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
22731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Mentor USB OTG Core functionality common for both Host and Device
32731b9a8SJean-Christophe PLAGNIOL-VILLARD  * functionality.
42731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
52731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Copyright (c) 2008 Texas Instruments
62731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
82731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
92731b9a8SJean-Christophe PLAGNIOL-VILLARD  * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
102731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
112731b9a8SJean-Christophe PLAGNIOL-VILLARD 
122731b9a8SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
132731b9a8SJean-Christophe PLAGNIOL-VILLARD 
142731b9a8SJean-Christophe PLAGNIOL-VILLARD #include "musb_core.h"
152731b9a8SJean-Christophe PLAGNIOL-VILLARD struct musb_regs *musbr;
162731b9a8SJean-Christophe PLAGNIOL-VILLARD 
172731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
182731b9a8SJean-Christophe PLAGNIOL-VILLARD  * program the mentor core to start (enable interrupts, dma, etc.)
192731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
musb_start(void)202731b9a8SJean-Christophe PLAGNIOL-VILLARD void musb_start(void)
212731b9a8SJean-Christophe PLAGNIOL-VILLARD {
22*95de1e2fSPaul Kocialkowski #if defined(CONFIG_USB_MUSB_HCD)
232731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8 devctl;
249bb47abfSAjay Kumar Gupta 	u8 busctl;
25f298e4b6STom Rix #endif
262731b9a8SJean-Christophe PLAGNIOL-VILLARD 
272731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* disable all interrupts */
282731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writew(0, &musbr->intrtxe);
292731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writew(0, &musbr->intrrxe);
302731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writeb(0, &musbr->intrusbe);
312731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writeb(0, &musbr->testmode);
322731b9a8SJean-Christophe PLAGNIOL-VILLARD 
332731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* put into basic highspeed mode and start session */
342731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writeb(MUSB_POWER_HSENAB, &musbr->power);
35*95de1e2fSPaul Kocialkowski #if defined(CONFIG_USB_MUSB_HCD)
369bb47abfSAjay Kumar Gupta 	/* Program PHY to use EXT VBUS if required */
379bb47abfSAjay Kumar Gupta 	if (musb_cfg.extvbus == 1) {
389bb47abfSAjay Kumar Gupta 		busctl = musb_read_ulpi_buscontrol(musbr);
399bb47abfSAjay Kumar Gupta 		musb_write_ulpi_buscontrol(musbr, busctl | ULPI_USE_EXTVBUS);
409bb47abfSAjay Kumar Gupta 	}
419bb47abfSAjay Kumar Gupta 
422731b9a8SJean-Christophe PLAGNIOL-VILLARD 	devctl = readb(&musbr->devctl);
432731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writeb(devctl | MUSB_DEVCTL_SESSION, &musbr->devctl);
442731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
452731b9a8SJean-Christophe PLAGNIOL-VILLARD }
462731b9a8SJean-Christophe PLAGNIOL-VILLARD 
47df402ba3SBryan Wu #ifdef MUSB_NO_DYNAMIC_FIFO
48df402ba3SBryan Wu # define config_fifo(dir, idx, addr)
49df402ba3SBryan Wu #else
50df402ba3SBryan Wu # define config_fifo(dir, idx, addr) \
51df402ba3SBryan Wu 	do { \
52df402ba3SBryan Wu 		writeb(idx, &musbr->dir##fifosz); \
53df402ba3SBryan Wu 		writew(fifoaddr >> 3, &musbr->dir##fifoadd); \
54df402ba3SBryan Wu 	} while (0)
55df402ba3SBryan Wu #endif
56df402ba3SBryan Wu 
572731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
582731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This function configures the endpoint configuration. The musb hcd or musb
592731b9a8SJean-Christophe PLAGNIOL-VILLARD  * device implementation can use this function to configure the endpoints
602731b9a8SJean-Christophe PLAGNIOL-VILLARD  * and set the FIFO sizes. Note: The summation of FIFO sizes of all endpoints
612731b9a8SJean-Christophe PLAGNIOL-VILLARD  * should not be more than the available FIFO size.
622731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
632731b9a8SJean-Christophe PLAGNIOL-VILLARD  * epinfo	- Pointer to EP configuration table
642731b9a8SJean-Christophe PLAGNIOL-VILLARD  * cnt		- Number of entries in the EP conf table.
652731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
musb_configure_ep(const struct musb_epinfo * epinfo,u8 cnt)660228348eSMike Frysinger void musb_configure_ep(const struct musb_epinfo *epinfo, u8 cnt)
672731b9a8SJean-Christophe PLAGNIOL-VILLARD {
682731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u16 csr;
692731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u16 fifoaddr = 64; /* First 64 bytes of FIFO reserved for EP0 */
702731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u32 fifosize;
712731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8  idx;
722731b9a8SJean-Christophe PLAGNIOL-VILLARD 
732731b9a8SJean-Christophe PLAGNIOL-VILLARD 	while (cnt--) {
742731b9a8SJean-Christophe PLAGNIOL-VILLARD 		/* prepare fifosize to write to register */
752731b9a8SJean-Christophe PLAGNIOL-VILLARD 		fifosize = epinfo->epsize >> 3;
762731b9a8SJean-Christophe PLAGNIOL-VILLARD 		idx = ffs(fifosize) - 1;
772731b9a8SJean-Christophe PLAGNIOL-VILLARD 
782731b9a8SJean-Christophe PLAGNIOL-VILLARD 		writeb(epinfo->epnum, &musbr->index);
792731b9a8SJean-Christophe PLAGNIOL-VILLARD 		if (epinfo->epdir) {
802731b9a8SJean-Christophe PLAGNIOL-VILLARD 			/* Configure fifo size and fifo base address */
81df402ba3SBryan Wu 			config_fifo(tx, idx, fifoaddr);
82f298e4b6STom Rix 
83f298e4b6STom Rix 			csr = readw(&musbr->txcsr);
84*95de1e2fSPaul Kocialkowski #if defined(CONFIG_USB_MUSB_HCD)
852731b9a8SJean-Christophe PLAGNIOL-VILLARD 			/* clear the data toggle bit */
862731b9a8SJean-Christophe PLAGNIOL-VILLARD 			writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
872731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
882731b9a8SJean-Christophe PLAGNIOL-VILLARD 			/* Flush fifo if required */
892731b9a8SJean-Christophe PLAGNIOL-VILLARD 			if (csr & MUSB_TXCSR_TXPKTRDY)
902731b9a8SJean-Christophe PLAGNIOL-VILLARD 				writew(csr | MUSB_TXCSR_FLUSHFIFO,
912731b9a8SJean-Christophe PLAGNIOL-VILLARD 					&musbr->txcsr);
922731b9a8SJean-Christophe PLAGNIOL-VILLARD 		} else {
932731b9a8SJean-Christophe PLAGNIOL-VILLARD 			/* Configure fifo size and fifo base address */
94df402ba3SBryan Wu 			config_fifo(rx, idx, fifoaddr);
95f298e4b6STom Rix 
96f298e4b6STom Rix 			csr = readw(&musbr->rxcsr);
97*95de1e2fSPaul Kocialkowski #if defined(CONFIG_USB_MUSB_HCD)
982731b9a8SJean-Christophe PLAGNIOL-VILLARD 			/* clear the data toggle bit */
992731b9a8SJean-Christophe PLAGNIOL-VILLARD 			writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
1002731b9a8SJean-Christophe PLAGNIOL-VILLARD #endif
1012731b9a8SJean-Christophe PLAGNIOL-VILLARD 			/* Flush fifo if required */
1022731b9a8SJean-Christophe PLAGNIOL-VILLARD 			if (csr & MUSB_RXCSR_RXPKTRDY)
1032731b9a8SJean-Christophe PLAGNIOL-VILLARD 				writew(csr | MUSB_RXCSR_FLUSHFIFO,
1042731b9a8SJean-Christophe PLAGNIOL-VILLARD 					&musbr->rxcsr);
1052731b9a8SJean-Christophe PLAGNIOL-VILLARD 		}
1062731b9a8SJean-Christophe PLAGNIOL-VILLARD 		fifoaddr += epinfo->epsize;
1072731b9a8SJean-Christophe PLAGNIOL-VILLARD 		epinfo++;
1082731b9a8SJean-Christophe PLAGNIOL-VILLARD 	}
1092731b9a8SJean-Christophe PLAGNIOL-VILLARD }
1102731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1112731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
1122731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This function writes data to endpoint fifo
1132731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
1142731b9a8SJean-Christophe PLAGNIOL-VILLARD  * ep		- endpoint number
1152731b9a8SJean-Christophe PLAGNIOL-VILLARD  * length	- number of bytes to write to FIFO
1162731b9a8SJean-Christophe PLAGNIOL-VILLARD  * fifo_data	- Pointer to data buffer that contains the data to write
1172731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
118df402ba3SBryan Wu __attribute__((weak))
write_fifo(u8 ep,u32 length,void * fifo_data)1192731b9a8SJean-Christophe PLAGNIOL-VILLARD void write_fifo(u8 ep, u32 length, void *fifo_data)
1202731b9a8SJean-Christophe PLAGNIOL-VILLARD {
1212731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8  *data = (u8 *)fifo_data;
1222731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1232731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* select the endpoint index */
1242731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writeb(ep, &musbr->index);
1252731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1262731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* write the data to the fifo */
1272731b9a8SJean-Christophe PLAGNIOL-VILLARD 	while (length--)
1282731b9a8SJean-Christophe PLAGNIOL-VILLARD 		writeb(*data++, &musbr->fifox[ep]);
1292731b9a8SJean-Christophe PLAGNIOL-VILLARD }
1302731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1312731b9a8SJean-Christophe PLAGNIOL-VILLARD /*
1325689f4b5SAjay Kumar Gupta  * AM35x supports only 32bit read operations so
1335689f4b5SAjay Kumar Gupta  * use seperate read_fifo() function for it.
1345689f4b5SAjay Kumar Gupta  */
1355689f4b5SAjay Kumar Gupta #ifndef CONFIG_USB_AM35X
1365689f4b5SAjay Kumar Gupta /*
1372731b9a8SJean-Christophe PLAGNIOL-VILLARD  * This function reads data from endpoint fifo
1382731b9a8SJean-Christophe PLAGNIOL-VILLARD  *
1392731b9a8SJean-Christophe PLAGNIOL-VILLARD  * ep           - endpoint number
1402731b9a8SJean-Christophe PLAGNIOL-VILLARD  * length       - number of bytes to read from FIFO
1412731b9a8SJean-Christophe PLAGNIOL-VILLARD  * fifo_data    - pointer to data buffer into which data is read
1422731b9a8SJean-Christophe PLAGNIOL-VILLARD  */
143df402ba3SBryan Wu __attribute__((weak))
read_fifo(u8 ep,u32 length,void * fifo_data)1442731b9a8SJean-Christophe PLAGNIOL-VILLARD void read_fifo(u8 ep, u32 length, void *fifo_data)
1452731b9a8SJean-Christophe PLAGNIOL-VILLARD {
1462731b9a8SJean-Christophe PLAGNIOL-VILLARD 	u8  *data = (u8 *)fifo_data;
1472731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1482731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* select the endpoint index */
1492731b9a8SJean-Christophe PLAGNIOL-VILLARD 	writeb(ep, &musbr->index);
1502731b9a8SJean-Christophe PLAGNIOL-VILLARD 
1512731b9a8SJean-Christophe PLAGNIOL-VILLARD 	/* read the data to the fifo */
1522731b9a8SJean-Christophe PLAGNIOL-VILLARD 	while (length--)
1532731b9a8SJean-Christophe PLAGNIOL-VILLARD 		*data++ = readb(&musbr->fifox[ep]);
1542731b9a8SJean-Christophe PLAGNIOL-VILLARD }
1555689f4b5SAjay Kumar Gupta #endif /* CONFIG_USB_AM35X */
156