Merge git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-mn10300
[pandora-kernel.git] / arch / mn10300 / unit-asb2305 / include / unit / timex.h
index d1c72d5..758af30 100644 (file)
@@ -1,6 +1,6 @@
-/* ASB2305 timer specifcations
+/* ASB2305-specific timer specifications
  *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2007, 2010 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
 
 #include <asm/timer-regs.h>
 #include <unit/clock.h>
+#include <asm/param.h>
 
 /*
  * jiffies counter specifications
  */
 
 #define        TMJCBR_MAX              0xffff
-#define        TMJCBC                  TM01BC
-
-#define        TMJCMD                  TM01MD
-#define        TMJCBR                  TM01BR
 #define        TMJCIRQ                 TM1IRQ
 #define        TMJCICR                 TM1ICR
-#define        TMJCICR_LEVEL           GxICR_LEVEL_5
 
 #ifndef __ASSEMBLY__
 
-static inline void startup_jiffies_counter(void)
+#define MN10300_SRC_IOCLK      MN10300_IOCLK
+
+#ifndef HZ
+# error HZ undeclared.
+#endif /* !HZ */
+/* use as little prescaling as possible to avoid losing accuracy */
+#if (MN10300_SRC_IOCLK + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE                1
+# define JC_TIMER_CLKSRC       TM0MD_SRC_IOCLK
+# define TSC_TIMER_CLKSRC      TM4MD_SRC_IOCLK
+#elif (MN10300_SRC_IOCLK / 8 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE                8
+# define JC_TIMER_CLKSRC       TM0MD_SRC_IOCLK_8
+# define TSC_TIMER_CLKSRC      TM4MD_SRC_IOCLK_8
+#elif (MN10300_SRC_IOCLK / 32 + HZ / 2) / HZ - 1 <= TMJCBR_MAX
+# define IOCLK_PRESCALE                32
+# define JC_TIMER_CLKSRC       TM0MD_SRC_IOCLK_32
+# define TSC_TIMER_CLKSRC      TM4MD_SRC_IOCLK_32
+#else
+# error You lose.
+#endif
+
+#define MN10300_JCCLK          (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
+#define MN10300_TSCCLK         (MN10300_SRC_IOCLK / IOCLK_PRESCALE)
+
+#define MN10300_JC_PER_HZ      ((MN10300_JCCLK + HZ / 2) / HZ)
+#define MN10300_TSC_PER_HZ     ((MN10300_TSCCLK + HZ / 2) / HZ)
+
+static inline void stop_jiffies_counter(void)
 {
-       unsigned rate;
-       u16 md, t16;
-
-       /* use as little prescaling as possible to avoid losing accuracy */
-       md = TM0MD_SRC_IOCLK;
-       rate = MN10300_JCCLK / HZ;
-
-       if (rate > TMJCBR_MAX) {
-               md = TM0MD_SRC_IOCLK_8;
-               rate = MN10300_JCCLK / 8 / HZ;
-
-               if (rate > TMJCBR_MAX) {
-                       md = TM0MD_SRC_IOCLK_32;
-                       rate = MN10300_JCCLK / 32 / HZ;
-
-                       if (rate > TMJCBR_MAX)
-                               BUG();
-               }
-       }
+       u16 tmp;
+       TM01MD = JC_TIMER_CLKSRC | TM1MD_SRC_TM0CASCADE << 8;
+       tmp = TM01MD;
+}
 
-       TMJCBR = rate - 1;
-       t16 = TMJCBR;
+static inline void reload_jiffies_counter(u32 cnt)
+{
+       u32 tmp;
 
-       TMJCMD =
-               md |
-               TM1MD_SRC_TM0CASCADE << 8 |
-               TM0MD_INIT_COUNTER |
-               TM1MD_INIT_COUNTER << 8;
+       TM01BR = cnt;
+       tmp = TM01BR;
 
-       TMJCMD =
-               md |
-               TM1MD_SRC_TM0CASCADE << 8 |
-               TM0MD_COUNT_ENABLE |
-               TM1MD_COUNT_ENABLE << 8;
+       TM01MD = JC_TIMER_CLKSRC |              \
+                TM1MD_SRC_TM0CASCADE << 8 |    \
+                TM0MD_INIT_COUNTER |           \
+                TM1MD_INIT_COUNTER << 8;
 
-       t16 = TMJCMD;
 
-       TMJCICR |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
-       t16 = TMJCICR;
-}
+       TM01MD = JC_TIMER_CLKSRC |              \
+                TM1MD_SRC_TM0CASCADE << 8 |    \
+                TM0MD_COUNT_ENABLE |           \
+                TM1MD_COUNT_ENABLE << 8;
 
-static inline void shutdown_jiffies_counter(void)
-{
+       tmp = TM01MD;
 }
 
 #endif /* !__ASSEMBLY__ */
@@ -94,29 +99,39 @@ static inline void shutdown_jiffies_counter(void)
 
 static inline void startup_timestamp_counter(void)
 {
+       u32 t32;
+
        /* set up timer 4 & 5 cascaded as a 32-bit counter to count real time
         * - count down from 4Gig-1 to 0 and wrap at IOCLK rate
         */
        TM45BR = TMTSCBR_MAX;
+       t32 = TM45BR;
 
-       TM4MD = TM4MD_SRC_IOCLK;
+       TM4MD = TSC_TIMER_CLKSRC;
        TM4MD |= TM4MD_INIT_COUNTER;
        TM4MD &= ~TM4MD_INIT_COUNTER;
        TM4ICR = 0;
+       t32 = TM4ICR;
 
        TM5MD = TM5MD_SRC_TM4CASCADE;
        TM5MD |= TM5MD_INIT_COUNTER;
        TM5MD &= ~TM5MD_INIT_COUNTER;
        TM5ICR = 0;
+       t32 = TM5ICR;
 
        TM5MD |= TM5MD_COUNT_ENABLE;
        TM4MD |= TM4MD_COUNT_ENABLE;
+       t32 = TM5MD;
+       t32 = TM4MD;
 }
 
 static inline void shutdown_timestamp_counter(void)
 {
+       u8 t8;
        TM4MD = 0;
        TM5MD = 0;
+       t8 = TM4MD;
+       t8 = TM5MD;
 }
 
 /*
@@ -127,7 +142,7 @@ typedef unsigned long cycles_t;
 
 static inline cycles_t read_timestamp_counter(void)
 {
-       return (cycles_t) TMTSCBC;
+       return (cycles_t)~TMTSCBC;
 }
 
 #endif /* !__ASSEMBLY__ */