From 539ffaa1b9e7628cfacdea63d11b270acb945411 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 28 Oct 2023 07:56:31 +0200 Subject: parisc: Add timer2() wait function to cope with 32-bit timer limit Signed-off-by: Helge Deller --- src/hw/usb-ohci.c | 25 +++++++++++++++++++------ src/parisc/parisc.c | 2 +- src/parisc/timer.c | 27 +++++++++++++++++++++++++++ src/util.h | 7 +++++++ 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/hw/usb-ohci.c b/src/hw/usb-ohci.c index c839d11..cc35bae 100644 --- a/src/hw/usb-ohci.c +++ b/src/hw/usb-ohci.c @@ -64,13 +64,15 @@ ohci_hub_reset(struct usbhub_s *hub, u32 port) struct usb_ohci_s *cntl = container_of(hub->cntl, struct usb_ohci_s, usb); writel(&cntl->regs->roothub_portstatus[port], RH_PS_PRS); u32 sts; - u32 end = timer_calc(USB_TIME_DRSTR * 2); + struct wait_t end; + + timer_calc2_ms(&end, USB_TIME_DRSTR * 2); for (;;) { sts = readl(&cntl->regs->roothub_portstatus[port]); if (!(sts & RH_PS_PRS)) // XXX - need to ensure USB_TIME_DRSTR time in reset? break; - if (timer_check(end)) { + if (timer_check2(&end)) { // Timeout. warn_timeout(); ohci_hub_disconnect(hub, port); @@ -128,11 +130,13 @@ ohci_waittick(struct ohci_regs *regs) barrier(); struct ohci_hcca *hcca = (void*)readl(®s->hcca); u32 startframe = hcca->frame_no; - u32 end = timer_calc(1000 * 5); + struct wait_t end; + + timer_calc2_ms(&end, 1000 * 5); for (;;) { if (hcca->frame_no != startframe) break; - if (timer_check(end)) { + if (timer_check2(&end)) { warn_timeout(); return; } @@ -442,11 +446,20 @@ ohci_realloc_pipe(struct usbdevice_s *usbdev, struct usb_pipe *upipe static int wait_ed(struct ohci_ed *ed, int timeout) { - u32 end = timer_calc(timeout); + struct wait_t end; + + timer_calc2_ms(&end, timeout); +#if 0 + while (1) { + timer_calc2_ms(&end, 1000); + while (!timer_check2(&end)) { }; + dprintf(1, "Tick\n"); + } +#endif for (;;) { if ((le32_to_cpu(ed->hwHeadP) & ~(ED_C|ED_H)) == le32_to_cpu(ed->hwTailP)) return 0; - if (timer_check(end)) { + if (timer_check2(&end)) { warn_timeout(); dprintf(1, "ohci ed info=%x tail=%x head=%x next=%x\n", le32_to_cpu(ed->hwINFO), le32_to_cpu(ed->hwTailP), diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 92d044e..9c8375d 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -2917,8 +2917,8 @@ void __VISIBLE start_parisc_firmware(void) find_serial_pci_card(); serial_setup(); + // usb_setup(); // ohci_setup(); - usb_setup(); block_setup(); /* find SCSI PCI card when running on Astro or Dino */ diff --git a/src/parisc/timer.c b/src/parisc/timer.c index 9605f91..c3169f3 100644 --- a/src/parisc/timer.c +++ b/src/parisc/timer.c @@ -94,6 +94,33 @@ timer_calc_usec(u32 usecs) return ((usecs * PAGE0->mem_10msec / 10) / 1000) + timer_read(); } +void +timer_calc2_ms(struct wait_t *w, u32 msecs) +{ + w->usecs = msecs / 1000; + w->end = msecs % 1000; + if (w->end == 0) { + w->end = 1000; + w->usecs -= 1; + } + w->end = timer_calc(w->end); +} + +int +timer_check2(struct wait_t *w) +{ + s32 remain; + + /* return 1 if timed out */ + remain = (s32)(timer_read() - w->end); + if (remain <= 0) + return 0; + if (w->usecs == 0) + return 1; + w->usecs -= 1; + w->end = timer_calc(1000); + return 0; +} void pit_setup(void) diff --git a/src/util.h b/src/util.h index 0de3522..dd919a8 100644 --- a/src/util.h +++ b/src/util.h @@ -71,6 +71,13 @@ u32 irqtimer_calc(u32 msecs); int irqtimer_check(u32 end); void handle_1586(struct bregs *regs); +struct wait_t { + u32 usecs; + u32 end; +}; +void timer_calc2_ms(struct wait_t *w, u32 msecs); +int timer_check2(struct wait_t *w); + // fw/acpi.c void acpi_setup(void); -- cgit v1.1