// SPDX-License-Identifier: GPL-2.0-or-later
/* Driver for Realtek PCI-Express card reader
 *
 * Copyright(c) 2018-2019 Realtek Semiconductor Corp. All rights reserved.
 *
 * Author:
 *   Rui FENG <rui_feng@realsil.com.cn>
 *   Wei WANG <wei_wang@realsil.com.cn>
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/rtsx_pci.h>

#include "rts5261.h"
#include "rtsx_pcr.h"

static u8 rts5261_get_ic_version(struct rtsx_pcr *pcr)
{
	u8 val;

	rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
	return val & IC_VERSION_MASK;
}

static void rts5261_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
{
	u8 driving_3v3[4][3] = {
		{0x96, 0x96, 0x96},
		{0x96, 0x96, 0x96},
		{0x7F, 0x7F, 0x7F},
		{0x13, 0x13, 0x13},
	};
	u8 driving_1v8[4][3] = {
		{0xB3, 0xB3, 0xB3},
		{0x3A, 0x3A, 0x3A},
		{0xE6, 0xE6, 0xE6},
		{0x99, 0x99, 0x99},
	};
	u8 (*driving)[3], drive_sel;

	if (voltage == OUTPUT_3V3) {
		driving = driving_3v3;
		drive_sel = pcr->sd30_drive_sel_3v3;
	} else {
		driving = driving_1v8;
		drive_sel = pcr->sd30_drive_sel_1v8;
	}

	rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL,
			 0xFF, driving[drive_sel][0]);

	rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
			 0xFF, driving[drive_sel][1]);

	rtsx_pci_write_register(pcr, SD30_DAT_DRIVE_SEL,
			 0xFF, driving[drive_sel][2]);
}

static void rtsx5261_fetch_vendor_settings(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	u32 reg;

	/* 0x814~0x817 */
	pci_read_config_dword(pdev, PCR_SETTING_REG2, &reg);
	pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);

	if (!rts5261_vendor_setting_valid(reg)) {
		/* Not support MMC default */
		pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
		pcr_dbg(pcr, "skip fetch vendor setting\n");
		return;
	}

	if (!rts5261_reg_check_mmc_support(reg))
		pcr->extra_caps |= EXTRA_CAPS_NO_MMC;

	/* TO do: need to add rtd3 function */
	pcr->rtd3_en = rts5261_reg_to_rtd3(reg);

	if (rts5261_reg_check_reverse_socket(reg))
		pcr->flags |= PCR_REVERSE_SOCKET;

	/* 0x724~0x727 */
	pci_read_config_dword(pdev, PCR_SETTING_REG1, &reg);
	pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);

	pcr->aspm_en = rts5261_reg_to_aspm(reg);
	pcr->sd30_drive_sel_1v8 = rts5261_reg_to_sd30_drive_sel_1v8(reg);
	pcr->sd30_drive_sel_3v3 = rts5261_reg_to_sd30_drive_sel_3v3(reg);
}

static void rts5261_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
{
	/* Set relink_time to 0 */
	rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0);
	rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0);
	rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3,
				RELINK_TIME_MASK, 0);

	if (pm_state == HOST_ENTER_S3)
		rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3,
					D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);

	rtsx_pci_write_register(pcr, RTS5261_REG_FPDCTL,
		SSC_POWER_DOWN, SSC_POWER_DOWN);
}

static int rts5261_enable_auto_blink(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_register(pcr, OLT_LED_CTL,
		LED_SHINE_MASK, LED_SHINE_EN);
}

static int rts5261_disable_auto_blink(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_register(pcr, OLT_LED_CTL,
		LED_SHINE_MASK, LED_SHINE_DISABLE);
}

static int rts5261_turn_on_led(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_register(pcr, GPIO_CTL,
		0x02, 0x02);
}

static int rts5261_turn_off_led(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_register(pcr, GPIO_CTL,
		0x02, 0x00);
}

/* SD Pull Control Enable:
 *     SD_DAT[3:0] ==> pull up
 *     SD_CD       ==> pull up
 *     SD_WP       ==> pull up
 *     SD_CMD      ==> pull up
 *     SD_CLK      ==> pull down
 */
