rtw88: 8723d: Add mac power-on/-off function
authorPing-Ke Shih <pkshih@realtek.com>
Wed, 22 Apr 2020 03:46:02 +0000 (11:46 +0800)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 23 Apr 2020 04:47:21 +0000 (07:47 +0300)
The mac power-on flow consists of three steps:
1. pre_sys_cfg  (Before switching power state)
2. power_switch (Switching power state)
3. init_sys_cfg (Settings after swtiching power state)

When switching power state, driver will load and parse the power sequence
tables. For 8723D devices, the logics for parsing are most same except for
the polling function. 8723D devices need to toggle BIT_PFM_WOWL twice.

The settings after power state is switched for 8723D devices are quite
different with other devices, extract a legacy function for them.

For power-off flow, 8723D devices have the same logic with existing chips.
But warning printed if we run power-off sequence in power-off state:

   rtw_pci 0000:03:00.0: failed to poll offset=0x5f8 mask=0xff value=0x0

The scenario is user do 'ifconfig up' that will run power-on sequence to
bring up and then run power-off sequence to enter idle
(IEEE80211_CONF_IDLE). Then, user do 'ifconfig down' that will run
power-off sequence again, and the warning is shown. Original code check
power-on state to avoid to run power-on sequence twice, and this commit
extends to check both power-on and power-off states.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200422034607.28747-4-yhchuang@realtek.com
drivers/net/wireless/realtek/rtw88/mac.c
drivers/net/wireless/realtek/rtw88/reg.h

index 6092604..21b5c71 100644 (file)
@@ -61,6 +61,14 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
 
        rtw_write8(rtwdev, REG_RSV_CTRL, 0);
 
+       if (rtw_chip_wcpu_11n(rtwdev)) {
+               if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO)
+                       rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL);
+               else
+                       rtw_write8(rtwdev, REG_LDO_SWR_CTRL, SPS_SEL);
+               return 0;
+       }
+
        switch (rtw_hci_type(rtwdev)) {
        case RTW_HCI_TYPE_PCIE:
                rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN);
@@ -123,10 +131,19 @@ static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev,
                        if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE &&
                            flag == 0) {
                                value = rtw_read8(rtwdev, REG_SYS_PW_CTRL);
-                               value |= BIT(3);
+                               if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) {
+                                       value &= ~BIT_PFM_WOWL;
+                                       rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+                               }
+                               value |= BIT_PFM_WOWL;
                                rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
-                               value &= ~BIT(3);
+                               value &= ~BIT_PFM_WOWL;
                                rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+                               if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) {
+                                       value |= BIT_PFM_WOWL;
+                                       rtw_write8(rtwdev, REG_SYS_PW_CTRL, value);
+                               }
+
                                cnt = RTW_PWR_POLLING_CNT;
                                flag = 1;
                        } else {
@@ -228,12 +245,14 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
        u8 rpwm;
        bool cur_pwr;
 
-       rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
+       if (rtw_chip_wcpu_11ac(rtwdev)) {
+               rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr);
 
-       /* Check FW still exist or not */
-       if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) {
-               rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE;
-               rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm);
+               /* Check FW still exist or not */
+               if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) {
+                       rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE;
+                       rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm);
+               }
        }
 
        if (rtw_read8(rtwdev, REG_CR) == 0xea)
@@ -244,7 +263,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
        else
                cur_pwr = true;
 
-       if (pwr_on && cur_pwr)
+       if (pwr_on == cur_pwr)
                return -EALREADY;
 
        pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq;
@@ -254,7 +273,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
        return 0;
 }
 
-static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
+static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
 {
        u8 sys_func_en = rtwdev->chip->sys_func_en;
        u8 value8;
@@ -279,6 +298,29 @@ static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
        return 0;
 }
 
+static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev)
+{
+       rtw_write8(rtwdev, REG_CR, 0xff);
+       mdelay(2);
+       rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0x7f);
+       mdelay(2);
+
+       rtw_write8_set(rtwdev, REG_SYS_CLKR, BIT_WAKEPAD_EN);
+       rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC);
+
+       rtw_write16(rtwdev, REG_CR, 0x2ff);
+
+       return 0;
+}
+
+static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
+{
+       if (rtw_chip_wcpu_11n(rtwdev))
+               return __rtw_mac_init_system_cfg_legacy(rtwdev);
+
+       return __rtw_mac_init_system_cfg(rtwdev);
+}
+
 int rtw_mac_power_on(struct rtw_dev *rtwdev)
 {
        int ret = 0;
index 89868ac..c1e66d6 100644 (file)
 #define BIT_R_DIS_PRST         BIT(6)
 #define BIT_WLOCK_1C_B6                BIT(5)
 #define REG_SYS_PW_CTRL                0x0004
+#define BIT_PFM_WOWL           BIT(3)
 #define REG_SYS_CLK_CTRL       0x0008
 #define BIT_CPU_CLK_EN         BIT(14)
 
 #define REG_SYS_CLKR           0x0008
 #define BIT_ANA8M              BIT(1)
+#define BIT_WAKEPAD_EN         BIT(3)
 #define BIT_LOADER_CLK_EN      BIT(5)
 
 #define REG_RSV_CTRL           0x001C
@@ -49,6 +51,7 @@
 
 #define REG_GPIO_MUXCFG                0x0040
 #define BIT_FSPI_EN            BIT(19)
+#define BIT_EN_SIC             BIT(12)
 #define BIT_BT_AOD_GPIO3       BIT(9)
 #define BIT_BT_PTA_EN          BIT(5)
 #define BIT_WLRFE_4_5_EN       BIT(2)
 #define BIT_LTE_MUX_CTRL_PATH  BIT(26)
 #define REG_HCI_OPT_CTRL       0x0074
 
+#define REG_LDO_SWR_CTRL       0x007C
+#define LDO_SEL                        0xC3
+#define SPS_SEL                        0x83
+
 #define REG_MCUFW_CTRL         0x0080
 #define BIT_ANA_PORT_EN                BIT(22)
 #define BIT_MAC_PORT_EN                BIT(21)
 #define BIT_BT_INT_EN          BIT(15)
 #define REG_SYS_CFG1           0x00F0
 #define        BIT_RTL_ID              BIT(23)
+#define BIT_LDO                        BIT(24)
 #define BIT_RF_TYPE_ID         BIT(27)
 #define BIT_SHIFT_VENDOR_ID    16
 #define BIT_MASK_VENDOR_ID     0xf
 #define REG_FWHW_TXQ_CTRL      0x0420
 #define BIT_EN_BCNQ_DL         BIT(22)
 #define BIT_EN_WR_FREE_TAIL    BIT(20)
+#define REG_HWSEQ_CTRL         0x0423
+
 #define REG_BCNQ_BDNY_V1       0x0424
 #define REG_LIFETIME_EN                0x0426
 #define BIT_BA_PARSER_EN       BIT(5)