]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: rtw88: mac: Support SDIO specific bits in the power on sequence
authorMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Wed, 5 Apr 2023 20:07:23 +0000 (22:07 +0200)
committerKalle Valo <kvalo@kernel.org>
Wed, 12 Apr 2023 12:51:08 +0000 (15:51 +0300)
Add the code specific to SDIO HCI in the MAC power on sequence. This is
based on the RTL8822BS and RTL8822CS vendor drivers.

Co-developed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Reviewed-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230405200729.632435-4-martin.blumenstingl@googlemail.com
drivers/net/wireless/realtek/rtw88/mac.c

index 2fcba43a6f72ae7288fd612b73350a77cd86a139..44e07b61b9b9c747d295718c705727d9f9c91aa3 100644 (file)
@@ -61,6 +61,7 @@ EXPORT_SYMBOL(rtw_set_channel_mac);
 
 static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
 {
+       unsigned int retry;
        u32 value32;
        u8 value8;
 
@@ -78,6 +79,28 @@ static int rtw_mac_pre_system_cfg(struct rtw_dev *rtwdev)
        case RTW_HCI_TYPE_PCIE:
                rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS);
                break;
+       case RTW_HCI_TYPE_SDIO:
+               rtw_write8_clr(rtwdev, REG_SDIO_HSUS_CTRL, BIT_HCI_SUS_REQ);
+
+               for (retry = 0; retry < RTW_PWR_POLLING_CNT; retry++) {
+                       if (rtw_read8(rtwdev, REG_SDIO_HSUS_CTRL) & BIT_HCI_RESUME_RDY)
+                               break;
+
+                       usleep_range(10, 50);
+               }
+
+               if (retry == RTW_PWR_POLLING_CNT) {
+                       rtw_err(rtwdev, "failed to poll REG_SDIO_HSUS_CTRL[1]");
+                       return -ETIMEDOUT;
+               }
+
+               if (rtw_sdio_is_sdio30_supported(rtwdev))
+                       rtw_write8_set(rtwdev, REG_HCI_OPT_CTRL + 2,
+                                      BIT_SDIO_PAD_E5 >> 16);
+               else
+                       rtw_write8_clr(rtwdev, REG_HCI_OPT_CTRL + 2,
+                                      BIT_SDIO_PAD_E5 >> 16);
+               break;
        case RTW_HCI_TYPE_USB:
                break;
        default:
@@ -249,6 +272,7 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
 {
        const struct rtw_chip_info *chip = rtwdev->chip;
        const struct rtw_pwr_seq_cmd **pwr_seq;
+       u32 imr = 0;
        u8 rpwm;
        bool cur_pwr;
        int ret;
@@ -274,18 +298,24 @@ static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
        if (pwr_on == cur_pwr)
                return -EALREADY;
 
+       if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) {
+               imr = rtw_read32(rtwdev, REG_SDIO_HIMR);
+               rtw_write32(rtwdev, REG_SDIO_HIMR, 0);
+       }
+
        if (!pwr_on)
                clear_bit(RTW_FLAG_POWERON, rtwdev->flags);
 
        pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq;
        ret = rtw_pwr_seq_parser(rtwdev, pwr_seq);
-       if (ret)
-               return ret;
 
-       if (pwr_on)
+       if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO)
+               rtw_write32(rtwdev, REG_SDIO_HIMR, imr);
+
+       if (!ret && pwr_on)
                set_bit(RTW_FLAG_POWERON, rtwdev->flags);
 
-       return 0;
+       return ret;
 }
 
 static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev)
@@ -456,6 +486,9 @@ static void download_firmware_reg_backup(struct rtw_dev *rtwdev,
        rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, 0x200);
        rtw_write32(rtwdev, REG_RQPN_CTRL_2, bckp[bckp_idx - 1].val);
 
+       if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO)
+               rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);
+
        /* Disable beacon related functions */
        tmp = rtw_read8(rtwdev, REG_BCN_CTRL);
        bckp[bckp_idx].len = 1;
@@ -1068,8 +1101,12 @@ static int txdma_queue_mapping(struct rtw_dev *rtwdev)
        if (rtw_chip_wcpu_11ac(rtwdev))
                rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL);
 
-       if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB)
+       if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_SDIO) {
+               rtw_read32(rtwdev, REG_SDIO_FREE_TXPG);
+               rtw_write32(rtwdev, REG_SDIO_TX_CTRL, 0);
+       } else if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB) {
                rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_ARBBW_EN);
+       }
 
        return 0;
 }