// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2023  Realtek Corporation
 */

#include <linux/pci.h>

#include "mac.h"
#include "pci.h"
#include "reg.h"

enum pcie_rxbd_mode {
	PCIE_RXBD_NORM = 0,
	PCIE_RXBD_SEP,
	PCIE_RXBD_EXT,
};

#define PL0_TMR_SCALE_ASIC 1
#define PL0_TMR_ANA_172US 0x800
#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)
		rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1);
	else
		rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, BIT_WAKE_CTRL_V1);
}

static void rtw89_pci_set_io_rcy_be(struct rtw89_dev *rtwdev)
{
	const struct rtw89_pci_info *info = rtwdev->pci_info;
	u32 scale = PL0_TMR_SCALE_ASIC;
	u32 val32;

	if (info->io_rcy_en == MAC_AX_PCIE_ENABLE) {
		val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
			PL0_TMR_ANA_172US : info->io_rcy_tmr;
		val32 /= scale;

		rtw89_write32(rtwdev, R_BE_AON_WDT_TMR, val32);
		rtw89_write32(rtwdev, R_BE_MDIO_WDT_TMR, val32);
		rtw89_write32(rtwdev, R_BE_LA_MODE_WDT_TMR, val32);
		rtw89_write32(rtwdev, R_BE_WDT_AR_TMR, val32);
		rtw89_write32(rtwdev, R_BE_WDT_AW_TMR, val32);
		rtw89_write32(rtwdev, R_BE_WDT_W_TMR, val32);
		rtw89_write32(rtwdev, R_BE_WDT_B_TMR, val32);
		rtw89_write32(rtwdev, R_BE_WDT_R_TMR, val32);

		val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
			PL0_TMR_MAC_1MS : info->io_rcy_tmr;
		val32 /= scale;
		rtw89_write32(rtwdev, R_BE_WLAN_WDT_TMR, val32);
		rtw89_write32(rtwdev, R_BE_AXIDMA_WDT_TMR, val32);

		val32 = info->io_rcy_tmr == MAC_AX_IO_RCY_ANA_TMR_DEF ?
			PL0_TMR_AUX_1MS : info->io_rcy_tmr;
		val32 /= scale;
		rtw89_write32(rtwdev, R_BE_LOCAL_WDT_TMR, val32);
	} else {
		rtw89_write32_clr(rtwdev, R_BE_WLAN_WDT, B_BE_WLAN_WDT_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_AXIDMA_WDT, B_BE_AXIDMA_WDT_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_AON_WDT, B_BE_AON_WDT_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_LOCAL_WDT, B_BE_LOCAL_WDT_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_MDIO_WDT, B_BE_MDIO_WDT_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_LA_MODE_WDT, B_BE_LA_MODE_WDT_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_WDT_AR, B_BE_WDT_AR_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_WDT_AW, B_BE_WDT_AW_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_WDT_W, B_BE_WDT_W_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_WDT_B, B_BE_WDT_B_ENABLE);
		rtw89_write32_clr(rtwdev, R_BE_WDT_R, B_BE_WDT_R_ENABLE);
	}
}

static void rtw89_pci_ctrl_wpdma_pcie_be(struct rtw89_dev *rtwdev, bool en)
{
	if (en)
		rtw89_write32_clr(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA);
	else
		rtw89_write32_set(rtwdev, R_BE_HAXI_DMA_STOP1, B_BE_STOP_WPDMA);
}

static void rtw89_pci_ctrl_trxdma_pcie_be(struct rtw89_dev *rtwdev,
					  enum mac_ax_pcie_func_ctrl tx_en,
					  enum mac_ax_pcie_func_ctrl rx_en,
					  enum mac_ax_pcie_func_ctrl io_en)
{
	u32 val;