static const u32 rts5261_sd_pull_ctl_enable_tbl[] = {
	RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
	RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
	0,
};

/* SD Pull Control Disable:
 *     SD_DAT[3:0] ==> pull down
 *     SD_CD       ==> pull up
 *     SD_WP       ==> pull down
 *     SD_CMD      ==> pull down
 *     SD_CLK      ==> pull down
 */
static const u32 rts5261_sd_pull_ctl_disable_tbl[] = {
	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
	RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
	0,
};

static int rts5261_sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr)
{
	rtsx_pci_write_register(pcr, SD_CFG1, SD_MODE_SELECT_MASK
		| SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
	rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
	rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF,
			CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
	rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);

	return 0;
}

static int rts5261_card_power_on(struct rtsx_pcr *pcr, int card)
{
	struct rtsx_cr_option *option = &pcr->option;

	if (option->ocp_en)
		rtsx_pci_enable_ocp(pcr);

	rtsx_pci_write_register(pcr, REG_CRC_DUMMY_0,
		CFG_SD_POW_AUTO_PD, CFG_SD_POW_AUTO_PD);

	rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG1,
			RTS5261_LDO1_TUNE_MASK, RTS5261_LDO1_33);
	rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL,
			RTS5261_LDO1_POWERON, RTS5261_LDO1_POWERON);

	rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL,
			RTS5261_LDO3318_POWERON, RTS5261_LDO3318_POWERON);

	msleep(20);

	rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN);

	/* Initialize SD_CFG1 register */
	rtsx_pci_write_register(pcr, SD_CFG1, 0xFF,
			SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1BIT);

	rtsx_pci_write_register(pcr, SD_SAMPLE_POINT_CTL,
			0xFF, SD20_RX_POS_EDGE);
	rtsx_pci_write_register(pcr, SD_PUSH_POINT_CTL, 0xFF, 0);
	rtsx_pci_write_register(pcr, CARD_STOP, SD_STOP | SD_CLR_ERR,
			SD_STOP | SD_CLR_ERR);

	/* Reset SD_CFG3 register */
	rtsx_pci_write_register(pcr, SD_CFG3, SD30_CLK_END_EN, 0);
	rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG,
			SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 |
			SD30_CLK_STOP_CFG0, 0);

	if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
	    pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
		rts5261_sd_set_sample_push_timing_sd30(pcr);

	return 0;
}

static int rts5261_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
	int err;
	u16 val = 0;

	rtsx_pci_write_register(pcr, RTS5261_CARD_PWR_CTL,
			RTS5261_PUPDC, RTS5261_PUPDC);

	switch (voltage) {
	case OUTPUT_3V3:
		rtsx_pci_read_phy_register(pcr, PHY_TUNE, &val);
		val |= PHY_TUNE_SDBUS_33;
		err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, val);
		if (err < 0)
			return err;

		rtsx_pci_write_register(pcr, RTS5261_DV3318_CFG,
				RTS5261_DV3318_TUNE_MASK, RTS5261_DV3318_33);
		rtsx_pci_write_register(pcr, SD_PAD_CTL,
				SD_IO_USING_1V8, 0);
		break;
	case OUTPUT_1V8:
		rtsx_pci_read_phy_register(pcr, PHY_TUNE, &val);
		val &= ~PHY_TUNE_SDBUS_33;
		err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, val);
		if (err < 0)
			return err;

		rtsx_pci_write_register(pcr, RTS5261_DV3318_CFG,
				RTS5261_DV3318_TUNE_MASK, RTS5261_DV3318_18);
		rtsx_pci_write_register(pcr, SD_PAD_CTL,
				SD_IO_USING_1V8, SD_IO_USING_1V8);
		break;
	default:
		return -EINVAL;
	}

	/* set pad drive */
	rts5261_fill_driving(pcr, voltage);

	return 0;
}

static void rts5261_stop_cmd(struct rtsx_pcr *pcr)
{
	rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
	rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
	rtsx_pci_write_register(pcr, RTS5260_DMA_RST_CTL_0,
				RTS5260_DMA_RST | RTS5260_ADMA3_RST,
				RTS5260_DMA_RST | RTS5260_ADMA3_RST);
	rtsx_pci_write_register(pcr, RBCTL, RB_FLUSH, RB_FLUSH);
}

