]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: pci: implement PCI CLK/ASPM/L1SS for WiFi 7 chips
authorChin-Yen Lee <timlee@realtek.com>
Thu, 22 Feb 2024 06:42:58 +0000 (14:42 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 27 Feb 2024 14:55:13 +0000 (16:55 +0200)
PCI CLK/ASPM/L1SS is power management mechanism used to reduce power
consumption of PCI chip. The registers for setting of these features
in WiFi 7 Chip are different from WiFi 6 chip, so separate them
in generation information.

Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240222064258.59782-4-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/pci.c
drivers/net/wireless/realtek/rtw89/pci.h
drivers/net/wireless/realtek/rtw89/pci_be.c

index 67d7294e488a66f857c02222a6242c83f643fbca..d4c8799d6f2ebda0e423be4aace5575d16ba2013 100644 (file)
@@ -3652,12 +3652,20 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
 
 static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable)
 {
-       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
-       int ret;
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+       const struct rtw89_pci_gen_def *gen_def = info->gen_def;
 
        if (rtw89_pci_disable_clkreq)
                return;
 
+       gen_def->clkreq_set(rtwdev, enable);
+}
+
+static void rtw89_pci_clkreq_set_ax(struct rtw89_dev *rtwdev, bool enable)
+{
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       int ret;
+
        ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_CLK_CTRL,
                                          PCIE_CLKDLY_HW_30US);
        if (ret)
