linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
@ 2019-03-07  9:44 ricky_wu
  2019-04-01  6:40 ` 吳昊澄 Ricky
  0 siblings, 1 reply; 6+ messages in thread
From: ricky_wu @ 2019-03-07  9:44 UTC (permalink / raw)
  To: arnd, gregkh, colin.king, axboe, linux-kernel; +Cc: RickyWu

From: RickyWu <ricky_wu@realtek.com>

this enables and adds OCP function for Realtek A series cardreader chips
and fixes some OCP flow in rts5260.c

Signed-off-by: RickyWu <ricky_wu@realtek.com>
---
 drivers/misc/cardreader/rts5227.c  |  58 ++++++++++--
 drivers/misc/cardreader/rts5249.c  |  29 ++++--
 drivers/misc/cardreader/rts5260.c  | 136 ++++++++++-------------------
 drivers/misc/cardreader/rtsx_pcr.c |  38 ++++++--
 drivers/misc/cardreader/rtsx_pcr.h |   5 ++
 5 files changed, 154 insertions(+), 112 deletions(-)

diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c
index 024dcba8d6c8..95394c6ca5c7 100644
--- a/drivers/misc/cardreader/rts5227.c
+++ b/drivers/misc/cardreader/rts5227.c
@@ -170,6 +170,9 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
 {
 	int err;
 
+	if (pcr->option.ocp_en)
+		rtsx_pci_enable_ocp(pcr);
+
 	rtsx_pci_init_cmd(pcr);
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 			SD_POWER_MASK, SD_PARTIAL_POWER_ON);
@@ -180,25 +183,30 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card)
 		return err;
 
 	/* To avoid too large in-rush current */
-	udelay(150);
+	msleep(20);
 
 	rtsx_pci_init_cmd(pcr);
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 			SD_POWER_MASK, SD_POWER_ON);
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
 			LDO3318_PWR_MASK, 0x06);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
+			SD_OUTPUT_EN, SD_OUTPUT_EN);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
+			MS_OUTPUT_EN, MS_OUTPUT_EN);
 	return rtsx_pci_send_cmd(pcr, 100);
 }
 
 static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
 {
-	rtsx_pci_init_cmd(pcr);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
-			SD_POWER_MASK | PMOS_STRG_MASK,
-			SD_POWER_OFF | PMOS_STRG_400mA);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
-			LDO3318_PWR_MASK, 0X00);
-	return rtsx_pci_send_cmd(pcr, 100);
+	if (pcr->option.ocp_en)
+		rtsx_pci_disable_ocp(pcr);
+
+	rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK |
+			PMOS_STRG_MASK, SD_POWER_OFF | PMOS_STRG_400mA);
+	rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0X00);
+
+	return 0;
 }
 
 static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
@@ -348,6 +356,32 @@ static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
 	return 0;
 }
 
+static int rts522a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+	int err;
+
+	if (voltage == OUTPUT_3V3) {
+		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x57E4);
+		if (err < 0)
+			return err;
+	} else if (voltage == OUTPUT_1V8) {
+		err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
+		if (err < 0)
+			return err;
+		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x54A4);
+		if (err < 0)
+			return err;
+	} else {
+		return -EINVAL;
+	}
+
+	/* set pad drive */
+	rtsx_pci_init_cmd(pcr);
+	rts5227_fill_driving(pcr, voltage);
+	return rtsx_pci_send_cmd(pcr, 100);
+}
+
+
 /* rts522a operations mainly derived from rts5227, except phy/hw init setting.
  */
 static const struct pcr_ops rts522a_pcr_ops = {
@@ -360,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = {
 	.disable_auto_blink = rts5227_disable_auto_blink,
 	.card_power_on = rts5227_card_power_on,
 	.card_power_off = rts5227_card_power_off,
-	.switch_output_voltage = rts5227_switch_output_voltage,
+	.switch_output_voltage = rts522a_switch_output_voltage,
 	.cd_deglitch = NULL,
 	.conv_clk_and_div_n = NULL,
 	.force_power_down = rts5227_force_power_down,
@@ -371,4 +405,10 @@ void rts522a_init_params(struct rtsx_pcr *pcr)
 	rts5227_init_params(pcr);
 
 	pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
+
+	pcr->option.ocp_en = 1;
+	pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
+	pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
+	pcr->option.sd_800mA_ocp_thd = RTS522A_OCP_THD_800;
+
 }
diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c
index dbe013abdb83..a3273669fb9c 100644
--- a/drivers/misc/cardreader/rts5249.c
+++ b/drivers/misc/cardreader/rts5249.c
@@ -283,8 +283,12 @@ static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
 
 static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
 {
+	struct rtsx_cr_option *option = &pcr->option;
 	int err;
 
+	if (option->ocp_en)
+		rtsx_pci_enable_ocp(pcr);
+
 	rtsx_pci_init_cmd(pcr);
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
 			SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
@@ -306,12 +310,15 @@ static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
 
 static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
 {
-	rtsx_pci_init_cmd(pcr);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
-			SD_POWER_MASK, SD_POWER_OFF);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
-			LDO3318_PWR_MASK, 0x00);
-	return rtsx_pci_send_cmd(pcr, 100);
+	struct rtsx_cr_option *option = &pcr->option;
+
+	if (option->ocp_en)
+		rtsx_pci_disable_ocp(pcr);
+
+	rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK, SD_POWER_OFF);
+
+	rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0x00);
+	return 0;
 }
 
 static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
@@ -629,6 +636,11 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
 
 	pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
 	pcr->ops = &rts524a_pcr_ops;
+
+	pcr->option.ocp_en = 1;
+	pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
+	pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
+	pcr->option.sd_800mA_ocp_thd = RTS524A_OCP_THD_800;
 }
 
 static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
@@ -737,4 +749,9 @@ void rts525a_init_params(struct rtsx_pcr *pcr)
 
 	pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
 	pcr->ops = &rts525a_pcr_ops;
+
+	pcr->option.ocp_en = 1;
+	pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
+	pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
+	pcr->option.sd_800mA_ocp_thd = RTS525A_OCP_THD_800;
 }
diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c
index a493b01c5bc6..ff303a770fef 100644
--- a/drivers/misc/cardreader/rts5260.c
+++ b/drivers/misc/cardreader/rts5260.c
@@ -64,11 +64,13 @@ static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
 		drive_sel = pcr->sd30_drive_sel_1v8;
 	}
 
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+	rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL,
 			 0xFF, driving[drive_sel][0]);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+
+	rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
 			 0xFF, driving[drive_sel][1]);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+
+	rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
 			 0xFF, driving[drive_sel][2]);
 }
 
@@ -193,7 +195,7 @@ static int sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr)
 		| 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);
+		       CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
 	rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
 
 	return 0;
@@ -207,22 +209,16 @@ static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card)
 	if (option->ocp_en)
 		rtsx_pci_enable_ocp(pcr);
 
-	rtsx_pci_init_cmd(pcr);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
-			 DV331812_VDD1, DV331812_VDD1);
-	err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
-	if (err < 0)
-		return err;
 
-	rtsx_pci_init_cmd(pcr);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0,
-			 RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
-			 LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
-			 DV331812_POWERON, DV331812_POWERON);
-	err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
+	rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1, DV331812_VDD1);
+	rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
+			 	RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
 
+	rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_POW_SDVDD1_MASK,
+				LDO_POW_SDVDD1_ON);
+
+	rtsx_pci_write_register(pcr, LDO_CONFIG2,
+			 	DV331812_POWERON, DV331812_POWERON);
 	msleep(20);
 
 	if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
@@ -273,9 +269,9 @@ static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
 	}
 
 	/* set pad drive */
-	rtsx_pci_init_cmd(pcr);
 	rts5260_fill_driving(pcr, voltage);
-	return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
+
+	return 0;
 }
 
 static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
@@ -290,29 +286,22 @@ static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
 
 static void rts5260_card_before_power_off(struct rtsx_pcr *pcr)
 {
-	struct rtsx_cr_option *option = &pcr->option;
-
 	rts5260_stop_cmd(pcr);
 	rts5260_switch_output_voltage(pcr, OUTPUT_3V3);
 
-	if (option->ocp_en)
-		rtsx_pci_disable_ocp(pcr);
 }
 
 static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card)
 {
-	int err = 0;
-
 	rts5260_card_before_power_off(pcr);
+	rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
+				LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
+	rtsx_pci_write_register(pcr, LDO_CONFIG2,
+				DV331812_POWERON, DV331812_POWEROFF);
+	if (pcr->option.ocp_en)
+		rtsx_pci_disable_ocp(pcr);
 
-	rtsx_pci_init_cmd(pcr);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
-			 LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
-			 DV331812_POWERON, DV331812_POWEROFF);
-	err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
-
-	return err;
+	return 0;
 }
 
 static void rts5260_init_ocp(struct rtsx_pcr *pcr)
@@ -322,41 +311,29 @@ static void rts5260_init_ocp(struct rtsx_pcr *pcr)
 	if (option->ocp_en) {
 		u8 mask, val;
 
-		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
-					RTS5260_DVCC_OCP_EN |
-					RTS5260_DVCC_OCP_CL_EN,
-					RTS5260_DVCC_OCP_EN |
-					RTS5260_DVCC_OCP_CL_EN);
-		rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
-					RTS5260_DVIO_OCP_EN |
-					RTS5260_DVIO_OCP_CL_EN,
-					RTS5260_DVIO_OCP_EN |
-					RTS5260_DVIO_OCP_CL_EN);
 
 		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
 					RTS5260_DVCC_OCP_THD_MASK,
-					option->sd_400mA_ocp_thd);
-
-		rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
-					RTS5260_DVIO_OCP_THD_MASK,
-					RTS5260_DVIO_OCP_THD_350);
+					option->sd_800mA_ocp_thd);
 
 		rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
 					RTS5260_DV331812_OCP_THD_MASK,
-					RTS5260_DV331812_OCP_THD_210);
+					RTS5260_DV331812_OCP_THD_270);
 
-		mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
+		mask = SD_OCP_GLITCH_MASK;
 		val = pcr->hw_param.ocp_glitch;
 		rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
+		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
+					RTS5260_DVCC_OCP_EN |
+					RTS5260_DVCC_OCP_CL_EN,
+					RTS5260_DVCC_OCP_EN |
+					RTS5260_DVCC_OCP_CL_EN);
 
 		rtsx_pci_enable_ocp(pcr);
 	} else {
 		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
 					RTS5260_DVCC_OCP_EN |
 					RTS5260_DVCC_OCP_CL_EN, 0);
-		rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
-					RTS5260_DVIO_OCP_EN |
-					RTS5260_DVIO_OCP_CL_EN, 0);
 	}
 }
 
@@ -364,14 +341,8 @@ static void rts5260_enable_ocp(struct rtsx_pcr *pcr)
 {
 	u8 val = 0;
 
-	rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
-
 	val = SD_OCP_INT_EN | SD_DETECT_EN;
-	val |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
 	rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
-	rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
-				DV3318_DETECT_EN | DV3318_OCP_INT_EN,
-				DV3318_DETECT_EN | DV3318_OCP_INT_EN);
 }
 
 static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
@@ -379,15 +350,10 @@ static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
 	u8 mask = 0;
 
 	mask = SD_OCP_INT_EN | SD_DETECT_EN;
-	mask |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
 	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
-	rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
-				DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0);
-
-	rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
-				OC_POWER_DOWN);
 }
 
+
 static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
 {
 	return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
@@ -404,9 +370,7 @@ static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
 	u8 val = 0;
 
 	mask = SD_OCP_INT_CLR | SD_OC_CLR;
-	mask |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
 	val = SD_OCP_INT_CLR | SD_OC_CLR;
-	val |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
 
 	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
 	rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
@@ -425,36 +389,22 @@ static void rts5260_process_ocp(struct rtsx_pcr *pcr)
 
 	rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
 	rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
-	if (pcr->card_exist & SD_EXIST)
-		rtsx_sd_power_off_card3v3(pcr);
-	else if (pcr->card_exist & MS_EXIST)
-		rtsx_ms_power_off_card3v3(pcr);
-
-	if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) {
-		if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
-			SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
-			(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER)))
-			rtsx_pci_clear_ocpstat(pcr);
+
+	if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) ||
+		(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
+		rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+		rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
+		rtsx_pci_clear_ocpstat(pcr);
 		pcr->ocp_stat = 0;
 		pcr->ocp_stat2 = 0;
 	}
 
-	if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
-			SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
-			(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
-		if (pcr->card_exist & SD_EXIST)
-			rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
-		else if (pcr->card_exist & MS_EXIST)
-			rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
-	}
 }
 
 static int rts5260_init_hw(struct rtsx_pcr *pcr)
 {
 	int err;
 
-	rtsx_pci_init_ocp(pcr);
-
 	rtsx_pci_init_cmd(pcr);
 
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1,
@@ -483,6 +433,8 @@ static int rts5260_init_hw(struct rtsx_pcr *pcr)
 	if (err < 0)
 		return err;
 
+	rtsx_pci_init_ocp(pcr);
+
 	return 0;
 }
 
@@ -499,6 +451,12 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)
 		pcr_dbg(pcr, "Set parameters for L1.2.");
 		rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
 					0xFF, PCIE_L1_2_EN);
+		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
+					RTS5260_DVCC_OCP_EN |
+					RTS5260_DVCC_OCP_CL_EN,
+					RTS5260_DVCC_OCP_EN |
+					RTS5260_DVCC_OCP_CL_EN);
+
 		rtsx_pci_write_register(pcr, PWR_FE_CTL,
 					0xFF, PCIE_L1_2_PD_FE_EN);
 	} else if (lss_l1_1) {
@@ -742,7 +700,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr)
 	option->ocp_en = 1;
 	if (option->ocp_en)
 		hw_param->interrupt_en |= SD_OC_INT_EN;
-	hw_param->ocp_glitch = SD_OCP_GLITCH_10M | SDVIO_OCP_GLITCH_800U;
+	hw_param->ocp_glitch = SD_OCP_GLITCH_100U | SDVIO_OCP_GLITCH_800U;
 	option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
 	option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
 }
diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c
index da445223f4cc..e8072804d83a 100644
--- a/drivers/misc/cardreader/rtsx_pcr.c
+++ b/drivers/misc/cardreader/rtsx_pcr.c
@@ -703,7 +703,10 @@ EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
 
 static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
 {
-	pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN;
+	struct rtsx_hw_param *hw_param = &pcr->hw_param;
+
+	pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN |
+		hw_param->interrupt_en;
 
 	if (pcr->num_slots > 1)
 		pcr->bier |= MS_INT_EN;
@@ -969,8 +972,19 @@ static void rtsx_pci_card_detect(struct work_struct *work)
 
 static void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
 {
-	if (pcr->ops->process_ocp)
+	if (pcr->ops->process_ocp) {
 		pcr->ops->process_ocp(pcr);
+	} else {
+		if (!pcr->option.ocp_en)
+			return;
+		rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
+		if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
+			rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+			rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
+			rtsx_pci_clear_ocpstat(pcr);
+			pcr->ocp_stat = 0;
+		}
+	}
 }
 
 static int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
@@ -1039,7 +1053,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
 		}
 	}
 
-	if (pcr->card_inserted || pcr->card_removed)
+	if ((pcr->card_inserted || pcr->card_removed) && !(int_reg & SD_OC_INT))
 		schedule_delayed_work(&pcr->carddet_work,
 				msecs_to_jiffies(200));
 
@@ -1144,10 +1158,12 @@ void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
 {
 	u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
 
-	if (pcr->ops->enable_ocp)
+	if (pcr->ops->enable_ocp) {
 		pcr->ops->enable_ocp(pcr);
-	else
+	} else {
+		rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
 		rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
+	}
 
 }
 
@@ -1155,10 +1171,13 @@ void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
 {
 	u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
 
-	if (pcr->ops->disable_ocp)
+	if (pcr->ops->disable_ocp) {
 		pcr->ops->disable_ocp(pcr);
-	else
+	} else {
 		rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
+		rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
+				OC_POWER_DOWN);
+	}
 }
 
 void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
@@ -1169,7 +1188,7 @@ void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
 		struct rtsx_cr_option *option = &(pcr->option);
 
 		if (option->ocp_en) {
-			u8 val = option->sd_400mA_ocp_thd;
+			u8 val = option->sd_800mA_ocp_thd;
 
 			rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
 			rtsx_pci_write_register(pcr, REG_OCPPARA1,
@@ -1204,6 +1223,7 @@ void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
 		u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
 
 		rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
+		udelay(100);
 		rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
 	}
 }
@@ -1313,6 +1333,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
 		break;
 	}
 
+	rtsx_pci_init_ocp(pcr);
+
 	/* Enable clk_request_n to enable clock power management */
 	rtsx_pci_write_config_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL + 1, 1);
 	/* Enter L1 when host tx idle */
diff --git a/drivers/misc/cardreader/rtsx_pcr.h b/drivers/misc/cardreader/rtsx_pcr.h
index 6ea1655db0bb..300fc31d8e67 100644
--- a/drivers/misc/cardreader/rtsx_pcr.h
+++ b/drivers/misc/cardreader/rtsx_pcr.h
@@ -46,6 +46,11 @@
 
 #define SSC_CLOCK_STABLE_WAIT	130
 
+#define RTS524A_OCP_THD_800	0x04
+#define RTS525A_OCP_THD_800	0x05
+#define RTS522A_OCP_THD_800	0x06
+
+
 int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
 int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
  2019-03-07  9:44 [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260 ricky_wu
@ 2019-04-01  6:40 ` 吳昊澄 Ricky
  2019-04-01  7:04   ` gregkh
  0 siblings, 1 reply; 6+ messages in thread
From: 吳昊澄 Ricky @ 2019-04-01  6:40 UTC (permalink / raw)
  To: arnd, gregkh, colin.king, axboe, linux-kernel

Dear all,

May I know how is this patch going on ? 
Is it work well on your side?
We have some guest want to know what stage is this patch going to

Thank you

Best regards,
Ricky_wu 

> -----Original Message-----
> From: 吳昊澄 Ricky
> Sent: Thursday, March 07, 2019 5:44 PM
> To: arnd@arndb.de; gregkh@linuxfoundation.org; colin.king@canonical.com;
> axboe@kernel.dk; linux-kernel@vger.kernel.org
> Cc: 吳昊澄 Ricky
> Subject: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
> 
> From: RickyWu <ricky_wu@realtek.com>
> 
> this enables and adds OCP function for Realtek A series cardreader chips
> and fixes some OCP flow in rts5260.c
> 
> Signed-off-by: RickyWu <ricky_wu@realtek.com>
> ---
>  drivers/misc/cardreader/rts5227.c  |  58 ++++++++++--
>  drivers/misc/cardreader/rts5249.c  |  29 ++++--
>  drivers/misc/cardreader/rts5260.c  | 136 ++++++++++-------------------
>  drivers/misc/cardreader/rtsx_pcr.c |  38 ++++++--
>  drivers/misc/cardreader/rtsx_pcr.h |   5 ++
>  5 files changed, 154 insertions(+), 112 deletions(-)
> 
> diff --git a/drivers/misc/cardreader/rts5227.c
> b/drivers/misc/cardreader/rts5227.c
> index 024dcba8d6c8..95394c6ca5c7 100644
> --- a/drivers/misc/cardreader/rts5227.c
> +++ b/drivers/misc/cardreader/rts5227.c
> @@ -170,6 +170,9 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr,
> int card)
>  {
>  	int err;
> 
> +	if (pcr->option.ocp_en)
> +		rtsx_pci_enable_ocp(pcr);
> +
>  	rtsx_pci_init_cmd(pcr);
>  	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
>  			SD_POWER_MASK, SD_PARTIAL_POWER_ON);
> @@ -180,25 +183,30 @@ static int rts5227_card_power_on(struct rtsx_pcr
> *pcr, int card)
>  		return err;
> 
>  	/* To avoid too large in-rush current */
> -	udelay(150);
> +	msleep(20);
> 
>  	rtsx_pci_init_cmd(pcr);
>  	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
>  			SD_POWER_MASK, SD_POWER_ON);
>  	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
>  			LDO3318_PWR_MASK, 0x06);
> +	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
> +			SD_OUTPUT_EN, SD_OUTPUT_EN);
> +	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE,
> +			MS_OUTPUT_EN, MS_OUTPUT_EN);
>  	return rtsx_pci_send_cmd(pcr, 100);
>  }
> 
>  static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card)
>  {
> -	rtsx_pci_init_cmd(pcr);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> -			SD_POWER_MASK | PMOS_STRG_MASK,
> -			SD_POWER_OFF | PMOS_STRG_400mA);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
> -			LDO3318_PWR_MASK, 0X00);
> -	return rtsx_pci_send_cmd(pcr, 100);
> +	if (pcr->option.ocp_en)
> +		rtsx_pci_disable_ocp(pcr);
> +
> +	rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK |
> +			PMOS_STRG_MASK, SD_POWER_OFF | PMOS_STRG_400mA);
> +	rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK,
> 0X00);
> +
> +	return 0;
>  }
> 
>  static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> @@ -348,6 +356,32 @@ static int rts522a_extra_init_hw(struct rtsx_pcr *pcr)
>  	return 0;
>  }
> 
> +static int rts522a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> +{
> +	int err;
> +
> +	if (voltage == OUTPUT_3V3) {
> +		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x57E4);
> +		if (err < 0)
> +			return err;
> +	} else if (voltage == OUTPUT_1V8) {
> +		err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02);
> +		if (err < 0)
> +			return err;
> +		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x54A4);
> +		if (err < 0)
> +			return err;
> +	} else {
> +		return -EINVAL;
> +	}
> +
> +	/* set pad drive */
> +	rtsx_pci_init_cmd(pcr);
> +	rts5227_fill_driving(pcr, voltage);
> +	return rtsx_pci_send_cmd(pcr, 100);
> +}
> +
> +
>  /* rts522a operations mainly derived from rts5227, except phy/hw init setting.
>   */
>  static const struct pcr_ops rts522a_pcr_ops = {
> @@ -360,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = {
>  	.disable_auto_blink = rts5227_disable_auto_blink,
>  	.card_power_on = rts5227_card_power_on,
>  	.card_power_off = rts5227_card_power_off,
> -	.switch_output_voltage = rts5227_switch_output_voltage,
> +	.switch_output_voltage = rts522a_switch_output_voltage,
>  	.cd_deglitch = NULL,
>  	.conv_clk_and_div_n = NULL,
>  	.force_power_down = rts5227_force_power_down,
> @@ -371,4 +405,10 @@ void rts522a_init_params(struct rtsx_pcr *pcr)
>  	rts5227_init_params(pcr);
> 
>  	pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3;
> +
> +	pcr->option.ocp_en = 1;
> +	pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
> +	pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
> +	pcr->option.sd_800mA_ocp_thd = RTS522A_OCP_THD_800;
> +
>  }
> diff --git a/drivers/misc/cardreader/rts5249.c
> b/drivers/misc/cardreader/rts5249.c
> index dbe013abdb83..a3273669fb9c 100644
> --- a/drivers/misc/cardreader/rts5249.c
> +++ b/drivers/misc/cardreader/rts5249.c
> @@ -283,8 +283,12 @@ static int rtsx_base_disable_auto_blink(struct rtsx_pcr
> *pcr)
> 
>  static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
>  {
> +	struct rtsx_cr_option *option = &pcr->option;
>  	int err;
> 
> +	if (option->ocp_en)
> +		rtsx_pci_enable_ocp(pcr);
> +
>  	rtsx_pci_init_cmd(pcr);
>  	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
>  			SD_POWER_MASK, SD_VCC_PARTIAL_POWER_ON);
> @@ -306,12 +310,15 @@ static int rtsx_base_card_power_on(struct rtsx_pcr
> *pcr, int card)
> 
>  static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
>  {
> -	rtsx_pci_init_cmd(pcr);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
> -			SD_POWER_MASK, SD_POWER_OFF);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
> -			LDO3318_PWR_MASK, 0x00);
> -	return rtsx_pci_send_cmd(pcr, 100);
> +	struct rtsx_cr_option *option = &pcr->option;
> +
> +	if (option->ocp_en)
> +		rtsx_pci_disable_ocp(pcr);
> +
> +	rtsx_pci_write_register(pcr, CARD_PWR_CTL, SD_POWER_MASK,
> SD_POWER_OFF);
> +
> +	rtsx_pci_write_register(pcr, PWR_GATE_CTRL, LDO3318_PWR_MASK,
> 0x00);
> +	return 0;
>  }
> 
>  static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> @@ -629,6 +636,11 @@ void rts524a_init_params(struct rtsx_pcr *pcr)
> 
>  	pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
>  	pcr->ops = &rts524a_pcr_ops;
> +
> +	pcr->option.ocp_en = 1;
> +	pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
> +	pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
> +	pcr->option.sd_800mA_ocp_thd = RTS524A_OCP_THD_800;
>  }
> 
>  static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
> @@ -737,4 +749,9 @@ void rts525a_init_params(struct rtsx_pcr *pcr)
> 
>  	pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
>  	pcr->ops = &rts525a_pcr_ops;
> +
> +	pcr->option.ocp_en = 1;
> +	pcr->hw_param.interrupt_en |= SD_OC_INT_EN;
> +	pcr->hw_param.ocp_glitch = SD_OCP_GLITCH_10M;
> +	pcr->option.sd_800mA_ocp_thd = RTS525A_OCP_THD_800;
>  }
> diff --git a/drivers/misc/cardreader/rts5260.c
> b/drivers/misc/cardreader/rts5260.c
> index a493b01c5bc6..ff303a770fef 100644
> --- a/drivers/misc/cardreader/rts5260.c
> +++ b/drivers/misc/cardreader/rts5260.c
> @@ -64,11 +64,13 @@ static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8
> voltage)
>  		drive_sel = pcr->sd30_drive_sel_1v8;
>  	}
> 
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
> +	rtsx_pci_write_register(pcr, SD30_CLK_DRIVE_SEL,
>  			 0xFF, driving[drive_sel][0]);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
> +
> +	rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
>  			 0xFF, driving[drive_sel][1]);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
> +
> +	rtsx_pci_write_register(pcr, SD30_CMD_DRIVE_SEL,
>  			 0xFF, driving[drive_sel][2]);
>  }
> 
> @@ -193,7 +195,7 @@ static int sd_set_sample_push_timing_sd30(struct
> rtsx_pcr *pcr)
>  		| 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);
> +		       CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
>  	rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
> 
>  	return 0;
> @@ -207,22 +209,16 @@ static int rts5260_card_power_on(struct rtsx_pcr
> *pcr, int card)
>  	if (option->ocp_en)
>  		rtsx_pci_enable_ocp(pcr);
> 
> -	rtsx_pci_init_cmd(pcr);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
> -			 DV331812_VDD1, DV331812_VDD1);
> -	err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> -	if (err < 0)
> -		return err;
> 
> -	rtsx_pci_init_cmd(pcr);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0,
> -			 RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
> -			 LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
> -			 DV331812_POWERON, DV331812_POWERON);
> -	err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> +	rtsx_pci_write_register(pcr, LDO_CONFIG2, DV331812_VDD1,
> DV331812_VDD1);
> +	rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
> +			 	RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
> 
> +	rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_POW_SDVDD1_MASK,
> +				LDO_POW_SDVDD1_ON);
> +
> +	rtsx_pci_write_register(pcr, LDO_CONFIG2,
> +			 	DV331812_POWERON, DV331812_POWERON);
>  	msleep(20);
> 
>  	if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
> @@ -273,9 +269,9 @@ static int rts5260_switch_output_voltage(struct
> rtsx_pcr *pcr, u8 voltage)
>  	}
> 
>  	/* set pad drive */
> -	rtsx_pci_init_cmd(pcr);
>  	rts5260_fill_driving(pcr, voltage);
> -	return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> +
> +	return 0;
>  }
> 
>  static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
> @@ -290,29 +286,22 @@ static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
> 
>  static void rts5260_card_before_power_off(struct rtsx_pcr *pcr)
>  {
> -	struct rtsx_cr_option *option = &pcr->option;
> -
>  	rts5260_stop_cmd(pcr);
>  	rts5260_switch_output_voltage(pcr, OUTPUT_3V3);
> 
> -	if (option->ocp_en)
> -		rtsx_pci_disable_ocp(pcr);
>  }
> 
>  static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card)
>  {
> -	int err = 0;
> -
>  	rts5260_card_before_power_off(pcr);
> +	rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
> +				LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
> +	rtsx_pci_write_register(pcr, LDO_CONFIG2,
> +				DV331812_POWERON, DV331812_POWEROFF);
> +	if (pcr->option.ocp_en)
> +		rtsx_pci_disable_ocp(pcr);
> 
> -	rtsx_pci_init_cmd(pcr);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
> -			 LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
> -	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
> -			 DV331812_POWERON, DV331812_POWEROFF);
> -	err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> -
> -	return err;
> +	return 0;
>  }
> 
>  static void rts5260_init_ocp(struct rtsx_pcr *pcr)
> @@ -322,41 +311,29 @@ static void rts5260_init_ocp(struct rtsx_pcr *pcr)
>  	if (option->ocp_en) {
>  		u8 mask, val;
> 
> -		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> -					RTS5260_DVCC_OCP_EN |
> -					RTS5260_DVCC_OCP_CL_EN,
> -					RTS5260_DVCC_OCP_EN |
> -					RTS5260_DVCC_OCP_CL_EN);
> -		rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
> -					RTS5260_DVIO_OCP_EN |
> -					RTS5260_DVIO_OCP_CL_EN,
> -					RTS5260_DVIO_OCP_EN |
> -					RTS5260_DVIO_OCP_CL_EN);
> 
>  		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
>  					RTS5260_DVCC_OCP_THD_MASK,
> -					option->sd_400mA_ocp_thd);
> -
> -		rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
> -					RTS5260_DVIO_OCP_THD_MASK,
> -					RTS5260_DVIO_OCP_THD_350);
> +					option->sd_800mA_ocp_thd);
> 
>  		rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
>  					RTS5260_DV331812_OCP_THD_MASK,
> -					RTS5260_DV331812_OCP_THD_210);
> +					RTS5260_DV331812_OCP_THD_270);
> 
> -		mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
> +		mask = SD_OCP_GLITCH_MASK;
>  		val = pcr->hw_param.ocp_glitch;
>  		rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
> +		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> +					RTS5260_DVCC_OCP_EN |
> +					RTS5260_DVCC_OCP_CL_EN,
> +					RTS5260_DVCC_OCP_EN |
> +					RTS5260_DVCC_OCP_CL_EN);
> 
>  		rtsx_pci_enable_ocp(pcr);
>  	} else {
>  		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
>  					RTS5260_DVCC_OCP_EN |
>  					RTS5260_DVCC_OCP_CL_EN, 0);
> -		rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
> -					RTS5260_DVIO_OCP_EN |
> -					RTS5260_DVIO_OCP_CL_EN, 0);
>  	}
>  }
> 
> @@ -364,14 +341,8 @@ static void rts5260_enable_ocp(struct rtsx_pcr *pcr)
>  {
>  	u8 val = 0;
> 
> -	rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
> -
>  	val = SD_OCP_INT_EN | SD_DETECT_EN;
> -	val |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
>  	rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
> -	rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> -				DV3318_DETECT_EN | DV3318_OCP_INT_EN,
> -				DV3318_DETECT_EN | DV3318_OCP_INT_EN);
>  }
> 
>  static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
> @@ -379,15 +350,10 @@ static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
>  	u8 mask = 0;
> 
>  	mask = SD_OCP_INT_EN | SD_DETECT_EN;
> -	mask |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
>  	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> -	rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> -				DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0);
> -
> -	rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
> -				OC_POWER_DOWN);
>  }
> 
> +
>  static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
>  {
>  	return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
> @@ -404,9 +370,7 @@ static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
>  	u8 val = 0;
> 
>  	mask = SD_OCP_INT_CLR | SD_OC_CLR;
> -	mask |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
>  	val = SD_OCP_INT_CLR | SD_OC_CLR;
> -	val |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
> 
>  	rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
>  	rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> @@ -425,36 +389,22 @@ static void rts5260_process_ocp(struct rtsx_pcr *pcr)
> 
>  	rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
>  	rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
> -	if (pcr->card_exist & SD_EXIST)
> -		rtsx_sd_power_off_card3v3(pcr);
> -	else if (pcr->card_exist & MS_EXIST)
> -		rtsx_ms_power_off_card3v3(pcr);
> -
> -	if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) {
> -		if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
> -			SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
> -			(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER)))
> -			rtsx_pci_clear_ocpstat(pcr);
> +
> +	if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) ||
> +		(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
> +		rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
> +		rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> +		rtsx_pci_clear_ocpstat(pcr);
>  		pcr->ocp_stat = 0;
>  		pcr->ocp_stat2 = 0;
>  	}
> 
> -	if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
> -			SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
> -			(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
> -		if (pcr->card_exist & SD_EXIST)
> -			rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> -		else if (pcr->card_exist & MS_EXIST)
> -			rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
> -	}
>  }
> 
>  static int rts5260_init_hw(struct rtsx_pcr *pcr)
>  {
>  	int err;
> 
> -	rtsx_pci_init_ocp(pcr);
> -
>  	rtsx_pci_init_cmd(pcr);
> 
>  	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1,
> @@ -483,6 +433,8 @@ static int rts5260_init_hw(struct rtsx_pcr *pcr)
>  	if (err < 0)
>  		return err;
> 
> +	rtsx_pci_init_ocp(pcr);
> +
>  	return 0;
>  }
> 
> @@ -499,6 +451,12 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr
> *pcr)
>  		pcr_dbg(pcr, "Set parameters for L1.2.");
>  		rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
>  					0xFF, PCIE_L1_2_EN);
> +		rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
> +					RTS5260_DVCC_OCP_EN |
> +					RTS5260_DVCC_OCP_CL_EN,
> +					RTS5260_DVCC_OCP_EN |
> +					RTS5260_DVCC_OCP_CL_EN);
> +
>  		rtsx_pci_write_register(pcr, PWR_FE_CTL,
>  					0xFF, PCIE_L1_2_PD_FE_EN);
>  	} else if (lss_l1_1) {
> @@ -742,7 +700,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr)
>  	option->ocp_en = 1;
>  	if (option->ocp_en)
>  		hw_param->interrupt_en |= SD_OC_INT_EN;
> -	hw_param->ocp_glitch = SD_OCP_GLITCH_10M |
> SDVIO_OCP_GLITCH_800U;
> +	hw_param->ocp_glitch = SD_OCP_GLITCH_100U |
> SDVIO_OCP_GLITCH_800U;
>  	option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
>  	option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
>  }
> diff --git a/drivers/misc/cardreader/rtsx_pcr.c
> b/drivers/misc/cardreader/rtsx_pcr.c
> index da445223f4cc..e8072804d83a 100644
> --- a/drivers/misc/cardreader/rtsx_pcr.c
> +++ b/drivers/misc/cardreader/rtsx_pcr.c
> @@ -703,7 +703,10 @@ EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
> 
>  static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
>  {
> -	pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN;
> +	struct rtsx_hw_param *hw_param = &pcr->hw_param;
> +
> +	pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN |
> +		hw_param->interrupt_en;
> 
>  	if (pcr->num_slots > 1)
>  		pcr->bier |= MS_INT_EN;
> @@ -969,8 +972,19 @@ static void rtsx_pci_card_detect(struct work_struct
> *work)
> 
>  static void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
>  {
> -	if (pcr->ops->process_ocp)
> +	if (pcr->ops->process_ocp) {
>  		pcr->ops->process_ocp(pcr);
> +	} else {
> +		if (!pcr->option.ocp_en)
> +			return;
> +		rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
> +		if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) {
> +			rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
> +			rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> +			rtsx_pci_clear_ocpstat(pcr);
> +			pcr->ocp_stat = 0;
> +		}
> +	}
>  }
> 
>  static int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
> @@ -1039,7 +1053,7 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
>  		}
>  	}
> 
> -	if (pcr->card_inserted || pcr->card_removed)
> +	if ((pcr->card_inserted || pcr->card_removed) && !(int_reg & SD_OC_INT))
>  		schedule_delayed_work(&pcr->carddet_work,
>  				msecs_to_jiffies(200));
> 
> @@ -1144,10 +1158,12 @@ void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
>  {
>  	u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
> 
> -	if (pcr->ops->enable_ocp)
> +	if (pcr->ops->enable_ocp) {
>  		pcr->ops->enable_ocp(pcr);
> -	else
> +	} else {
> +		rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
>  		rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
> +	}
> 
>  }
> 
> @@ -1155,10 +1171,13 @@ void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
>  {
>  	u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
> 
> -	if (pcr->ops->disable_ocp)
> +	if (pcr->ops->disable_ocp) {
>  		pcr->ops->disable_ocp(pcr);
> -	else
> +	} else {
>  		rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> +		rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
> +				OC_POWER_DOWN);
> +	}
>  }
> 
>  void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
> @@ -1169,7 +1188,7 @@ void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
>  		struct rtsx_cr_option *option = &(pcr->option);
> 
>  		if (option->ocp_en) {
> -			u8 val = option->sd_400mA_ocp_thd;
> +			u8 val = option->sd_800mA_ocp_thd;
> 
>  			rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
>  			rtsx_pci_write_register(pcr, REG_OCPPARA1,
> @@ -1204,6 +1223,7 @@ void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
>  		u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
> 
>  		rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
> +		udelay(100);
>  		rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
>  	}
>  }
> @@ -1313,6 +1333,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
>  		break;
>  	}
> 
> +	rtsx_pci_init_ocp(pcr);
> +
>  	/* Enable clk_request_n to enable clock power management */
>  	rtsx_pci_write_config_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL + 1, 1);
>  	/* Enter L1 when host tx idle */
> diff --git a/drivers/misc/cardreader/rtsx_pcr.h
> b/drivers/misc/cardreader/rtsx_pcr.h
> index 6ea1655db0bb..300fc31d8e67 100644
> --- a/drivers/misc/cardreader/rtsx_pcr.h
> +++ b/drivers/misc/cardreader/rtsx_pcr.h
> @@ -46,6 +46,11 @@
> 
>  #define SSC_CLOCK_STABLE_WAIT	130
> 
> +#define RTS524A_OCP_THD_800	0x04
> +#define RTS525A_OCP_THD_800	0x05
> +#define RTS522A_OCP_THD_800	0x06
> +
> +
>  int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
>  int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
> 
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
  2019-04-01  6:40 ` 吳昊澄 Ricky
