[rtems-libbsd commit] dwc_otg: Update host frame interval
Sebastian Huber
sebh at rtems.org
Tue Oct 27 05:32:36 UTC 2020
Module: rtems-libbsd
Branch: 6-freebsd-12
Commit: 8c4c7807f52636fa2b6ed6f867f966a9cf7455be
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=8c4c7807f52636fa2b6ed6f867f966a9cf7455be
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Thu Apr 2 16:34:42 2020 +0200
dwc_otg: Update host frame interval
Update the host frame interval after a device connection. Select also
the FS/LS PHY clock. It is not clear if this works on all platforms.
Update #3910.
---
freebsd/sys/dev/usb/controller/dwc_otg.c | 64 ++++++++++++--------------------
1 file changed, 24 insertions(+), 40 deletions(-)
diff --git a/freebsd/sys/dev/usb/controller/dwc_otg.c b/freebsd/sys/dev/usb/controller/dwc_otg.c
index 005c7ec..b75b887 100644
--- a/freebsd/sys/dev/usb/controller/dwc_otg.c
+++ b/freebsd/sys/dev/usb/controller/dwc_otg.c
@@ -470,38 +470,31 @@ dwc_otg_uses_split(struct usb_device *udev)
static void
dwc_otg_update_host_frame_interval(struct dwc_otg_softc *sc)
{
-
- /*
- * Disabled until further. Assuming that the register is already
- * programmed correctly by the boot loader.
- */
-#if 0
+ uint32_t fslpclksel;
+ uint32_t frint;
uint32_t temp;
- /* setup HOST frame interval register, based on existing value */
- temp = DWC_OTG_READ_4(sc, DOTG_HFIR) & HFIR_FRINT_MASK;
- if (temp >= 10000)
- temp /= 1000;
- else
- temp /= 125;
-
- /* figure out nearest X-tal value */
- if (temp >= 54)
- temp = 60; /* MHz */
- else if (temp >= 39)
- temp = 48; /* MHz */
- else
- temp = 30; /* MHz */
-
- if (sc->sc_flags.status_high_speed)
- temp *= 125;
- else
- temp *= 1000;
-
- DPRINTF("HFIR=0x%08x\n", temp);
+ if (sc->sc_flags.status_high_speed ||
+ sc->sc_phy_type != DWC_OTG_PHY_INTERNAL) {
+ fslpclksel = 0;
+ frint = 60000;
+ } else if (sc->sc_flags.status_low_speed) {
+ fslpclksel = 2;
+ frint = 6000;
+ } else {
+ fslpclksel = 1;
+ frint = 48000;
+ }
+ temp = DWC_OTG_READ_4(sc, DOTG_HFIR);
+ temp &= ~HFIR_FRINT_MASK;
+ temp |= frint;
DWC_OTG_WRITE_4(sc, DOTG_HFIR, temp);
-#endif
+
+ temp = DWC_OTG_READ_4(sc, DOTG_HCFG);
+ temp &= ~(HCFG_FSLSSUPP | HCFG_FSLSPCLKSEL_MASK);
+ temp |= (fslpclksel << HCFG_FSLSPCLKSEL_SHIFT);
+ DWC_OTG_WRITE_4(sc, DOTG_HCFG, temp);
}
static void
@@ -3049,8 +3042,10 @@ dwc_otg_interrupt(void *arg)
else
sc->sc_flags.status_high_speed = 0;
- if (hprt & HPRT_PRTCONNDET)
+ if (hprt & HPRT_PRTCONNDET) {
sc->sc_flags.change_connect = 1;
+ dwc_otg_update_host_frame_interval(sc);
+ }
if (hprt & HPRT_PRTSUSP)
dwc_otg_suspend_irq(sc);
@@ -3059,9 +3054,6 @@ dwc_otg_interrupt(void *arg)
/* complete root HUB interrupt endpoint */
dwc_otg_root_intr(sc);
-
- /* update host frame interval */
- dwc_otg_update_host_frame_interval(sc);
}
/*
@@ -4049,14 +4041,6 @@ dwc_otg_init(struct dwc_otg_softc *sc)
DWC_OTG_WRITE_4(sc, DOTG_DAINTMSK, 0xFFFF);
}
- if (sc->sc_mode == DWC_MODE_OTG || sc->sc_mode == DWC_MODE_HOST) {
- /* setup clocks */
- temp = DWC_OTG_READ_4(sc, DOTG_HCFG);
- temp &= ~(HCFG_FSLSSUPP | HCFG_FSLSPCLKSEL_MASK);
- temp |= (1 << HCFG_FSLSPCLKSEL_SHIFT);
- DWC_OTG_WRITE_4(sc, DOTG_HCFG, temp);
- }
-
/* only enable global IRQ */
DWC_OTG_WRITE_4(sc, DOTG_GAHBCFG,
GAHBCFG_GLBLINTRMSK);
More information about the vc
mailing list