@@ -3689,24 +3697,31 @@ static void rtw89_pci_clkreq_set(struct rtw89_dev *rtwdev, bool enable)
 
 static void rtw89_pci_aspm_set(struct rtw89_dev *rtwdev, bool enable)
 {
-       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
-       u8 value = 0;
-       int ret;
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+       const struct rtw89_pci_gen_def *gen_def = info->gen_def;
 
        if (rtw89_pci_disable_aspm_l1)
                return;
 
+       gen_def->aspm_set(rtwdev, enable);
+}
+
+static void rtw89_pci_aspm_set_ax(struct rtw89_dev *rtwdev, bool enable)
+{
+       enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
+       u8 value = 0;
+       int ret;
+
        ret = rtw89_pci_read_config_byte(rtwdev, RTW89_PCIE_ASPM_CTRL, &value);
        if (ret)
-               rtw89_err(rtwdev, "failed to read ASPM Delay\n");
+               rtw89_warn(rtwdev, "failed to read ASPM Delay\n");
 
-       value &= ~(RTW89_L1DLY_MASK | RTW89_L0DLY_MASK);
-       value |= FIELD_PREP(RTW89_L1DLY_MASK, PCIE_L1DLY_16US) |
-                FIELD_PREP(RTW89_L0DLY_MASK, PCIE_L0SDLY_4US);
+       u8p_replace_bits(&value, PCIE_L1DLY_16US, RTW89_L1DLY_MASK);
+       u8p_replace_bits(&value, PCIE_L0SDLY_4US, RTW89_L0DLY_MASK);
 
        ret = rtw89_pci_write_config_byte(rtwdev, RTW89_PCIE_ASPM_CTRL, value);
        if (ret)
-               rtw89_err(rtwdev, "failed to read ASPM Delay\n");
+               rtw89_warn(rtwdev, "failed to read ASPM Delay\n");
 
        if (chip_id == RTL8852A || chip_id == RTL8852B || chip_id == RTL8851B) {
                if (enable)
@@ -3792,6 +3807,17 @@ static void rtw89_pci_link_cfg(struct rtw89_dev *rtwdev)
 }
 
 static void rtw89_pci_l1ss_set(struct rtw89_dev *rtwdev, bool enable)
+{
+       const struct rtw89_pci_info *info = rtwdev->pci_info;
+       const struct rtw89_pci_gen_def *gen_def = info->gen_def;
+
+       if (rtw89_pci_disable_l1ss)
+               return;
+
+       gen_def->l1ss_set(rtwdev, enable);
+}
+
+static void rtw89_pci_l1ss_set_ax(struct rtw89_dev *rtwdev, bool enable)
 {
        enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
        int ret;
@@ -4066,6 +4092,10 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
 
        .lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_ax,
        .lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_ax,
+
+       .aspm_set = rtw89_pci_aspm_set_ax,
+       .clkreq_set = rtw89_pci_clkreq_set_ax,
+       .l1ss_set = rtw89_pci_l1ss_set_ax,
 };
 EXPORT_SYMBOL(rtw89_pci_gen_ax);
 
index 532f78eaf6df3165289f384e236287c745de5744..c1954cb120300e46d5aaa8f3bc0c41ab05097f06 100644 (file)
 #define B_BE_PCIE_EN_SWENT_L23 BIT(1)
 #define B_BE_SEL_REQ_EXIT_L1 BIT(0)
 
+#define R_BE_PCIE_MIX_CFG 0x300C
+#define B_BE_L1SS_TIMEOUT_CTRL BIT(18)
+#define B_BE_ASPM_CTRL_L1 BIT(17)
+#define B_BE_ASPM_CTRL_L0 BIT(16)
+#define B_BE_XFER_PENDING_FW BIT(11)
+#define B_BE_XFER_PENDING BIT(10)
+#define B_BE_REQ_EXIT_L1 BIT(9)
+#define B_BE_REQ_ENTR_L1 BIT(8)
+#define B_BE_L1SUB_ENABLE BIT(0)
+
+#define R_BE_L1_CLK_CTRL 0x3010
+#define B_BE_RAS_SD_HOLD_LTSSM BIT(12)
+#define B_BE_CLK_REQ_N BIT(1)
+#define B_BE_CLK_PM_EN BIT(0)
+
 #define R_BE_PCIE_LAT_CTRL 0x3044
 #define B_BE_ELBI_PHY_REMAP_MASK GENMASK(29, 24)
 #define B_BE_SYS_SUS_L12_EN BIT(17)
 #define B_BE_RTK_LDO_POWER_LATENCY_MASK GENMASK(11, 10)
 #define B_BE_RTK_LDO_BIAS_LATENCY_MASK GENMASK(9, 8)
 #define B_BE_CLK_REQ_LAT_MASK GENMASK(7, 4)
+#define B_BE_RTK_PM_SEL_OPT BIT(1)
+#define B_BE_CLK_REQ_SEL BIT(0)
 
 #define R_BE_PCIE_HIMR0 0x30B0
 #define B_BE_PCIE_HB1_IND_INTA_IMR BIT(31)
@@ -1066,6 +1083,15 @@ enum rtw89_pcie_clkdly_hw {
        PCIE_CLKDLY_HW_200US = 0x5,
 };
 
+enum rtw89_pcie_clkdly_hw_v1 {
+       PCIE_CLKDLY_HW_V1_0 = 0,
+       PCIE_CLKDLY_HW_V1_16US = 0x1,
+       PCIE_CLKDLY_HW_V1_32US = 0x2,
+       PCIE_CLKDLY_HW_V1_64US = 0x3,
+       PCIE_CLKDLY_HW_V1_80US = 0x4,
+       PCIE_CLKDLY_HW_V1_96US = 0x5,
+};
+
 enum mac_ax_bd_trunc_mode {
        MAC_AX_BD_NORM,
        MAC_AX_BD_TRUNC,
@@ -1216,6 +1242,10 @@ struct rtw89_pci_gen_def {
 
        int (*lv1rst_stop_dma)(struct rtw89_dev *rtwdev);
        int (*lv1rst_start_dma)(struct rtw89_dev *rtwdev);
+
+       void (*aspm_set)(struct rtw89_dev *rtwdev, bool enable);
+       void (*clkreq_set)(struct rtw89_dev *rtwdev, bool enable);
+       void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable);
 };
 
 struct rtw89_pci_info {
index 5c9e39357773a0ae163601726df828ff92d2c689..0276d5d05925e12fd6827c9e8ebcc3946cf43f37 100644 (file)
@@ -19,6 +19,54 @@ enum pcie_rxbd_mode {
 #define PL0_TMR_MAC_1MS 0x27100
 #define PL0_TMR_AUX_1MS 0x1E848
 
+static void rtw89_pci_aspm_set_be(struct rtw89_dev *rtwdev, bool enable)
+{
+       struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
+       struct pci_dev *pdev = rtwpci->pdev;
+       u8 value = 0;
+       int ret;
+
+       ret = pci_read_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, &value);
+       if (ret)
+               rtw89_warn(rtwdev, "failed to read ASPM Delay\n");
+
+       u8p_replace_bits(&value, PCIE_L1DLY_16US, RTW89_L1DLY_MASK);
+
+       ret = pci_write_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, value);
+       if (ret)
+               rtw89_warn(rtwdev, "failed to write ASPM Delay\n");
+
+       if (enable)
+               rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1,
+                                 B_BE_ASPM_CTRL_L1);
+       else
+               rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1,
+                                 B_BE_ASPM_CTRL_L1);
+}
+
+static void rtw89_pci_l1ss_set_be(struct rtw89_dev *rtwdev, bool enable)
+{
+       if (enable)
+               rtw89_write32_set(rtwdev, R_BE_PCIE_MIX_CFG,
+                                 B_BE_L1SUB_ENABLE);
+       else
+               rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG,
+                                 B_BE_L1SUB_ENABLE);
+}
+
+static void rtw89_pci_clkreq_set_be(struct rtw89_dev *rtwdev, bool enable)
+{
+       rtw89_write32_mask(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_CLK_REQ_LAT_MASK,
+                          PCIE_CLKDLY_HW_V1_0);
+
+       if (enable)
+               rtw89_write32_set(rtwdev, R_BE_L1_CLK_CTRL,
+                                 B_BE_CLK_PM_EN);
+       else
+               rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL,
+                                 B_BE_CLK_PM_EN);
+}
+
 static void _patch_pcie_power_wake_be(struct rtw89_dev *rtwdev, bool power_up)
 {
        if (power_up)
@@ -510,5 +558,9 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
 
        .lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_be,
        .lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_be,
+
+       .aspm_set = rtw89_pci_aspm_set_be,
+       .clkreq_set = rtw89_pci_clkreq_set_be,
+       .l1ss_set = rtw89_pci_l1ss_set_be,
 };
 EXPORT_SYMBOL(rtw89_pci_gen_be);