xref: /freebsd/sys/contrib/dev/rtw89/pci_be.c (revision 6d67aabd63555ab62a2f2b7f52a75ef100a2fe75)
1*6d67aabdSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*6d67aabdSBjoern A. Zeeb /* Copyright(c) 2023  Realtek Corporation
3*6d67aabdSBjoern A. Zeeb  */
4*6d67aabdSBjoern A. Zeeb 
5*6d67aabdSBjoern A. Zeeb #include <linux/pci.h>
6*6d67aabdSBjoern A. Zeeb 
7*6d67aabdSBjoern A. Zeeb #include "mac.h"
8*6d67aabdSBjoern A. Zeeb #include "pci.h"
9*6d67aabdSBjoern A. Zeeb #include "reg.h"
10*6d67aabdSBjoern A. Zeeb 
11*6d67aabdSBjoern A. Zeeb enum pcie_rxbd_mode {
12*6d67aabdSBjoern A. Zeeb 	PCIE_RXBD_NORM = 0,
13*6d67aabdSBjoern A. Zeeb 	PCIE_RXBD_SEP,
14*6d67aabdSBjoern A. Zeeb 	PCIE_RXBD_EXT,
15*6d67aabdSBjoern A. Zeeb };
16*6d67aabdSBjoern A. Zeeb 
17*6d67aabdSBjoern A. Zeeb #define PL0_TMR_SCALE_ASIC 1
18*6d67aabdSBjoern A. Zeeb #define PL0_TMR_ANA_172US 0x800
19*6d67aabdSBjoern A. Zeeb #define PL0_TMR_MAC_1MS 0x27100
20*6d67aabdSBjoern A. Zeeb #define PL0_TMR_AUX_1MS 0x1E848
21*6d67aabdSBjoern A. Zeeb 
22*6d67aabdSBjoern A. Zeeb static void rtw89_pci_aspm_set_be(struct rtw89_dev *rtwdev, bool enable)
23*6d67aabdSBjoern A. Zeeb {
24*6d67aabdSBjoern A. Zeeb 	struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
25*6d67aabdSBjoern A. Zeeb 	struct pci_dev *pdev = rtwpci->pdev;
26*6d67aabdSBjoern A. Zeeb 	u8 value = 0;
27*6d67aabdSBjoern A. Zeeb 	int ret;
28*6d67aabdSBjoern A. Zeeb 
29*6d67aabdSBjoern A. Zeeb 	ret = pci_read_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, &value);
30*6d67aabdSBjoern A. Zeeb 	if (ret)
31*6d67aabdSBjoern A. Zeeb 		rtw89_warn(rtwdev, "failed to read ASPM Delay\n");
32*6d67aabdSBjoern A. Zeeb 
33*6d67aabdSBjoern A. Zeeb 	u8p_replace_bits(&value, PCIE_L1DLY_16US, RTW89_L1DLY_MASK);
34*6d67aabdSBjoern A. Zeeb 
35*6d67aabdSBjoern A. Zeeb 	ret = pci_write_config_byte(pdev, RTW89_PCIE_ASPM_CTRL, value);
36*6d67aabdSBjoern A. Zeeb 	if (ret)
37*6d67aabdSBjoern A. Zeeb 		rtw89_warn(rtwdev, "failed to write ASPM Delay\n");
38*6d67aabdSBjoern A. Zeeb 
39*6d67aabdSBjoern A. Zeeb 	if (enable)
40*6d67aabdSBjoern A. Zeeb 		rtw89_write32_set(rtwdev, R_AX_PCIE_MIX_CFG_V1,
41*6d67aabdSBjoern A. Zeeb 				  B_BE_ASPM_CTRL_L1);
42*6d67aabdSBjoern A. Zeeb 	else
43*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_AX_PCIE_MIX_CFG_V1,
44*6d67aabdSBjoern A. Zeeb 				  B_BE_ASPM_CTRL_L1);
45*6d67aabdSBjoern A. Zeeb }
46*6d67aabdSBjoern A. Zeeb 
47*6d67aabdSBjoern A. Zeeb static void rtw89_pci_l1ss_set_be(struct rtw89_dev *rtwdev, bool enable)
48*6d67aabdSBjoern A. Zeeb {
49*6d67aabdSBjoern A. Zeeb 	if (enable)
50*6d67aabdSBjoern A. Zeeb 		rtw89_write32_set(rtwdev, R_BE_PCIE_MIX_CFG,
51*6d67aabdSBjoern A. Zeeb 				  B_BE_L1SUB_ENABLE);
52*6d67aabdSBjoern A. Zeeb 	else
53*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG,
54*6d67aabdSBjoern A. Zeeb 				  B_BE_L1SUB_ENABLE);
55*6d67aabdSBjoern A. Zeeb }
56*6d67aabdSBjoern A. Zeeb 
57*6d67aabdSBjoern A. Zeeb static void rtw89_pci_clkreq_set_be(struct rtw89_dev *rtwdev, bool enable)
58*6d67aabdSBjoern A. Zeeb {
59*6d67aabdSBjoern A. Zeeb 	rtw89_write32_mask(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_CLK_REQ_LAT_MASK,
60*6d67aabdSBjoern A. Zeeb 			   PCIE_CLKDLY_HW_V1_0);
61*6d67aabdSBjoern A. Zeeb 
62*6d67aabdSBjoern A. Zeeb 	if (enable)
63*6d67aabdSBjoern A. Zeeb 		rtw89_write32_set(rtwdev, R_BE_L1_CLK_CTRL,
64*6d67aabdSBjoern A. Zeeb 				  B_BE_CLK_PM_EN);
65*6d67aabdSBjoern A. Zeeb 	else
66*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_AX_L1_CLK_CTRL,
67*6d67aabdSBjoern A. Zeeb 				  B_BE_CLK_PM_EN);
68*6d67aabdSBjoern A. Zeeb }
69*6d67aabdSBjoern A. Zeeb 
70*6d67aabdSBjoern A. Zeeb static void _patch_pcie_power_wake_be(struct rtw89_dev *rtwdev, bool power_up)
71*6d67aabdSBjoern A. Zeeb {
72*6d67aabdSBjoern A. Zeeb 	if (power_up)
73*6d67aabdSBjoern A. Zeeb 		rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1);
74*6d67aabdSBjoern A. Zeeb 	else
75*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1);
76*6d67aabdSBjoern A. Zeeb }
77*6d67aabdSBjoern A. Zeeb 
78*6d67aabdSBjoern A. Zeeb static void rtw89_pci_set_io_rcy_be(struct rtw89_dev *rtwdev)
79*6d67aabdSBjoern A. Zeeb {
80*6d67aabdSBjoern A. Zeeb 	const struct rtw89_pci_info *info = rtwdev->pci_info;
81*6d67aabdSBjoern A. Zeeb 	u32 scale = PL0_TMR_SCALE_ASIC;
82*6d67aabdSBjoern A. Zeeb 	u32 val32;
83*6d67aabdSBjoern A. Zeeb 
84*6d67aabdSBjoern A. Zeeb 	if (info->io_rcy_en == MAC_AX_PCIE_ENABLE) {
85*6d67aabdSBjoern A. Zeeb 		val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
86*6d67aabdSBjoern A. Zeeb 			PL0_TMR_ANA_172US : info->io_rcy_tmr;
87*6d67aabdSBjoern A. Zeeb 		val32 /= scale;
88*6d67aabdSBjoern A. Zeeb 
89*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_AON_WDT_TMR, val32);
90*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_MDIO_WDT_TMR, val32);
91*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_LA_MODE_WDT_TMR, val32);
92*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_WDT_AR_TMR, val32);
93*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_WDT_AW_TMR, val32);
94*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_WDT_W_TMR, val32);
95*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_WDT_B_TMR, val32);
96*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_WDT_R_TMR, val32);
97*6d67aabdSBjoern A. Zeeb 
98*6d67aabdSBjoern A. Zeeb 		val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
99*6d67aabdSBjoern A. Zeeb 			PL0_TMR_MAC_1MS : info->io_rcy_tmr;
100*6d67aabdSBjoern A. Zeeb 		val32 /= scale;
101*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_WLAN_WDT_TMR, val32);
102*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_AXIDMA_WDT_TMR, val32);
103*6d67aabdSBjoern A. Zeeb 
104*6d67aabdSBjoern A. Zeeb 		val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
105*6d67aabdSBjoern A. Zeeb 			PL0_TMR_AUX_1MS : info->io_rcy_tmr;
106*6d67aabdSBjoern A. Zeeb 		val32 /= scale;
107*6d67aabdSBjoern A. Zeeb 		rtw89_write32(rtwdev, R_BE_LOCAL_WDT_TMR, val32);
108*6d67aabdSBjoern A. Zeeb 	} else {
109*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_WLAN_WDT, B_BE_WLAN_WDT_ENABLE);
110*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_AXIDMA_WDT, B_BE_AXIDMA_WDT_ENABLE);
111*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_AON_WDT, B_BE_AON_WDT_ENABLE);
112*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_LOCAL_WDT, B_BE_LOCAL_WDT_ENABLE);
113*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_MDIO_WDT, B_BE_MDIO_WDT_ENABLE);
114*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_LA_MODE_WDT, B_BE_LA_MODE_WDT_ENABLE);
115*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_WDT_AR, B_BE_WDT_AR_ENABLE);
116*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_WDT_AW, B_BE_WDT_AW_ENABLE);
117*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_WDT_W, B_BE_WDT_W_ENABLE);
118*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_WDT_B, B_BE_WDT_B_ENABLE);
119*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_WDT_R, B_BE_WDT_R_ENABLE);
120*6d67aabdSBjoern A. Zeeb 	}
121*6d67aabdSBjoern A. Zeeb }
122*6d67aabdSBjoern A. Zeeb 
123*6d67aabdSBjoern A. Zeeb static void rtw89_pci_ctrl_wpdma_pcie_be(struct rtw89_dev *rtwdev, bool en)
124*6d67aabdSBjoern A. Zeeb {
125*6d67aabdSBjoern A. Zeeb 	if (en)
126*6d67aabdSBjoern A. Zeeb 		rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA);
127*6d67aabdSBjoern A. Zeeb 	else
128*6d67aabdSBjoern A. Zeeb 		rtw89_write32_set(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA);
129*6d67aabdSBjoern A. Zeeb }
130*6d67aabdSBjoern A. Zeeb 
131*6d67aabdSBjoern A. Zeeb static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev,
132*6d67aabdSBjoern A. Zeeb 					  enum mac_ax_pcie_func_ctrl tx_en,
133*6d67aabdSBjoern A. Zeeb 					  enum mac_ax_pcie_func_ctrl rx_en,
134*6d67aabdSBjoern A. Zeeb 					  enum mac_ax_pcie_func_ctrl io_en)
135*6d67aabdSBjoern A. Zeeb {
136*6d67aabdSBjoern A. Zeeb 	u32 val;
137*6d67aabdSBjoern A. Zeeb 
138*6d67aabdSBjoern A. Zeeb 	val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
139*6d67aabdSBjoern A. Zeeb 
140*6d67aabdSBjoern A. Zeeb 	if (tx_en == MAC_AX_PCIE_ENABLE)
141*6d67aabdSBjoern A. Zeeb 		val |= B_BE_TXDMA_EN;
142*6d67aabdSBjoern A. Zeeb 	else if (tx_en == MAC_AX_PCIE_DISABLE)
143*6d67aabdSBjoern A. Zeeb 		val &= ~B_BE_TXDMA_EN;
144*6d67aabdSBjoern A. Zeeb 
145*6d67aabdSBjoern A. Zeeb 	if (rx_en == MAC_AX_PCIE_ENABLE)
146*6d67aabdSBjoern A. Zeeb 		val |= B_BE_RXDMA_EN;
147*6d67aabdSBjoern A. Zeeb 	else if (rx_en == MAC_AX_PCIE_DISABLE)
148*6d67aabdSBjoern A. Zeeb 		val &= ~B_BE_RXDMA_EN;
149*6d67aabdSBjoern A. Zeeb 
150*6d67aabdSBjoern A. Zeeb 	if (io_en == MAC_AX_PCIE_ENABLE)
151*6d67aabdSBjoern A. Zeeb 		val &= ~B_BE_STOP_AXI_MST;
152*6d67aabdSBjoern A. Zeeb 	else if (io_en == MAC_AX_PCIE_DISABLE)
153*6d67aabdSBjoern A. Zeeb 		val |= B_BE_STOP_AXI_MST;
154*6d67aabdSBjoern A. Zeeb 
155*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val);
156*6d67aabdSBjoern A. Zeeb 
157*6d67aabdSBjoern A. Zeeb 	if (io_en == MAC_AX_PCIE_ENABLE)
158*6d67aabdSBjoern A. Zeeb 		rtw89_write32_mask(rtwdev, R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1,
159*6d67aabdSBjoern A. Zeeb 				   B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK, 4);
160*6d67aabdSBjoern A. Zeeb }
161*6d67aabdSBjoern A. Zeeb 
162*6d67aabdSBjoern A. Zeeb static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev)
163*6d67aabdSBjoern A. Zeeb {
164*6d67aabdSBjoern A. Zeeb 	struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
165*6d67aabdSBjoern A. Zeeb 	struct rtw89_pci_rx_ring *rx_ring;
166*6d67aabdSBjoern A. Zeeb 	u32 val;
167*6d67aabdSBjoern A. Zeeb 
168*6d67aabdSBjoern A. Zeeb 	val = B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | B_BE_CLR_CH2_IDX |
169*6d67aabdSBjoern A. Zeeb 	      B_BE_CLR_CH3_IDX | B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX |
170*6d67aabdSBjoern A. Zeeb 	      B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | B_BE_CLR_CH8_IDX |
171*6d67aabdSBjoern A. Zeeb 	      B_BE_CLR_CH9_IDX | B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX |
172*6d67aabdSBjoern A. Zeeb 	      B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | B_BE_CLR_CH14_IDX;
173*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_TXBD_RWPTR_CLR1, val);
174*6d67aabdSBjoern A. Zeeb 
175*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_RXBD_RWPTR_CLR1_V1,
176*6d67aabdSBjoern A. Zeeb 		      B_BE_CLR_RXQ0_IDX | B_BE_CLR_RPQ0_IDX);
177*6d67aabdSBjoern A. Zeeb 
178*6d67aabdSBjoern A. Zeeb 	rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RXQ];
179*6d67aabdSBjoern A. Zeeb 	rtw89_write16(rtwdev, R_BE_RXQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1);
180*6d67aabdSBjoern A. Zeeb 
181*6d67aabdSBjoern A. Zeeb 	rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ];
182*6d67aabdSBjoern A. Zeeb 	rtw89_write16(rtwdev, R_BE_RPQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1);
183*6d67aabdSBjoern A. Zeeb }
184*6d67aabdSBjoern A. Zeeb 
185*6d67aabdSBjoern A. Zeeb static int rtw89_pci_poll_txdma_ch_idle_be(struct rtw89_dev *rtwdev)
186*6d67aabdSBjoern A. Zeeb {
187*6d67aabdSBjoern A. Zeeb 	u32 val;
188*6d67aabdSBjoern A. Zeeb 
189*6d67aabdSBjoern A. Zeeb 	return read_poll_timeout(rtw89_read32, val, (val & DMA_BUSY1_CHECK_BE) == 0,
190*6d67aabdSBjoern A. Zeeb 				 10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1);
191*6d67aabdSBjoern A. Zeeb }
192*6d67aabdSBjoern A. Zeeb 
193*6d67aabdSBjoern A. Zeeb static int rtw89_pci_poll_rxdma_ch_idle_be(struct rtw89_dev *rtwdev)
194*6d67aabdSBjoern A. Zeeb {
195*6d67aabdSBjoern A. Zeeb 	u32 check;
196*6d67aabdSBjoern A. Zeeb 	u32 val;
197*6d67aabdSBjoern A. Zeeb 
198*6d67aabdSBjoern A. Zeeb 	check = B_BE_RXQ0_BUSY_V1 | B_BE_RPQ0_BUSY_V1;
199*6d67aabdSBjoern A. Zeeb 
200*6d67aabdSBjoern A. Zeeb 	return read_poll_timeout(rtw89_read32, val, (val & check) == 0,
201*6d67aabdSBjoern A. Zeeb 				 10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1);
202*6d67aabdSBjoern A. Zeeb }
203*6d67aabdSBjoern A. Zeeb 
204*6d67aabdSBjoern A. Zeeb static int rtw89_pci_poll_dma_all_idle_be(struct rtw89_dev *rtwdev)
205*6d67aabdSBjoern A. Zeeb {
206*6d67aabdSBjoern A. Zeeb 	int ret;
207*6d67aabdSBjoern A. Zeeb 
208*6d67aabdSBjoern A. Zeeb 	ret = rtw89_pci_poll_txdma_ch_idle_be(rtwdev);
209*6d67aabdSBjoern A. Zeeb 	if (ret) {
210*6d67aabdSBjoern A. Zeeb 		rtw89_err(rtwdev, "txdma ch busy\n");
211*6d67aabdSBjoern A. Zeeb 		return ret;
212*6d67aabdSBjoern A. Zeeb 	}
213*6d67aabdSBjoern A. Zeeb 
214*6d67aabdSBjoern A. Zeeb 	ret = rtw89_pci_poll_rxdma_ch_idle_be(rtwdev);
215*6d67aabdSBjoern A. Zeeb 	if (ret) {
216*6d67aabdSBjoern A. Zeeb 		rtw89_err(rtwdev, "rxdma ch busy\n");
217*6d67aabdSBjoern A. Zeeb 		return ret;
218*6d67aabdSBjoern A. Zeeb 	}
219*6d67aabdSBjoern A. Zeeb 
220*6d67aabdSBjoern A. Zeeb 	return 0;
221*6d67aabdSBjoern A. Zeeb }
222*6d67aabdSBjoern A. Zeeb 
223*6d67aabdSBjoern A. Zeeb static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev)
224*6d67aabdSBjoern A. Zeeb {
225*6d67aabdSBjoern A. Zeeb 	const struct rtw89_pci_info *info = rtwdev->pci_info;
226*6d67aabdSBjoern A. Zeeb 	u32 val32_init1, val32_rxapp, val32_exp;
227*6d67aabdSBjoern A. Zeeb 
228*6d67aabdSBjoern A. Zeeb 	val32_init1 = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
229*6d67aabdSBjoern A. Zeeb 	val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE);
230*6d67aabdSBjoern A. Zeeb 	val32_exp = rtw89_read32(rtwdev, R_BE_HAXI_EXP_CTRL_V1);
231*6d67aabdSBjoern A. Zeeb 
232*6d67aabdSBjoern A. Zeeb 	if (info->rxbd_mode == MAC_AX_RXBD_PKT) {
233*6d67aabdSBjoern A. Zeeb 		val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM,
234*6d67aabdSBjoern A. Zeeb 					       B_BE_RXQ_RXBD_MODE_MASK);
235*6d67aabdSBjoern A. Zeeb 	} else if (info->rxbd_mode == MAC_AX_RXBD_SEP) {
236*6d67aabdSBjoern A. Zeeb 		val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP,
237*6d67aabdSBjoern A. Zeeb 					       B_BE_RXQ_RXBD_MODE_MASK);
238*6d67aabdSBjoern A. Zeeb 		val32_rxapp = u32_replace_bits(val32_rxapp, 0,
239*6d67aabdSBjoern A. Zeeb 					       B_BE_APPEND_LEN_MASK);
240*6d67aabdSBjoern A. Zeeb 	}
241*6d67aabdSBjoern A. Zeeb 
242*6d67aabdSBjoern A. Zeeb 	val32_init1 = u32_replace_bits(val32_init1, info->tx_burst,
243*6d67aabdSBjoern A. Zeeb 				       B_BE_MAX_TXDMA_MASK);
244*6d67aabdSBjoern A. Zeeb 	val32_init1 = u32_replace_bits(val32_init1, info->rx_burst,
245*6d67aabdSBjoern A. Zeeb 				       B_BE_MAX_RXDMA_MASK);
246*6d67aabdSBjoern A. Zeeb 	val32_exp = u32_replace_bits(val32_exp, info->multi_tag_num,
247*6d67aabdSBjoern A. Zeeb 				     B_BE_MAX_TAG_NUM_MASK);
248*6d67aabdSBjoern A. Zeeb 	val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_idle_intvl,
249*6d67aabdSBjoern A. Zeeb 				       B_BE_CFG_WD_PERIOD_IDLE_MASK);
250*6d67aabdSBjoern A. Zeeb 	val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_act_intvl,
251*6d67aabdSBjoern A. Zeeb 				       B_BE_CFG_WD_PERIOD_ACTIVE_MASK);
252*6d67aabdSBjoern A. Zeeb 
253*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val32_init1);
254*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp);
255*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_HAXI_EXP_CTRL_V1, val32_exp);
256*6d67aabdSBjoern A. Zeeb }
257*6d67aabdSBjoern A. Zeeb 
258*6d67aabdSBjoern A. Zeeb static int rtw89_pci_rst_bdram_be(struct rtw89_dev *rtwdev)
259*6d67aabdSBjoern A. Zeeb {
260*6d67aabdSBjoern A. Zeeb 	u32 val;
261*6d67aabdSBjoern A. Zeeb 
262*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_HAXI_INIT_CFG1, B_BE_SET_BDRAM_BOUND);
263*6d67aabdSBjoern A. Zeeb 
264*6d67aabdSBjoern A. Zeeb 	return read_poll_timeout(rtw89_read32, val, !(val & B_BE_SET_BDRAM_BOUND),
265*6d67aabdSBjoern A. Zeeb 				 50, 500000, false, rtwdev, R_BE_HAXI_INIT_CFG1);
266*6d67aabdSBjoern A. Zeeb }
267*6d67aabdSBjoern A. Zeeb 
268*6d67aabdSBjoern A. Zeeb static void rtw89_pci_debounce_be(struct rtw89_dev *rtwdev)
269*6d67aabdSBjoern A. Zeeb {
270*6d67aabdSBjoern A. Zeeb 	u32 val32;
271*6d67aabdSBjoern A. Zeeb 
272*6d67aabdSBjoern A. Zeeb 	val32 = rtw89_read32(rtwdev, R_BE_SYS_PAGE_CLK_GATED);
273*6d67aabdSBjoern A. Zeeb 	val32 = u32_replace_bits(val32, 0, B_BE_PCIE_PRST_DEBUNC_PERIOD_MASK);
274*6d67aabdSBjoern A. Zeeb 	val32 |= B_BE_SYM_PRST_DEBUNC_SEL;
275*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_SYS_PAGE_CLK_GATED, val32);
276*6d67aabdSBjoern A. Zeeb }
277*6d67aabdSBjoern A. Zeeb 
278*6d67aabdSBjoern A. Zeeb static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev)
279*6d67aabdSBjoern A. Zeeb {
280*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_PSUS_OFF_CAPC_EN);
281*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_SYS_PAGE_CLK_GATED,
282*6d67aabdSBjoern A. Zeeb 			  B_BE_SOP_OFFPOOBS_PC | B_BE_CPHY_AUXCLK_OP |
283*6d67aabdSBjoern A. Zeeb 			  B_BE_CPHY_POWER_READY_CHK);
284*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN |
285*6d67aabdSBjoern A. Zeeb 						      B_BE_PCIE_DIS_L2_RTK_PERST |
286*6d67aabdSBjoern A. Zeeb 						      B_BE_PCIE_DIS_L2__CTRL_LDO_HCI);
287*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, B_BE_PCIE_DIS_L1_2_CTRL_HCILDO);
288*6d67aabdSBjoern A. Zeeb }
289*6d67aabdSBjoern A. Zeeb 
290*6d67aabdSBjoern A. Zeeb static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev)
291*6d67aabdSBjoern A. Zeeb {
292*6d67aabdSBjoern A. Zeeb 	const struct rtw89_chip_info *chip = rtwdev->chip;
293*6d67aabdSBjoern A. Zeeb 	struct rtw89_hal *hal = &rtwdev->hal;
294*6d67aabdSBjoern A. Zeeb 
295*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_EN_AUX_CLK);
296*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_PCIE_PS_CTRL, B_BE_CMAC_EXIT_L1_EN);
297*6d67aabdSBjoern A. Zeeb 
298*6d67aabdSBjoern A. Zeeb 	if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV)
299*6d67aabdSBjoern A. Zeeb 		return;
300*6d67aabdSBjoern A. Zeeb 
301*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL);
302*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_SYM_AUX_CLK_SEL);
303*6d67aabdSBjoern A. Zeeb }
304*6d67aabdSBjoern A. Zeeb 
305*6d67aabdSBjoern A. Zeeb static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev)
306*6d67aabdSBjoern A. Zeeb {
307*6d67aabdSBjoern A. Zeeb 	u32 val32;
308*6d67aabdSBjoern A. Zeeb 
309*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0);
310*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_FWS1IMR, B_BE_PCIE_SER_TIMEOUT_INDIC_EN);
311*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
312*6d67aabdSBjoern A. Zeeb 	rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK, 1);
313*6d67aabdSBjoern A. Zeeb 
314*6d67aabdSBjoern A. Zeeb 	val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
315*6d67aabdSBjoern A. Zeeb 	val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR |
316*6d67aabdSBjoern A. Zeeb 		 B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK;
317*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
318*6d67aabdSBjoern A. Zeeb }
319*6d67aabdSBjoern A. Zeeb 
320*6d67aabdSBjoern A. Zeeb static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable)
321*6d67aabdSBjoern A. Zeeb {
322*6d67aabdSBjoern A. Zeeb 	u32 mask_all;
323*6d67aabdSBjoern A. Zeeb 	u32 val;
324*6d67aabdSBjoern A. Zeeb 
325*6d67aabdSBjoern A. Zeeb 	mask_all = B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 |
326*6d67aabdSBjoern A. Zeeb 		   B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 |
327*6d67aabdSBjoern A. Zeeb 		   B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 |
328*6d67aabdSBjoern A. Zeeb 		   B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11;
329*6d67aabdSBjoern A. Zeeb 
330*6d67aabdSBjoern A. Zeeb 	val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1);
331*6d67aabdSBjoern A. Zeeb 	val |= B_BE_STOP_CH13 | B_BE_STOP_CH14;
332*6d67aabdSBjoern A. Zeeb 
333*6d67aabdSBjoern A. Zeeb 	if (enable)
334*6d67aabdSBjoern A. Zeeb 		val &= ~mask_all;
335*6d67aabdSBjoern A. Zeeb 	else
336*6d67aabdSBjoern A. Zeeb 		val |= mask_all;
337*6d67aabdSBjoern A. Zeeb 
338*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val);
339*6d67aabdSBjoern A. Zeeb }
340*6d67aabdSBjoern A. Zeeb 
341*6d67aabdSBjoern A. Zeeb static void rtw89_pci_ctrl_txdma_fw_ch_be(struct rtw89_dev *rtwdev, bool enable)
342*6d67aabdSBjoern A. Zeeb {
343*6d67aabdSBjoern A. Zeeb 	u32 val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1);
344*6d67aabdSBjoern A. Zeeb 
345*6d67aabdSBjoern A. Zeeb 	if (enable)
346*6d67aabdSBjoern A. Zeeb 		val &= ~B_BE_STOP_CH12;
347*6d67aabdSBjoern A. Zeeb 	else
348*6d67aabdSBjoern A. Zeeb 		val |= B_BE_STOP_CH12;
349*6d67aabdSBjoern A. Zeeb 
350*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val);
351*6d67aabdSBjoern A. Zeeb }
352*6d67aabdSBjoern A. Zeeb 
353*6d67aabdSBjoern A. Zeeb static int rtw89_pci_ops_mac_pre_init_be(struct rtw89_dev *rtwdev)
354*6d67aabdSBjoern A. Zeeb {
355*6d67aabdSBjoern A. Zeeb 	int ret;
356*6d67aabdSBjoern A. Zeeb 
357*6d67aabdSBjoern A. Zeeb 	rtw89_pci_set_io_rcy_be(rtwdev);
358*6d67aabdSBjoern A. Zeeb 	_patch_pcie_power_wake_be(rtwdev, true);
359*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, false);
360*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE,
361*6d67aabdSBjoern A. Zeeb 				      MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE);
362*6d67aabdSBjoern A. Zeeb 	rtw89_pci_clr_idx_all_be(rtwdev);
363*6d67aabdSBjoern A. Zeeb 
364*6d67aabdSBjoern A. Zeeb 	ret = rtw89_pci_poll_dma_all_idle_be(rtwdev);
365*6d67aabdSBjoern A. Zeeb 	if (ret) {
366*6d67aabdSBjoern A. Zeeb 		rtw89_err(rtwdev, "[ERR] poll pcie dma all idle\n");
367*6d67aabdSBjoern A. Zeeb 		return ret;
368*6d67aabdSBjoern A. Zeeb 	}
369*6d67aabdSBjoern A. Zeeb 
370*6d67aabdSBjoern A. Zeeb 	rtw89_pci_mode_op_be(rtwdev);
371*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ops_reset(rtwdev);
372*6d67aabdSBjoern A. Zeeb 
373*6d67aabdSBjoern A. Zeeb 	ret = rtw89_pci_rst_bdram_be(rtwdev);
374*6d67aabdSBjoern A. Zeeb 	if (ret) {
375*6d67aabdSBjoern A. Zeeb 		rtw89_err(rtwdev, "[ERR]pcie rst bdram\n");
376*6d67aabdSBjoern A. Zeeb 		return ret;
377*6d67aabdSBjoern A. Zeeb 	}
378*6d67aabdSBjoern A. Zeeb 
379*6d67aabdSBjoern A. Zeeb 	rtw89_pci_debounce_be(rtwdev);
380*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ldo_low_pwr_be(rtwdev);
381*6d67aabdSBjoern A. Zeeb 	rtw89_pci_pcie_setting_be(rtwdev);
382*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ser_setting_be(rtwdev);
383*6d67aabdSBjoern A. Zeeb 
384*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_txdma_ch_be(rtwdev, false);
385*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true);
386*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_ENABLE,
387*6d67aabdSBjoern A. Zeeb 				      MAC_AX_PCIE_ENABLE, MAC_AX_PCIE_ENABLE);
388*6d67aabdSBjoern A. Zeeb 
389*6d67aabdSBjoern A. Zeeb 	return 0;
390*6d67aabdSBjoern A. Zeeb }
391*6d67aabdSBjoern A. Zeeb 
392*6d67aabdSBjoern A. Zeeb static int rtw89_pci_ops_mac_pre_deinit_be(struct rtw89_dev *rtwdev)
393*6d67aabdSBjoern A. Zeeb {
394*6d67aabdSBjoern A. Zeeb 	u32 val;
395*6d67aabdSBjoern A. Zeeb 
396*6d67aabdSBjoern A. Zeeb 	_patch_pcie_power_wake_be(rtwdev, false);
397*6d67aabdSBjoern A. Zeeb 
398*6d67aabdSBjoern A. Zeeb 	val = rtw89_read32_mask(rtwdev, R_BE_IC_PWR_STATE, B_BE_WLMAC_PWR_STE_MASK);
399*6d67aabdSBjoern A. Zeeb 	if (val == 0)
400*6d67aabdSBjoern A. Zeeb 		return 0;
401*6d67aabdSBjoern A. Zeeb 
402*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_DISABLE,
403*6d67aabdSBjoern A. Zeeb 				      MAC_AX_PCIE_DISABLE, MAC_AX_PCIE_DISABLE);
404*6d67aabdSBjoern A. Zeeb 	rtw89_pci_clr_idx_all_be(rtwdev);
405*6d67aabdSBjoern A. Zeeb 
406*6d67aabdSBjoern A. Zeeb 	return 0;
407*6d67aabdSBjoern A. Zeeb }
408*6d67aabdSBjoern A. Zeeb 
409*6d67aabdSBjoern A. Zeeb int rtw89_pci_ltr_set_v2(struct rtw89_dev *rtwdev, bool en)
410*6d67aabdSBjoern A. Zeeb {
411*6d67aabdSBjoern A. Zeeb 	u32 ctrl0, cfg0, cfg1, dec_ctrl, idle_ltcy, act_ltcy, dis_ltcy;
412*6d67aabdSBjoern A. Zeeb 
413*6d67aabdSBjoern A. Zeeb 	ctrl0 = rtw89_read32(rtwdev, R_BE_LTR_CTRL_0);
414*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(ctrl0))
415*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
416*6d67aabdSBjoern A. Zeeb 	cfg0 = rtw89_read32(rtwdev, R_BE_LTR_CFG_0);
417*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(cfg0))
418*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
419*6d67aabdSBjoern A. Zeeb 	cfg1 = rtw89_read32(rtwdev, R_BE_LTR_CFG_1);
420*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(cfg1))
421*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
422*6d67aabdSBjoern A. Zeeb 	dec_ctrl = rtw89_read32(rtwdev, R_BE_LTR_DECISION_CTRL_V1);
423*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(dec_ctrl))
424*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
425*6d67aabdSBjoern A. Zeeb 	idle_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1);
426*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(idle_ltcy))
427*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
428*6d67aabdSBjoern A. Zeeb 	act_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1);
429*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(act_ltcy))
430*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
431*6d67aabdSBjoern A. Zeeb 	dis_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1);
432*6d67aabdSBjoern A. Zeeb 	if (rtw89_pci_ltr_is_err_reg_val(dis_ltcy))
433*6d67aabdSBjoern A. Zeeb 		return -EINVAL;
434*6d67aabdSBjoern A. Zeeb 
435*6d67aabdSBjoern A. Zeeb 	if (en) {
436*6d67aabdSBjoern A. Zeeb 		dec_ctrl |= B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1;
437*6d67aabdSBjoern A. Zeeb 		ctrl0 |= B_BE_LTR_HW_EN;
438*6d67aabdSBjoern A. Zeeb 	} else {
439*6d67aabdSBjoern A. Zeeb 		dec_ctrl &= ~(B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1 |
440*6d67aabdSBjoern A. Zeeb 			      B_BE_LTR_EN_PORT_V1_MASK);
441*6d67aabdSBjoern A. Zeeb 		ctrl0 &= ~B_BE_LTR_HW_EN;
442*6d67aabdSBjoern A. Zeeb 	}
443*6d67aabdSBjoern A. Zeeb 
444*6d67aabdSBjoern A. Zeeb 	dec_ctrl = u32_replace_bits(dec_ctrl, PCI_LTR_SPC_500US,
445*6d67aabdSBjoern A. Zeeb 				    B_BE_LTR_SPACE_IDX_MASK);
446*6d67aabdSBjoern A. Zeeb 	cfg0 = u32_replace_bits(cfg0, PCI_LTR_IDLE_TIMER_3_2MS,
447*6d67aabdSBjoern A. Zeeb 				B_BE_LTR_IDLE_TIMER_IDX_MASK);
448*6d67aabdSBjoern A. Zeeb 	cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK);
449*6d67aabdSBjoern A. Zeeb 	cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK);
450*6d67aabdSBjoern A. Zeeb 	cfg0 = u32_replace_bits(cfg0, 1, B_BE_LTR_IDX_ACTIVE_MASK);
451*6d67aabdSBjoern A. Zeeb 	cfg0 = u32_replace_bits(cfg0, 3, B_BE_LTR_IDX_IDLE_MASK);
452*6d67aabdSBjoern A. Zeeb 	dec_ctrl = u32_replace_bits(dec_ctrl, 0, B_BE_LTR_IDX_DISABLE_V1_MASK);
453*6d67aabdSBjoern A. Zeeb 
454*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, 0x90039003);
455*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, 0x880b880b);
456*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1, 0);
457*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_DECISION_CTRL_V1, dec_ctrl);
458*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_CFG_0, cfg0);
459*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_CFG_1, cfg1);
460*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_LTR_CTRL_0, ctrl0);
461*6d67aabdSBjoern A. Zeeb 
462*6d67aabdSBjoern A. Zeeb 	return 0;
463*6d67aabdSBjoern A. Zeeb }
464*6d67aabdSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_pci_ltr_set_v2);
465*6d67aabdSBjoern A. Zeeb 
466*6d67aabdSBjoern A. Zeeb static void rtw89_pci_configure_mit_be(struct rtw89_dev *rtwdev)
467*6d67aabdSBjoern A. Zeeb {
468*6d67aabdSBjoern A. Zeeb 	u32 cnt;
469*6d67aabdSBjoern A. Zeeb 	u32 val;
470*6d67aabdSBjoern A. Zeeb 
471*6d67aabdSBjoern A. Zeeb 	rtw89_write32_mask(rtwdev, R_BE_PCIE_MIT0_TMR,
472*6d67aabdSBjoern A. Zeeb 			   B_BE_PCIE_MIT0_RX_TMR_MASK, BE_MIT0_TMR_UNIT_1MS);
473*6d67aabdSBjoern A. Zeeb 
474*6d67aabdSBjoern A. Zeeb 	val = rtw89_read32(rtwdev, R_BE_PCIE_MIT0_CNT);
475*6d67aabdSBjoern A. Zeeb 	cnt = min_t(u32, U8_MAX, RTW89_PCI_RXBD_NUM_MAX / 2);
476*6d67aabdSBjoern A. Zeeb 	val = u32_replace_bits(val, cnt, B_BE_PCIE_RX_MIT0_CNT_MASK);
477*6d67aabdSBjoern A. Zeeb 	val = u32_replace_bits(val, 2, B_BE_PCIE_RX_MIT0_TMR_CNT_MASK);
478*6d67aabdSBjoern A. Zeeb 	rtw89_write32(rtwdev, R_BE_PCIE_MIT0_CNT, val);
479*6d67aabdSBjoern A. Zeeb }
480*6d67aabdSBjoern A. Zeeb 
481*6d67aabdSBjoern A. Zeeb static int rtw89_pci_ops_mac_post_init_be(struct rtw89_dev *rtwdev)
482*6d67aabdSBjoern A. Zeeb {
483*6d67aabdSBjoern A. Zeeb 	const struct rtw89_pci_info *info = rtwdev->pci_info;
484*6d67aabdSBjoern A. Zeeb 	int ret;
485*6d67aabdSBjoern A. Zeeb 
486*6d67aabdSBjoern A. Zeeb 	ret = info->ltr_set(rtwdev, true);
487*6d67aabdSBjoern A. Zeeb 	if (ret) {
488*6d67aabdSBjoern A. Zeeb 		rtw89_err(rtwdev, "pci ltr set fail\n");
489*6d67aabdSBjoern A. Zeeb 		return ret;
490*6d67aabdSBjoern A. Zeeb 	}
491*6d67aabdSBjoern A. Zeeb 
492*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_IGNORE,
493*6d67aabdSBjoern A. Zeeb 				      MAC_AX_PCIE_IGNORE, MAC_AX_PCIE_ENABLE);
494*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, true);
495*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_txdma_ch_be(rtwdev, true);
496*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true);
497*6d67aabdSBjoern A. Zeeb 	rtw89_pci_configure_mit_be(rtwdev);
498*6d67aabdSBjoern A. Zeeb 
499*6d67aabdSBjoern A. Zeeb 	return 0;
500*6d67aabdSBjoern A. Zeeb }
501*6d67aabdSBjoern A. Zeeb 
502*6d67aabdSBjoern A. Zeeb static int rtw89_pci_poll_io_idle_be(struct rtw89_dev *rtwdev)
503*6d67aabdSBjoern A. Zeeb {
504*6d67aabdSBjoern A. Zeeb 	u32 sts;
505*6d67aabdSBjoern A. Zeeb 	int ret;
506*6d67aabdSBjoern A. Zeeb 
507*6d67aabdSBjoern A. Zeeb 	ret = read_poll_timeout_atomic(rtw89_read32, sts,
508*6d67aabdSBjoern A. Zeeb 				       !(sts & B_BE_HAXI_MST_BUSY),
509*6d67aabdSBjoern A. Zeeb 				       10, 1000, false, rtwdev,
510*6d67aabdSBjoern A. Zeeb 				       R_BE_HAXI_DMA_BUSY1);
511*6d67aabdSBjoern A. Zeeb 	if (ret) {
512*6d67aabdSBjoern A. Zeeb 		rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", sts);
513*6d67aabdSBjoern A. Zeeb 		return ret;
514*6d67aabdSBjoern A. Zeeb 	}
515*6d67aabdSBjoern A. Zeeb 
516*6d67aabdSBjoern A. Zeeb 	return 0;
517*6d67aabdSBjoern A. Zeeb }
518*6d67aabdSBjoern A. Zeeb 
519*6d67aabdSBjoern A. Zeeb static int rtw89_pci_lv1rst_stop_dma_be(struct rtw89_dev *rtwdev)
520*6d67aabdSBjoern A. Zeeb {
521*6d67aabdSBjoern A. Zeeb 	int ret;
522*6d67aabdSBjoern A. Zeeb 
523*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_dma_all(rtwdev, false);
524*6d67aabdSBjoern A. Zeeb 	ret = rtw89_pci_poll_io_idle_be(rtwdev);
525*6d67aabdSBjoern A. Zeeb 	if (!ret)
526*6d67aabdSBjoern A. Zeeb 		return 0;
527*6d67aabdSBjoern A. Zeeb 
528*6d67aabdSBjoern A. Zeeb 	rtw89_debug(rtwdev, RTW89_DBG_HCI,
529*6d67aabdSBjoern A. Zeeb 		    "[PCIe] poll_io_idle fail; reset hci dma trx\n");
530*6d67aabdSBjoern A. Zeeb 
531*6d67aabdSBjoern A. Zeeb 	rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
532*6d67aabdSBjoern A. Zeeb 	rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
533*6d67aabdSBjoern A. Zeeb 
534*6d67aabdSBjoern A. Zeeb 	return rtw89_pci_poll_io_idle_be(rtwdev);
535*6d67aabdSBjoern A. Zeeb }
536*6d67aabdSBjoern A. Zeeb 
537*6d67aabdSBjoern A. Zeeb static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
538*6d67aabdSBjoern A. Zeeb {
539*6d67aabdSBjoern A. Zeeb 	int ret;
540*6d67aabdSBjoern A. Zeeb 
541*6d67aabdSBjoern A. Zeeb 	rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
542*6d67aabdSBjoern A. Zeeb 	rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
543*6d67aabdSBjoern A. Zeeb 	rtw89_pci_clr_idx_all(rtwdev);
544*6d67aabdSBjoern A. Zeeb 
545*6d67aabdSBjoern A. Zeeb 	ret = rtw89_pci_rst_bdram_be(rtwdev);
546*6d67aabdSBjoern A. Zeeb 	if (ret)
547*6d67aabdSBjoern A. Zeeb 		return ret;
548*6d67aabdSBjoern A. Zeeb 
549*6d67aabdSBjoern A. Zeeb 	rtw89_pci_ctrl_dma_all(rtwdev, true);
550*6d67aabdSBjoern A. Zeeb 	return 0;
551*6d67aabdSBjoern A. Zeeb }
552*6d67aabdSBjoern A. Zeeb 
553*6d67aabdSBjoern A. Zeeb static int __maybe_unused rtw89_pci_suspend_be(struct device *dev)
554*6d67aabdSBjoern A. Zeeb {
555*6d67aabdSBjoern A. Zeeb 	struct ieee80211_hw *hw = dev_get_drvdata(dev);
556*6d67aabdSBjoern A. Zeeb 	struct rtw89_dev *rtwdev = hw->priv;
557*6d67aabdSBjoern A. Zeeb 
558*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
559*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST);
560*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
561*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST);
562*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);
563*6d67aabdSBjoern A. Zeeb 	return 0;
564*6d67aabdSBjoern A. Zeeb }
565*6d67aabdSBjoern A. Zeeb 
566*6d67aabdSBjoern A. Zeeb static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
567*6d67aabdSBjoern A. Zeeb {
568*6d67aabdSBjoern A. Zeeb 	struct ieee80211_hw *hw = dev_get_drvdata(dev);
569*6d67aabdSBjoern A. Zeeb 	struct rtw89_dev *rtwdev = hw->priv;
570*6d67aabdSBjoern A. Zeeb 	u32 polling;
571*6d67aabdSBjoern A. Zeeb 	int ret;
572*6d67aabdSBjoern A. Zeeb 
573*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
574*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST);
575*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
576*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST);
577*6d67aabdSBjoern A. Zeeb 	rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
578*6d67aabdSBjoern A. Zeeb 
579*6d67aabdSBjoern A. Zeeb 	ret = read_poll_timeout_atomic(rtw89_read32, polling, !polling, 1, 1000,
580*6d67aabdSBjoern A. Zeeb 				       false, rtwdev, R_BE_REG_PL1_ISR);
581*6d67aabdSBjoern A. Zeeb 	if (ret)
582*6d67aabdSBjoern A. Zeeb 		rtw89_warn(rtwdev, "[ERR] PCIE SER clear polling fail\n");
583*6d67aabdSBjoern A. Zeeb 
584*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
585*6d67aabdSBjoern A. Zeeb 	rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);
586*6d67aabdSBjoern A. Zeeb 
587*6d67aabdSBjoern A. Zeeb 	return 0;
588*6d67aabdSBjoern A. Zeeb }
589*6d67aabdSBjoern A. Zeeb 
590*6d67aabdSBjoern A. Zeeb SIMPLE_DEV_PM_OPS(rtw89_pm_ops_be, rtw89_pci_suspend_be, rtw89_pci_resume_be);
591*6d67aabdSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_pm_ops_be);
592*6d67aabdSBjoern A. Zeeb 
593*6d67aabdSBjoern A. Zeeb const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
594*6d67aabdSBjoern A. Zeeb 	.isr_rdu = B_BE_RDU_CH1_INT | B_BE_RDU_CH0_INT,
595*6d67aabdSBjoern A. Zeeb 	.isr_halt_c2h = B_BE_HALT_C2H_INT,
596*6d67aabdSBjoern A. Zeeb 	.isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT,
597*6d67aabdSBjoern A. Zeeb 	.isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
598*6d67aabdSBjoern A. Zeeb 	.isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1},
599*6d67aabdSBjoern A. Zeeb 
600*6d67aabdSBjoern A. Zeeb 	.mac_pre_init = rtw89_pci_ops_mac_pre_init_be,
601*6d67aabdSBjoern A. Zeeb 	.mac_pre_deinit = rtw89_pci_ops_mac_pre_deinit_be,
602*6d67aabdSBjoern A. Zeeb 	.mac_post_init = rtw89_pci_ops_mac_post_init_be,
603*6d67aabdSBjoern A. Zeeb 
604*6d67aabdSBjoern A. Zeeb 	.clr_idx_all = rtw89_pci_clr_idx_all_be,
605*6d67aabdSBjoern A. Zeeb 	.rst_bdram = rtw89_pci_rst_bdram_be,
606*6d67aabdSBjoern A. Zeeb 
607*6d67aabdSBjoern A. Zeeb 	.lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_be,
608*6d67aabdSBjoern A. Zeeb 	.lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_be,
609*6d67aabdSBjoern A. Zeeb 
610*6d67aabdSBjoern A. Zeeb 	.ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_be,
611*6d67aabdSBjoern A. Zeeb 	.ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_be,
612*6d67aabdSBjoern A. Zeeb 	.poll_txdma_ch_idle = rtw89_pci_poll_txdma_ch_idle_be,
613*6d67aabdSBjoern A. Zeeb 
614*6d67aabdSBjoern A. Zeeb 	.aspm_set = rtw89_pci_aspm_set_be,
615*6d67aabdSBjoern A. Zeeb 	.clkreq_set = rtw89_pci_clkreq_set_be,
616*6d67aabdSBjoern A. Zeeb 	.l1ss_set = rtw89_pci_l1ss_set_be,
617*6d67aabdSBjoern A. Zeeb };
618*6d67aabdSBjoern A. Zeeb EXPORT_SYMBOL(rtw89_pci_gen_be);
619