static void rts5261_card_before_power_off(struct rtsx_pcr *pcr)
{
	rts5261_stop_cmd(pcr);
	rts5261_switch_output_voltage(pcr, OUTPUT_3V3);

}

static void rts5261_enable_ocp(struct rtsx_pcr *pcr)
{
	u8 val = 0;

	val = SD_OCP_INT_EN | SD_DETECT_EN;
	rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
			RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN,
			RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN);
	rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);

}

static void rts5261_disable_ocp(struct rtsx_pcr *pcr)
{
	u8 mask = 0;

	mask = SD_OCP_INT_EN | SD_DETECT_EN;
	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
	rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
			RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN, 0);

}

static int rts5261_card_power_off(struct rtsx_pcr *pcr, int card)
{
	int err = 0;

	rts5261_card_before_power_off(pcr);
	err = rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL,
				RTS5261_LDO_POWERON_MASK, 0);

	rtsx_pci_write_register(pcr, REG_CRC_DUMMY_0,
		CFG_SD_POW_AUTO_PD, 0);
	if (pcr->option.ocp_en)
		rtsx_pci_disable_ocp(pcr);

	return err;
}

static void rts5261_init_ocp(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;

	if (option->ocp_en) {
		u8 mask, val;

		rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
			RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN,
			RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN);

		rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
			RTS5261_LDO1_OCP_THD_MASK, option->sd_800mA_ocp_thd);

		rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
			RTS5261_LDO1_OCP_LMT_THD_MASK,
			RTS5261_LDO1_LMT_THD_2000);

		mask = SD_OCP_GLITCH_MASK;
		val = pcr->hw_param.ocp_glitch;
		rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);

		rts5261_enable_ocp(pcr);
	} else {
		rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0,
			RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN, 0);
	}
}

static void rts5261_clear_ocpstat(struct rtsx_pcr *pcr)
{
	u8 mask = 0;
	u8 val = 0;

	mask = SD_OCP_INT_CLR | SD_OC_CLR;
	val = SD_OCP_INT_CLR | SD_OC_CLR;

	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);

	udelay(1000);
	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);

}

static void rts5261_process_ocp(struct rtsx_pcr *pcr)
{
	if (!pcr->option.ocp_en)
		return;

	rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);

	if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
		rts5261_clear_ocpstat(pcr);
		rts5261_card_power_off(pcr, RTSX_SD_CARD);
		rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
		pcr->ocp_stat = 0;
	}

}

static int rts5261_init_from_hw(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int retval;
	u32 lval, i;
	u8 valid, efuse_valid, tmp;

	rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
		REG_EFUSE_POR | REG_EFUSE_POWER_MASK,
		REG_EFUSE_POR | REG_EFUSE_POWERON);
	udelay(1);
	rtsx_pci_write_register(pcr, RTS5261_EFUSE_ADDR,
		RTS5261_EFUSE_ADDR_MASK, 0x00);
	rtsx_pci_write_register(pcr, RTS5261_EFUSE_CTL,
		RTS5261_EFUSE_ENABLE | RTS5261_EFUSE_MODE_MASK,
		RTS5261_EFUSE_ENABLE);

	/* Wait transfer end */
	for (i = 0; i < MAX_RW_REG_CNT; i++) {
		rtsx_pci_read_register(pcr, RTS5261_EFUSE_CTL, &tmp);
		if ((tmp & 0x80) == 0)
			break;
	}
	rtsx_pci_read_register(pcr, RTS5261_EFUSE_READ_DATA, &tmp);
	efuse_valid = ((tmp & 0x0C) >> 2);
	pcr_dbg(pcr, "Load efuse valid: 0x%x\n", efuse_valid);

	if (efuse_valid == 0) {
		retval = pci_read_config_dword(pdev, PCR_SETTING_REG2, &lval);
		if (retval != 0)
			pcr_dbg(pcr, "read 0x814 DW fail\n");
		pcr_dbg(pcr, "DW from 0x814: 0x%x\n", lval);
		/* 0x816 */
		valid = (u8)((lval >> 16) & 0x03);
		pcr_dbg(pcr, "0x816: %d\n", valid);
	}
	rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
		REG_EFUSE_POR, 0);
	pcr_dbg(pcr, "Disable efuse por!\n");

	pci_read_config_dword(pdev, PCR_SETTING_REG2, &lval);
	lval = lval & 0x00FFFFFF;
	retval = pci_write_config_dword(pdev, PCR_SETTING_REG2, lval);
	if (retval != 0)
		pcr_dbg(pcr, "write config fail\n");

	return retval;
}