	val = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);

	if (tx_en == MAC_AX_PCIE_ENABLE)
		val |= B_BE_TXDMA_EN;
	else if (tx_en == MAC_AX_PCIE_DISABLE)
		val &= ~B_BE_TXDMA_EN;

	if (rx_en == MAC_AX_PCIE_ENABLE)
		val |= B_BE_RXDMA_EN;
	else if (rx_en == MAC_AX_PCIE_DISABLE)
		val &= ~B_BE_RXDMA_EN;

	if (io_en == MAC_AX_PCIE_ENABLE)
		val &= ~B_BE_STOP_AXI_MST;
	else if (io_en == MAC_AX_PCIE_DISABLE)
		val |= B_BE_STOP_AXI_MST;

	rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val);

	if (io_en == MAC_AX_PCIE_ENABLE)
		rtw89_write32_mask(rtwdev, R_BE_HAXI_MST_WDT_TIMEOUT_SEL_V1,
				   B_BE_HAXI_MST_WDT_TIMEOUT_SEL_MASK, 4);
}

static void rtw89_pci_clr_idx_all_be(struct rtw89_dev *rtwdev)
{
	struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
	struct rtw89_pci_rx_ring *rx_ring;
	u32 val;

	val = B_BE_CLR_CH0_IDX | B_BE_CLR_CH1_IDX | B_BE_CLR_CH2_IDX |
	      B_BE_CLR_CH3_IDX | B_BE_CLR_CH4_IDX | B_BE_CLR_CH5_IDX |
	      B_BE_CLR_CH6_IDX | B_BE_CLR_CH7_IDX | B_BE_CLR_CH8_IDX |
	      B_BE_CLR_CH9_IDX | B_BE_CLR_CH10_IDX | B_BE_CLR_CH11_IDX |
	      B_BE_CLR_CH12_IDX | B_BE_CLR_CH13_IDX | B_BE_CLR_CH14_IDX;
	rtw89_write32(rtwdev, R_BE_TXBD_RWPTR_CLR1, val);

	rtw89_write32(rtwdev, R_BE_RXBD_RWPTR_CLR1_V1,
		      B_BE_CLR_RXQ0_IDX | B_BE_CLR_RPQ0_IDX);

	rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RXQ];
	rtw89_write16(rtwdev, R_BE_RXQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1);

	rx_ring = &rtwpci->rx_rings[RTW89_RXCH_RPQ];
	rtw89_write16(rtwdev, R_BE_RPQ0_RXBD_IDX_V1, rx_ring->bd_ring.len - 1);
}

static int rtw89_pci_poll_txdma_ch_idle_be(struct rtw89_dev *rtwdev)
{
	u32 val;

	return read_poll_timeout(rtw89_read32, val, (val & DMA_BUSY1_CHECK_BE) == 0,
				 10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1);
}

static int rtw89_pci_poll_rxdma_ch_idle_be(struct rtw89_dev *rtwdev)
{
	u32 check;
	u32 val;

	check = B_BE_RXQ0_BUSY_V1 | B_BE_RPQ0_BUSY_V1;

	return read_poll_timeout(rtw89_read32, val, (val & check) == 0,
				 10, 1000, false, rtwdev, R_BE_HAXI_DMA_BUSY1);
}

static int rtw89_pci_poll_dma_all_idle_be(struct rtw89_dev *rtwdev)
{
	int ret;

	ret = rtw89_pci_poll_txdma_ch_idle_be(rtwdev);
	if (ret) {
		rtw89_err(rtwdev, "txdma ch busy\n");
		return ret;
	}

	ret = rtw89_pci_poll_rxdma_ch_idle_be(rtwdev);
	if (ret) {
		rtw89_err(rtwdev, "rxdma ch busy\n");
		return ret;
	}

	return 0;
}

