xref: /netbsd-src/sys/arch/arm/imx/imx23_usb.c (revision 0b303a9fd61d02c3ad67a62b4890948945ac163c)
1*0b303a9fSandvar /* $Id: imx23_usb.c,v 1.7 2024/01/15 17:29:27 andvar Exp $ */
294de0730Smatt 
394de0730Smatt /*
494de0730Smatt  * Copyright (c) 2013 The NetBSD Foundation, Inc.
594de0730Smatt  * All rights reserved.
694de0730Smatt  *
794de0730Smatt  * This code is derived from software contributed to The NetBSD Foundation
894de0730Smatt  * by Petri Laakso.
994de0730Smatt  *
1094de0730Smatt  * Redistribution and use in source and binary forms, with or without
1194de0730Smatt  * modification, are permitted provided that the following conditions
1294de0730Smatt  * are met:
1394de0730Smatt  * 1. Redistributions of source code must retain the above copyright
1494de0730Smatt  *    notice, this list of conditions and the following disclaimer.
1594de0730Smatt  * 2. Redistributions in binary form must reproduce the above copyright
1694de0730Smatt  *    notice, this list of conditions and the following disclaimer in the
1794de0730Smatt  *    documentation and/or other materials provided with the distribution.
1894de0730Smatt  *
1994de0730Smatt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2094de0730Smatt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2194de0730Smatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2294de0730Smatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2394de0730Smatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2494de0730Smatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2594de0730Smatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2694de0730Smatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2794de0730Smatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2894de0730Smatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2994de0730Smatt  * POSSIBILITY OF SUCH DAMAGE.
3094de0730Smatt  */
3194de0730Smatt 
3294de0730Smatt #include <sys/param.h>
3394de0730Smatt #include <sys/types.h>
3494de0730Smatt #include <sys/bus.h>
3594de0730Smatt #include <sys/errno.h>
3694de0730Smatt 
3794de0730Smatt #include <arm/pic/picvar.h>
3894de0730Smatt 
3994de0730Smatt #include <dev/usb/usb.h>
4094de0730Smatt #include <dev/usb/usbdi.h>
4194de0730Smatt #include <dev/usb/usbdivar.h>
4294de0730Smatt #include <dev/usb/usb_mem.h>
4394de0730Smatt #include <dev/usb/ehcireg.h>
4494de0730Smatt #include <dev/usb/ehcivar.h>
4594de0730Smatt #include <arm/imx/imxusbvar.h>
4605ac7a10Shkenken #include <arm/imx/imxusbreg.h>
4794de0730Smatt 
4894de0730Smatt #include <arm/mainbus/mainbus.h>
4994de0730Smatt 
5094de0730Smatt #include <arm/imx/imx23_clkctrlvar.h>
5194de0730Smatt #include <arm/imx/imx23_digctlvar.h>
5294de0730Smatt #include <arm/imx/imx23_pinctrlvar.h>
5394de0730Smatt #include <arm/imx/imx23var.h>
5494de0730Smatt 
5594de0730Smatt #include "locators.h"
5694de0730Smatt 
5794de0730Smatt struct imx23_usb_softc {
5805ac7a10Shkenken 	struct imxusbc_softc  sc_imxusbc; /* Must be first */
5994de0730Smatt };
6094de0730Smatt 
6194de0730Smatt static int	imx23_usb_match(device_t, cfdata_t, void *);
6294de0730Smatt static void	imx23_usb_attach(device_t, device_t, void *);
6394de0730Smatt static int	imx23_usb_activate(device_t, enum devact);
6494de0730Smatt 
6594de0730Smatt static int      imxusbc_search(device_t, cfdata_t, const int *, void *);
66*0b303a9fSandvar static void	imx23_usb_init(struct imxehci_softc *, uintptr_t);
6794de0730Smatt 
6894de0730Smatt CFATTACH_DECL3_NEW(imxusbc,
6994de0730Smatt         sizeof(struct imx23_usb_softc),
7094de0730Smatt         imx23_usb_match,
7194de0730Smatt         imx23_usb_attach,
7294de0730Smatt         NULL,
7394de0730Smatt         imx23_usb_activate,
7494de0730Smatt         NULL,
7594de0730Smatt         NULL,
7694de0730Smatt         0
7794de0730Smatt );
7894de0730Smatt 
7994de0730Smatt #define AHB_USB		0x80080000
8094de0730Smatt #define AHB_USB_SIZE	0x40000
8194de0730Smatt 
8294de0730Smatt static int
imx23_usb_match(device_t parent,cfdata_t match,void * aux)8394de0730Smatt imx23_usb_match(device_t parent, cfdata_t match, void *aux)
8494de0730Smatt {
8594de0730Smatt 	struct ahb_attach_args *aa = aux;
8694de0730Smatt 
8794de0730Smatt 	if ((aa->aa_addr == AHB_USB) && (aa->aa_size == AHB_USB_SIZE))
8894de0730Smatt 		return 1;
8994de0730Smatt 
9094de0730Smatt 	return 0;
9194de0730Smatt }
9294de0730Smatt 
9394de0730Smatt static void
imx23_usb_attach(device_t parent,device_t self,void * aux)9494de0730Smatt imx23_usb_attach(device_t parent, device_t self, void *aux)
9594de0730Smatt {
9694de0730Smatt 	struct imxusbc_softc *sc = device_private(self);
9794de0730Smatt 
9805ac7a10Shkenken 	sc->sc_dev = self;
9994de0730Smatt 	sc->sc_iot = &imx23_bus_space;
10005ac7a10Shkenken 	sc->sc_ehci_size = IMXUSB_EHCI_SIZE;
10105ac7a10Shkenken 	sc->sc_ehci_offset = IMXUSB_EHCI_SIZE;
10205ac7a10Shkenken 
10305ac7a10Shkenken 	sc->sc_init_md_hook = imx23_usb_init;
10405ac7a10Shkenken 	sc->sc_intr_establish_md_hook = NULL;
10505ac7a10Shkenken 	sc->sc_setup_md_hook = NULL;
10694de0730Smatt 
10794de0730Smatt 	if (bus_space_map(sc->sc_iot, AHB_USB, AHB_USB_SIZE, 0, &sc->sc_ioh)) {
10894de0730Smatt 		aprint_error_dev(sc->sc_dev, "Unable to map bus space");
10994de0730Smatt 		return;
11094de0730Smatt 	}
11194de0730Smatt 
11294de0730Smatt 	/* Enable PLL outputs for USB PHY. */
11394de0730Smatt 	clkctrl_en_usb();
11494de0730Smatt 
11594de0730Smatt 	/* Enable external USB chip. */
11668bc6eb1Sskrll 	imx23_pinctrl_en_usb();
11794de0730Smatt 
11894de0730Smatt 	/* USB clock on. */
11994de0730Smatt 	digctl_usb_clkgate(0);
12094de0730Smatt 
12194de0730Smatt 	aprint_normal("\n");
12294de0730Smatt 
12394de0730Smatt 	/* attach OTG/EHCI host controllers */
1242685996bSthorpej 	config_search(self, NULL,
125c7fb772bSthorpej 	    CFARGS(.search = imxusbc_search));
12694de0730Smatt 
12794de0730Smatt 	return;
12894de0730Smatt }
12994de0730Smatt 
13094de0730Smatt static int
imx23_usb_activate(device_t self,enum devact act)13194de0730Smatt imx23_usb_activate(device_t self, enum devact act)
13294de0730Smatt {
13394de0730Smatt 	return EOPNOTSUPP;
13494de0730Smatt }
13594de0730Smatt 
13694de0730Smatt static int
imxusbc_search(device_t parent,cfdata_t cf,const int * ldesc,void * aux)13794de0730Smatt imxusbc_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
13894de0730Smatt {
13994de0730Smatt         struct imxusbc_softc *sc = device_private(parent);
14094de0730Smatt         struct imxusbc_attach_args aa;
14194de0730Smatt 
14294de0730Smatt         aa.aa_iot = sc->sc_iot;
14394de0730Smatt         aa.aa_ioh = sc->sc_ioh;
14494de0730Smatt         aa.aa_dmat = &imx23_bus_dma_tag;
14594de0730Smatt         aa.aa_unit = cf->cf_loc[IMXUSBCCF_UNIT];
14694de0730Smatt         aa.aa_irq = cf->cf_loc[IMXUSBCCF_IRQ];
14794de0730Smatt 
1482685996bSthorpej         if (config_probe(parent, cf, &aa))
149c7fb772bSthorpej                 config_attach(parent, cf, &aa, NULL, CFARGS_NONE);
15094de0730Smatt 
15194de0730Smatt         return 0;
15294de0730Smatt }
15394de0730Smatt 
15494de0730Smatt static
imx23_usb_init(struct imxehci_softc * sc,uintptr_t data)1551b53f886Sbouyer void imx23_usb_init(struct imxehci_softc *sc, uintptr_t data)
15694de0730Smatt {
15794de0730Smatt 
15894de0730Smatt 	sc->sc_iftype = IMXUSBC_IF_UTMI;
15994de0730Smatt 
16094de0730Smatt 	return;
16194de0730Smatt }
162