carl9170 firmware: fix time accouting
authorChristian Lamparter <chunkeey@googlemail.com>
Thu, 30 Jun 2011 17:21:05 +0000 (19:21 +0200)
committerChristian Lamparter <chunkeey@googlemail.com>
Thu, 30 Jun 2011 17:21:05 +0000 (19:21 +0200)
This patch tries to partially fix the old issue with
the inaccurate clocks.

Note: It also adds a Timer1, which goes off every msec
on the clock.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
carlfw/include/carl9170.h
carlfw/include/timer.h
carlfw/src/main.c
carlfw/src/rf.c

index 4b0738d651a3fd0bdc93552284c3ed4e63652b85..d3afcdbc2849e87ebce06e4ec6918686db0ec8fb 100644 (file)
@@ -78,7 +78,7 @@ typedef void (*fw_desc_callback_t)(void *, const bool);
 
 struct firmware_context_struct {
        /* timer / clocks */
-       unsigned int ticks_per_msec;
+       unsigned int ticks_per_usec;
        unsigned int counter;                   /* main() cycles */
 
        /* misc */
index 7e4cb4cd69a2a5a4bebac5a8f4b38f206b7e1fd9..1c1c6cd4fa6f0f30c9f539c0a110c8f78baed5ee 100644 (file)
@@ -47,7 +47,7 @@ static inline __inline uint32_t get_clock_counter(void)
  */
 static inline __inline bool is_after_msecs(const uint32_t t0, const uint32_t msecs)
 {
-       return ((get_clock_counter() - t0) / 1000) > (msecs * fw.ticks_per_msec);
+       return ((get_clock_counter() - t0) / 1000) > (msecs * fw.ticks_per_usec);
 }
 
 /*
@@ -60,7 +60,7 @@ static inline __inline void delay(const uint32_t msec)
 {
        uint32_t t1, t2, dt, wt;
 
-       wt = msec * fw.ticks_per_msec;
+       wt = msec * fw.ticks_per_usec;
 
        t1 = get_clock_counter();
        while (1) {
@@ -79,7 +79,7 @@ static inline __inline void udelay(const uint32_t usec)
        while (1) {
                t2 = get_clock_counter();
                dt = (t2 - t1);
-               if (dt >= (usec * fw.ticks_per_msec))
+               if (dt >= (usec * fw.ticks_per_usec))
                        break;
        }
 }
index 574154bafd1faaba526feb007e3f3bbd3009d764..bfcd341fb06cd97ad107949be3bfca1a89c1bb9a 100644 (file)
@@ -45,17 +45,36 @@ static void timer_init(const unsigned int timer, const unsigned int interval)
        orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer));
 }
 
-void clock_set(enum cpu_clock_t _clock, bool on)
+void clock_set(enum cpu_clock_t clock_, bool on)
 {
        /*
         * Word of Warning!
         * This setting does more than just mess with the CPU Clock.
         * So watch out, if you need _stable_ timer interrupts.
         */
+        if (fw.phy.frequency < 3000000)
+               set(AR9170_PWR_REG_PLL_ADDAC, 0x5163);
+        else
+                set(AR9170_PWR_REG_PLL_ADDAC, 0x5143);
+
+       fw.ticks_per_usec = GET_VAL(AR9170_PWR_PLL_ADDAC_DIV,
+               get(AR9170_PWR_REG_PLL_ADDAC));
+
+       set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | clock_));
+
+       switch (clock_) {
+       case AHB_20_22MHZ:
+               fw.ticks_per_usec >>= 1;
+       case AHB_40MHZ_OSC:
+       case AHB_40_44MHZ:
+               fw.ticks_per_usec >>= 1;
+       case AHB_80_88MHZ:
+               break;
+       }
 
-       fw.ticks_per_msec = GET_VAL(AR9170_PWR_PLL_ADDAC_DIV, get(AR9170_PWR_REG_PLL_ADDAC)) >> 1;
+       timer_init(1, (fw.ticks_per_usec * 25) >> 1);
 
-       set(AR9170_PWR_REG_CLOCK_SEL, (uint32_t) ((on ? 0x70 : 0x600) | _clock));
+       INFO("SET CLOCK c:%d t:%d tt:%d f:%d\n", clock_, fw.ticks_per_usec, (fw.ticks_per_usec * 25) >> 1, fw.phy.frequency);
 }
 
 static void init(void)
@@ -119,6 +138,10 @@ static void timer0_isr(void)
 #endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */
 }
 
+static void timer1_isr(void)
+{
+}
+
 static void handle_timer(void)
 {
        uint32_t intr;
@@ -138,6 +161,8 @@ static void handle_timer(void)
 
        HANDLER(intr, BIT(0), timer0_isr);
 
+       HANDLER(intr, BIT(1), timer1_isr);
+
        if (intr)
                DBG("Unhandled Timer Event %x", (unsigned int) intr);
 
index ae9fd5464e4fcb6f59150c1f34e22dda95e30b4d..9537c2a747f4d3d48849c4b36e45884f6ccd4e0e 100644 (file)
@@ -199,6 +199,9 @@ void rf_cmd(const struct carl9170_cmd *cmd, struct carl9170_rsp *resp)
        fw.phy.ht_settings = cmd->rf_init.ht_settings;
        fw.phy.frequency = cmd->rf_init.freq;
 
+       /*
+        * Is the clock controlled by the PHY?
+        */
        if ((fw.phy.ht_settings & EIGHTY_FLAG) == EIGHTY_FLAG)
                clock_set(AHB_80_88MHZ, true);
        else
@@ -269,7 +272,7 @@ void rf_psm(void)
                }
        }
 
-       if (fw.phy.frequency < 30000000)
+       if (fw.phy.frequency < 3000000)
                bank3 |= 0x00800000;
 
        set(0x1c58f0, bank3);