static void rts5261_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int l1ss;
	u32 lval;
	struct rtsx_cr_option *option = &pcr->option;

	l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
	if (!l1ss)
		return;

	pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
		rtsx_set_dev_flag(pcr, PM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
		rtsx_set_dev_flag(pcr, PM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_2_EN);

	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
	if (option->ltr_en) {
		u16 val;

		pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
			option->ltr_enabled = true;
			option->ltr_active = true;
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
		} else {
			option->ltr_enabled = false;
		}
	}

	if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
				| PM_L1_1_EN | PM_L1_2_EN))
		option->force_clkreq_0 = false;
	else
		option->force_clkreq_0 = true;
}

static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;
	u32 val;

	rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1,
			CD_RESUME_EN_MASK, CD_RESUME_EN_MASK);

	rts5261_init_from_cfg(pcr);
	rts5261_init_from_hw(pcr);

	/* power off efuse */
	rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
			REG_EFUSE_POWER_MASK, REG_EFUSE_POWEROFF);
	rtsx_pci_write_register(pcr, L1SUB_CONFIG1,
			AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE);
	rtsx_pci_write_register(pcr, L1SUB_CONFIG3, 0xFF, 0);

	if (is_version_higher_than(pcr, PID_5261, IC_VER_B)) {
		val = rtsx_pci_readl(pcr, RTSX_DUM_REG);
		rtsx_pci_writel(pcr, RTSX_DUM_REG, val | 0x1);
	}
	rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG4,
			RTS5261_AUX_CLK_16M_EN, 0);

	/* Release PRSNT# */
	rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG4,
			RTS5261_FORCE_PRSNT_LOW, 0);
	rtsx_pci_write_register(pcr, FUNC_FORCE_CTL,
			FUNC_FORCE_UPME_XMT_DBG, FUNC_FORCE_UPME_XMT_DBG);

	rtsx_pci_write_register(pcr, PCLK_CTL,
			PCLK_MODE_SEL, PCLK_MODE_SEL);

	rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
	rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, CLK_PM_EN, CLK_PM_EN);

	/* LED shine disabled, set initial shine cycle period */
	rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x0F, 0x02);

	/* Configure driving */
	rts5261_fill_driving(pcr, OUTPUT_3V3);

	if (pcr->flags & PCR_REVERSE_SOCKET)
		rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x30);
	else
		rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);

	/*
	 * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
	 * to drive low, and we forcibly request clock.
	 */
	if (option->force_clkreq_0)
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
	else
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

	rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB);
	rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00);
	rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
			FORCE_PM_CONTROL | FORCE_PM_VALUE, FORCE_PM_CONTROL);

	/* Clear Enter RTD3_cold Information*/
	rtsx_pci_write_register(pcr, RTS5261_FW_CTL,
		RTS5261_INFORM_RTD3_COLD, 0);

	return 0;
}

static void rts5261_enable_aspm(struct rtsx_pcr *pcr, bool enable)
{
	u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
	u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;

	if (pcr->aspm_enabled == enable)
		return;

	val |= (pcr->aspm_en & 0x02);
	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
	pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL,
					   PCI_EXP_LNKCTL_ASPMC, pcr->aspm_en);
	pcr->aspm_enabled = enable;
}

static void rts5261_disable_aspm(struct rtsx_pcr *pcr, bool enable)
{
	u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;
	u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1;

	if (pcr->aspm_enabled == enable)
		return;

	pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL,
					   PCI_EXP_LNKCTL_ASPMC, 0);
	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
	rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0);
	udelay(10);
	pcr->aspm_enabled = enable;
}

