From dbb81597c39e9ecf9a76420ac374a179d5b94c91 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 14 Sep 2012 00:49:25 +0200 Subject: [PATCH] carl9170 firmware: refactor timer functions Thanks to LTO, the timer routines can be moved into a proper context without added overhead at runtime. Signed-off-by: Christian Lamparter --- carlfw/CMakeLists.txt | 2 +- carlfw/include/timer.h | 3 ++ carlfw/src/main.c | 82 ------------------------------ carlfw/src/timer.c | 112 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 83 deletions(-) create mode 100644 carlfw/src/timer.c diff --git a/carlfw/CMakeLists.txt b/carlfw/CMakeLists.txt index 81b1346..be09ab4 100644 --- a/carlfw/CMakeLists.txt +++ b/carlfw/CMakeLists.txt @@ -16,7 +16,7 @@ set(CARLFW_CFLAGS "${CARLFW_CFLAGS_DEF} ${CARLFW_CFLAGS_EXTRA} ${CARLFW_CFLAGS_A include_directories (../include/linux ../include/shared ../include include) -set(carl9170_main_src src/main.c src/wlan.c src/fw.c src/gpio.c +set(carl9170_main_src src/main.c src/wlan.c src/fw.c src/gpio.c src/timer.c src/cmd.c src/uart.c src/dma.c src/hostif.c src/reboot.S src/printf.c src/rf.c src/cam.c src/wol.c) diff --git a/carlfw/include/timer.h b/carlfw/include/timer.h index 1c1c6cd..1b9d1c1 100644 --- a/carlfw/include/timer.h +++ b/carlfw/include/timer.h @@ -85,4 +85,7 @@ static inline __inline void udelay(const uint32_t usec) } void clock_set(enum cpu_clock_t _clock, bool on); +void handle_timer(void); +void timer_init(const unsigned int timer, const unsigned int interval); + #endif /* __CARL9170FW_TIMER_H */ diff --git a/carlfw/src/main.c b/carlfw/src/main.c index 80e7e21..e36dfad 100644 --- a/carlfw/src/main.c +++ b/carlfw/src/main.c @@ -34,50 +34,6 @@ #define AR9170_WATCH_DOG_TIMER 0x100 -static void timer_init(const unsigned int timer, const unsigned int interval) -{ - /* Set timer to periodic mode */ - orl(AR9170_TIMER_REG_CONTROL, BIT(timer)); - - /* Set time interval */ - set(AR9170_TIMER_REG_TIMER0 + (timer << 2), interval - 1); - - /* Clear timer interrupt flag */ - orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer)); -} - -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. - */ -#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS - if (fw.phy.frequency < 3000000) - set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); - else - set(AR9170_PWR_REG_PLL_ADDAC, 0x5143); -#else - set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); -#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ - - 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; - } -} - static void init(void) { led_init(); @@ -126,44 +82,6 @@ static void handle_fw(void) reboot(); } -static void timer0_isr(void) -{ - wlan_timer(); - -#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT - gpio_timer(); -#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ - -#ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT - set(AR9170_GPIO_REG_PORT_DATA, get(AR9170_GPIO_REG_PORT_DATA) ^ 1); -#endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ -} - -static void handle_timer(void) -{ - uint32_t intr; - - intr = get(AR9170_TIMER_REG_INTERRUPT); - - /* ACK timer interrupt */ - set(AR9170_TIMER_REG_INTERRUPT, intr); - -#define HANDLER(intr, flag, func) \ - do { \ - if ((intr & flag) != 0) { \ - intr &= ~flag; \ - func(); \ - } \ - } while (0) - - HANDLER(intr, BIT(0), timer0_isr); - - if (intr) - DBG("Unhandled Timer Event %x", (unsigned int) intr); - -#undef HANDLER -} - static void tally_update(void) { unsigned int boff, time, delta; diff --git a/carlfw/src/timer.c b/carlfw/src/timer.c new file mode 100644 index 0000000..9505818 --- /dev/null +++ b/carlfw/src/timer.c @@ -0,0 +1,112 @@ +/* + * carl9170 firmware - used by the ar9170 wireless device + * + * timer code + * + * Copyright (c) 2000-2005 ZyDAS Technology Corporation + * Copyright (c) 2007-2009 Atheros Communications, Inc. + * Copyright 2009 Johannes Berg + * Copyright 2009-2012 Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "carl9170.h" +#include "timer.h" +#include "gpio.h" +#include "printf.h" +#include "wl.h" + +void timer_init(const unsigned int timer, const unsigned int interval) +{ + /* Set timer to periodic mode */ + orl(AR9170_TIMER_REG_CONTROL, BIT(timer)); + + /* Set time interval */ + set(AR9170_TIMER_REG_TIMER0 + (timer << 2), interval - 1); + + /* Clear timer interrupt flag */ + orl(AR9170_TIMER_REG_INTERRUPT, BIT(timer)); +} + +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. + */ +#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS + if (fw.phy.frequency < 3000000) + set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); + else + set(AR9170_PWR_REG_PLL_ADDAC, 0x5143); +#else + set(AR9170_PWR_REG_PLL_ADDAC, 0x5163); +#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */ + + 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; + } +} + +static void timer0_isr(void) +{ + wlan_timer(); + +#ifdef CONFIG_CARL9170FW_GPIO_INTERRUPT + gpio_timer(); +#endif /* CONFIG_CARL9170FW_GPIO_INTERRUPT */ + +#ifdef CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT + set(AR9170_GPIO_REG_PORT_DATA, get(AR9170_GPIO_REG_PORT_DATA) ^ 1); +#endif /* CONFIG_CARL9170FW_DEBUG_LED_HEARTBEAT */ +} + +void handle_timer(void) +{ + uint32_t intr; + + intr = get(AR9170_TIMER_REG_INTERRUPT); + + /* ACK timer interrupt */ + set(AR9170_TIMER_REG_INTERRUPT, intr); + +#define HANDLER(intr, flag, func) \ + do { \ + if ((intr & flag) != 0) { \ + intr &= ~flag; \ + func(); \ + } \ + } while (0) + + HANDLER(intr, BIT(0), timer0_isr); + + if (intr) + DBG("Unhandled Timer Event %x", (unsigned int) intr); + +#undef HANDLER +} -- 2.31.1