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.
This commit is contained in:
Sebastian Huber 2020-04-02 16:34:42 +02:00
parent c28f67a9be
commit 2237f4b053

View File

@ -470,38 +470,31 @@ dwc_otg_uses_split(struct usb_device *udev)
static void static void
dwc_otg_update_host_frame_interval(struct dwc_otg_softc *sc) dwc_otg_update_host_frame_interval(struct dwc_otg_softc *sc)
{ {
uint32_t fslpclksel;
/* uint32_t frint;
* Disabled until further. Assuming that the register is already
* programmed correctly by the boot loader.
*/
#if 0
uint32_t temp; uint32_t temp;
/* setup HOST frame interval register, based on existing value */ if (sc->sc_flags.status_high_speed ||
temp = DWC_OTG_READ_4(sc, DOTG_HFIR) & HFIR_FRINT_MASK; sc->sc_phy_type != DWC_OTG_PHY_INTERNAL) {
if (temp >= 10000) fslpclksel = 0;
temp /= 1000; frint = 60000;
else } else if (sc->sc_flags.status_low_speed) {
temp /= 125; fslpclksel = 2;
frint = 6000;
/* figure out nearest X-tal value */ } else {
if (temp >= 54) fslpclksel = 1;
temp = 60; /* MHz */ frint = 48000;
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);
temp = DWC_OTG_READ_4(sc, DOTG_HFIR);
temp &= ~HFIR_FRINT_MASK;
temp |= frint;
DWC_OTG_WRITE_4(sc, DOTG_HFIR, temp); 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 static void
@ -3049,8 +3042,10 @@ dwc_otg_interrupt(void *arg)
else else
sc->sc_flags.status_high_speed = 0; sc->sc_flags.status_high_speed = 0;
if (hprt & HPRT_PRTCONNDET) if (hprt & HPRT_PRTCONNDET) {
sc->sc_flags.change_connect = 1; sc->sc_flags.change_connect = 1;
dwc_otg_update_host_frame_interval(sc);
}
if (hprt & HPRT_PRTSUSP) if (hprt & HPRT_PRTSUSP)
dwc_otg_suspend_irq(sc); dwc_otg_suspend_irq(sc);
@ -3059,9 +3054,6 @@ dwc_otg_interrupt(void *arg)
/* complete root HUB interrupt endpoint */ /* complete root HUB interrupt endpoint */
dwc_otg_root_intr(sc); 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); 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 */ /* only enable global IRQ */
DWC_OTG_WRITE_4(sc, DOTG_GAHBCFG, DWC_OTG_WRITE_4(sc, DOTG_GAHBCFG,
GAHBCFG_GLBLINTRMSK); GAHBCFG_GLBLINTRMSK);