static void rts5261_set_aspm(struct rtsx_pcr *pcr, bool enable)
{
	if (enable)
		rts5261_enable_aspm(pcr, true);
	else
		rts5261_disable_aspm(pcr, false);
}

static void rts5261_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active)
{
	struct rtsx_cr_option *option = &pcr->option;
	int aspm_L1_1, aspm_L1_2;
	u8 val = 0;

	aspm_L1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN);
	aspm_L1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN);

	if (active) {
		/* run, latency: 60us */
		if (aspm_L1_1)
			val = option->ltr_l1off_snooze_sspwrgate;
	} else {
		/* l1off, latency: 300us */
		if (aspm_L1_2)
			val = option->ltr_l1off_sspwrgate;
	}

	rtsx_set_l1off_sub(pcr, val);
}

static const struct pcr_ops rts5261_pcr_ops = {
	.fetch_vendor_settings = rtsx5261_fetch_vendor_settings,
	.turn_on_led = rts5261_turn_on_led,
	.turn_off_led = rts5261_turn_off_led,
	.extra_init_hw = rts5261_extra_init_hw,
	.enable_auto_blink = rts5261_enable_auto_blink,
	.disable_auto_blink = rts5261_disable_auto_blink,
	.card_power_on = rts5261_card_power_on,
	.card_power_off = rts5261_card_power_off,
	.switch_output_voltage = rts5261_switch_output_voltage,
	.force_power_down = rts5261_force_power_down,
	.stop_cmd = rts5261_stop_cmd,
	.set_aspm = rts5261_set_aspm,
	.set_l1off_cfg_sub_d0 = rts5261_set_l1off_cfg_sub_d0,
	.enable_ocp = rts5261_enable_ocp,
	.disable_ocp = rts5261_disable_ocp,
	.init_ocp = rts5261_init_ocp,
	.process_ocp = rts5261_process_ocp,
	.clear_ocpstat = rts5261_clear_ocpstat,
};

static inline u8 double_ssc_depth(u8 depth)
{
	return ((depth > 1) ? (depth - 1) : depth);
}

int rts5261_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
		u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk)
{
	int err, clk;
	u16 n;
	u8 clk_divider, mcu_cnt, div;
	static const u8 depth[] = {
		[RTSX_SSC_DEPTH_4M] = RTS5261_SSC_DEPTH_4M,
		[RTSX_SSC_DEPTH_2M] = RTS5261_SSC_DEPTH_2M,
		[RTSX_SSC_DEPTH_1M] = RTS5261_SSC_DEPTH_1M,
		[RTSX_SSC_DEPTH_500K] = RTS5261_SSC_DEPTH_512K,
	};

	if (initial_mode) {
		/* We use 250k(around) here, in initial stage */
		if (is_version_higher_than(pcr, PID_5261, IC_VER_C)) {
			clk_divider = SD_CLK_DIVIDE_256;
			card_clock = 60000000;
		} else {
			clk_divider = SD_CLK_DIVIDE_128;
			card_clock = 30000000;
		}
	} else {
		clk_divider = SD_CLK_DIVIDE_0;
	}
	err = rtsx_pci_write_register(pcr, SD_CFG1,
			SD_CLK_DIVIDE_MASK, clk_divider);
	if (err < 0)
		return err;

	card_clock /= 1000000;
	pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock);

	clk = card_clock;
	if (!initial_mode && double_clk)
		clk = card_clock * 2;
	pcr_dbg(pcr, "Internal SSC clock: %dMHz (cur_clock = %d)\n",
		clk, pcr->cur_clock);

	if (clk == pcr->cur_clock)
		return 0;

	if (pcr->ops->conv_clk_and_div_n)
		n = pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N);
	else
		n = clk - 4;
	if ((clk <= 4) || (n > 396))
		return -EINVAL;

	mcu_cnt = 125/clk + 3;
	if (mcu_cnt > 15)
		mcu_cnt = 15;

	div = CLK_DIV_1;
	while ((n < MIN_DIV_N_PCR - 4) && (div < CLK_DIV_8)) {
		if (pcr->ops->conv_clk_and_div_n) {
			int dbl_clk = pcr->ops->conv_clk_and_div_n(n,
					DIV_N_TO_CLK) * 2;
			n = pcr->ops->conv_clk_and_div_n(dbl_clk,
					CLK_TO_DIV_N);
		} else {
			n = (n + 4) * 2 - 4;
		}
		div++;
	}

	n = (n / 2) - 1;
	pcr_dbg(pcr, "n = %d, div = %d\n", n, div);

	ssc_depth = depth[ssc_depth];
	if (double_clk)
		ssc_depth = double_ssc_depth(ssc_depth);

	if (ssc_depth) {
		if (div == CLK_DIV_2) {
			if (ssc_depth > 1)
				ssc_depth -= 1;
			else
				ssc_depth = RTS5261_SSC_DEPTH_8M;
		} else if (div == CLK_DIV_4) {
			if (ssc_depth > 2)
				ssc_depth -= 2;
			else
				ssc_depth = RTS5261_SSC_DEPTH_8M;
		} else if (div == CLK_DIV_8) {
			if (ssc_depth > 3)
				ssc_depth -= 3;
			else
				ssc_depth = RTS5261_SSC_DEPTH_8M;
		}
	} else {
		ssc_depth = 0;
	}
	pcr_dbg(pcr, "ssc_depth = %d\n", ssc_depth);

	rtsx_pci_init_cmd(pcr);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
				CLK_LOW_FREQ, CLK_LOW_FREQ);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV,
			0xFF, (div << 4) | mcu_cnt);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2,
			SSC_DEPTH_MASK, ssc_depth);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB);
	if (vpclk) {
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
				PHASE_NOT_RESET, 0);
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK1_CTL,
				PHASE_NOT_RESET, 0);
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL,
				PHASE_NOT_RESET, PHASE_NOT_RESET);
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK1_CTL,
				PHASE_NOT_RESET, PHASE_NOT_RESET);
	}

	err = rtsx_pci_send_cmd(pcr, 2000);
	if (err < 0)
		return err;

	/* Wait SSC clock stable */
	udelay(SSC_CLOCK_STABLE_WAIT);
	err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
	if (err < 0)
		return err;

	pcr->cur_clock = clk;
	return 0;

}

