Home | History | Annotate | Line # | Download | only in imx
      1  1.19   bouyer /*	$NetBSD: imxusb.c,v 1.19 2023/05/04 17:09:44 bouyer Exp $	*/
      2   1.1      bsh /*
      3   1.1      bsh  * Copyright (c) 2009, 2010  Genetec Corporation.  All rights reserved.
      4   1.1      bsh  * Written by Hashimoto Kenichi and Hiroyuki Bessho for Genetec Corporation.
      5   1.1      bsh  *
      6   1.1      bsh  * Redistribution and use in source and binary forms, with or without
      7   1.1      bsh  * modification, are permitted provided that the following conditions
      8   1.1      bsh  * are met:
      9   1.1      bsh  * 1. Redistributions of source code must retain the above copyright
     10   1.1      bsh  *    notice, this list of conditions and the following disclaimer.
     11   1.1      bsh  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1      bsh  *    notice, this list of conditions and the following disclaimer in the
     13   1.1      bsh  *    documentation and/or other materials provided with the distribution.
     14   1.1      bsh  *
     15   1.1      bsh  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
     16   1.1      bsh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17   1.1      bsh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18   1.1      bsh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
     19   1.1      bsh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20   1.1      bsh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21   1.1      bsh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22   1.1      bsh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23   1.1      bsh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24   1.1      bsh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25   1.1      bsh  * POSSIBILITY OF SUCH DAMAGE.
     26   1.1      bsh  */
     27   1.1      bsh #include <sys/cdefs.h>
     28  1.19   bouyer __KERNEL_RCSID(0, "$NetBSD: imxusb.c,v 1.19 2023/05/04 17:09:44 bouyer Exp $");
     29   1.6  hkenken 
     30  1.14  hkenken #include "locators.h"
     31  1.16    skrll #include "opt_imx.h"
     32   1.1      bsh 
     33   1.1      bsh #include <sys/param.h>
     34   1.1      bsh #include <sys/systm.h>
     35   1.1      bsh #include <sys/conf.h>
     36   1.1      bsh #include <sys/kernel.h>
     37   1.1      bsh #include <sys/device.h>
     38   1.1      bsh #include <sys/intr.h>
     39   1.1      bsh #include <sys/bus.h>
     40   1.1      bsh 
     41   1.1      bsh #include <dev/usb/usb.h>
     42   1.1      bsh #include <dev/usb/usbdi.h>
     43   1.1      bsh #include <dev/usb/usbdivar.h>
     44   1.1      bsh #include <dev/usb/usb_mem.h>
     45   1.1      bsh 
     46   1.1      bsh #include <dev/usb/ehcireg.h>
     47   1.1      bsh #include <dev/usb/ehcivar.h>
     48   1.1      bsh 
     49   1.5     matt #include <arm/pic/picvar.h>	/* XXX: for intr_establish! */
     50   1.5     matt 
     51   1.1      bsh #include <arm/imx/imxusbreg.h>
     52   1.1      bsh #include <arm/imx/imxusbvar.h>
     53   1.1      bsh 
     54   1.1      bsh #include <dev/usb/ulpireg.h>	/* for test */
     55   1.1      bsh 
     56   1.1      bsh static int	imxehci_match(device_t, cfdata_t, void *);
     57   1.1      bsh static void	imxehci_attach(device_t, device_t, void *);
     58  1.10    skrll 
     59   1.1      bsh uint8_t imxusb_ulpi_read(struct imxehci_softc *sc, int addr);
     60   1.1      bsh void imxusb_ulpi_write(struct imxehci_softc *sc, int addr, uint8_t data);
     61   1.1      bsh static void ulpi_reset(struct imxehci_softc *sc);
     62   1.1      bsh 
     63   1.9  hkenken static void imxehci_select_interface(struct imxehci_softc *, enum imx_usb_if);
     64   1.9  hkenken static void imxehci_init(struct ehci_softc *);
     65   1.1      bsh 
     66   1.1      bsh /* attach structures */
     67   1.1      bsh CFATTACH_DECL_NEW(imxehci, sizeof(struct imxehci_softc),
     68   1.1      bsh     imxehci_match, imxehci_attach, NULL, NULL);
     69   1.1      bsh 
     70   1.1      bsh static int
     71   1.1      bsh imxehci_match(device_t parent, cfdata_t cf, void *aux)
     72   1.1      bsh {
     73   1.1      bsh 	struct imxusbc_attach_args *aa = aux;
     74  1.10    skrll 
     75  1.14  hkenken 	if (aa->aa_unit < 0 || 3 < aa->aa_unit)
     76   1.1      bsh 		return 0;
     77  1.10    skrll 
     78   1.1      bsh 	return 1;
     79   1.1      bsh }
     80   1.1      bsh 
     81   1.1      bsh static void
     82   1.1      bsh imxehci_attach(device_t parent, device_t self, void *aux)
     83   1.1      bsh {
     84   1.1      bsh 	struct imxusbc_attach_args *aa = aux;
     85   1.1      bsh 	struct imxusbc_softc *usbc = device_private(parent);
     86   1.1      bsh 	struct imxehci_softc *sc = device_private(self);
     87   1.1      bsh 	ehci_softc_t *hsc = &sc->sc_hsc;
     88   1.1      bsh 	bus_space_tag_t iot;
     89   1.1      bsh 	uint16_t hcirev;
     90   1.1      bsh 	uint32_t id, hwhost, hwdevice;
     91   1.1      bsh 	const char *comma;
     92   1.7      ryo 
     93  1.14  hkenken 	iot = aa->aa_iot;
     94  1.14  hkenken 
     95  1.14  hkenken 	sc->sc_dev = self;
     96   1.1      bsh 	sc->sc_unit = aa->aa_unit;
     97   1.1      bsh 	sc->sc_usbc = usbc;
     98  1.14  hkenken 	sc->sc_iot = iot;
     99  1.14  hkenken 
    100  1.14  hkenken 	hsc->sc_dev = self;
    101  1.14  hkenken 	hsc->iot = iot;
    102  1.11    skrll 	hsc->sc_bus.ub_hcpriv = sc;
    103  1.14  hkenken 	hsc->sc_bus.ub_dmatag = aa->aa_dmat;
    104   1.4     matt 	hsc->sc_flags |= EHCIF_ETTF;
    105   1.9  hkenken 	hsc->sc_vendor_init = imxehci_init;
    106   1.1      bsh 
    107   1.7      ryo 	aprint_naive("\n");
    108   1.7      ryo 	aprint_normal(": i.MX USB Controller\n");
    109   1.1      bsh 
    110  1.12      ryo 	if (usbc->sc_ehci_size == 0)
    111  1.12      ryo 		usbc->sc_ehci_size = IMXUSB_EHCI_SIZE;	/* use default */
    112  1.12      ryo 
    113   1.1      bsh 	/* per unit registers */
    114  1.10    skrll 	if (bus_space_subregion(iot, aa->aa_ioh,
    115  1.14  hkenken 		sc->sc_unit * usbc->sc_ehci_offset, usbc->sc_ehci_size,
    116   1.1      bsh 		&sc->sc_ioh) ||
    117   1.1      bsh 	    bus_space_subregion(iot, aa->aa_ioh,
    118  1.14  hkenken 		sc->sc_unit * usbc->sc_ehci_offset + IMXUSB_EHCIREGS,
    119  1.12      ryo 		usbc->sc_ehci_size - IMXUSB_EHCIREGS,
    120  1.14  hkenken 		&hsc->ioh)) {
    121   1.1      bsh 
    122   1.1      bsh 		aprint_error_dev(self, "can't subregion\n");
    123   1.1      bsh 		return;
    124   1.1      bsh 	}
    125   1.1      bsh 
    126   1.1      bsh 	id = bus_space_read_4(iot, sc->sc_ioh, IMXUSB_ID);
    127  1.14  hkenken 	hcirev = bus_space_read_2(iot, hsc->ioh, EHCI_HCIVERSION);
    128   1.1      bsh 
    129   1.1      bsh 	aprint_normal_dev(self,
    130  1.10    skrll 	    "id=%d revision=%d HCI revision=0x%x\n",
    131   1.6  hkenken 	    (int)__SHIFTOUT(id, IMXUSB_ID_ID),
    132   1.6  hkenken 	    (int)__SHIFTOUT(id, IMXUSB_ID_REVISION),
    133   1.1      bsh 	    hcirev);
    134  1.10    skrll 
    135   1.1      bsh 	hwhost = bus_space_read_4(iot, sc->sc_ioh, IMXUSB_HWHOST);
    136   1.1      bsh 	hwdevice = bus_space_read_4(iot, sc->sc_ioh, IMXUSB_HWDEVICE);
    137   1.1      bsh 
    138   1.1      bsh 	aprint_normal_dev(self, "");
    139   1.1      bsh 
    140   1.1      bsh 	comma = "";
    141   1.1      bsh 	if (hwhost & HWHOST_HC) {
    142   1.6  hkenken 		int n_ports = 1 + __SHIFTOUT(hwhost, HWHOST_NPORT);
    143   1.1      bsh 		aprint_normal("%d host port%s",
    144   1.1      bsh 		    n_ports, n_ports > 1 ? "s" : "");
    145   1.1      bsh 		comma = ", ";
    146   1.1      bsh 	}
    147   1.1      bsh 
    148   1.1      bsh 	if (hwdevice & HWDEVICE_DC) {
    149   1.6  hkenken 		int n_endpoints = __SHIFTOUT(hwdevice, HWDEVICE_DEVEP);
    150   1.1      bsh 		aprint_normal("%sdevice capable, %d endpoint%s",
    151   1.1      bsh 		    comma,
    152   1.1      bsh 		    n_endpoints, n_endpoints > 1 ? "s" : "");
    153   1.1      bsh 	}
    154   1.1      bsh 	aprint_normal("\n");
    155   1.1      bsh 
    156  1.14  hkenken 	hsc->sc_offs = bus_space_read_1(iot, hsc->ioh,
    157   1.1      bsh 	    EHCI_CAPLENGTH);
    158   1.1      bsh 
    159   1.1      bsh 	/* Platform dependent setup */
    160   1.1      bsh 	if (usbc->sc_init_md_hook)
    161  1.19   bouyer 		usbc->sc_init_md_hook(sc, usbc->sc_md_hook_data);
    162  1.11    skrll 
    163   1.1      bsh 	imxehci_reset(sc);
    164   1.1      bsh 	imxehci_select_interface(sc, sc->sc_iftype);
    165   1.1      bsh 
    166   1.1      bsh 	if (sc->sc_iftype == IMXUSBC_IF_ULPI) {
    167   1.1      bsh 		bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW, 0);
    168   1.1      bsh 
    169   1.1      bsh 		aprint_normal_dev(hsc->sc_dev,
    170   1.1      bsh 		    "ULPI phy VID 0x%04x PID 0x%04x\n",
    171   1.1      bsh 		    (imxusb_ulpi_read(sc, ULPI_VENDOR_ID_LOW) |
    172   1.1      bsh 			imxusb_ulpi_read(sc, ULPI_VENDOR_ID_HIGH) << 8),
    173   1.1      bsh 		    (imxusb_ulpi_read(sc, ULPI_PRODUCT_ID_LOW) |
    174   1.1      bsh 			imxusb_ulpi_read(sc, ULPI_PRODUCT_ID_HIGH) << 8));
    175   1.1      bsh 
    176   1.1      bsh 		ulpi_reset(sc);
    177   1.1      bsh 
    178   1.1      bsh 	}
    179   1.1      bsh 
    180   1.1      bsh 	if (usbc->sc_setup_md_hook)
    181  1.19   bouyer 		usbc->sc_setup_md_hook(sc, IMXUSB_HOST, usbc->sc_md_hook_data);
    182   1.6  hkenken 
    183   1.6  hkenken 	if (sc->sc_iftype == IMXUSBC_IF_ULPI) {
    184   1.6  hkenken #if 0
    185  1.11    skrll 		if(hsc->sc_bus.ub_revision == USBREV_2_0)
    186   1.6  hkenken 			ulpi_write(hsc, ULPI_FUNCTION_CONTROL + ULPI_REG_CLEAR, (1 << 0));
    187   1.6  hkenken 		else
    188   1.6  hkenken 			ulpi_write(hsc, ULPI_FUNCTION_CONTROL + ULPI_REG_SET, (1 << 2));
    189   1.6  hkenken #endif
    190   1.6  hkenken 
    191   1.1      bsh 		imxusb_ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_CLEAR,
    192   1.1      bsh 		    OTG_CONTROL_IDPULLUP);
    193   1.1      bsh 
    194   1.1      bsh 		imxusb_ulpi_write(sc, ULPI_OTG_CONTROL + ULPI_REG_SET,
    195   1.1      bsh 		    OTG_CONTROL_USEEXTVBUSIND |
    196   1.1      bsh 		    OTG_CONTROL_DRVVBUSEXT |
    197   1.1      bsh 		    OTG_CONTROL_DRVVBUS |
    198  1.14  hkenken 		    OTG_CONTROL_CHRGVBUS);
    199   1.1      bsh 	}
    200   1.1      bsh 
    201   1.1      bsh 	/* Disable interrupts, so we don't get any spurious ones. */
    202   1.2     matt 	EOWRITE4(hsc, EHCI_USBINTR, 0);
    203   1.1      bsh 
    204  1.14  hkenken 	if (usbc->sc_intr_establish_md_hook)
    205  1.19   bouyer 		sc->sc_ih = usbc->sc_intr_establish_md_hook(sc,
    206  1.19   bouyer 		    usbc->sc_md_hook_data);
    207  1.14  hkenken 	else if (aa->aa_irq > 0)
    208  1.14  hkenken 		sc->sc_ih = intr_establish(aa->aa_irq, IPL_USB, IST_LEVEL, ehci_intr, hsc);
    209  1.14  hkenken 	KASSERT(sc->sc_ih != NULL);
    210   1.1      bsh 
    211  1.11    skrll 	int err = ehci_init(hsc);
    212  1.11    skrll 	if (err) {
    213  1.11    skrll 		aprint_error_dev(self, "init failed, error=%d\n", err);
    214   1.1      bsh 		return;
    215   1.1      bsh 	}
    216   1.1      bsh 
    217   1.1      bsh 	/* Attach usb device. */
    218  1.17  thorpej 	hsc->sc_child = config_found(self, &hsc->sc_bus, usbctlprint,
    219  1.18  thorpej 	    CFARGS_NONE);
    220   1.1      bsh }
    221   1.1      bsh 
    222   1.9  hkenken static void
    223   1.1      bsh imxehci_select_interface(struct imxehci_softc *sc, enum imx_usb_if interface)
    224   1.1      bsh {
    225   1.1      bsh 	uint32_t reg;
    226   1.1      bsh 	struct ehci_softc *hsc = &sc->sc_hsc;
    227   1.1      bsh 
    228   1.1      bsh 	reg = EOREAD4(hsc, EHCI_PORTSC(1));
    229  1.12      ryo 	reg &= ~(PORTSC_PTS | PORTSC_PTW | PORTSC_PTS2);
    230   1.6  hkenken 	switch (interface) {
    231   1.6  hkenken 	case IMXUSBC_IF_UTMI_WIDE:
    232   1.6  hkenken 		reg |= PORTSC_PTW_16;
    233   1.6  hkenken 	case IMXUSBC_IF_UTMI:
    234   1.6  hkenken 		reg |= PORTSC_PTS_UTMI;
    235   1.6  hkenken 		break;
    236   1.6  hkenken 	case IMXUSBC_IF_PHILIPS:
    237   1.6  hkenken 		reg |= PORTSC_PTS_PHILIPS;
    238   1.6  hkenken 		break;
    239   1.6  hkenken 	case IMXUSBC_IF_ULPI:
    240   1.6  hkenken 		reg |= PORTSC_PTS_ULPI;
    241   1.6  hkenken 		break;
    242   1.6  hkenken 	case IMXUSBC_IF_SERIAL:
    243   1.6  hkenken 		reg |= PORTSC_PTS_SERIAL;
    244   1.6  hkenken 		break;
    245  1.12      ryo 	case IMXUSBC_IF_HSIC:
    246  1.12      ryo 		reg |= PORTSC_PTS2;
    247  1.12      ryo 		break;
    248   1.6  hkenken 	}
    249   1.1      bsh 	EOWRITE4(hsc, EHCI_PORTSC(1), reg);
    250   1.1      bsh }
    251   1.1      bsh 
    252   1.1      bsh static uint32_t
    253   1.1      bsh ulpi_wakeup(struct imxehci_softc *sc, int tout)
    254   1.1      bsh {
    255  1.14  hkenken 	struct ehci_softc *hsc = &sc->sc_hsc;
    256   1.1      bsh 	uint32_t ulpi_view;
    257  1.14  hkenken 
    258   1.1      bsh 	ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW);
    259   1.1      bsh 
    260  1.14  hkenken 	if (!(ulpi_view & ULPI_SS)) {
    261   1.1      bsh 		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
    262   1.1      bsh 		    IMXUSB_ULPIVIEW, ULPI_WU);
    263  1.14  hkenken 		while (tout-- > 0) {
    264   1.1      bsh 			ulpi_view = bus_space_read_4(sc->sc_iot,
    265   1.1      bsh 			    sc->sc_ioh, IMXUSB_ULPIVIEW);
    266  1.14  hkenken 			if (!(ulpi_view & ULPI_WU))
    267   1.1      bsh 				break;
    268   1.1      bsh 			delay(1);
    269   1.1      bsh 		};
    270   1.1      bsh 	}
    271   1.1      bsh 
    272  1.14  hkenken 	if (tout == 0)
    273  1.14  hkenken 		aprint_error_dev(hsc->sc_dev, "%s: timeout\n", __func__);
    274   1.1      bsh 
    275   1.1      bsh 	return ulpi_view;
    276   1.1      bsh }
    277   1.1      bsh 
    278   1.1      bsh static uint32_t
    279   1.1      bsh ulpi_wait(struct imxehci_softc *sc, int tout)
    280   1.1      bsh {
    281  1.14  hkenken 	struct ehci_softc *hsc = &sc->sc_hsc;
    282   1.1      bsh 	uint32_t ulpi_view;
    283  1.14  hkenken 
    284   1.1      bsh 	ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW);
    285   1.1      bsh 
    286  1.14  hkenken 	while (tout-- > 0) {
    287   1.1      bsh 		ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
    288   1.1      bsh 		    IMXUSB_ULPIVIEW);
    289   1.1      bsh 		if (!(ulpi_view & ULPI_RUN))
    290   1.1      bsh 			break;
    291   1.1      bsh 		delay(1);
    292   1.1      bsh 	}
    293   1.1      bsh 
    294  1.14  hkenken 	if (tout == 0)
    295  1.14  hkenken 		aprint_error_dev(hsc->sc_dev, "%s: timeout\n", __func__);
    296   1.1      bsh 
    297   1.1      bsh 	return ulpi_view;
    298   1.1      bsh }
    299   1.1      bsh 
    300   1.1      bsh #define	TIMEOUT	100000
    301  1.10    skrll 
    302   1.1      bsh uint8_t
    303   1.1      bsh imxusb_ulpi_read(struct imxehci_softc *sc, int addr)
    304   1.1      bsh {
    305  1.14  hkenken 	uint32_t reg;
    306   1.1      bsh 
    307   1.1      bsh 	ulpi_wakeup(sc, TIMEOUT);
    308   1.1      bsh 
    309  1.14  hkenken 	reg = ULPI_RUN | __SHIFTIN(addr, ULPI_ADDR);
    310  1.14  hkenken 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW, reg);
    311   1.1      bsh 
    312  1.14  hkenken 	reg = ulpi_wait(sc, TIMEOUT);
    313   1.1      bsh 
    314  1.14  hkenken 	return __SHIFTOUT(reg, ULPI_DATRD);
    315   1.1      bsh }
    316   1.1      bsh 
    317   1.1      bsh void
    318   1.1      bsh imxusb_ulpi_write(struct imxehci_softc *sc, int addr, uint8_t data)
    319   1.1      bsh {
    320   1.1      bsh 	uint32_t reg;
    321   1.1      bsh 
    322   1.1      bsh 	ulpi_wakeup(sc, TIMEOUT);
    323   1.1      bsh 
    324   1.6  hkenken 	reg = ULPI_RUN | ULPI_RW | __SHIFTIN(addr, ULPI_ADDR) | __SHIFTIN(data, ULPI_DATWR);
    325   1.1      bsh 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW, reg);
    326   1.1      bsh 
    327   1.1      bsh 	ulpi_wait(sc, TIMEOUT);
    328   1.1      bsh 
    329   1.1      bsh 	return;
    330   1.1      bsh }
    331   1.1      bsh 
    332   1.1      bsh static void
    333   1.1      bsh ulpi_reset(struct imxehci_softc *sc)
    334   1.1      bsh {
    335  1.14  hkenken 	struct ehci_softc *hsc = &sc->sc_hsc;
    336   1.1      bsh 	uint8_t data;
    337   1.1      bsh 	int timo = 1000 * 1000;	/* XXXX: 1sec */
    338   1.1      bsh 
    339   1.1      bsh 	imxusb_ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_SET,
    340   1.1      bsh 	    FUNCTION_CONTROL_RESET /*0x20*/);
    341   1.1      bsh 	do {
    342   1.1      bsh 		data = imxusb_ulpi_read(sc, ULPI_FUNCTION_CONTROL);
    343   1.1      bsh 		if (!(data & FUNCTION_CONTROL_RESET))
    344   1.1      bsh 			break;
    345   1.1      bsh 		delay(100);
    346   1.1      bsh 		timo -= 100;
    347   1.1      bsh 	} while (timo > 0);
    348  1.14  hkenken 
    349   1.1      bsh 	if (timo <= 0) {
    350  1.14  hkenken 		aprint_error_dev(hsc->sc_dev, "%s: reset failed!!\n",
    351   1.1      bsh 		    __func__);
    352   1.1      bsh 		return;
    353   1.1      bsh 	}
    354   1.1      bsh 
    355   1.1      bsh 	return;
    356   1.1      bsh }
    357   1.1      bsh 
    358   1.1      bsh void
    359   1.1      bsh imxehci_reset(struct imxehci_softc *sc)
    360   1.1      bsh {
    361   1.3    skrll 	uint32_t reg;
    362   1.1      bsh 	struct ehci_softc *hsc = &sc->sc_hsc;
    363  1.14  hkenken 	int tout;
    364   1.1      bsh #define	RESET_TIMEOUT 100
    365   1.1      bsh 
    366   1.1      bsh 	reg = EOREAD4(hsc, EHCI_USBCMD);
    367   1.1      bsh 	reg &= ~EHCI_CMD_RS;
    368   1.1      bsh 	EOWRITE4(hsc, EHCI_USBCMD, reg);
    369   1.1      bsh 
    370  1.14  hkenken 	for (tout = RESET_TIMEOUT; tout > 0; tout--) {
    371   1.1      bsh 		reg = EOREAD4(hsc, EHCI_USBCMD);
    372   1.1      bsh 		if ((reg & EHCI_CMD_RS) == 0)
    373   1.1      bsh 			break;
    374   1.1      bsh 		usb_delay_ms(&hsc->sc_bus, 1);
    375   1.1      bsh 	}
    376   1.1      bsh 
    377   1.1      bsh 	EOWRITE4(hsc, EHCI_USBCMD, reg | EHCI_CMD_HCRESET);
    378  1.14  hkenken 
    379  1.14  hkenken 	for (tout = RESET_TIMEOUT; tout > 0; tout--) {
    380   1.1      bsh 		reg = EOREAD4(hsc, EHCI_USBCMD);
    381   1.1      bsh 		if ((reg &  EHCI_CMD_HCRESET) == 0)
    382   1.1      bsh 			break;
    383   1.1      bsh 		usb_delay_ms(&hsc->sc_bus, 1);
    384   1.1      bsh 	}
    385  1.14  hkenken 
    386  1.14  hkenken 	if (tout == 0)
    387   1.1      bsh 		aprint_error_dev(hsc->sc_dev, "reset timeout (%x)\n", reg);
    388   1.1      bsh 
    389   1.1      bsh 	usb_delay_ms(&hsc->sc_bus, 100);
    390   1.1      bsh }
    391   1.1      bsh 
    392   1.9  hkenken static void
    393   1.9  hkenken imxehci_init(struct ehci_softc *hsc)
    394   1.1      bsh {
    395   1.9  hkenken 	struct imxehci_softc *sc = device_private(hsc->sc_dev);
    396   1.1      bsh 	uint32_t reg;
    397   1.1      bsh 
    398   1.1      bsh 	reg = EOREAD4(hsc, EHCI_PORTSC(1));
    399   1.1      bsh 	reg &= ~(EHCI_PS_CSC | EHCI_PS_PEC | EHCI_PS_OCC);
    400   1.1      bsh 	reg |= EHCI_PS_PP | EHCI_PS_PE;
    401   1.1      bsh 	EOWRITE4(hsc, EHCI_PORTSC(1), reg);
    402   1.1      bsh 
    403   1.1      bsh 	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_OTGSC);
    404   1.1      bsh 	reg |= OTGSC_IDPU;
    405   1.5     matt 	/* disable IDIE not to conflict with SSP1_DETECT. */
    406   1.5     matt 	//reg |= OTGSC_DPIE | OTGSC_IDIE;
    407   1.5     matt 	reg |= OTGSC_DPIE;
    408   1.1      bsh 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_OTGSC, reg);
    409   1.1      bsh 
    410   1.8    skrll 	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_USBMODE);
    411   1.9  hkenken 	reg &= ~USBMODE_CM;
    412   1.6  hkenken 	reg |= USBMODE_CM_HOST;
    413   1.8    skrll 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_USBMODE, reg);
    414   1.1      bsh }
    415