11.9Sthorpej/* $Id: at91ohci.c,v 1.9 2021/08/07 16:18:43 thorpej Exp $ */ 21.9Sthorpej/* $NetBSD: at91ohci.c,v 1.9 2021/08/07 16:18:43 thorpej Exp $ */ 31.2Smatt 41.2Smatt/*- 51.2Smatt * Copyright (c) 2007 Embedtronics Oy. 61.2Smatt * All rights reserved. 71.2Smatt * 81.6Sskrll * Based on arch/arm/ep93xx/epohci.c, 91.2Smatt * Copyright (c) 2004 Jesse Off 101.2Smatt * All rights reserved. 111.2Smatt * 121.2Smatt * Redistribution and use in source and binary forms, with or without 131.2Smatt * modification, are permitted provided that the following conditions 141.2Smatt * are met: 151.2Smatt * 1. Redistributions of source code must retain the above copyright 161.2Smatt * notice, this list of conditions and the following disclaimer. 171.2Smatt * 2. Redistributions in binary form must reproduce the above copyright 181.2Smatt * notice, this list of conditions and the following disclaimer in the 191.2Smatt * documentation and/or other materials provided with the distribution. 201.2Smatt * 211.2Smatt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 221.2Smatt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231.2Smatt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241.2Smatt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 251.2Smatt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261.2Smatt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271.2Smatt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281.2Smatt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291.2Smatt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301.2Smatt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311.2Smatt * SUCH DAMAGE. 321.2Smatt */ 331.2Smatt 341.2Smatt/* 351.2Smatt * USB Open Host Controller driver. 361.2Smatt * 371.2Smatt * OHCI spec: ftp://ftp.compaq.com/pub/supportinformation/papers/hcir1_0a.exe 381.2Smatt * USB spec: http://www.usb.org/developers/data/usb11.pdf 391.2Smatt */ 401.2Smatt 411.2Smatt#include <sys/cdefs.h> 421.9Sthorpej__KERNEL_RCSID(0, "$NetBSD: at91ohci.c,v 1.9 2021/08/07 16:18:43 thorpej Exp $"); 431.2Smatt 441.2Smatt#include <sys/param.h> 451.2Smatt#include <sys/systm.h> 461.2Smatt#include <sys/kernel.h> 471.2Smatt#include <sys/device.h> 481.2Smatt#include <sys/proc.h> 491.2Smatt#include <sys/queue.h> 501.2Smatt 511.2Smatt/* busdma */ 521.2Smatt#include <sys/mbuf.h> 531.2Smatt#include <uvm/uvm_extern.h> 541.2Smatt 551.4Sdyoung#include <sys/bus.h> 561.2Smatt 571.2Smatt#include <dev/usb/usb.h> 581.2Smatt#include <dev/usb/usbdi.h> 591.2Smatt#include <dev/usb/usbdivar.h> 601.2Smatt#include <dev/usb/usb_mem.h> 611.2Smatt 621.2Smatt#include <dev/usb/ohcireg.h> 631.2Smatt#include <dev/usb/ohcivar.h> 641.2Smatt 651.2Smatt#include <arm/at91/at91reg.h> 661.2Smatt#include <arm/at91/at91var.h> 671.2Smatt 681.2Smattint at91ohci_match(device_t, cfdata_t, void *); 691.2Smattvoid at91ohci_attach(device_t, device_t, void *); 701.2Smattvoid at91ohci_callback(device_t ); 711.2Smatt 721.2Smattstruct at91ohci_softc { 731.2Smatt struct ohci_softc sc; 741.2Smatt void *sc_ih; 751.2Smatt int sc_pid; 761.2Smatt}; 771.2Smatt 781.5SaymericCFATTACH_DECL_NEW(at91ohci, sizeof(struct at91ohci_softc), 791.2Smatt at91ohci_match, at91ohci_attach, NULL, NULL); 801.2Smatt 811.2Smattint 821.2Smattat91ohci_match(device_t parent, cfdata_t match, void *aux) 831.2Smatt{ 841.2Smatt /* AT91X builtin OHCI module */ 851.2Smatt if (strcmp(match->cf_name, "ohci") == 0 && strcmp(match->cf_atname, "at91ohci") == 0) 861.6Sskrll return 2; 871.2Smatt return(0); 881.2Smatt} 891.2Smatt 901.2Smattvoid 911.2Smattat91ohci_attach(device_t parent, device_t self, void *aux) 921.2Smatt{ 931.5Saymeric struct at91ohci_softc *sc = device_private(self); 941.2Smatt struct at91bus_attach_args *sa = aux; 951.2Smatt 961.5Saymeric sc->sc.sc_dev = self; 971.6Sskrll sc->sc.sc_bus.ub_hcpriv = sc; 981.6Sskrll sc->sc.sc_bus.ub_dmatag = sa->sa_dmat; 991.2Smatt sc->sc.iot = sa->sa_iot; 1001.2Smatt sc->sc_pid = sa->sa_pid; 1011.2Smatt 1021.2Smatt /* Map I/O space */ 1031.6Sskrll if (bus_space_map(sc->sc.iot, sa->sa_addr, sa->sa_size, 1041.2Smatt 0, &sc->sc.ioh)) { 1051.2Smatt printf(": cannot map mem space\n"); 1061.2Smatt return; 1071.2Smatt } 1081.2Smatt 1091.5Saymeric sc->sc.sc_size = sa->sa_size; 1101.5Saymeric 1111.2Smatt /* enable peripheral clock */ 1121.2Smatt at91_peripheral_clock(sc->sc_pid, 1); 1131.2Smatt 1141.2Smatt printf("\n"); 1151.2Smatt 1161.2Smatt /* Defer the rest until later */ 1171.2Smatt config_defer(self, at91ohci_callback); 1181.2Smatt} 1191.2Smatt 1201.2Smattvoid 1211.3Sdslat91ohci_callback(device_t self) 1221.2Smatt{ 1231.5Saymeric struct at91ohci_softc *sc = device_private(self); 1241.2Smatt 1251.2Smatt /* Disable interrupts, so we don't get any spurious ones. */ 1261.2Smatt bus_space_write_4(sc->sc.iot, sc->sc.ioh, OHCI_INTERRUPT_DISABLE, 1271.2Smatt OHCI_ALL_INTRS); 1281.2Smatt 1291.2Smatt sc->sc_ih = at91_intr_establish(sc->sc_pid, IPL_USB, INTR_HIGH_LEVEL, ohci_intr, sc); 1301.6Sskrll int err = ohci_init(&sc->sc); 1311.2Smatt 1321.6Sskrll if (err) { 1331.6Sskrll printf("%s: init failed, error=%d\n", device_xname(self), err); 1341.2Smatt 1351.2Smatt at91_intr_disestablish(sc->sc_ih); 1361.2Smatt return; 1371.2Smatt } 1381.2Smatt 1391.2Smatt /* Attach usb device. */ 1401.8Sthorpej sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint, 1411.9Sthorpej CFARGS_NONE); 1421.2Smatt} 143