static void rtw89_pci_mode_op_be(struct rtw89_dev *rtwdev)
{
	const struct rtw89_pci_info *info = rtwdev->pci_info;
	u32 val32_init1, val32_rxapp, val32_exp;

	val32_init1 = rtw89_read32(rtwdev, R_BE_HAXI_INIT_CFG1);
	val32_rxapp = rtw89_read32(rtwdev, R_BE_RX_APPEND_MODE);
	val32_exp = rtw89_read32(rtwdev, R_BE_HAXI_EXP_CTRL_V1);

	if (info->rxbd_mode == MAC_AX_RXBD_PKT) {
		val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_NORM,
					       B_BE_RXQ_RXBD_MODE_MASK);
	} else if (info->rxbd_mode == MAC_AX_RXBD_SEP) {
		val32_init1 = u32_replace_bits(val32_init1, PCIE_RXBD_SEP,
					       B_BE_RXQ_RXBD_MODE_MASK);
		val32_rxapp = u32_replace_bits(val32_rxapp, 0,
					       B_BE_APPEND_LEN_MASK);
	}

	val32_init1 = u32_replace_bits(val32_init1, info->tx_burst,
				       B_BE_MAX_TXDMA_MASK);
	val32_init1 = u32_replace_bits(val32_init1, info->rx_burst,
				       B_BE_MAX_RXDMA_MASK);
	val32_exp = u32_replace_bits(val32_exp, info->multi_tag_num,
				     B_BE_MAX_TAG_NUM_MASK);
	val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_idle_intvl,
				       B_BE_CFG_WD_PERIOD_IDLE_MASK);
	val32_init1 = u32_replace_bits(val32_init1, info->wd_dma_act_intvl,
				       B_BE_CFG_WD_PERIOD_ACTIVE_MASK);

	rtw89_write32(rtwdev, R_BE_HAXI_INIT_CFG1, val32_init1);
	rtw89_write32(rtwdev, R_BE_RX_APPEND_MODE, val32_rxapp);
	rtw89_write32(rtwdev, R_BE_HAXI_EXP_CTRL_V1, val32_exp);
}

static int rtw89_pci_rst_bdram_be(struct rtw89_dev *rtwdev)
{
	u32 val;

	rtw89_write32_set(rtwdev, R_BE_HAXI_INIT_CFG1, B_BE_SET_BDRAM_BOUND);

	return read_poll_timeout(rtw89_read32, val, !(val & B_BE_SET_BDRAM_BOUND),
				 50, 500000, false, rtwdev, R_BE_HAXI_INIT_CFG1);
}

static void rtw89_pci_debounce_be(struct rtw89_dev *rtwdev)
{
	u32 val32;

	val32 = rtw89_read32(rtwdev, R_BE_SYS_PAGE_CLK_GATED);
	val32 = u32_replace_bits(val32, 0, B_BE_PCIE_PRST_DEBUNC_PERIOD_MASK);
	val32 |= B_BE_SYM_PRST_DEBUNC_SEL;
	rtw89_write32(rtwdev, R_BE_SYS_PAGE_CLK_GATED, val32);
}

static void rtw89_pci_ldo_low_pwr_be(struct rtw89_dev *rtwdev)
{
	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_PSUS_OFF_CAPC_EN);
	rtw89_write32_set(rtwdev, R_BE_SYS_PAGE_CLK_GATED,
			  B_BE_SOP_OFFPOOBS_PC | B_BE_CPHY_AUXCLK_OP |
			  B_BE_CPHY_POWER_READY_CHK);
	rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN |
						      B_BE_PCIE_DIS_L2_RTK_PERST |
						      B_BE_PCIE_DIS_L2__CTRL_LDO_HCI);
	rtw89_write32_clr(rtwdev, R_BE_L1_2_CTRL_HCILDO, B_BE_PCIE_DIS_L1_2_CTRL_HCILDO);
}

static void rtw89_pci_pcie_setting_be(struct rtw89_dev *rtwdev)
{
	const struct rtw89_chip_info *chip = rtwdev->chip;
	struct rtw89_hal *hal = &rtwdev->hal;

	rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_EN_AUX_CLK);
	rtw89_write32_clr(rtwdev, R_BE_PCIE_PS_CTRL, B_BE_CMAC_EXIT_L1_EN);

	if (chip->chip_id == RTL8922A && hal->cv == CHIP_CAV)
		return;

	rtw89_write32_set(rtwdev, R_BE_EFUSE_CTRL_2_V1, B_BE_R_SYM_AUTOLOAD_WITH_PMC_SEL);
	rtw89_write32_set(rtwdev, R_BE_PCIE_LAT_CTRL, B_BE_SYM_AUX_CLK_SEL);
}

