Add OMAP3 USB support.
This commit is contained in:
parent
7448d10076
commit
b99e71cc64
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.ti,v 1.16 2019/10/29 22:19:13 jmcneill Exp $
|
||||
# $NetBSD: files.ti,v 1.17 2019/10/30 21:41:40 jmcneill Exp $
|
||||
#
|
||||
|
||||
file arch/arm/ti/ti_cpufreq.c soc_ti
|
||||
@ -88,6 +88,17 @@ device tiotg { } : fdt
|
||||
attach tiotg at fdt with ti_otg
|
||||
file arch/arm/ti/ti_otg.c ti_otg
|
||||
|
||||
device tiusb { } : fdt
|
||||
attach tiusb at fdt with ti_usb
|
||||
file arch/arm/ti/ti_usb.c ti_usb
|
||||
|
||||
device tiusbtll
|
||||
attach tiusbtll at fdt with ti_usbtll
|
||||
file arch/arm/ti/ti_usbtll.c ti_usbtll
|
||||
|
||||
attach ehci at fdt with ti_ehci
|
||||
file arch/arm/ti/ti_ehci.c ti_ehci
|
||||
|
||||
attach motg at fdt with ti_motg
|
||||
file arch/arm/ti/ti_motg.c ti_motg
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $ */
|
||||
/* $NetBSD: omap3_cm.c,v 1.2 2019/10/30 21:41:40 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__KERNEL_RCSID(1, "$NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $");
|
||||
__KERNEL_RCSID(1, "$NetBSD: omap3_cm.c,v 1.2 2019/10/30 21:41:40 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
@ -43,11 +43,20 @@ __KERNEL_RCSID(1, "$NetBSD: omap3_cm.c,v 1.1 2019/10/29 22:19:13 jmcneill Exp $"
|
||||
#define CM_CORE1_BASE 0x0a00
|
||||
#define CM_CORE3_BASE 0x0a08
|
||||
#define CM_WKUP_BASE 0x0c00
|
||||
#define CM_CLK_CTRL_REG_BASE 0x0d00
|
||||
#define CM_PER_BASE 0x1000
|
||||
#define CM_USBHOST_BASE 0x1400
|
||||
|
||||
#define CM_FCLKEN 0x00
|
||||
#define CM_ICLKEN 0x10
|
||||
#define CM_AUTOIDLE 0x30
|
||||
#define CM_CLKSEL 0x40
|
||||
|
||||
#define CM_CLKEN2_PLL 0x04
|
||||
#define CM_IDLEST2_CKGEN 0x24
|
||||
#define CM_AUTOIDLE2_PLL 0x34
|
||||
#define CM_CLKSEL4_PLL 0x4c
|
||||
#define CM_CLKSEL5_PLL 0x50
|
||||
|
||||
static int omap3_cm_match(device_t, cfdata_t, void *);
|
||||
static void omap3_cm_attach(device_t, device_t, void *);
|
||||
@ -71,19 +80,25 @@ omap3_cm_hwmod_enable(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enab
|
||||
val &= ~tc->u.hwmod.mask;
|
||||
PRCM_WRITE(sc, tc->u.hwmod.reg + CM_ICLKEN, val);
|
||||
|
||||
if (tc->u.hwmod.flags & TI_HWMOD_DISABLE_AUTOIDLE) {
|
||||
val = PRCM_READ(sc, tc->u.hwmod.reg + CM_AUTOIDLE);
|
||||
val &= ~tc->u.hwmod.mask;
|
||||
PRCM_WRITE(sc, tc->u.hwmod.reg + CM_AUTOIDLE, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OMAP3_CM_HWMOD_CORE1(_name, _bit, _parent) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_CORE1_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
|
||||
#define OMAP3_CM_HWMOD_CORE3(_name, _bit, _parent) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_CORE3_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
|
||||
#define OMAP3_CM_HWMOD_WKUP(_name, _bit, _parent) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_WKUP_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
|
||||
#define OMAP3_CM_HWMOD_PER(_name, _bit, _parent) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_PER_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable)
|
||||
#define OMAP3_CM_HWMOD_USBHOST(_name, _mask, _parent) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_USBHOST_BASE, (_mask), (_parent), omap3_cm_hwmod_enable)
|
||||
#define OMAP3_CM_HWMOD_CORE1(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_CORE1_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_CORE3(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_CORE3_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_WKUP(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_WKUP_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_PER(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_PER_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
#define OMAP3_CM_HWMOD_USBHOST(_name, _bit, _parent, _flags) \
|
||||
TI_PRCM_HWMOD_MASK((_name), CM_USBHOST_BASE, __BIT(_bit), (_parent), omap3_cm_hwmod_enable, (_flags))
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,omap3-cm",
|
||||
@ -96,59 +111,79 @@ CFATTACH_DECL_NEW(omap3_cm, sizeof(struct ti_prcm_softc),
|
||||
static struct ti_prcm_clk omap3_cm_clks[] = {
|
||||
/* XXX until we get a proper clock tree */
|
||||
TI_PRCM_FIXED("FIXED_32K", 32768),
|
||||
TI_PRCM_FIXED("FIXED_48MHZ", 48000000),
|
||||
TI_PRCM_FIXED("FIXED_96MHZ", 96000000),
|
||||
TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "FIXED_48MHZ"),
|
||||
TI_PRCM_FIXED_FACTOR("MMC_CLK", 1, 1, "FIXED_96MHZ"),
|
||||
TI_PRCM_FIXED("SYS_CLK", 13000000),
|
||||
TI_PRCM_FIXED("MMC_CLK", 96000000),
|
||||
TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "SYS_CLK"),
|
||||
|
||||
OMAP3_CM_HWMOD_CORE1("usb_otg_hs", 4, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mcbsp1", 9, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mcbsp5", 10, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("timer10", 11, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("timer11", 12, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("uart1", 13, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("uart2", 14, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c1", 15, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c2", 16, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c3", 17, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi1", 18, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi2", 19, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi3", 20, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi4", 21, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("hdq1w", 22, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc1", 24, "MMC_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc2", 25, "MMC_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc3", 30, "MMC_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE1("usb_otg_hs", 4, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcbsp1", 9, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcbsp5", 10, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("timer10", 11, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("timer11", 12, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("uart1", 13, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("uart2", 14, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c1", 15, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c2", 16, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("i2c3", 17, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi1", 18, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi2", 19, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi3", 20, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mcspi4", 21, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("hdq1w", 22, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc1", 24, "MMC_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc2", 25, "MMC_CLK", 0),
|
||||
OMAP3_CM_HWMOD_CORE1("mmc3", 30, "MMC_CLK", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_CORE3("usb_tll_hs", 2, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_CORE3("usb_tll_hs", 2, "PERIPH_CLK", TI_HWMOD_DISABLE_AUTOIDLE),
|
||||
|
||||
OMAP3_CM_HWMOD_WKUP("timer1", 0, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_WKUP("counter_32k", 2, "FIXED_32K"),
|
||||
OMAP3_CM_HWMOD_WKUP("gpio1", 3, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_WKUP("wd_timer2", 5, "FIXED_32K"),
|
||||
OMAP3_CM_HWMOD_WKUP("timer1", 0, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_WKUP("counter_32k", 2, "FIXED_32K", 0),
|
||||
OMAP3_CM_HWMOD_WKUP("gpio1", 3, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_WKUP("wd_timer2", 5, "FIXED_32K", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_PER("mcbsp2", 0, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp3", 1, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp4", 2, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer2", 3, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer3", 4, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer4", 5, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer5", 6, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer6", 7, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer7", 8, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer8", 9, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("timer9", 10, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("uart3", 11, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("wd_timer3", 12, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("gpio2", 13, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("gpio3", 14, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("gpio4", 15, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("gpio5", 16, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("gpio6", 17, "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp2", 0, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp3", 1, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("mcbsp4", 2, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer2", 3, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer3", 4, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer4", 5, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer5", 6, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer6", 7, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer7", 8, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer8", 9, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("timer9", 10, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("uart3", 11, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("wd_timer3", 12, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio2", 13, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio3", 14, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio4", 15, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio5", 16, "PERIPH_CLK", 0),
|
||||
OMAP3_CM_HWMOD_PER("gpio6", 17, "PERIPH_CLK", 0),
|
||||
|
||||
OMAP3_CM_HWMOD_USBHOST("usb_host_hs", __BITS(1,0), "PERIPH_CLK"),
|
||||
OMAP3_CM_HWMOD_USBHOST("usb_host_hs", 0, "PERIPH_CLK", 0),
|
||||
};
|
||||
|
||||
static void
|
||||
omap3_cm_initclocks(struct ti_prcm_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
/* Select SYS_CLK for GPTIMER 2 and 3 */
|
||||
val = PRCM_READ(sc, CM_PER_BASE + CM_CLKSEL);
|
||||
val |= __BIT(0); /* CLKSEL_GPT2 0x1: source is SYS_CLK */
|
||||
val |= __BIT(1); /* CLKSEL_GPT3 0x1: source is SYS_CLK */
|
||||
PRCM_WRITE(sc, CM_PER_BASE + CM_CLKSEL, val);
|
||||
|
||||
/* Enable DPLL5 */
|
||||
const u_int m = 443, n = 11, m2 = 4;
|
||||
PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_CLKEN2_PLL, (0x4 << 4) | 0x7);
|
||||
PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_CLKSEL4_PLL, (m << 8) | n);
|
||||
PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_CLKSEL5_PLL, m2);
|
||||
PRCM_WRITE(sc, CM_CLK_CTRL_REG_BASE + CM_AUTOIDLE2_PLL, 1);
|
||||
while ((PRCM_READ(sc, CM_CLK_CTRL_REG_BASE + CM_IDLEST2_CKGEN) & 1) == 0)
|
||||
delay(100);
|
||||
}
|
||||
|
||||
static int
|
||||
omap3_cm_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
@ -177,6 +212,8 @@ omap3_cm_attach(device_t parent, device_t self, void *aux)
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": OMAP3xxx CM\n");
|
||||
|
||||
omap3_cm_initclocks(sc);
|
||||
|
||||
clocks = of_find_firstchild_byname(sc->sc_phandle, "clocks");
|
||||
if (clocks > 0)
|
||||
fdt_add_bus(self, clocks, faa);
|
||||
|
157
sys/arch/arm/ti/ti_ehci.c
Normal file
157
sys/arch/arm/ti/ti_ehci.c
Normal file
@ -0,0 +1,157 @@
|
||||
/* $NetBSD: ti_ehci.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015-2019 Jared McNeill <jmcneill@invisible.ca>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_ehci.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <dev/usb/usb.h>
|
||||
#include <dev/usb/usbdi.h>
|
||||
#include <dev/usb/usbdivar.h>
|
||||
#include <dev/usb/usb_mem.h>
|
||||
#include <dev/usb/ehcireg.h>
|
||||
#include <dev/usb/ehcivar.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#define TI_EHCI_NPORTS 3
|
||||
|
||||
static int ti_ehci_match(device_t, cfdata_t, void *);
|
||||
static void ti_ehci_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL2_NEW(ti_ehci, sizeof(struct ehci_softc),
|
||||
ti_ehci_match, ti_ehci_attach, NULL,
|
||||
ehci_activate, NULL, ehci_childdet);
|
||||
|
||||
static int
|
||||
ti_ehci_match(device_t parent, cfdata_t cf, void *aux)
|
||||
{
|
||||
const char * const compatible[] = {
|
||||
"ti,ehci-omap",
|
||||
NULL
|
||||
};
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_ehci_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ehci_softc * const sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
struct fdtbus_reset *rst;
|
||||
struct fdtbus_phy *phy;
|
||||
struct clk *clk;
|
||||
char intrstr[128];
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
int error;
|
||||
void *ih;
|
||||
u_int n;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable clocks */
|
||||
for (n = 0; (clk = fdtbus_clock_get_index(phandle, n)) != NULL; n++)
|
||||
if (clk_enable(clk) != 0) {
|
||||
aprint_error(": couldn't enable clock #%d\n", n);
|
||||
return;
|
||||
}
|
||||
/* De-assert resets */
|
||||
for (n = 0; (rst = fdtbus_reset_get_index(phandle, n)) != NULL; n++)
|
||||
if (fdtbus_reset_deassert(rst) != 0) {
|
||||
aprint_error(": couldn't de-assert reset #%d\n", n);
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_bus.ub_hcpriv = sc;
|
||||
sc->sc_bus.ub_dmatag = faa->faa_dmat;
|
||||
sc->sc_bus.ub_revision = USBREV_2_0;
|
||||
if (of_hasprop(phandle, "has-transaction-translator"))
|
||||
sc->sc_flags |= EHCIF_ETTF;
|
||||
else
|
||||
sc->sc_ncomp = 1;
|
||||
sc->sc_size = size;
|
||||
sc->iot = faa->faa_bst;
|
||||
if (bus_space_map(sc->iot, addr, size, 0, &sc->ioh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": EHCI\n");
|
||||
|
||||
/* Enable PHYs */
|
||||
for (n = 0; n < TI_EHCI_NPORTS; n++) {
|
||||
phy = fdtbus_phy_get_index(phandle, n);
|
||||
if (phy && fdtbus_phy_enable(phy, true) != 0) {
|
||||
aprint_error(": couldn't enable phy\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable interrupts */
|
||||
sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
|
||||
EOWRITE4(sc, EHCI_USBINTR, 0);
|
||||
|
||||
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
|
||||
aprint_error_dev(self, "failed to decode interrupt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ih = fdtbus_intr_establish(phandle, 0, IPL_USB, FDT_INTR_MPSAFE,
|
||||
ehci_intr, sc);
|
||||
if (ih == NULL) {
|
||||
aprint_error_dev(self, "couldn't establish interrupt on %s\n",
|
||||
intrstr);
|
||||
return;
|
||||
}
|
||||
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
|
||||
|
||||
error = ehci_init(sc);
|
||||
if (error) {
|
||||
aprint_error_dev(self, "init failed, error = %d\n", error);
|
||||
return;
|
||||
}
|
||||
|
||||
pmf_device_register1(self, NULL, NULL, ehci_shutdown);
|
||||
|
||||
sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ti_prcm.h,v 1.3 2019/10/29 22:19:13 jmcneill Exp $ */
|
||||
/* $NetBSD: ti_prcm.h,v 1.4 2019/10/30 21:41:40 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
|
||||
@ -57,8 +57,11 @@ struct ti_prcm_hwmod {
|
||||
bus_size_t reg;
|
||||
uint32_t mask;
|
||||
const char *parent;
|
||||
u_int flags;
|
||||
};
|
||||
|
||||
#define TI_HWMOD_DISABLE_AUTOIDLE 0x01
|
||||
|
||||
struct ti_prcm_clk {
|
||||
struct clk base;
|
||||
enum ti_prcm_clktype type;
|
||||
@ -138,13 +141,14 @@ ti_prcm_hwmod_get_parent(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc)
|
||||
}
|
||||
|
||||
#define TI_PRCM_HWMOD(_name, _reg, _parent, _enable) \
|
||||
TI_PRCM_HWMOD_MASK(_name, _reg, 0, _parent, _enable)
|
||||
TI_PRCM_HWMOD_MASK(_name, _reg, 0, _parent, _enable, 0)
|
||||
|
||||
#define TI_PRCM_HWMOD_MASK(_name, _reg, _mask, _parent, _enable) \
|
||||
#define TI_PRCM_HWMOD_MASK(_name, _reg, _mask, _parent, _enable, _flags) \
|
||||
{ \
|
||||
.type = TI_PRCM_HWMOD, .base.name = (_name), \
|
||||
.u.hwmod.reg = (_reg), \
|
||||
.u.hwmod.mask = (_mask), \
|
||||
.u.hwmod.flags = (_flags), \
|
||||
.u.hwmod.parent = (_parent), \
|
||||
.enable = (_enable), \
|
||||
.get_parent = ti_prcm_hwmod_get_parent, \
|
||||
|
221
sys/arch/arm/ti/ti_usb.c
Normal file
221
sys/arch/arm/ti/ti_usb.c
Normal file
@ -0,0 +1,221 @@
|
||||
/* $NetBSD: ti_usb.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_usb.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#define UHH_SYSCONFIG 0x10
|
||||
#define UHH_SYSCONFIG_MIDLEMODE_MASK 0x00003000
|
||||
#define UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x00002000
|
||||
#define UHH_SYSCONFIG_CLOCKACTIVITY 0x00000100
|
||||
#define UHH_SYSCONFIG_SIDLEMODE_MASK 0x00000018
|
||||
#define UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE 0x00000008
|
||||
#define UHH_SYSCONFIG_ENAWAKEUP 0x00000004
|
||||
#define UHH_SYSCONFIG_SOFTRESET 0x00000002
|
||||
#define UHH_SYSCONFIG_AUTOIDLE 0x00000001
|
||||
|
||||
#define UHH_HOSTCONFIG 0x40
|
||||
#define UHH_HOSTCONFIG_APP_START_CLK __BIT(31)
|
||||
#define UHH_HOSTCONFIG_P3_MODE __BITS(21,20)
|
||||
#define UHH_HOSTCONFIG_P2_MODE __BITS(19,18)
|
||||
#define UHH_HOSTCONFIG_P1_MODE __BITS(17,16)
|
||||
#define UHH_HOSTCONFIG_PMODE_ULPI_PHY 0
|
||||
#define UHH_HOSTCONFIG_PMODE_UTMI 1
|
||||
#define UHH_HOSTCONFIG_PMODE_HSIC 3
|
||||
#define UHH_HOSTCONFIG_P3_ULPI_BYPASS __BIT(12)
|
||||
#define UHH_HOSTCONFIG_P2_ULPI_BYPASS __BIT(11)
|
||||
#define UHH_HOSTCONFIG_P3_CONNECT_STATUS __BIT(10)
|
||||
#define UHH_HOSTCONFIG_P2_CONNECT_STATUS __BIT(9)
|
||||
#define UHH_HOSTCONFIG_P1_CONNECT_STATUS __BIT(8)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR_ALIGN __BIT(5)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR16 __BIT(4)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR8 __BIT(3)
|
||||
#define UHH_HOSTCONFIG_ENA_INCR4 __BIT(2)
|
||||
#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN __BIT(1)
|
||||
#define UHH_HOSTCONFIG_P1_ULPI_BYPASS __BIT(0)
|
||||
|
||||
extern void tl_usbtll_enable_port(u_int);
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,usbhs-host",
|
||||
NULL
|
||||
};
|
||||
|
||||
#define TI_USB_NPORTS 3
|
||||
|
||||
enum {
|
||||
CONNECT_STATUS,
|
||||
ULPI_BYPASS,
|
||||
TI_USB_NBITS
|
||||
};
|
||||
|
||||
static const uint32_t ti_usb_portbits[TI_USB_NPORTS][TI_USB_NBITS] = {
|
||||
[0] = {
|
||||
[CONNECT_STATUS] = UHH_HOSTCONFIG_P1_CONNECT_STATUS,
|
||||
[ULPI_BYPASS] = UHH_HOSTCONFIG_P1_ULPI_BYPASS,
|
||||
},
|
||||
[1] = {
|
||||
[CONNECT_STATUS] = UHH_HOSTCONFIG_P2_CONNECT_STATUS,
|
||||
[ULPI_BYPASS] = UHH_HOSTCONFIG_P2_ULPI_BYPASS,
|
||||
},
|
||||
[2] = {
|
||||
[CONNECT_STATUS] = UHH_HOSTCONFIG_P3_CONNECT_STATUS,
|
||||
[ULPI_BYPASS] = UHH_HOSTCONFIG_P3_ULPI_BYPASS,
|
||||
},
|
||||
};
|
||||
|
||||
enum {
|
||||
PORT_UNUSED,
|
||||
PORT_EHCI_PHY,
|
||||
PORT_EHCI_TLL,
|
||||
PORT_EHCI_HSIC,
|
||||
};
|
||||
|
||||
struct ti_usb_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
|
||||
u_int sc_portmode[TI_USB_NPORTS];
|
||||
};
|
||||
|
||||
static int ti_usb_match(device_t, cfdata_t, void *);
|
||||
static void ti_usb_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_usb, sizeof(struct ti_usb_softc),
|
||||
ti_usb_match, ti_usb_attach, NULL, NULL);
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
static void
|
||||
ti_usb_init(struct ti_usb_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
int port;
|
||||
|
||||
val = RD4(sc, UHH_SYSCONFIG);
|
||||
val &= ~(UHH_SYSCONFIG_SIDLEMODE_MASK|UHH_SYSCONFIG_MIDLEMODE_MASK);
|
||||
val |= UHH_SYSCONFIG_MIDLEMODE_SMARTSTANDBY;
|
||||
val |= UHH_SYSCONFIG_CLOCKACTIVITY;
|
||||
val |= UHH_SYSCONFIG_SIDLEMODE_SMARTIDLE;
|
||||
val |= UHH_SYSCONFIG_ENAWAKEUP;
|
||||
val &= ~UHH_SYSCONFIG_AUTOIDLE;
|
||||
WR4(sc, UHH_SYSCONFIG, val);
|
||||
|
||||
val = RD4(sc, UHH_SYSCONFIG);
|
||||
|
||||
val = RD4(sc, UHH_HOSTCONFIG);
|
||||
val |= UHH_HOSTCONFIG_ENA_INCR16;
|
||||
val |= UHH_HOSTCONFIG_ENA_INCR8;
|
||||
val |= UHH_HOSTCONFIG_ENA_INCR4;
|
||||
val |= UHH_HOSTCONFIG_APP_START_CLK;
|
||||
val &= ~UHH_HOSTCONFIG_ENA_INCR_ALIGN;
|
||||
for (port = 0; port < TI_USB_NPORTS; port++) {
|
||||
if (sc->sc_portmode[port] == PORT_UNUSED)
|
||||
val &= ~ti_usb_portbits[port][CONNECT_STATUS];
|
||||
if (sc->sc_portmode[port] == PORT_EHCI_PHY)
|
||||
val &= ~ti_usb_portbits[port][ULPI_BYPASS];
|
||||
else
|
||||
val |= ti_usb_portbits[port][ULPI_BYPASS];
|
||||
}
|
||||
WR4(sc, UHH_HOSTCONFIG, val);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_usb_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usb_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_usb_softc *sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
char propname[16];
|
||||
const char *portmode;
|
||||
int port;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (port = 0; port < TI_USB_NPORTS; port++) {
|
||||
snprintf(propname, sizeof(propname), "port%d-mode", port + 1);
|
||||
portmode = fdtbus_get_string(phandle, propname);
|
||||
if (portmode == NULL)
|
||||
continue;
|
||||
if (strcmp(portmode, "ehci-phy") == 0)
|
||||
sc->sc_portmode[port] = PORT_EHCI_PHY;
|
||||
else if (strcmp(portmode, "ehci-tll") == 0)
|
||||
sc->sc_portmode[port] = PORT_EHCI_TLL;
|
||||
else if (strcmp(portmode, "ehci-hsic") == 0)
|
||||
sc->sc_portmode[port] = PORT_EHCI_HSIC;
|
||||
|
||||
if (sc->sc_portmode[port] != PORT_UNUSED)
|
||||
tl_usbtll_enable_port(port);
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": OMAP HS USB Host\n");
|
||||
|
||||
ti_usb_init(sc);
|
||||
|
||||
fdt_add_bus(self, phandle, faa);
|
||||
}
|
203
sys/arch/arm/ti/ti_usbtll.c
Normal file
203
sys/arch/arm/ti/ti_usbtll.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* $NetBSD: ti_usbtll.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ti_usbtll.c,v 1.1 2019/10/30 21:41:40 jmcneill Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/fdt/fdtvar.h>
|
||||
|
||||
#include <arm/ti/ti_prcm.h>
|
||||
|
||||
#define USBTLL_SYSCONFIG 0x10
|
||||
#define USBTLL_SYSCONFIG_CLOCKACTIVITY 0x00000100
|
||||
#define USBTLL_SYSCONFIG_SIDLEMODE 0x00000018
|
||||
#define USBTLL_SYSCONFIG_ENAWAKEUP 0x00000004
|
||||
#define USBTLL_SYSCONFIG_SOFTRESET 0x00000002
|
||||
#define USBTLL_SYSCONFIG_AUTOIDLE 0x00000001
|
||||
|
||||
#define USBTLL_SYSSTATUS 0x14
|
||||
#define USBTLL_SYSSTATUS_RESETDONE 0x00000001
|
||||
|
||||
#define USBTLL_SHARED_CONF 0x30
|
||||
#define USBTLL_SHARED_CONF_USB_90D_DDR_EN 0x00000040
|
||||
#define USBTLL_SHARED_CONF_USB_180D_SDR_EN 0x00000020
|
||||
#define USBTLL_SHARED_CONF_USB_DIVRATIO 0x0000001c
|
||||
#define USBTLL_SHARED_CONF_FCLK_REQ 0x00000002
|
||||
#define USBTLL_SHARED_CONF_FCLK_IS_ON 0x00000001
|
||||
|
||||
#define USBTLL_CHANNEL_CONF(i) (0x40 + (0x04 * (i)))
|
||||
#define USBTLL_CHANNEL_CONF_FSLSLINESTATE 0x30000000
|
||||
#define USBTLL_CHANNEL_CONF_FSLSMODE 0x0f000000
|
||||
#define USBTLL_CHANNEL_CONF_TESTTXSE0 0x00100000
|
||||
#define USBTLL_CHANNEL_CONF_TESTTXDAT 0x00080000
|
||||
#define USBTLL_CHANNEL_CONF_TESTTXEN 0x00040000
|
||||
#define USBTLL_CHANNEL_CONF_TESTEN 0x00020000
|
||||
#define USBTLL_CHANNEL_CONF_DRVVBUS 0x00010000
|
||||
#define USBTLL_CHANNEL_CONF_CHRGVBUS 0x00008000
|
||||
#define USBTLL_CHANNEL_CONF_ULPINOBITSTUFF 0x00000800
|
||||
#define USBTLL_CHANNEL_CONF_ULPIAUTOIDLE 0x00000400
|
||||
#define USBTLL_CHANNEL_CONF_UTMIAUTOIDLE 0x00000200
|
||||
#define USBTLL_CHANNEL_CONF_ULPIDDRMODE 0x00000100
|
||||
#define USBTLL_CHANNEL_CONF_ULPIOUTCLKMODE 0x00000080
|
||||
#define USBTLL_CHANNEL_CONF_TLLFULLSPEED 0x00000040
|
||||
#define USBTLL_CHANNEL_CONF_TLLCONNECT 0x00000020
|
||||
#define USBTLL_CHANNEL_CONF_TLLATTACH 0x00000010
|
||||
#define USBTLL_CHANNEL_CONF_UTMIISADEV 0x00000008
|
||||
#define USBTLL_CHANNEL_CONF_CHANMODE 0x00000006
|
||||
#define USBTLL_CHANNEL_CONF_CHANEN 0x00000001
|
||||
|
||||
static const char * const compatible[] = {
|
||||
"ti,usbhs-tll",
|
||||
NULL
|
||||
};
|
||||
|
||||
struct ti_usbtll_softc {
|
||||
device_t sc_dev;
|
||||
bus_space_tag_t sc_bst;
|
||||
bus_space_handle_t sc_bsh;
|
||||
};
|
||||
|
||||
static int ti_usbtll_match(device_t, cfdata_t, void *);
|
||||
static void ti_usbtll_attach(device_t, device_t, void *);
|
||||
|
||||
CFATTACH_DECL_NEW(ti_usbtll, sizeof(struct ti_usbtll_softc),
|
||||
ti_usbtll_match, ti_usbtll_attach, NULL, NULL);
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
|
||||
#define WR4(sc, reg, val) \
|
||||
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
|
||||
|
||||
static struct ti_usbtll_softc *ti_usbtll_sc = NULL;
|
||||
|
||||
void tl_usbtll_enable_port(u_int);
|
||||
|
||||
void
|
||||
tl_usbtll_enable_port(u_int port)
|
||||
{
|
||||
struct ti_usbtll_softc *sc = ti_usbtll_sc;
|
||||
uint32_t val;
|
||||
|
||||
if (sc == NULL) {
|
||||
printf("%s: driver not loaded\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
val = RD4(sc, USBTLL_CHANNEL_CONF(port));
|
||||
val &= ~(USBTLL_CHANNEL_CONF_ULPINOBITSTUFF|
|
||||
USBTLL_CHANNEL_CONF_ULPIAUTOIDLE|
|
||||
USBTLL_CHANNEL_CONF_ULPIDDRMODE);
|
||||
val |= USBTLL_CHANNEL_CONF_CHANEN;
|
||||
WR4(sc, USBTLL_CHANNEL_CONF(port), val);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usbtll_reset(struct ti_usbtll_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
int retry = 5000;
|
||||
|
||||
WR4(sc, USBTLL_SYSCONFIG, USBTLL_SYSCONFIG_SOFTRESET);
|
||||
do {
|
||||
val = RD4(sc, USBTLL_SYSSTATUS);
|
||||
if (val & USBTLL_SYSSTATUS_RESETDONE)
|
||||
break;
|
||||
delay(10);
|
||||
} while (--retry > 0);
|
||||
if (retry == 0)
|
||||
aprint_error_dev(sc->sc_dev, "reset timeout\n");
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usbtll_init(struct ti_usbtll_softc *sc)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
ti_usbtll_reset(sc);
|
||||
|
||||
val = USBTLL_SYSCONFIG_ENAWAKEUP |
|
||||
USBTLL_SYSCONFIG_AUTOIDLE |
|
||||
USBTLL_SYSCONFIG_SIDLEMODE |
|
||||
USBTLL_SYSCONFIG_CLOCKACTIVITY;
|
||||
WR4(sc, USBTLL_SYSCONFIG, val);
|
||||
|
||||
val = RD4(sc, USBTLL_SHARED_CONF);
|
||||
val |= (USBTLL_SHARED_CONF_FCLK_IS_ON | (1 << 2));
|
||||
val &= ~USBTLL_SHARED_CONF_USB_90D_DDR_EN;
|
||||
val &= ~USBTLL_SHARED_CONF_USB_180D_SDR_EN;
|
||||
WR4(sc, USBTLL_SHARED_CONF, val);
|
||||
}
|
||||
|
||||
static int
|
||||
ti_usbtll_match(device_t parent, cfdata_t match, void *aux)
|
||||
{
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
|
||||
return of_match_compatible(faa->faa_phandle, compatible);
|
||||
}
|
||||
|
||||
static void
|
||||
ti_usbtll_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
struct ti_usbtll_softc *sc = device_private(self);
|
||||
struct fdt_attach_args * const faa = aux;
|
||||
const int phandle = faa->faa_phandle;
|
||||
bus_addr_t addr;
|
||||
bus_size_t size;
|
||||
|
||||
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
|
||||
aprint_error(": couldn't get registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ti_prcm_enable_hwmod(phandle, 0) != 0) {
|
||||
aprint_error(": couldn't enable module\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sc->sc_dev = self;
|
||||
sc->sc_bst = faa->faa_bst;
|
||||
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
|
||||
aprint_error(": couldn't map registers\n");
|
||||
return;
|
||||
}
|
||||
|
||||
aprint_naive("\n");
|
||||
aprint_normal(": OMAP HS USB Host TLL\n");
|
||||
|
||||
ti_usbtll_init(sc);
|
||||
|
||||
if (ti_usbtll_sc == NULL)
|
||||
ti_usbtll_sc = sc;
|
||||
}
|
Loading…
Reference in New Issue
Block a user