From 1dbab55a460484fd655c44c99fc192b9e3702485 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 14 Aug 2010 02:36:52 +0200 Subject: [PATCH] carl9170 firmware: revamp reset code Getting the reset code to work 100% proved to be a wild-goose chase. Therefore we'll settle with an easier solution and let the usb subsystem take care of the clean-up operation. Signed-off-by: Christian Lamparter --- carlfw/include/carl9170.h | 1 + carlfw/include/cmd.h | 1 - carlfw/include/usb.h | 1 + carlfw/src/cmd.c | 4 +--- carlfw/src/main.c | 12 ++++++++++-- carlfw/usb/main.c | 38 ++++++++++---------------------------- include/shared/hw.h | 15 +++++++++++---- 7 files changed, 34 insertions(+), 38 deletions(-) diff --git a/carlfw/include/carl9170.h b/carlfw/include/carl9170.h index 6c19c32..c85a4f3 100644 --- a/carlfw/include/carl9170.h +++ b/carlfw/include/carl9170.h @@ -75,6 +75,7 @@ struct firmware_context_struct { /* misc */ unsigned int watchdog_enable; + unsigned int reboot; struct { /* Host Interface DMA queues */ diff --git a/carlfw/include/cmd.h b/carlfw/include/cmd.h index 809a6c2..c213704 100644 --- a/carlfw/include/cmd.h +++ b/carlfw/include/cmd.h @@ -50,6 +50,5 @@ static inline void __check(void) } void handle_cmd(struct carl9170_rsp *resp); -void __attribute__((noreturn)) reboot(void); #endif /* __CARL9170FW_CMD_H */ diff --git a/carlfw/include/usb.h b/carlfw/include/usb.h index 6501e19..5908839 100644 --- a/carlfw/include/usb.h +++ b/carlfw/include/usb.h @@ -181,6 +181,7 @@ void usb_init_highspeed_fifo_cfg(void); void usb_init_fullspeed_fifo_cfg(void); void start(void); +void __attribute__((noreturn)) reboot(void); #ifdef CONFIG_CARL9170FW_USB_WATCHDOG void usb_watchdog_timer(void); diff --git a/carlfw/src/cmd.c b/carlfw/src/cmd.c index 058f967..a9bdb63 100644 --- a/carlfw/src/cmd.c +++ b/carlfw/src/cmd.c @@ -69,11 +69,9 @@ void handle_cmd(struct carl9170_rsp *resp) case CARL9170_CMD_REBOOT: /* - * reboot does not return and generates no response * resp->len = 0; */ - - reboot(); + fw.reboot = 1; break; case CARL9170_CMD_READ_TSF: diff --git a/carlfw/src/main.c b/carlfw/src/main.c index 35f5d29..a9a1306 100644 --- a/carlfw/src/main.c +++ b/carlfw/src/main.c @@ -75,14 +75,22 @@ static void init(void) down_trigger(); } +static void handle_fw(void) +{ + if (fw.watchdog_enable == 1) + set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER); + + if (fw.reboot) + reboot(); +} + static void __attribute__((noreturn)) main_loop(void) { clock_set(true, AHB_40MHZ_OSC); /* main loop */ while (1) { - if (fw.watchdog_enable == 1) - set(AR9170_TIMER_REG_WATCH_DOG, AR9170_WATCH_DOG_TIMER); + handle_fw(); /* * Due to frame order persevation, the wlan subroutines diff --git a/carlfw/usb/main.c b/carlfw/usb/main.c index 1429607..00c9326 100644 --- a/carlfw/usb/main.c +++ b/carlfw/usb/main.c @@ -27,7 +27,6 @@ #include "printf.h" #include "timer.h" #include "rom.h" -#include "gpio.h" #include "shared/phy.h" #ifdef CONFIG_CARL9170FW_DEBUG_USB @@ -210,26 +209,6 @@ void send_cmd_to_host(const uint8_t len, const uint8_t type, usb_trigger_in(); } -/* Reset all the USB FIFO used for WLAN */ -static void usb_reset_FIFO(void) -{ - uint32_t val; - - /* - * of course, - * simpley ORing AR9170_MAC_POWER_STATE_CTRL_RESET - * would be... I dunno, maybe: just to simple? - */ - - val = get(AR9170_MAC_REG_POWER_STATE_CTRL); - val |= AR9170_MAC_POWER_STATE_CTRL_RESET; - set(AR9170_MAC_REG_POWER_STATE_CTRL, val); - - /* Reset USB FIFO */ - set(AR9170_PWR_REG_ADDA_BB, AR9170_PWR_ADDA_BB_USB_FIFO_RESET); - set(AR9170_PWR_REG_ADDA_BB, 0x0); -} - /* Turn off ADDA/RF power, PLL */ static void turn_power_off(void) { @@ -237,11 +216,20 @@ static void turn_power_off(void) set(AR9170_PHY_REG_ADC_CTL, 0xa0000000 | AR9170_PHY_ADC_CTL_OFF_PWDADC | AR9170_PHY_ADC_CTL_OFF_PWDDAC); + /* This will also turn-off the LEDs */ set(AR9170_GPIO_REG_PORT_DATA, 0); set(AR9170_GPIO_REG_PORT_TYPE, 0xf); set(AR9170_PWR_REG_BASE, 0x40021); - set(AR9170_PWR_REG_ADDA_BB, 0); + + set(AR9170_MAC_REG_POWER_STATE_CTRL, + AR9170_MAC_POWER_STATE_CTRL_RESET); + + /* Reset USB FIFO */ + set(AR9170_PWR_REG_RESET, AR9170_PWR_RESET_COMMIT_RESET_MASK | + AR9170_PWR_RESET_DMA_MASK | + AR9170_PWR_RESET_WLAN_MASK); + set(AR9170_PWR_REG_RESET, 0x0); clock_set(false, AHB_20_22MHZ); @@ -282,9 +270,6 @@ static void turn_power_off(void) void __attribute__((noreturn)) reboot(void) { - /* turn off leds */ - led_set(0); - /* write watchdog magic pattern for suspend */ andl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0xffff); orl(AR9170_PWR_REG_WATCH_DOG_MAGIC, 0x98760000); @@ -292,9 +277,6 @@ void __attribute__((noreturn)) reboot(void) /* Disable watchdog */ orl(AR9170_TIMER_REG_WATCH_DOG, 0xffff); - /* Reset USB FIFO */ - usb_reset_FIFO(); - /* Turn off power */ turn_power_off(); diff --git a/include/shared/hw.h b/include/shared/hw.h index 33e856b..30b19a7 100644 --- a/include/shared/hw.h +++ b/include/shared/hw.h @@ -445,10 +445,17 @@ #define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000) -#define AR9170_PWR_REG_ADDA_BB (AR9170_PWR_REG_BASE + 0x004) -#define AR9170_PWR_ADDA_BB_USB_FIFO_RESET 0x00000005 -#define AR9170_PWR_ADDA_BB_COLD_RESET 0x00000800 -#define AR9170_PWR_ADDA_BB_WARM_RESET 0x00000400 +#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004) +#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0) +#define AR9170_PWR_RESET_WLAN_MASK BIT(1) +#define AR9170_PWR_RESET_DMA_MASK BIT(2) +#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3) +#define AR9170_PWR_RESET_AHB_MASK BIT(9) +#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10) +#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11) +#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12) +#define AR9170_PWR_RESET_PLL BIT(13) +#define AR9170_PWR_RESET_USB_PLL BIT(14) #define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) #define AR9170_PWR_CLK_AHB_40MHZ 0 -- 2.31.1