xref: /freebsd/sys/arm/ti/usb/omap_tll.c (revision fdafd315)
15b03aba6SOleksandr Tymoshenko /*-
25b03aba6SOleksandr Tymoshenko  * Copyright (c) 2011
35b03aba6SOleksandr Tymoshenko  *	Ben Gray <ben.r.gray@gmail.com>.
45b03aba6SOleksandr Tymoshenko  * All rights reserved.
55b03aba6SOleksandr Tymoshenko  *
65b03aba6SOleksandr Tymoshenko  * Redistribution and use in source and binary forms, with or without
75b03aba6SOleksandr Tymoshenko  * modification, are permitted provided that the following conditions
85b03aba6SOleksandr Tymoshenko  * are met:
95b03aba6SOleksandr Tymoshenko  * 1. Redistributions of source code must retain the above copyright
105b03aba6SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer.
115b03aba6SOleksandr Tymoshenko  * 2. Redistributions in binary form must reproduce the above copyright
125b03aba6SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer in the
135b03aba6SOleksandr Tymoshenko  *    documentation and/or other materials provided with the distribution.
145b03aba6SOleksandr Tymoshenko  *
155b03aba6SOleksandr Tymoshenko  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
165b03aba6SOleksandr Tymoshenko  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
175b03aba6SOleksandr Tymoshenko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
185b03aba6SOleksandr Tymoshenko  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
195b03aba6SOleksandr Tymoshenko  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
205b03aba6SOleksandr Tymoshenko  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
215b03aba6SOleksandr Tymoshenko  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
225b03aba6SOleksandr Tymoshenko  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
235b03aba6SOleksandr Tymoshenko  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
245b03aba6SOleksandr Tymoshenko  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
255b03aba6SOleksandr Tymoshenko  * SUCH DAMAGE.
265b03aba6SOleksandr Tymoshenko  */
275b03aba6SOleksandr Tymoshenko 
285b03aba6SOleksandr Tymoshenko #include <sys/param.h>
295b03aba6SOleksandr Tymoshenko #include <sys/systm.h>
305b03aba6SOleksandr Tymoshenko #include <sys/conf.h>
315b03aba6SOleksandr Tymoshenko #include <sys/kernel.h>
325b03aba6SOleksandr Tymoshenko #include <sys/rman.h>
335b03aba6SOleksandr Tymoshenko #include <sys/module.h>
345b03aba6SOleksandr Tymoshenko 
355b03aba6SOleksandr Tymoshenko #include <dev/ofw/ofw_bus_subr.h>
365b03aba6SOleksandr Tymoshenko 
375b03aba6SOleksandr Tymoshenko #include <machine/bus.h>
385b03aba6SOleksandr Tymoshenko 
390050ea24SMichal Meloun #include <arm/ti/ti_sysc.h>
405b03aba6SOleksandr Tymoshenko #include <arm/ti/usb/omap_usb.h>
415b03aba6SOleksandr Tymoshenko 
425b03aba6SOleksandr Tymoshenko /*
435b03aba6SOleksandr Tymoshenko  * USB TLL Module
445b03aba6SOleksandr Tymoshenko  */
455b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_REVISION                        0x0000
465b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_SYSCONFIG                       0x0010
475b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_SYSSTATUS                       0x0014
485b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_IRQSTATUS                       0x0018
495b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_IRQENABLE                       0x001C
505b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_TLL_SHARED_CONF                 0x0030
515b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_TLL_CHANNEL_CONF(i)             (0x0040 + (0x04 * (i)))
525b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_SAR_CNTX(i)                     (0x0400 + (0x04 * (i)))
535b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_ID_LO(i)            (0x0800 + (0x100 * (i)))
545b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_ID_HI(i)            (0x0801 + (0x100 * (i)))
555b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_PRODUCT_ID_LO(i)           (0x0802 + (0x100 * (i)))
565b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_PRODUCT_ID_HI(i)           (0x0803 + (0x100 * (i)))
575b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_FUNCTION_CTRL(i)           (0x0804 + (0x100 * (i)))
585b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_FUNCTION_CTRL_SET(i)       (0x0805 + (0x100 * (i)))
595b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_FUNCTION_CTRL_CLR(i)       (0x0806 + (0x100 * (i)))
605b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_INTERFACE_CTRL(i)          (0x0807 + (0x100 * (i)))
615b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_INTERFACE_CTRL_SET(i)      (0x0808 + (0x100 * (i)))
625b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_INTERFACE_CTRL_CLR(i)      (0x0809 + (0x100 * (i)))
635b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_OTG_CTRL(i)                (0x080A + (0x100 * (i)))
645b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_OTG_CTRL_SET(i)            (0x080B + (0x100 * (i)))
655b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_OTG_CTRL_CLR(i)            (0x080C + (0x100 * (i)))
665b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE(i)         (0x080D + (0x100 * (i)))
675b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE_SET(i)     (0x080E + (0x100 * (i)))
685b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_EN_RISE_CLR(i)     (0x080F + (0x100 * (i)))
695b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL(i)         (0x0810 + (0x100 * (i)))
705b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL_SET(i)     (0x0811 + (0x100 * (i)))
715b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_EN_FALL_CLR(i)     (0x0812 + (0x100 * (i)))
725b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_STATUS(i)          (0x0813 + (0x100 * (i)))
735b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_LATCH(i)           (0x0814 + (0x100 * (i)))
745b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_DEBUG(i)                   (0x0815 + (0x100 * (i)))
755b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER(i)        (0x0816 + (0x100 * (i)))
765b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER_SET(i)    (0x0817 + (0x100 * (i)))
775b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_SCRATCH_REGISTER_CLR(i)    (0x0818 + (0x100 * (i)))
785b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_EXTENDED_SET_ACCESS(i)     (0x082F + (0x100 * (i)))
795b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN(i)        (0x0830 + (0x100 * (i)))
805b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_SET(i)    (0x0831 + (0x100 * (i)))
815b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_EN_CLR(i)    (0x0832 + (0x100 * (i)))
825b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_STATUS(i)    (0x0833 + (0x100 * (i)))
835b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VCONTROL_LATCH(i)     (0x0834 + (0x100 * (i)))
845b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VSTATUS(i)            (0x0835 + (0x100 * (i)))
855b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VSTATUS_SET(i)        (0x0836 + (0x100 * (i)))
865b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_UTMI_VSTATUS_CLR(i)        (0x0837 + (0x100 * (i)))
875b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_USB_INT_LATCH_NOCLR(i)     (0x0838 + (0x100 * (i)))
885b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_INT_EN(i)           (0x083B + (0x100 * (i)))
895b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_INT_EN_SET(i)       (0x083C + (0x100 * (i)))
905b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_INT_EN_CLR(i)       (0x083D + (0x100 * (i)))
915b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_INT_STATUS(i)       (0x083E + (0x100 * (i)))
925b03aba6SOleksandr Tymoshenko #define	OMAP_USBTLL_ULPI_VENDOR_INT_LATCH(i)        (0x083F + (0x100 * (i)))
935b03aba6SOleksandr Tymoshenko 
945b03aba6SOleksandr Tymoshenko /* TLL Register Set */
955b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_CACTIVITY                 (1UL << 8)
965b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_SIDLE_SMART_IDLE          (2UL << 3)
975b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_SIDLE_NO_IDLE             (1UL << 3)
985b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_SIDLE_FORCED_IDLE         (0UL << 3)
995b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_ENAWAKEUP                 (1UL << 2)
1005b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_SOFTRESET                 (1UL << 1)
1015b03aba6SOleksandr Tymoshenko #define	TLL_SYSCONFIG_AUTOIDLE                  (1UL << 0)
1025b03aba6SOleksandr Tymoshenko 
1035b03aba6SOleksandr Tymoshenko #define	TLL_SYSSTATUS_RESETDONE                 (1UL << 0)
1045b03aba6SOleksandr Tymoshenko 
1055b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_90D_DDR_EN          (1UL << 6)
1065b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_180D_SDR_EN         (1UL << 5)
1075b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_MASK       (7UL << 2)
1085b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_128        (7UL << 2)
1095b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_64         (6UL << 2)
1105b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_32         (5UL << 2)
1115b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_16         (4UL << 2)
1125b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_8          (3UL << 2)
1135b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_4          (2UL << 2)
1145b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_2          (1UL << 2)
1155b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_USB_DIVRATIO_1          (0UL << 2)
1165b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_FCLK_REQ                (1UL << 1)
1175b03aba6SOleksandr Tymoshenko #define TLL_SHARED_CONF_FCLK_IS_ON              (1UL << 0)
1185b03aba6SOleksandr Tymoshenko 
1195b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_DRVVBUS                (1UL << 16)
1205b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_CHRGVBUS               (1UL << 15)
1215b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_ULPINOBITSTUFF         (1UL << 11)
1225b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_ULPIAUTOIDLE           (1UL << 10)
1235b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_UTMIAUTOIDLE           (1UL << 9)
1245b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_ULPIDDRMODE            (1UL << 8)
1255b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_ULPIOUTCLKMODE         (1UL << 7)
1265b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_TLLFULLSPEED           (1UL << 6)
1275b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_TLLCONNECT             (1UL << 5)
1285b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_TLLATTACH              (1UL << 4)
1295b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_UTMIISADEV             (1UL << 3)
1305b03aba6SOleksandr Tymoshenko #define TLL_CHANNEL_CONF_CHANEN                 (1UL << 0)
1315b03aba6SOleksandr Tymoshenko 
1325b03aba6SOleksandr Tymoshenko struct omap_tll_softc {
1335b03aba6SOleksandr Tymoshenko 	device_t		sc_dev;
1345b03aba6SOleksandr Tymoshenko 
1355b03aba6SOleksandr Tymoshenko 	/* TLL register set */
1365b03aba6SOleksandr Tymoshenko 	struct resource*	tll_mem_res;
1375b03aba6SOleksandr Tymoshenko 	int			tll_mem_rid;
1385b03aba6SOleksandr Tymoshenko };
1395b03aba6SOleksandr Tymoshenko 
1405b03aba6SOleksandr Tymoshenko static struct omap_tll_softc *omap_tll_sc;
1415b03aba6SOleksandr Tymoshenko 
1425b03aba6SOleksandr Tymoshenko static int omap_tll_attach(device_t dev);
1435b03aba6SOleksandr Tymoshenko static int omap_tll_detach(device_t dev);
1445b03aba6SOleksandr Tymoshenko 
1455b03aba6SOleksandr Tymoshenko static inline uint32_t
omap_tll_read_4(struct omap_tll_softc * sc,bus_size_t off)1465b03aba6SOleksandr Tymoshenko omap_tll_read_4(struct omap_tll_softc *sc, bus_size_t off)
1475b03aba6SOleksandr Tymoshenko {
1485b03aba6SOleksandr Tymoshenko 	return bus_read_4(sc->tll_mem_res, off);
1495b03aba6SOleksandr Tymoshenko }
1505b03aba6SOleksandr Tymoshenko 
1515b03aba6SOleksandr Tymoshenko static inline void
omap_tll_write_4(struct omap_tll_softc * sc,bus_size_t off,uint32_t val)1525b03aba6SOleksandr Tymoshenko omap_tll_write_4(struct omap_tll_softc *sc, bus_size_t off, uint32_t val)
1535b03aba6SOleksandr Tymoshenko {
1545b03aba6SOleksandr Tymoshenko 	bus_write_4(sc->tll_mem_res, off, val);
1555b03aba6SOleksandr Tymoshenko }
1565b03aba6SOleksandr Tymoshenko 
1575b03aba6SOleksandr Tymoshenko void
omap_tll_utmi_enable(unsigned int en_mask)1585b03aba6SOleksandr Tymoshenko omap_tll_utmi_enable(unsigned int en_mask)
1595b03aba6SOleksandr Tymoshenko {
1605b03aba6SOleksandr Tymoshenko 	struct omap_tll_softc *sc;
1615b03aba6SOleksandr Tymoshenko 	unsigned int i;
1625b03aba6SOleksandr Tymoshenko 	uint32_t reg;
1635b03aba6SOleksandr Tymoshenko 
1645b03aba6SOleksandr Tymoshenko 	sc = omap_tll_sc;
1655b03aba6SOleksandr Tymoshenko 	if (sc == NULL)
1665b03aba6SOleksandr Tymoshenko 		return;
1675b03aba6SOleksandr Tymoshenko 
1685b03aba6SOleksandr Tymoshenko 	/* There are 3 TLL channels, one per USB controller so set them all up the
1695b03aba6SOleksandr Tymoshenko 	 * same, SDR mode, bit stuffing and no autoidle.
1705b03aba6SOleksandr Tymoshenko 	 */
1715b03aba6SOleksandr Tymoshenko 	for (i=0; i<3; i++) {
1725b03aba6SOleksandr Tymoshenko 		reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
1735b03aba6SOleksandr Tymoshenko 
1745b03aba6SOleksandr Tymoshenko 		reg &= ~(TLL_CHANNEL_CONF_UTMIAUTOIDLE
1755b03aba6SOleksandr Tymoshenko 				 | TLL_CHANNEL_CONF_ULPINOBITSTUFF
1765b03aba6SOleksandr Tymoshenko 				 | TLL_CHANNEL_CONF_ULPIDDRMODE);
1775b03aba6SOleksandr Tymoshenko 
1785b03aba6SOleksandr Tymoshenko 		omap_tll_write_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
1795b03aba6SOleksandr Tymoshenko 	}
1805b03aba6SOleksandr Tymoshenko 
1815b03aba6SOleksandr Tymoshenko 	/* Program the common TLL register */
1825b03aba6SOleksandr Tymoshenko 	reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_SHARED_CONF);
1835b03aba6SOleksandr Tymoshenko 
1845b03aba6SOleksandr Tymoshenko 	reg &= ~( TLL_SHARED_CONF_USB_90D_DDR_EN
1855b03aba6SOleksandr Tymoshenko 			| TLL_SHARED_CONF_USB_DIVRATIO_MASK);
1865b03aba6SOleksandr Tymoshenko 	reg |=  ( TLL_SHARED_CONF_FCLK_IS_ON
1875b03aba6SOleksandr Tymoshenko 			| TLL_SHARED_CONF_USB_DIVRATIO_2
1885b03aba6SOleksandr Tymoshenko 			| TLL_SHARED_CONF_USB_180D_SDR_EN);
1895b03aba6SOleksandr Tymoshenko 
1905b03aba6SOleksandr Tymoshenko 	omap_tll_write_4(sc, OMAP_USBTLL_TLL_SHARED_CONF, reg);
1915b03aba6SOleksandr Tymoshenko 
1925b03aba6SOleksandr Tymoshenko 	/* Enable channels now */
1935b03aba6SOleksandr Tymoshenko 	for (i = 0; i < 3; i++) {
1945b03aba6SOleksandr Tymoshenko 		reg = omap_tll_read_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i));
1955b03aba6SOleksandr Tymoshenko 
1965b03aba6SOleksandr Tymoshenko 		/* Enable only the reg that is needed */
1975b03aba6SOleksandr Tymoshenko 		if ((en_mask & (1 << i)) == 0)
1985b03aba6SOleksandr Tymoshenko 			continue;
1995b03aba6SOleksandr Tymoshenko 
2005b03aba6SOleksandr Tymoshenko 		reg |= TLL_CHANNEL_CONF_CHANEN;
2015b03aba6SOleksandr Tymoshenko 		omap_tll_write_4(sc, OMAP_USBTLL_TLL_CHANNEL_CONF(i), reg);
2025b03aba6SOleksandr Tymoshenko 	}
2035b03aba6SOleksandr Tymoshenko }
2045b03aba6SOleksandr Tymoshenko 
2055b03aba6SOleksandr Tymoshenko static int
omap_tll_init(struct omap_tll_softc * sc)2065b03aba6SOleksandr Tymoshenko omap_tll_init(struct omap_tll_softc *sc)
2075b03aba6SOleksandr Tymoshenko {
2085b03aba6SOleksandr Tymoshenko 	unsigned long timeout;
2095b03aba6SOleksandr Tymoshenko 	int ret = 0;
2105b03aba6SOleksandr Tymoshenko 
2115b03aba6SOleksandr Tymoshenko 	/* Enable the USB TLL */
2120050ea24SMichal Meloun 	ti_sysc_clock_enable(device_get_parent(sc->sc_dev));
2135b03aba6SOleksandr Tymoshenko 
2145b03aba6SOleksandr Tymoshenko 	/* Perform TLL soft reset, and wait until reset is complete */
2155b03aba6SOleksandr Tymoshenko 	omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_SOFTRESET);
2165b03aba6SOleksandr Tymoshenko 
2175b03aba6SOleksandr Tymoshenko 	/* Set the timeout to 100ms*/
2185b03aba6SOleksandr Tymoshenko 	timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
2195b03aba6SOleksandr Tymoshenko 
2205b03aba6SOleksandr Tymoshenko 	/* Wait for TLL reset to complete */
2215b03aba6SOleksandr Tymoshenko 	while ((omap_tll_read_4(sc, OMAP_USBTLL_SYSSTATUS) &
2225b03aba6SOleksandr Tymoshenko 	        TLL_SYSSTATUS_RESETDONE) == 0x00) {
2235b03aba6SOleksandr Tymoshenko 		/* Sleep for a tick */
2245b03aba6SOleksandr Tymoshenko 		pause("USBRESET", 1);
2255b03aba6SOleksandr Tymoshenko 
2265b03aba6SOleksandr Tymoshenko 		if (timeout-- == 0) {
2275b03aba6SOleksandr Tymoshenko 			device_printf(sc->sc_dev, "TLL reset operation timed out\n");
2285b03aba6SOleksandr Tymoshenko 			ret = EINVAL;
2295b03aba6SOleksandr Tymoshenko 			goto err_sys_status;
2305b03aba6SOleksandr Tymoshenko 		}
2315b03aba6SOleksandr Tymoshenko 	}
2325b03aba6SOleksandr Tymoshenko 
2335b03aba6SOleksandr Tymoshenko 	/* CLOCKACTIVITY = 1 : OCP-derived internal clocks ON during idle
2345b03aba6SOleksandr Tymoshenko 	 * SIDLEMODE = 2     : Smart-idle mode. Sidleack asserted after Idlereq
2355b03aba6SOleksandr Tymoshenko 	 *                     assertion when no more activity on the USB.
2365b03aba6SOleksandr Tymoshenko 	 * ENAWAKEUP = 1     : Wakeup generation enabled
2375b03aba6SOleksandr Tymoshenko 	 */
2385b03aba6SOleksandr Tymoshenko 	omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, TLL_SYSCONFIG_ENAWAKEUP |
2395b03aba6SOleksandr Tymoshenko 	                                            TLL_SYSCONFIG_AUTOIDLE |
2405b03aba6SOleksandr Tymoshenko 	                                            TLL_SYSCONFIG_SIDLE_SMART_IDLE |
2415b03aba6SOleksandr Tymoshenko 	                                            TLL_SYSCONFIG_CACTIVITY);
2425b03aba6SOleksandr Tymoshenko 
2435b03aba6SOleksandr Tymoshenko 	return(0);
2445b03aba6SOleksandr Tymoshenko 
2455b03aba6SOleksandr Tymoshenko err_sys_status:
2465b03aba6SOleksandr Tymoshenko 	/* Disable the TLL clocks */
2470050ea24SMichal Meloun 	ti_sysc_clock_disable(device_get_parent(sc->sc_dev));
2485b03aba6SOleksandr Tymoshenko 
2495b03aba6SOleksandr Tymoshenko 	return(ret);
2505b03aba6SOleksandr Tymoshenko }
2515b03aba6SOleksandr Tymoshenko 
2525b03aba6SOleksandr Tymoshenko static void
omap_tll_disable(struct omap_tll_softc * sc)2535b03aba6SOleksandr Tymoshenko omap_tll_disable(struct omap_tll_softc *sc)
2545b03aba6SOleksandr Tymoshenko {
2555b03aba6SOleksandr Tymoshenko 	unsigned long timeout;
2565b03aba6SOleksandr Tymoshenko 
2575b03aba6SOleksandr Tymoshenko 	timeout = (hz < 10) ? 1 : ((100 * hz) / 1000);
2585b03aba6SOleksandr Tymoshenko 
2595b03aba6SOleksandr Tymoshenko 	/* Reset the TLL module */
2605b03aba6SOleksandr Tymoshenko 	omap_tll_write_4(sc, OMAP_USBTLL_SYSCONFIG, 0x0002);
2615b03aba6SOleksandr Tymoshenko 	while ((omap_tll_read_4(sc, OMAP_USBTLL_SYSSTATUS) & (0x01)) == 0x00) {
2625b03aba6SOleksandr Tymoshenko 		/* Sleep for a tick */
2635b03aba6SOleksandr Tymoshenko 		pause("USBRESET", 1);
2645b03aba6SOleksandr Tymoshenko 
2655b03aba6SOleksandr Tymoshenko 		if (timeout-- == 0) {
2665b03aba6SOleksandr Tymoshenko 			device_printf(sc->sc_dev, "operation timed out\n");
2675b03aba6SOleksandr Tymoshenko 			break;
2685b03aba6SOleksandr Tymoshenko 		}
2695b03aba6SOleksandr Tymoshenko 	}
2705b03aba6SOleksandr Tymoshenko 
2715b03aba6SOleksandr Tymoshenko 	/* Disable functional and interface clocks for the TLL and HOST modules */
2720050ea24SMichal Meloun 	ti_sysc_clock_disable(device_get_parent(sc->sc_dev));
2735b03aba6SOleksandr Tymoshenko }
2745b03aba6SOleksandr Tymoshenko 
2755b03aba6SOleksandr Tymoshenko static int
omap_tll_probe(device_t dev)2765b03aba6SOleksandr Tymoshenko omap_tll_probe(device_t dev)
2775b03aba6SOleksandr Tymoshenko {
2785b03aba6SOleksandr Tymoshenko 
2795b03aba6SOleksandr Tymoshenko 	if (!ofw_bus_status_okay(dev))
2805b03aba6SOleksandr Tymoshenko 		return (ENXIO);
2815b03aba6SOleksandr Tymoshenko 
2825b03aba6SOleksandr Tymoshenko 	if (!ofw_bus_is_compatible(dev, "ti,usbhs-tll"))
2835b03aba6SOleksandr Tymoshenko 		return (ENXIO);
2845b03aba6SOleksandr Tymoshenko 
2855b03aba6SOleksandr Tymoshenko 	device_set_desc(dev, "TI OMAP USB 2.0 TLL module");
2865b03aba6SOleksandr Tymoshenko 
2875b03aba6SOleksandr Tymoshenko 	return (BUS_PROBE_DEFAULT);
2885b03aba6SOleksandr Tymoshenko }
2895b03aba6SOleksandr Tymoshenko 
2905b03aba6SOleksandr Tymoshenko static int
omap_tll_attach(device_t dev)2915b03aba6SOleksandr Tymoshenko omap_tll_attach(device_t dev)
2925b03aba6SOleksandr Tymoshenko {
2935b03aba6SOleksandr Tymoshenko 	struct omap_tll_softc *sc;
2945b03aba6SOleksandr Tymoshenko 
2955b03aba6SOleksandr Tymoshenko 	sc = device_get_softc(dev);
2965b03aba6SOleksandr Tymoshenko 	/* save the device */
2975b03aba6SOleksandr Tymoshenko 	sc->sc_dev = dev;
2985b03aba6SOleksandr Tymoshenko 
2995b03aba6SOleksandr Tymoshenko 	/* Allocate resource for the TLL register set */
3005b03aba6SOleksandr Tymoshenko 	sc->tll_mem_rid = 0;
3015b03aba6SOleksandr Tymoshenko 	sc->tll_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
3025b03aba6SOleksandr Tymoshenko 	    &sc->tll_mem_rid, RF_ACTIVE);
3035b03aba6SOleksandr Tymoshenko 	if (!sc->tll_mem_res) {
3045b03aba6SOleksandr Tymoshenko 		device_printf(dev, "Error: Could not map TLL memory\n");
3055b03aba6SOleksandr Tymoshenko 		goto error;
3065b03aba6SOleksandr Tymoshenko 	}
3075b03aba6SOleksandr Tymoshenko 
3085b03aba6SOleksandr Tymoshenko 	omap_tll_init(sc);
3095b03aba6SOleksandr Tymoshenko 
3105b03aba6SOleksandr Tymoshenko 	omap_tll_sc = sc;
3115b03aba6SOleksandr Tymoshenko 
3125b03aba6SOleksandr Tymoshenko 	return (0);
3135b03aba6SOleksandr Tymoshenko 
3145b03aba6SOleksandr Tymoshenko error:
3155b03aba6SOleksandr Tymoshenko 	omap_tll_detach(dev);
3165b03aba6SOleksandr Tymoshenko 	return (ENXIO);
3175b03aba6SOleksandr Tymoshenko }
3185b03aba6SOleksandr Tymoshenko 
3195b03aba6SOleksandr Tymoshenko static int
omap_tll_detach(device_t dev)3205b03aba6SOleksandr Tymoshenko omap_tll_detach(device_t dev)
3215b03aba6SOleksandr Tymoshenko {
3225b03aba6SOleksandr Tymoshenko 	struct omap_tll_softc *sc;
3235b03aba6SOleksandr Tymoshenko 
3245b03aba6SOleksandr Tymoshenko 	sc = device_get_softc(dev);
3255b03aba6SOleksandr Tymoshenko 	omap_tll_disable(sc);
3265b03aba6SOleksandr Tymoshenko 
3275b03aba6SOleksandr Tymoshenko 	/* Release the other register set memory maps */
3285b03aba6SOleksandr Tymoshenko 	if (sc->tll_mem_res) {
3295b03aba6SOleksandr Tymoshenko 		bus_release_resource(dev, SYS_RES_MEMORY,
3305b03aba6SOleksandr Tymoshenko 		    sc->tll_mem_rid, sc->tll_mem_res);
3315b03aba6SOleksandr Tymoshenko 		sc->tll_mem_res = NULL;
3325b03aba6SOleksandr Tymoshenko 	}
3335b03aba6SOleksandr Tymoshenko 
3345b03aba6SOleksandr Tymoshenko 	omap_tll_sc = NULL;
3355b03aba6SOleksandr Tymoshenko 
3365b03aba6SOleksandr Tymoshenko 	return (0);
3375b03aba6SOleksandr Tymoshenko }
3385b03aba6SOleksandr Tymoshenko 
3395b03aba6SOleksandr Tymoshenko static device_method_t omap_tll_methods[] = {
3405b03aba6SOleksandr Tymoshenko 	/* Device interface */
3415b03aba6SOleksandr Tymoshenko 	DEVMETHOD(device_probe, omap_tll_probe),
3425b03aba6SOleksandr Tymoshenko 	DEVMETHOD(device_attach, omap_tll_attach),
3435b03aba6SOleksandr Tymoshenko 	DEVMETHOD(device_detach, omap_tll_detach),
3445b03aba6SOleksandr Tymoshenko 	DEVMETHOD(device_suspend, bus_generic_suspend),
3455b03aba6SOleksandr Tymoshenko 	DEVMETHOD(device_resume, bus_generic_resume),
3465b03aba6SOleksandr Tymoshenko 	DEVMETHOD(device_shutdown, bus_generic_shutdown),
3475b03aba6SOleksandr Tymoshenko 	{0, 0}
3485b03aba6SOleksandr Tymoshenko };
3495b03aba6SOleksandr Tymoshenko 
3505b03aba6SOleksandr Tymoshenko static driver_t omap_tll_driver = {
3515b03aba6SOleksandr Tymoshenko 	"omap_tll",
3525b03aba6SOleksandr Tymoshenko 	omap_tll_methods,
3535b03aba6SOleksandr Tymoshenko 	sizeof(struct omap_tll_softc),
3545b03aba6SOleksandr Tymoshenko };
3555b03aba6SOleksandr Tymoshenko 
3568537e671SJohn Baldwin DRIVER_MODULE(omap_tll, simplebus, omap_tll_driver, 0, 0);
357