wil6210: reset flow updates
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Tue, 28 Oct 2014 14:50:07 +0000 (16:50 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 30 Oct 2014 19:26:50 +0000 (15:26 -0400)
As communicated with the firmware & hardware teams

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/wil6210/main.c
drivers/net/wireless/ath/wil6210/wil6210.h

index 79003844008a2df9de923c89500a297ad025da26..0e95557e177f89c6dd65e5575cf3be51939cd918 100644 (file)
@@ -400,7 +400,7 @@ static inline void wil_release_cpu(struct wil6210_priv *wil)
 static int wil_target_reset(struct wil6210_priv *wil)
 {
        int delay = 0;
-       u32 hw_state;
+       u32 x;
        u32 rev_id;
        bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW);
 
@@ -415,9 +415,22 @@ static int wil_target_reset(struct wil6210_priv *wil)
        S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_CAR_PERST_RST);
 
        wil_halt_cpu(wil);
-       C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); /* 40 MHz */
 
        if (is_sparrow) {
+               S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN);
+               /* XTAL stabilization should take about 3ms */
+               usleep_range(5000, 7000);
+               x = R(RGF_CAF_PLL_LOCK_STATUS);
+               if (!(x & BIT_CAF_OSC_DIG_XTAL_STABLE)) {
+                       wil_err(wil, "Xtal stabilization timeout\n"
+                               "RGF_CAF_PLL_LOCK_STATUS = 0x%08x\n", x);
+                       return -ETIME;
+               }
+               /* switch 10k to XTAL*/
+               C(RGF_USER_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF);
+               /* 40 MHz */
+               C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL);
+
                W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
                W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf);
        }
@@ -458,13 +471,13 @@ static int wil_target_reset(struct wil6210_priv *wil)
        /* wait until device ready. typical time is 200..250 msec */
        do {
                msleep(RST_DELAY);
-               hw_state = R(RGF_USER_HW_MACHINE_STATE);
+               x = R(RGF_USER_HW_MACHINE_STATE);
                if (delay++ > RST_COUNT) {
                        wil_err(wil, "Reset not completed, hw_state 0x%08x\n",
-                               hw_state);
+                               x);
                        return -ETIME;
                }
-       } while (hw_state != HW_MACHINE_BOOT_DONE);
+       } while (x != HW_MACHINE_BOOT_DONE);
 
        /* TODO: Erez check rev_id != 1 */
        if (!is_sparrow && (rev_id != 1))
index 7ffaf2fce097ef212b41a15f1ddcc3f0e41896c5..18f8729a6b2c3c9fed7a370e4617cbf98dbe5360 100644 (file)
@@ -117,6 +117,8 @@ struct RGF_ICR {
        #define BIT_USER_USER_ICR_SW_INT_2      BIT(18)
 #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0     (0x880c18)
 #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1     (0x880c2c)
+#define RGF_USER_SPARROW_M_4                   (0x880c50) /* Sparrow */
+       #define BIT_SPARROW_M_4_SEL_SLEEP_OR_REF        BIT(2)
 
 #define RGF_DMA_EP_TX_ICR              (0x881bb4) /* struct RGF_ICR */
        #define BIT_DMA_EP_TX_ICR_TX_DONE       BIT(0)
@@ -152,6 +154,10 @@ struct RGF_ICR {
 #define RGF_MAC_MTRL_COUNTER_0         (0x886aa8)
 
 #define RGF_CAF_ICR                    (0x88946c) /* struct RGF_ICR */
+#define RGF_CAF_OSC_CONTROL            (0x88afa4)
+       #define BIT_CAF_OSC_XTAL_EN             BIT(0)
+#define RGF_CAF_PLL_LOCK_STATUS                (0x88afec)
+       #define BIT_CAF_OSC_DIG_XTAL_STABLE     BIT(0)
 
 /* popular locations */
 #define HOST_MBOX   HOSTADDR(RGF_USER_USER_SCRATCH_PAD)