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
356*8537e671SJohn Baldwin DRIVER_MODULE(omap_tll, simplebus, omap_tll_driver, 0, 0);
357