static void rtw89_pci_ser_setting_be(struct rtw89_dev *rtwdev)
{
	u32 val32;

	rtw89_write32(rtwdev, R_BE_PL1_DBG_INFO, 0x0);
	rtw89_write32_set(rtwdev, R_BE_FWS1IMR, B_BE_PCIE_SER_TIMEOUT_INDIC_EN);
	rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
	rtw89_write32_mask(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_TIMER_UNIT_MASK, 1);

	val32 = rtw89_read32(rtwdev, R_BE_REG_PL1_MASK);
	val32 |= B_BE_SER_PMU_IMR | B_BE_SER_L1SUB_IMR | B_BE_SER_PM_MASTER_IMR |
		 B_BE_SER_LTSSM_IMR | B_BE_SER_PM_CLK_MASK | B_BE_SER_PCLKREQ_ACK_MASK;
	rtw89_write32(rtwdev, R_BE_REG_PL1_MASK, val32);
}

static void rtw89_pci_ctrl_txdma_ch_be(struct rtw89_dev *rtwdev, bool enable)
{
	u32 mask_all;
	u32 val;

	mask_all = B_BE_STOP_CH0 | B_BE_STOP_CH1 | B_BE_STOP_CH2 |
		   B_BE_STOP_CH3 | B_BE_STOP_CH4 | B_BE_STOP_CH5 |
		   B_BE_STOP_CH6 | B_BE_STOP_CH7 | B_BE_STOP_CH8 |
		   B_BE_STOP_CH9 | B_BE_STOP_CH10 | B_BE_STOP_CH11;

	val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1);
	val |= B_BE_STOP_CH13 | B_BE_STOP_CH14;

	if (enable)
		val &= ~mask_all;
	else
		val |= mask_all;

	rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val);
}

static void rtw89_pci_ctrl_txdma_fw_ch_be(struct rtw89_dev *rtwdev, bool enable)
{
	u32 val = rtw89_read32(rtwdev, R_BE_HAXI_DMA_STOP1);

	if (enable)
		val &= ~B_BE_STOP_CH12;
	else
		val |= B_BE_STOP_CH12;

	rtw89_write32(rtwdev, R_BE_HAXI_DMA_STOP1, val);
}

