wifi: rtw89: pci: add pre_deinit to be called after probe complete
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 10 Nov 2023 01:23:15 +0000 (09:23 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 14 Nov 2023 10:22:42 +0000 (12:22 +0200)
At probe stage, we only do partial initialization to enable ability to
download firmware and read capabilities. After that, we use this pre_deinit
to disable HCI to save power.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20231110012319.12727-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/pci.c
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/pci_be.c
drivers/net/wireless/realtek/rtw89/reg.h

index c689fc2b2d49e8e31acb852ef59a3dd9a1e6cd08..b18f54b16f9afb2b64dc656343a8e7fce4f1ce13 100644 (file)
@@ -4236,6 +4236,8 @@ static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev)
 
        rtw89_core_setup_phycap(rtwdev);
 
+       rtw89_hci_mac_pre_deinit(rtwdev);
+
        rtw89_mac_pwr_off(rtwdev);
 
        return 0;
index da8181539d1a53a6d68993d31073a418fb7f5664..07b529a763963863a6529edb883288ce76bd1bd3 100644 (file)
@@ -3064,6 +3064,7 @@ struct rtw89_hci_ops {
        void (*write32)(struct rtw89_dev *rtwdev, u32 addr, u32 data);
 
        int (*mac_pre_init)(struct rtw89_dev *rtwdev);
+       int (*mac_pre_deinit)(struct rtw89_dev *rtwdev);
        int (*mac_post_init)(struct rtw89_dev *rtwdev);
        int (*deinit)(struct rtw89_dev *rtwdev);
 
@@ -4803,6 +4804,11 @@ static inline void rtw89_hci_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch)
        return rtwdev->hci.ops->tx_kick_off(rtwdev, txch);
 }
 
+static inline int rtw89_hci_mac_pre_deinit(struct rtw89_dev *rtwdev)
+{
+       return rtwdev->hci.ops->mac_pre_deinit(rtwdev);
+}
+
 static inline void rtw89_hci_flush_queues(struct rtw89_dev *rtwdev, u32 queues,
                                          bool drop)
 {
index 822b914cf935e47d942e7d7831639ff7a4981812..013588a572c57424c9b5b90079fb771591ecc1c7 100644 (file)
@@ -3837,6 +3837,7 @@ EXPORT_SYMBOL(rtw89_pm_ops);
 
 const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
        .mac_pre_init = rtw89_pci_ops_mac_pre_init_ax,
+       .mac_pre_deinit = NULL,
        .mac_post_init = rtw89_pci_ops_mac_post_init_ax,
 
        .clr_idx_all = rtw89_pci_clr_idx_all_ax,
@@ -3866,6 +3867,7 @@ static const struct rtw89_hci_ops rtw89_pci_ops = {
        .write32        = rtw89_pci_ops_write32,
 
        .mac_pre_init   = rtw89_pci_ops_mac_pre_init,
+       .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit,
        .mac_post_init  = rtw89_pci_ops_mac_post_init,
        .deinit         = rtw89_pci_ops_deinit,
 
index 30ab9d41e0eeb57b4ae390b7ca51496340b1b90c..426f9d28650b2a1b7a5eb6c38b9e3afc34db82b3 100644 (file)
@@ -1038,6 +1038,7 @@ struct rtw89_pci_bd_ram {
 
 struct rtw89_pci_gen_def {
        int (*mac_pre_init)(struct rtw89_dev *rtwdev);
+       int (*mac_pre_deinit)(struct rtw89_dev *rtwdev);
        int (*mac_post_init)(struct rtw89_dev *rtwdev);
 
        void (*clr_idx_all)(struct rtw89_dev *rtwdev);
@@ -1464,6 +1465,17 @@ static inline int rtw89_pci_ops_mac_pre_init(struct rtw89_dev *rtwdev)
        return gen_def->mac_pre_init(rtwdev);
 }
 
+static inline int rtw89_pci_ops_mac_pre_deinit(struct rtw89_dev *rtwdev)
+{
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+       const struct rtw89_pci_gen_def *gen_def = info->gen_def;
+
+       if (!gen_def->mac_pre_deinit)
+               return 0;
+
+       return gen_def->mac_pre_deinit(rtwdev);
+}
+
 static inline int rtw89_pci_ops_mac_post_init(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_pci_info *info = rtwdev->pci_info;
index 01d72cde48a3fc3701979c7fb9714c30db1aa047..4f76395e243ad9c8c788976ffdfa2895f8b3292b 100644 (file)
@@ -329,6 +329,23 @@ static int rtw89_pci_ops_mac_pre_init_be(struct rtw89_dev *rtwdev)
        return 0;
 }
 
+static int rtw89_pci_ops_mac_pre_deinit_be(struct rtw89_dev *rtwdev)
+{
+       u32 val;
+
+       _patch_pcie_power_wake_be(rtwdev, false);
+
+       val = rtw89_read32_mask(rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK);
+       if (val == 0)
+               return 0;
+
+       rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE,
+                                     MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE);
+       rtw89_pci_clr_idx_all_be(rtwdev);
+
+       return 0;
+}
+
 int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en)
 {
        u32 ctrl0, cfg0, cfg1, dec_ctrl, idle_ltcy, act_ltcy, dis_ltcy;
@@ -474,6 +491,7 @@ static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
 
 const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
        .mac_pre_init = rtw89_pci_ops_mac_pre_init_be,
+       .mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_be,
        .mac_post_init = rtw89_pci_ops_mac_post_init_be,
 
        .clr_idx_all = rtw89_pci_clr_idx_all_be,
index 68a5d8ff6a700b6d9bf5ee6c58eedbde420ba1e7..470302e6de11c468f9f1c37be0463229cb15d426 100644 (file)
 #define R_BE_UDM2 0x01F8
 #define B_BE_UDM2_EPC_RA_MASK GENMASK(31, 0)
 
+#define R_BE_IC_PWR_STATE 0x03F0
+#define B_BE_WHOLE_SYS_PWR_STE_MASK GENMASK(25, 16)
+#define MAC_AX_SYS_ACT 0x220
+#define B_BE_WLMAC_PWR_STE_MASK GENMASK(9, 8)
+#define B_BE_UART_HCISYS_PWR_STE_MASK GENMASK(7, 6)
+#define B_BE_SDIO_HCISYS_PWR_STE_MASK GENMASK(5, 4)
+#define B_BE_USB_HCISYS_PWR_STE_MASK GENMASK(3, 2)
+#define B_BE_PCIE_HCISYS_PWR_STE_MASK GENMASK(1, 0)
+
 #define R_BE_DCPU_PLATFORM_ENABLE 0x0888
 #define B_BE_DCPU_SYM_DPLT_MEM_MUX_EN BIT(10)
 #define B_BE_DCPU_WARM_EN BIT(9)