@ 2019-04-01  7:04   ` gregkh
  2019-04-01  7:26     ` 吳昊澄 Ricky
  2019-04-01  8:34     ` 吳昊澄 Ricky
  0 siblings, 2 replies; 6+ messages in thread
From: gregkh @ 2019-04-01  7:04 UTC (permalink / raw)
  To: 吳昊澄 Ricky; +Cc: arnd, colin.king, axboe, linux-kernel

On Mon, Apr 01, 2019 at 06:40:19AM +0000, 吳昊澄 Ricky wrote:
> Dear all,
> 
> May I know how is this patch going on ? 
> Is it work well on your side?
> We have some guest want to know what stage is this patch going to

This patch is already in the 5.1-rc1 release, you can see it on
git.kernel.org in Linus's tree.  It will be in the final 5.1 release
which should happen in a few weeks.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
  2019-04-01  7:04   ` gregkh
@ 2019-04-01  7:26     ` 吳昊澄 Ricky
  2019-04-01  8:34     ` 吳昊澄 Ricky
  1 sibling, 0 replies; 6+ messages in thread
From: 吳昊澄 Ricky @ 2019-04-01  7:26 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, colin.king, axboe, linux-kernel

Dear Greg k-h,

Very thanks for your reply kindly

Ricky

> -----Original Message-----
> From: gregkh@linuxfoundation.org [mailto:gregkh@linuxfoundation.org]
> Sent: Monday, April 01, 2019 3:04 PM
> To: 吳昊澄 Ricky
> Cc: arnd@arndb.de; colin.king@canonical.com; axboe@kernel.dk;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a
> rts5260
> 
> On Mon, Apr 01, 2019 at 06:40:19AM +0000, 吳昊澄 Ricky wrote:
> > Dear all,
> >
> > May I know how is this patch going on ?
> > Is it work well on your side?
> > We have some guest want to know what stage is this patch going to
> 
> This patch is already in the 5.1-rc1 release, you can see it on
> git.kernel.org in Linus's tree.  It will be in the final 5.1 release
> which should happen in a few weeks.
> 
> thanks,
> 
> greg k-h
> 
> ------Please consider the environment before printing this e-mail.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
  2019-04-01  7:04   ` gregkh
  2019-04-01  7:26     ` 吳昊澄 Ricky
