wilc1000: configure registers to handle chip wakeup sequence
authorAjay Singh <ajay.kathat@microchip.com>
Thu, 16 Sep 2021 16:49:19 +0000 (16:49 +0000)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 21 Sep 2021 15:08:15 +0000 (18:08 +0300)
Use the correct sequence to configure clockless registers for chip wake-up.
The following sequence is expected from WILC chip for wakeup:
 - set wakeup bit in wakeup_reg register
 - after setting the wakeup bit, read back the clock status bit for wakeup
   complete.

For SDIO/SPI modules, the wakeup sequence is the same except uses different
register values so refactored the code to use common function for both
SDIO/SPI bus.

Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210916164902.74629-5-ajay.kathat@microchip.com
drivers/net/wireless/microchip/wilc1000/cfg80211.c
drivers/net/wireless/microchip/wilc1000/netdev.h
drivers/net/wireless/microchip/wilc1000/wlan.c
drivers/net/wireless/microchip/wilc1000/wlan.h
drivers/net/wireless/microchip/wilc1000/wlan_if.h

index 75160ab..91a471f 100644 (file)
@@ -1726,7 +1726,6 @@ int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
        *wilc = wl;
        wl->io_type = io_type;
        wl->hif_func = ops;
-       wl->chip_ps_state = WILC_CHIP_WAKEDUP;
 
        for (i = 0; i < NQUEUES; i++)
                INIT_LIST_HEAD(&wl->txq[i].txq_head.list);
index a39c62a..79f73a7 100644 (file)
@@ -265,7 +265,6 @@ struct wilc {
        bool suspend_event;
 
        struct workqueue_struct *hif_workqueue;
-       enum chip_ps_states chip_ps_state;
        struct wilc_cfg cfg;
        void *bus_data;
        struct net_device *monitor_dev;
index 200a103..1aad537 100644 (file)
@@ -10,6 +10,8 @@
 #include "cfg80211.h"
 #include "wlan_cfg.h"
 
+#define WAKE_UP_TRIAL_RETRY            10000
+
 static inline bool is_wilc1000(u32 id)
 {
        return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
@@ -611,60 +613,62 @@ EXPORT_SYMBOL_GPL(chip_allow_sleep);
 
 void chip_wakeup(struct wilc *wilc)
 {
-       u32 reg, clk_status_reg;
-       const struct wilc_hif_func *h = wilc->hif_func;
-
-       if (wilc->io_type == WILC_HIF_SPI) {
-               do {
-                       h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
-                       h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
-                                        reg | WILC_SPI_WAKEUP_BIT);
-                       h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
-                                        reg & ~WILC_SPI_WAKEUP_BIT);
-
-                       do {
-                               usleep_range(2000, 2500);
-                               wilc_get_chipid(wilc, true);
-                       } while (wilc_get_chipid(wilc, true) == 0);
-               } while (wilc_get_chipid(wilc, true) == 0);
-       } else if (wilc->io_type == WILC_HIF_SDIO) {
-               h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
-                                WILC_SDIO_HOST_TO_FW_BIT);
-               usleep_range(200, 400);
-               h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
-               do {
-                       h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
-                                        reg | WILC_SDIO_WAKEUP_BIT);
-                       h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
-                                       &clk_status_reg);
-
-                       while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
-                               usleep_range(2000, 2500);
+       u32 ret = 0;
+       u32 clk_status_val = 0, trials = 0;
+       u32 wakeup_reg, wakeup_bit;
+       u32 clk_status_reg, clk_status_bit;
+       u32 to_host_from_fw_reg, to_host_from_fw_bit;
+       u32 from_host_to_fw_reg, from_host_to_fw_bit;
+       const struct wilc_hif_func *hif_func = wilc->hif_func;
 
-                               h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
-                                               &clk_status_reg);
-                       }
-                       if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
-                               h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
-                                                reg & ~WILC_SDIO_WAKEUP_BIT);
-                       }
-               } while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
+       if (wilc->io_type == WILC_HIF_SDIO) {
+               wakeup_reg = WILC_SDIO_WAKEUP_REG;
+               wakeup_bit = WILC_SDIO_WAKEUP_BIT;
+               clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
+               clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
+               from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
+               from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
+               to_host_from_fw_reg = WILC_SDIO_FW_TO_HOST_REG;
+               to_host_from_fw_bit = WILC_SDIO_FW_TO_HOST_BIT;
+       } else {
+               wakeup_reg = WILC_SPI_WAKEUP_REG;
+               wakeup_bit = WILC_SPI_WAKEUP_BIT;
+               clk_status_reg = WILC_SPI_CLK_STATUS_REG;
+               clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
+               from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
+               from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
+               to_host_from_fw_reg = WILC_SPI_FW_TO_HOST_REG;
+               to_host_from_fw_bit = WILC_SPI_FW_TO_HOST_BIT;
        }
 
-       if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
-               if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
-                       u32 val32;
+       /* indicate host wakeup */
+       ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
+                                     from_host_to_fw_bit);
+       if (ret)
+               return;
 
-                       h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
-                       val32 |= BIT(6);
-                       h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
+       /* Set wake-up bit */
+       ret = hif_func->hif_write_reg(wilc, wakeup_reg,
+                                     wakeup_bit);
+       if (ret)
+               return;
 
-                       h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
-                       val32 |= BIT(6);
-                       h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
+       while (trials < WAKE_UP_TRIAL_RETRY) {
+               ret = hif_func->hif_read_reg(wilc, clk_status_reg,
+                                            &clk_status_val);
+               if (ret) {
+                       pr_err("Bus error %d %x\n", ret, clk_status_val);
+                       return;
                }
+               if (clk_status_val & clk_status_bit)
+                       break;
+
+               trials++;
+       }
+       if (trials >= WAKE_UP_TRIAL_RETRY) {
+               pr_err("Failed to wake-up the chip\n");
+               return;
        }
-       wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
 }
 EXPORT_SYMBOL_GPL(chip_wakeup);
 
index 771c25f..285e5d9 100644 (file)
@@ -97,6 +97,8 @@
 #define WILC_SPI_WAKEUP_REG            0x1
 #define WILC_SPI_WAKEUP_BIT            BIT(1)
 
+#define WILC_SPI_CLK_STATUS_REG        0x0f
+#define WILC_SPI_CLK_STATUS_BIT        BIT(2)
 #define WILC_SPI_HOST_TO_FW_REG                0x0b
 #define WILC_SPI_HOST_TO_FW_BIT                BIT(0)
 
index 31c6864..6eb7eb4 100644 (file)
@@ -48,12 +48,6 @@ enum {
        WILC_FW_MAX_PSPOLL_PS = 4
 };
 
-enum chip_ps_states {
-       WILC_CHIP_WAKEDUP = 0,
-       WILC_CHIP_SLEEPING_AUTO = 1,
-       WILC_CHIP_SLEEPING_MANUAL = 2
-};
-
 enum bus_acquire {
        WILC_BUS_ACQUIRE_ONLY = 0,
        WILC_BUS_ACQUIRE_AND_WAKEUP = 1,