static int rtw89_pci_ops_mac_pre_init_be(struct rtw89_dev *rtwdev)
{
	int ret;

	rtw89_pci_set_io_rcy_be(rtwdev);
	_patch_pcie_power_wake_be(rtwdev, true);
	rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, false);
	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);

	ret = rtw89_pci_poll_dma_all_idle_be(rtwdev);
	if (ret) {
		rtw89_err(rtwdev, "[ERR] poll pcie dma all idle\n");
		return ret;
	}

	rtw89_pci_mode_op_be(rtwdev);
	rtw89_pci_ops_reset(rtwdev);

	ret = rtw89_pci_rst_bdram_be(rtwdev);
	if (ret) {
		rtw89_err(rtwdev, "[ERR]pcie rst bdram\n");
		return ret;
	}

	rtw89_pci_debounce_be(rtwdev);
	rtw89_pci_ldo_low_pwr_be(rtwdev);
	rtw89_pci_pcie_setting_be(rtwdev);
	rtw89_pci_ser_setting_be(rtwdev);

	rtw89_pci_ctrl_txdma_ch_be(rtwdev, false);
	rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true);
	rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_ENABLE,
				      MAC_AX_PCIE_ENABLE, MAC_AX_PCIE_ENABLE);

	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;

	ctrl0 = rtw89_read32(rtwdev, R_BE_LTR_CTRL_0);
	if (rtw89_pci_ltr_is_err_reg_val(ctrl0))
		return -EINVAL;
	cfg0 = rtw89_read32(rtwdev, R_BE_LTR_CFG_0);
	if (rtw89_pci_ltr_is_err_reg_val(cfg0))
		return -EINVAL;
	cfg1 = rtw89_read32(rtwdev, R_BE_LTR_CFG_1);
	if (rtw89_pci_ltr_is_err_reg_val(cfg1))
		return -EINVAL;
	dec_ctrl = rtw89_read32(rtwdev, R_BE_LTR_DECISION_CTRL_V1);
	if (rtw89_pci_ltr_is_err_reg_val(dec_ctrl))
		return -EINVAL;
	idle_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1);
	if (rtw89_pci_ltr_is_err_reg_val(idle_ltcy))
		return -EINVAL;
	act_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1);
	if (rtw89_pci_ltr_is_err_reg_val(act_ltcy))
		return -EINVAL;
	dis_ltcy = rtw89_read32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1);
	if (rtw89_pci_ltr_is_err_reg_val(dis_ltcy))
		return -EINVAL;

	if (en) {
		dec_ctrl |= B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1;
		ctrl0 |= B_BE_LTR_HW_EN;
	} else {
		dec_ctrl &= ~(B_BE_ENABLE_LTR_CTL_DECISION | B_BE_LTR_HW_DEC_EN_V1 |
			      B_BE_LTR_EN_PORT_V1_MASK);
		ctrl0 &= ~B_BE_LTR_HW_EN;
	}

	dec_ctrl = u32_replace_bits(dec_ctrl, PCI_LTR_SPC_500US,
				    B_BE_LTR_SPACE_IDX_MASK);
	cfg0 = u32_replace_bits(cfg0, PCI_LTR_IDLE_TIMER_3_2MS,
				B_BE_LTR_IDLE_TIMER_IDX_MASK);
	cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC0_RX_USE_PG_TH_MASK);
	cfg1 = u32_replace_bits(cfg1, 0xC0, B_BE_LTR_CMAC1_RX_USE_PG_TH_MASK);
	cfg0 = u32_replace_bits(cfg0, 1, B_BE_LTR_IDX_ACTIVE_MASK);
	cfg0 = u32_replace_bits(cfg0, 3, B_BE_LTR_IDX_IDLE_MASK);
	dec_ctrl = u32_replace_bits(dec_ctrl, 0, B_BE_LTR_IDX_DISABLE_V1_MASK);

	rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX3_V1, 0x90039003);
	rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX1_V1, 0x880b880b);
	rtw89_write32(rtwdev, R_BE_LTR_LATENCY_IDX0_V1, 0);
	rtw89_write32(rtwdev, R_BE_LTR_DECISION_CTRL_V1, dec_ctrl);
	rtw89_write32(rtwdev, R_BE_LTR_CFG_0, cfg0);
	rtw89_write32(rtwdev, R_BE_LTR_CFG_1, cfg1);
	rtw89_write32(rtwdev, R_BE_LTR_CTRL_0, ctrl0);

	return 0;
}
EXPORT_SYMBOL(rtw89_pci_ltr_set_v2);

static void rtw89_pci_configure_mit_be(struct rtw89_dev *rtwdev)
{
	u32 cnt;
	u32 val;

	rtw89_write32_mask(rtwdev, R_BE_PCIE_MIT0_TMR,
			   B_BE_PCIE_MIT0_RX_TMR_MASK, BE_MIT0_TMR_UNIT_1MS);

	val = rtw89_read32(rtwdev, R_BE_PCIE_MIT0_CNT);
	cnt = min_t(u32, U8_MAX, RTW89_PCI_RXBD_NUM_MAX / 2);
	val = u32_replace_bits(val, cnt, B_BE_PCIE_RX_MIT0_CNT_MASK);
	val = u32_replace_bits(val, 2, B_BE_PCIE_RX_MIT0_TMR_CNT_MASK);
	rtw89_write32(rtwdev, R_BE_PCIE_MIT0_CNT, val);
}

static int rtw89_pci_ops_mac_post_init_be(struct rtw89_dev *rtwdev)
{
	const struct rtw89_pci_info *info = rtwdev->pci_info;
	int ret;

	ret = info->ltr_set(rtwdev, true);
	if (ret) {
		rtw89_err(rtwdev, "pci ltr set fail\n");
		return ret;
	}

	rtw89_pci_ctrl_trxdma_pcie_be(rtwdev, MAC_AX_PCIE_IGNORE,
				      MAC_AX_PCIE_IGNORE, MAC_AX_PCIE_ENABLE);
	rtw89_pci_ctrl_wpdma_pcie_be(rtwdev, true);
	rtw89_pci_ctrl_txdma_ch_be(rtwdev, true);
	rtw89_pci_ctrl_txdma_fw_ch_be(rtwdev, true);
	rtw89_pci_configure_mit_be(rtwdev);

	return 0;
}