@ 2019-04-01  8:34     ` 吳昊澄 Ricky
  2019-04-01  9:39       ` gregkh
  1 sibling, 1 reply; 6+ messages in thread
From: 吳昊澄 Ricky @ 2019-04-01  8:34 UTC (permalink / raw)
  To: gregkh; +Cc: arnd, colin.king, axboe, linux-kernel

Dear Greg k-h,

I saw the patch is already in Linus's tree
But I found it is not my v3-patch
Can you help me to check this status kindly?

Thank you

BR,
Ricky
> -----Original Message-----
> From: gregkh@linuxfoundation.org [mailto:gregkh@linuxfoundation.org]
> Sent: Monday, April 01, 2019 3:04 PM
> To: 吳昊澄 Ricky
> Cc: arnd@arndb.de; colin.king@canonical.com; axboe@kernel.dk;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a
> rts5260
> 
> On Mon, Apr 01, 2019 at 06:40:19AM +0000, 吳昊澄 Ricky wrote:
> > Dear all,
> >
> > May I know how is this patch going on ?
> > Is it work well on your side?
> > We have some guest want to know what stage is this patch going to
> 
> This patch is already in the 5.1-rc1 release, you can see it on
> git.kernel.org in Linus's tree.  It will be in the final 5.1 release
> which should happen in a few weeks.
> 
> thanks,
> 
> greg k-h
> 
> ------Please consider the environment before printing this e-mail.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260
  2019-04-01  8:34     ` 吳昊澄 Ricky
@ 2019-04-01  9:39       ` gregkh
  0 siblings, 0 replies; 6+ messages in thread
From: gregkh @ 2019-04-01  9:39 UTC (permalink / raw)
  To: 吳昊澄 Ricky; +Cc: arnd, colin.king, axboe, linux-kernel

On Mon, Apr 01, 2019 at 08:34:44AM +0000, 吳昊澄 Ricky wrote:
> Dear Greg k-h,
> 
> I saw the patch is already in Linus's tree
> But I found it is not my v3-patch
> Can you help me to check this status kindly?

I had already applied and submitted your patch when you sent the v3
patch.  I can not go back in time and change it.  If there is a
follow-on change that needs to be made, to bring it up to whatever your
v3 patch is, please send that so it can be applied.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-04-01  9:39 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-07  9:44 [PATCH v3] misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260 ricky_wu
2019-04-01  6:40 ` 吳昊澄 Ricky
2019-04-01  7:04   ` gregkh
2019-04-01  7:26     ` 吳昊澄 Ricky
2019-04-01  8:34     ` 吳昊澄 Ricky
2019-04-01  9:39       ` gregkh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).