svn commit: r248585 - head/sys/arm/broadcom/bcm2835

Alexander Motin mav at FreeBSD.org
Thu Mar 21 15:42:42 UTC 2013


Author: mav
Date: Thu Mar 21 15:42:41 2013
New Revision: 248585
URL: http://svnweb.freebsd.org/changeset/base/248585

Log:
  Minimal timer period of 100us introduced in r244758 is overkill.  While
  original 2us are indeed not enough, 3us are working quite well on my tests.
  To be more safe set minimal period to 5us and to be even more safe replicate
  here from HPET mechanism of rereading counter after programming comparator.
  
  This change allows to handle 30K of short nanosleep() calls per second on
  Raspberry Pi instead of just 8K before.
  
  Discussed with:	gonzo

Modified:
  head/sys/arm/broadcom/bcm2835/bcm2835_systimer.c

Modified: head/sys/arm/broadcom/bcm2835/bcm2835_systimer.c
==============================================================================
--- head/sys/arm/broadcom/bcm2835/bcm2835_systimer.c	Thu Mar 21 14:06:27 2013	(r248584)
+++ head/sys/arm/broadcom/bcm2835/bcm2835_systimer.c	Thu Mar 21 15:42:41 2013	(r248585)
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
 
 #define	DEFAULT_TIMER		3
 #define	DEFAULT_FREQUENCY	1000000
-#define	MIN_PERIOD		100LLU
+#define	MIN_PERIOD		5LLU
 
 #define	SYSTIMER_CS	0x00
 #define	SYSTIMER_CLO	0x04
@@ -121,7 +121,7 @@ static int
 bcm_systimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
 {
 	struct systimer *st = et->et_priv;
-	uint32_t clo;
+	uint32_t clo, clo1;
 	uint32_t count;
 	register_t s;
 
@@ -131,12 +131,19 @@ bcm_systimer_start(struct eventtimer *et
 
 		s = intr_disable();
 		clo = bcm_systimer_tc_read_4(SYSTIMER_CLO);
+restart:
 		clo += count;
 		/*
 		 * Clear pending interrupts
 		 */
 		bcm_systimer_tc_write_4(SYSTIMER_CS, (1 << st->index));
 		bcm_systimer_tc_write_4(SYSTIMER_C0 + st->index*4, clo);
+		clo1 = bcm_systimer_tc_read_4(SYSTIMER_CLO);
+		if ((int32_t)(clo1 - clo) >= 0) {
+			count *= 2;
+			clo = clo1;
+			goto restart;
+		}
 		st->enabled = 1;
 		intr_restore(s);
 
@@ -236,9 +243,9 @@ bcm_systimer_attach(device_t dev)
 	sc->st[DEFAULT_TIMER].et.et_quality = 1000;
 	sc->st[DEFAULT_TIMER].et.et_frequency = sc->sysclk_freq;
 	sc->st[DEFAULT_TIMER].et.et_min_period =
-	    (MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
+	    (MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency + 1;
 	sc->st[DEFAULT_TIMER].et.et_max_period =
-	    (0xfffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
+	    (0x7ffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
 	sc->st[DEFAULT_TIMER].et.et_start = bcm_systimer_start;
 	sc->st[DEFAULT_TIMER].et.et_stop = bcm_systimer_stop;
 	sc->st[DEFAULT_TIMER].et.et_priv = &sc->st[DEFAULT_TIMER];


More information about the svn-src-all mailing list