static int rtw89_pci_poll_io_idle_be(struct rtw89_dev *rtwdev)
{
	u32 sts;
	int ret;

	ret = read_poll_timeout_atomic(rtw89_read32, sts,
				       !(sts & B_BE_HAXI_MST_BUSY),
				       10, 1000, false, rtwdev,
				       R_BE_HAXI_DMA_BUSY1);
	if (ret) {
		rtw89_err(rtwdev, "pci dmach busy1 0x%X\n", sts);
		return ret;
	}

	return 0;
}

static int rtw89_pci_lv1rst_stop_dma_be(struct rtw89_dev *rtwdev)
{
	int ret;

	rtw89_pci_ctrl_dma_all(rtwdev, false);
	ret = rtw89_pci_poll_io_idle_be(rtwdev);
	if (!ret)
		return 0;

	rtw89_debug(rtwdev, RTW89_DBG_HCI,
		    "[PCIe] poll_io_idle fail; reset hci dma trx\n");

	rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
	rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);

	return rtw89_pci_poll_io_idle_be(rtwdev);
}

static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
{
	int ret;

	rtw89_mac_ctrl_hci_dma_trx(rtwdev, false);
	rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
	rtw89_pci_clr_idx_all(rtwdev);

	ret = rtw89_pci_rst_bdram_be(rtwdev);
	if (ret)
		return ret;

	rtw89_pci_ctrl_dma_all(rtwdev, true);
	return 0;
}

static int __maybe_unused rtw89_pci_suspend_be(struct device *dev)
{
	struct ieee80211_hw *hw = dev_get_drvdata(dev);
	struct rtw89_dev *rtwdev = hw->priv;

	rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
	rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST);
	rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
	rtw89_write32_set(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST);
	rtw89_write32_clr(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);
	return 0;
}

static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
{
	struct ieee80211_hw *hw = dev_get_drvdata(dev);
	struct rtw89_dev *rtwdev = hw->priv;
	u32 polling;
	int ret;

	rtw89_write32_set(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
	rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_R_DIS_PRST);
	rtw89_write32_clr(rtwdev, R_BE_RSV_CTRL, B_BE_WLOCK_1C_BIT6);
	rtw89_write32_clr(rtwdev, R_BE_PCIE_FRZ_CLK, B_BE_PCIE_FRZ_REG_RST);
	rtw89_write32_clr(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);

	ret = read_poll_timeout_atomic(rtw89_read32, polling, !polling, 1, 1000,
				       false, rtwdev, R_BE_REG_PL1_ISR);
	if (ret)
		rtw89_warn(rtwdev, "[ERR] PCIE SER clear polling fail\n");

	rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
	rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);

	return 0;
}

SIMPLE_DEV_PM_OPS(rtw89_pm_ops_be, rtw89_pci_suspend_be, rtw89_pci_resume_be);
EXPORT_SYMBOL(rtw89_pm_ops_be);

const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
	.isr_rdu = B_BE_RDU_CH1_INT | B_BE_RDU_CH0_INT,
	.isr_halt_c2h = B_BE_HALT_C2H_INT,
	.isr_wdt_timeout = B_BE_WDT_TIMEOUT_INT,
	.isr_clear_rpq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RPQ0_ISR_V1},
	.isr_clear_rxq = {R_BE_PCIE_DMA_ISR, B_BE_PCIE_RX_RX0P2_ISR_V1},

	.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,
	.rst_bdram = rtw89_pci_rst_bdram_be,

	.lv1rst_stop_dma = rtw89_pci_lv1rst_stop_dma_be,
	.lv1rst_start_dma = rtw89_pci_lv1rst_start_dma_be,

	.ctrl_txdma_ch = rtw89_pci_ctrl_txdma_ch_be,
	.ctrl_txdma_fw_ch = rtw89_pci_ctrl_txdma_fw_ch_be,
	.poll_txdma_ch_idle = rtw89_pci_poll_txdma_ch_idle_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);
