Author: mav
Date: Tue Aug 16 21:51:29 2011
New Revision: 224919
URL: http://svn.freebsd.org/changeset/base/224919

Log:
  Always check current HPET counter value after comparator programming to
  avoid lost timer interrupts. Previous optimization attempt doing it only
  for intervals less then 5000 ticks (~300us) reported to be unreliable by
  some people. Probably because of some heavy SMI code on their boards.
  Introduce additional safety interval of 128 counter ticks (~9us) between
  programmed comparator and counter values to cover different cases of
  delayed write found on some chipsets.
  
  Approved by:  re (kib)

Modified:
  head/sys/dev/acpica/acpi_hpet.c
  head/sys/dev/acpica/acpi_hpet.h

Modified: head/sys/dev/acpica/acpi_hpet.c
==============================================================================
--- head/sys/dev/acpica/acpi_hpet.c     Tue Aug 16 21:04:18 2011        
(r224918)
+++ head/sys/dev/acpica/acpi_hpet.c     Tue Aug 16 21:51:29 2011        
(r224919)
@@ -190,13 +190,10 @@ restart:
                bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num),
                    t->next);
        }
-       if (fdiv < 5000) {
-               bus_read_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num));
-               now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER);
-               if ((int32_t)(now - t->next) >= 0) {
-                       fdiv *= 2;
-                       goto restart;
-               }
+       now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER);
+       if ((int32_t)(now - t->next + HPET_MIN_CYCLES) >= 0) {
+               fdiv *= 2;
+               goto restart;
        }
        return (0);
 }
@@ -679,7 +676,8 @@ hpet_attach(device_t dev)
                        t->et.et_quality -= 10;
                t->et.et_frequency = sc->freq;
                t->et.et_min_period.sec = 0;
-               t->et.et_min_period.frac = 0x00008000LLU << 32;
+               t->et.et_min_period.frac =
+                   (((uint64_t)(HPET_MIN_CYCLES * 2) << 32) / sc->freq) << 32;
                t->et.et_max_period.sec = 0xfffffffeLLU / sc->freq;
                t->et.et_max_period.frac =
                    ((0xfffffffeLLU << 32) / sc->freq) << 32;

Modified: head/sys/dev/acpica/acpi_hpet.h
==============================================================================
--- head/sys/dev/acpica/acpi_hpet.h     Tue Aug 16 21:04:18 2011        
(r224918)
+++ head/sys/dev/acpica/acpi_hpet.h     Tue Aug 16 21:51:29 2011        
(r224919)
@@ -62,4 +62,6 @@
 #define        HPET_TIMER_FSB_VAL(x)   ((x) * 0x20 + 0x110)
 #define        HPET_TIMER_FSB_ADDR(x)  ((x) * 0x20 + 0x114)
 
+#define        HPET_MIN_CYCLES         128     /* Period considered reliable. 
*/
+
 #endif /* !__ACPI_HPET_H__ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to