void rts5261_init_params(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;
	struct rtsx_hw_param *hw_param = &pcr->hw_param;
	u8 val;

	pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
	rtsx_pci_read_register(pcr, RTS5261_FW_STATUS, &val);
	if (!(val & RTS5261_EXPRESS_LINK_FAIL_MASK))
		pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
	pcr->num_slots = 1;
	pcr->ops = &rts5261_pcr_ops;

	pcr->flags = 0;
	pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
	pcr->sd30_drive_sel_1v8 = 0x00;
	pcr->sd30_drive_sel_3v3 = 0x00;
	pcr->aspm_en = ASPM_L1_EN;
	pcr->aspm_mode = ASPM_MODE_REG;
	pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 11);
	pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);

	pcr->ic_version = rts5261_get_ic_version(pcr);
	pcr->sd_pull_ctl_enable_tbl = rts5261_sd_pull_ctl_enable_tbl;
	pcr->sd_pull_ctl_disable_tbl = rts5261_sd_pull_ctl_disable_tbl;

	pcr->reg_pm_ctrl3 = RTS5261_AUTOLOAD_CFG3;

	option->dev_flags = (LTR_L1SS_PWR_GATE_CHECK_CARD_EN
				| LTR_L1SS_PWR_GATE_EN);
	option->ltr_en = true;

	/* init latency of active, idle, L1OFF to 60us, 300us, 3ms */
	option->ltr_active_latency = LTR_ACTIVE_LATENCY_DEF;
	option->ltr_idle_latency = LTR_IDLE_LATENCY_DEF;
	option->ltr_l1off_latency = LTR_L1OFF_LATENCY_DEF;
	option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF;
	option->ltr_l1off_sspwrgate = 0x7F;
	option->ltr_l1off_snooze_sspwrgate = 0x78;

	option->ocp_en = 1;
	hw_param->interrupt_en |= SD_OC_INT_EN;
	hw_param->ocp_glitch =  SD_OCP_GLITCH_800U;
	option->sd_800mA_ocp_thd =  RTS5261_LDO1_OCP_THD_1040;
}
