* [PATCH] staging: rtsx: Add support for RTS5260
@ 2017-10-13 8:50 rui_feng
2017-10-13 9:26 ` Greg KH
2017-10-13 18:28 ` Mario Limonciello
0 siblings, 2 replies; 13+ messages in thread
From: rui_feng @ 2017-10-13 8:50 UTC (permalink / raw)
To: lee.jones, gregkh, linux-kernel, devel; +Cc: ricky_wu, rui_feng
From: rui_feng <rui_feng@realsil.com.cn>
Add support for new chip rts5260.
In order to support rts5260,the definitions of some internal
registers and workflow have to be modified and are different from its
predecessors and OCP function is added for RTS5260.
So we need this patch to ensure RTS5260 can work.
Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
---
drivers/mfd/Makefile | 4 +
drivers/mfd/rtsx_pcr.c | 127 ++++++-
drivers/mfd/rtsx_pcr.h | 12 +
drivers/staging/Kconfig | 2 +
drivers/staging/rts5260/Kconfig | 6 +
drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
drivers/staging/rts5260/rts5260.h | 45 +++
include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
8 files changed, 1173 insertions(+), 5 deletions(-)
create mode 100644 drivers/staging/rts5260/Kconfig
create mode 100644 drivers/staging/rts5260/rts5260.c
create mode 100644 drivers/staging/rts5260/rts5260.h
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 080793b..93edc5b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -18,6 +18,10 @@ obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
+ifneq ($(CONFIG_RTS5260), )
+ccflags-y += -DCONFIG_RTS5260
+rtsx_pci-objs += ../staging/rts5260/rts5260.o
+endif
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index 7c87485..1917125 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -62,6 +62,9 @@
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+#ifdef CONFIG_RTS5260
+ { PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+#endif
{ 0, }
};
@@ -334,6 +337,9 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
{
+ if (pcr->ops->stop_cmd)
+ return pcr->ops->stop_cmd(pcr);
+
rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
@@ -826,7 +832,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
return err;
/* Wait SSC clock stable */
- udelay(10);
+ udelay(SSC_CLOCK_STABLE_WAIT);
err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
if (err < 0)
return err;
@@ -963,6 +969,20 @@ static void rtsx_pci_card_detect(struct work_struct *work)
pcr->slots[RTSX_MS_CARD].p_dev);
}
+void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
+{
+ if (pcr->ops->process_ocp)
+ pcr->ops->process_ocp(pcr);
+}
+
+int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
+{
+ if (pcr->option.ocp_en)
+ rtsx_pci_process_ocp(pcr);
+
+ return 0;
+}
+
static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
{
struct rtsx_pcr *pcr = dev_id;
@@ -987,6 +1007,9 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
int_reg &= (pcr->bier | 0x7FFFFF);
+ if (int_reg & SD_OC_INT)
+ rtsx_pci_process_ocp_interrupt(pcr);
+
if (int_reg & SD_INT) {
if (int_reg & SD_EXIST) {
pcr->card_inserted |= SD_EXIST;
@@ -1119,6 +1142,102 @@ static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
}
#endif
+void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
+{
+ u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
+
+ if (pcr->ops->enable_ocp)
+ pcr->ops->enable_ocp(pcr);
+ else
+ rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
+
+}
+
+void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
+{
+ u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
+
+ if (pcr->ops->disable_ocp)
+ pcr->ops->disable_ocp(pcr);
+ else
+ rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
+}
+
+void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
+{
+ if (pcr->ops->init_ocp) {
+ pcr->ops->init_ocp(pcr);
+ } else {
+ struct rtsx_cr_option *option = &(pcr->option);
+
+ if (option->ocp_en) {
+ u8 val = option->sd_400mA_ocp_thd;
+
+ rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
+ rtsx_pci_write_register(pcr, REG_OCPPARA1,
+ SD_OCP_TIME_MASK, SD_OCP_TIME_800);
+ rtsx_pci_write_register(pcr, REG_OCPPARA2,
+ SD_OCP_THD_MASK, val);
+ rtsx_pci_write_register(pcr, REG_OCPGLITCH,
+ SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch);
+ rtsx_pci_enable_ocp(pcr);
+ } else {
+ /* OC power down */
+ rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
+ OC_POWER_DOWN);
+ }
+ }
+}
+
+int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
+{
+ if (pcr->ops->get_ocpstat)
+ return pcr->ops->get_ocpstat(pcr, val);
+ else
+ return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
+}
+
+void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
+{
+ if (pcr->ops->clear_ocpstat) {
+ pcr->ops->clear_ocpstat(pcr);
+ } else {
+ u8 mask = SD_OCP_INT_CLR | SD_OC_CLR;
+ u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
+
+ rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
+ rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
+ }
+}
+
+int sd_power_off_card3v3(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
+ MS_CLK_EN | SD40_CLK_EN, 0);
+ rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
+
+ rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
+
+ msleep(50);
+
+ rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
+
+ return 0;
+}
+
+int ms_power_off_card3v3(struct rtsx_pcr *pcr)
+{
+ rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
+ MS_CLK_EN | SD40_CLK_EN, 0);
+
+ rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
+
+ rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
+ rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
+
+ return 0;
+}
+
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
{
int err;
@@ -1189,6 +1308,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
case PID_5250:
case PID_524A:
case PID_525A:
+ case PID_5260:
rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1);
break;
default:
@@ -1265,6 +1385,11 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
case 0x5286:
rtl8402_init_params(pcr);
break;
+#ifdef CONFIG_RTS5260
+ case 0x5260:
+ rts5260_init_params(pcr);
+ break;
+#endif
}
pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h
index ec784e0..59090e1 100644
--- a/drivers/mfd/rtsx_pcr.h
+++ b/drivers/mfd/rtsx_pcr.h
@@ -44,6 +44,8 @@
#define ASPM_MASK_NEG 0xFC
#define MASK_8_BIT_DEF 0xFF
+#define SSC_CLOCK_STABLE_WAIT 130
+
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);
@@ -57,6 +59,9 @@
void rts524a_init_params(struct rtsx_pcr *pcr);
void rts525a_init_params(struct rtsx_pcr *pcr);
void rtl8411b_init_params(struct rtsx_pcr *pcr);
+#ifdef CONFIG_RTS5260
+void rts5260_init_params(struct rtsx_pcr *pcr);
+#endif
static inline u8 map_sd_drive(int idx)
{
@@ -99,5 +104,12 @@ static inline u8 map_sd_drive(int idx)
int rtsx_gops_pm_reset(struct rtsx_pcr *pcr);
int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency);
int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val);
+void rtsx_pci_init_ocp(struct rtsx_pcr *pcr);
+void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr);
+void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr);
+int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val);
+void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr);
+int sd_power_off_card3v3(struct rtsx_pcr *pcr);
+int ms_power_off_card3v3(struct rtsx_pcr *pcr);
#endif
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ef28a1c..1b27245 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -42,6 +42,8 @@ source "drivers/staging/rtl8188eu/Kconfig"
source "drivers/staging/rts5208/Kconfig"
+source "drivers/staging/rts5260/Kconfig"
+
source "drivers/staging/octeon/Kconfig"
source "drivers/staging/octeon-usb/Kconfig"
diff --git a/drivers/staging/rts5260/Kconfig b/drivers/staging/rts5260/Kconfig
new file mode 100644
index 0000000..5b7d328
--- /dev/null
+++ b/drivers/staging/rts5260/Kconfig
@@ -0,0 +1,6 @@
+config RTS5260
+ tristate "Realtek PCI-E Card Reader RTS5260 support"
+ help
+ Say Y here to include driver code to support the Realtek
+ PCI-E card reader rts5260.
+
diff --git a/drivers/staging/rts5260/rts5260.c b/drivers/staging/rts5260/rts5260.c
new file mode 100644
index 0000000..8dc22a67a
--- /dev/null
+++ b/drivers/staging/rts5260/rts5260.c
@@ -0,0 +1,748 @@
+/* Driver for Realtek PCI-Express card reader
+ *
+ * Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author:
+ * Steven FENG <steven_feng@realsil.com.cn>
+ * Rui FENG <rui_feng@realsil.com.cn>
+ * Wei WANG <wei_wang@realsil.com.cn>
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mfd/rtsx_pci.h>
+
+#include "rts5260.h"
+#include "../../mfd/rtsx_pcr.h"
+
+static u8 rts5260_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 rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
+{
+ u8 driving_3v3[6][3] = {
+ {0x94, 0x94, 0x94},
+ {0x11, 0x11, 0x18},
+ {0x55, 0x55, 0x5C},
+ {0x94, 0x94, 0x94},
+ {0x94, 0x94, 0x94},
+ {0xFF, 0xFF, 0xFF},
+ };
+ u8 driving_1v8[6][3] = {
+ {0x9A, 0x89, 0x89},
+ {0xC4, 0xC4, 0xC4},
+ {0x3C, 0x3C, 0x3C},
+ {0x9B, 0x99, 0x99},
+ {0x9A, 0x89, 0x89},
+ {0xFE, 0xFE, 0xFE},
+ };
+ 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_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
+ 0xFF, driving[drive_sel][0]);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
+ 0xFF, driving[drive_sel][1]);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
+ 0xFF, driving[drive_sel][2]);
+}
+
+static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
+{
+ u32 reg;
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
+ pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
+
+ if (!rtsx_vendor_setting_valid(reg)) {
+ pcr_dbg(pcr, "skip fetch vendor setting\n");
+ return;
+ }
+
+ pcr->aspm_en = rtsx_reg_to_aspm(reg);
+ pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
+ pcr->card_drive_sel &= 0x3F;
+ pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
+
+ rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
+ pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
+ pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
+ if (rtsx_reg_check_reverse_socket(reg))
+ pcr->flags |= PCR_REVERSE_SOCKET;
+}
+
+static void rtsx_base_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, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN);
+}
+
+static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, OLT_LED_CTL,
+ LED_SHINE_MASK, LED_SHINE_EN);
+}
+
+static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, OLT_LED_CTL,
+ LED_SHINE_MASK, LED_SHINE_DISABLE);
+}
+
+static int rts5260_turn_on_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0,
+ RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_ON);
+}
+
+static int rts5260_turn_off_led(struct rtsx_pcr *pcr)
+{
+ return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0,
+ RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_OFF);
+}
+
+/* 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 rts5260_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0xAA),
+ 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 rts5260_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ 0,
+};
+
+/* MS Pull Control Enable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5260_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+/* MS Pull Control Disable:
+ * MS CD ==> pull up
+ * others ==> pull down
+ */
+static const u32 rts5260_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
+ 0,
+};
+
+static int 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 rts5260_card_power_on(struct rtsx_pcr *pcr, int card)
+{
+ int err = 0;
+ struct rtsx_cr_option *option = &pcr->option;
+
+ 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);
+
+ msleep(20);
+
+ if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
+ pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
+ sd_set_sample_push_timing_sd30(pcr);
+
+ /* Initialize SD_CFG1 register */
+ rtsx_pci_write_register(pcr, SD_CFG1, 0xFF,
+ SD_CLK_DIVIDE_128 | SD_20_MODE);
+
+ 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);
+
+ rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, 0);
+
+ return err;
+}
+
+static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
+{
+ switch (voltage) {
+ case OUTPUT_3V3:
+ rtsx_pci_write_register(pcr, LDO_CONFIG2,
+ DV331812_VDD1, DV331812_VDD1);
+ rtsx_pci_write_register(pcr, LDO_DV18_CFG,
+ DV331812_MASK, DV331812_33);
+ rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
+ break;
+ case OUTPUT_1V8:
+ rtsx_pci_write_register(pcr, LDO_CONFIG2,
+ DV331812_VDD1, DV331812_VDD1);
+ rtsx_pci_write_register(pcr, LDO_DV18_CFG,
+ DV331812_MASK, DV331812_17);
+ rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
+ SD_IO_USING_1V8);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set pad drive */
+ rtsx_pci_init_cmd(pcr);
+ rts5260_fill_driving(pcr, voltage);
+ return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
+}
+
+static void rts5260_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 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_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;
+}
+
+static void rts5260_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, 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);
+
+ rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
+ RTS5260_DV331812_OCP_THD_MASK,
+ RTS5260_DV331812_OCP_THD_210);
+
+ mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
+ val = pcr->hw_param.ocp_glitch;
+ rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
+
+ 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);
+ }
+}
+
+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)
+{
+ 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);
+}
+
+int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
+{
+ return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
+}
+
+int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val)
+{
+ return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val);
+}
+
+void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
+{
+ u8 mask = 0;
+ 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,
+ DV3318_OCP_INT_CLR | DV3318_OCP_CLR,
+ DV3318_OCP_INT_CLR | DV3318_OCP_CLR);
+ udelay(10);
+ rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
+ rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
+ DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0);
+}
+
+void rts5260_process_ocp(struct rtsx_pcr *pcr)
+{
+ if (!pcr->option.ocp_en)
+ return;
+
+ rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
+ rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
+ if (pcr->card_exist & SD_EXIST)
+ sd_power_off_card3v3(pcr);
+ else if (pcr->card_exist & MS_EXIST)
+ 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);
+ 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);
+ }
+}
+
+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,
+ AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE);
+ /* Rest L1SUB Config */
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CLK_FORCE_CTL,
+ CLK_PM_EN, CLK_PM_EN);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWD_SUSPEND_EN, 0xFF, 0xFF);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
+ PWR_GATE_EN, PWR_GATE_EN);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, REG_VREF,
+ PWD_SUSPND_EN, PWD_SUSPND_EN);
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RBCTL,
+ U_AUTO_DMA_EN_MASK, U_AUTO_DMA_DISABLE);
+
+ if (pcr->flags & PCR_REVERSE_SOCKET)
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
+ else
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
+
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG,
+ OBFF_EN_MASK, OBFF_DISABLE);
+
+ err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)
+{
+ int lss_l1_1, lss_l1_2;
+
+ lss_l1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN)
+ | rtsx_check_dev_flag(pcr, PM_L1_1_EN);
+ lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN)
+ | rtsx_check_dev_flag(pcr, PM_L1_2_EN);
+
+ if (lss_l1_2) {
+ 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, PWR_FE_CTL,
+ 0xFF, PCIE_L1_2_PD_FE_EN);
+ } else if (lss_l1_1) {
+ pcr_dbg(pcr, "Set parameters for L1.1.");
+ rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
+ 0xFF, PCIE_L1_1_EN);
+ rtsx_pci_write_register(pcr, PWR_FE_CTL,
+ 0xFF, PCIE_L1_1_PD_FE_EN);
+ } else {
+ pcr_dbg(pcr, "Set parameters for L1.");
+ rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
+ 0xFF, PCIE_L1_0_EN);
+ rtsx_pci_write_register(pcr, PWR_FE_CTL,
+ 0xFF, PCIE_L1_0_PD_FE_EN);
+ }
+
+ rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_DPHY_RET_VALUE,
+ 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_MAC_RET_VALUE,
+ 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD30_RET_VALUE,
+ 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD40_RET_VALUE,
+ 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_L1_0_SYS_RET_VALUE,
+ 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
+ /*Option cut APHY*/
+ rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_0,
+ 0xFF, CFG_PCIE_APHY_OFF_0_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_1,
+ 0xFF, CFG_PCIE_APHY_OFF_1_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_2,
+ 0xFF, CFG_PCIE_APHY_OFF_2_DEFAULT);
+ rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_3,
+ 0xFF, CFG_PCIE_APHY_OFF_3_DEFAULT);
+ /*CDR DEC*/
+ rtsx_pci_write_register(pcr, PWC_CDR, 0xFF, PWC_CDR_DEFAULT);
+ /*PWMPFM*/
+ rtsx_pci_write_register(pcr, CFG_LP_FPWM_VALUE,
+ 0xFF, CFG_LP_FPWM_VALUE_DEFAULT);
+ /*No Power Saving WA*/
+ rtsx_pci_write_register(pcr, CFG_L1_0_CRC_MISC_RET_VALUE,
+ 0xFF, CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT);
+}
+
+static void rts5260_init_from_cfg(struct rtsx_pcr *pcr)
+{
+ struct rtsx_cr_option *option = &pcr->option;
+ u32 lval;
+
+ rtsx_pci_read_config_dword(pcr, PCR_ASPM_SETTING_5260, &lval);
+
+ if (lval & ASPM_L1_1_EN_MASK)
+ rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
+
+ if (lval & ASPM_L1_2_EN_MASK)
+ rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
+
+ if (lval & PM_L1_1_EN_MASK)
+ rtsx_set_dev_flag(pcr, PM_L1_1_EN);
+
+ if (lval & PM_L1_2_EN_MASK)
+ rtsx_set_dev_flag(pcr, PM_L1_2_EN);
+
+ rts5260_pwr_saving_setting(pcr);
+
+ if (option->ltr_en) {
+ u16 val;
+
+ pcie_capability_read_word(pcr->pci, 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 rts5260_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ struct rtsx_cr_option *option = &pcr->option;
+
+ /* Set mcu_cnt to 7 to ensure data can be sampled properly */
+ rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07);
+ rtsx_pci_write_register(pcr, SSC_DIV_N_0, 0xFF, 0x5D);
+
+ rts5260_init_from_cfg(pcr);
+
+ /* force no MDIO*/
+ rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4,
+ 0xFF, RTS5260_MIMO_DISABLE);
+ /*Modify SDVCC Tune Default Parameters!*/
+ rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
+ RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
+
+ rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
+
+ rts5260_init_hw(pcr);
+
+ /*
+ * 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_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
+ else
+ rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
+ FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);
+
+ return 0;
+}
+
+void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable)
+{
+ struct rtsx_cr_option *option = &pcr->option;
+ u8 val = 0;
+
+ if (pcr->aspm_enabled == enable)
+ return;
+
+ if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) {
+ if (enable)
+ val = pcr->aspm_en;
+ rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
+ ASPM_MASK_NEG, val);
+ } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) {
+ u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0;
+
+ if (!enable)
+ val = FORCE_ASPM_CTL0;
+ rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
+ }
+
+ pcr->aspm_enabled = enable;
+}
+
+static void rts5260_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active)
+{
+ struct rtsx_cr_option *option = &pcr->option;
+ u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR);
+ int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST);
+ 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;
+ }
+
+ if (aspm_L1_1 || aspm_L1_2) {
+ if (rtsx_check_dev_flag(pcr,
+ LTR_L1SS_PWR_GATE_CHECK_CARD_EN)) {
+ if (card_exist)
+ val &= ~L1OFF_MBIAS2_EN_5250;
+ else
+ val |= L1OFF_MBIAS2_EN_5250;
+ }
+ }
+ rtsx_set_l1off_sub(pcr, val);
+}
+
+static const struct pcr_ops rts5260_pcr_ops = {
+ .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
+ .turn_on_led = rts5260_turn_on_led,
+ .turn_off_led = rts5260_turn_off_led,
+ .extra_init_hw = rts5260_extra_init_hw,
+ .enable_auto_blink = rtsx_base_enable_auto_blink,
+ .disable_auto_blink = rtsx_base_disable_auto_blink,
+ .card_power_on = rts5260_card_power_on,
+ .card_power_off = rts5260_card_power_off,
+ .switch_output_voltage = rts5260_switch_output_voltage,
+ .force_power_down = rtsx_base_force_power_down,
+ .stop_cmd = rts5260_stop_cmd,
+ .set_aspm = rts5260_set_aspm,
+ .set_l1off_cfg_sub_d0 = rts5260_set_l1off_cfg_sub_d0,
+ .enable_ocp = rts5260_enable_ocp,
+ .disable_ocp = rts5260_disable_ocp,
+ .init_ocp = rts5260_init_ocp,
+ .process_ocp = rts5260_process_ocp,
+ .get_ocpstat = rts5260_get_ocpstat,
+ .clear_ocpstat = rts5260_clear_ocpstat,
+};
+
+void rts5260_init_params(struct rtsx_pcr *pcr)
+{
+ struct rtsx_cr_option *option = &pcr->option;
+ struct rtsx_hw_param *hw_param = &pcr->hw_param;
+
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+ pcr->num_slots = 2;
+
+ pcr->flags = 0;
+ pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
+ pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
+ pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
+ pcr->aspm_en = ASPM_L1_EN;
+ pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
+ pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
+
+ pcr->ic_version = rts5260_get_ic_version(pcr);
+ pcr->sd_pull_ctl_enable_tbl = rts5260_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl = rts5260_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl = rts5260_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl = rts5260_ms_pull_ctl_disable_tbl;
+
+ pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
+
+ pcr->ops = &rts5260_pcr_ops;
+
+ 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->dev_aspm_mode = DEV_ASPM_DYNAMIC;
+ option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF;
+ option->ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF;
+ option->ltr_l1off_snooze_sspwrgate =
+ LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF;
+
+ 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;
+ option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
+ option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
+}
diff --git a/drivers/staging/rts5260/rts5260.h b/drivers/staging/rts5260/rts5260.h
new file mode 100644
index 0000000..ff20eff
--- /dev/null
+++ b/drivers/staging/rts5260/rts5260.h
@@ -0,0 +1,45 @@
+#ifndef __RTS5260_H__
+#define __RTS5260_H__
+
+#define RTS5260_DVCC_CTRL 0xFF73
+#define RTS5260_DVCC_OCP_EN (0x01 << 7)
+#define RTS5260_DVCC_OCP_THD_MASK (0x07 << 4)
+#define RTS5260_DVCC_POWERON (0x01 << 3)
+#define RTS5260_DVCC_OCP_CL_EN (0x01 << 2)
+
+#define RTS5260_DVIO_CTRL 0xFF75
+#define RTS5260_DVIO_OCP_EN (0x01 << 7)
+#define RTS5260_DVIO_OCP_THD_MASK (0x07 << 4)
+#define RTS5260_DVIO_POWERON (0x01 << 3)
+#define RTS5260_DVIO_OCP_CL_EN (0x01 << 2)
+
+#define RTS5260_DV331812_CFG 0xFF71
+#define RTS5260_DV331812_OCP_EN (0x01 << 7)
+#define RTS5260_DV331812_OCP_THD_MASK (0x07 << 4)
+#define RTS5260_DV331812_POWERON (0x01 << 3)
+#define RTS5260_DV331812_SEL (0x01 << 2)
+#define RTS5260_DV331812_VDD1 (0x01 << 2)
+#define RTS5260_DV331812_VDD2 (0x00 << 2)
+
+#define RTS5260_DV331812_OCP_THD_120 (0x00 << 4)
+#define RTS5260_DV331812_OCP_THD_140 (0x01 << 4)
+#define RTS5260_DV331812_OCP_THD_160 (0x02 << 4)
+#define RTS5260_DV331812_OCP_THD_180 (0x03 << 4)
+#define RTS5260_DV331812_OCP_THD_210 (0x04 << 4)
+#define RTS5260_DV331812_OCP_THD_240 (0x05 << 4)
+#define RTS5260_DV331812_OCP_THD_270 (0x06 << 4)
+#define RTS5260_DV331812_OCP_THD_300 (0x07 << 4)
+
+#define RTS5260_DVIO_OCP_THD_250 (0x00 << 4)
+#define RTS5260_DVIO_OCP_THD_300 (0x01 << 4)
+#define RTS5260_DVIO_OCP_THD_350 (0x02 << 4)
+#define RTS5260_DVIO_OCP_THD_400 (0x03 << 4)
+#define RTS5260_DVIO_OCP_THD_450 (0x04 << 4)
+#define RTS5260_DVIO_OCP_THD_500 (0x05 << 4)
+#define RTS5260_DVIO_OCP_THD_550 (0x06 << 4)
+#define RTS5260_DVIO_OCP_THD_600 (0x07 << 4)
+
+#define RTS5260_DVCC_OCP_THD_550 (0x00 << 4)
+#define RTS5260_DVCC_OCP_THD_970 (0x05 << 4)
+
+#endif
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 57e23ad..d086acc 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -203,6 +203,7 @@
#define SD_DDR_MODE 0x04
#define SD_30_MODE 0x08
#define SD_CLK_DIVIDE_MASK 0xC0
+#define SD_MODE_SELECT_MASK 0x0C
#define SD_CFG2 0xFDA1
#define SD_CALCULATE_CRC7 0x00
#define SD_NO_CALCULATE_CRC7 0x80
@@ -226,6 +227,7 @@
#define SD_RSP_TYPE_R6 0x01
#define SD_RSP_TYPE_R7 0x01
#define SD_CFG3 0xFDA2
+#define SD30_CLK_END_EN 0x10
#define SD_RSP_80CLK_TIMEOUT_EN 0x01
#define SD_STAT1 0xFDA3
@@ -309,6 +311,12 @@
#define SD_DATA_STATE 0xFDB6
#define SD_DATA_IDLE 0x80
+#define REG_SD_STOP_SDCLK_CFG 0xFDB8
+#define SD30_CLK_STOP_CFG_EN 0x04
+#define SD30_CLK_STOP_CFG1 0x02
+#define SD30_CLK_STOP_CFG0 0x01
+#define REG_PRE_RW_MODE 0xFD70
+#define EN_INFINITE_MODE 0x01
#define SRCTL 0xFC13
@@ -433,6 +441,7 @@
#define CARD_CLK_EN 0xFD69
#define SD_CLK_EN 0x04
#define MS_CLK_EN 0x08
+#define SD40_CLK_EN 0x10
#define SDIO_CTRL 0xFD6B
#define CD_PAD_CTL 0xFD73
#define CD_DISABLE_MASK 0x07
@@ -452,8 +461,8 @@
#define FPDCTL 0xFC00
#define SSC_POWER_DOWN 0x01
#define SD_OC_POWER_DOWN 0x02
-#define ALL_POWER_DOWN 0x07
-#define OC_POWER_DOWN 0x06
+#define ALL_POWER_DOWN 0x03
+#define OC_POWER_DOWN 0x02
#define PDINFO 0xFC01
#define CLK_CTL 0xFC02
@@ -489,6 +498,9 @@
#define FPGA_PULL_CTL 0xFC1D
#define OLT_LED_CTL 0xFC1E
+#define LED_SHINE_MASK 0x08
+#define LED_SHINE_EN 0x08
+#define LED_SHINE_DISABLE 0x00
#define GPIO_CTL 0xFC1F
#define LDO_CTL 0xFC1E
@@ -510,7 +522,11 @@
#define BPP_LDO_ON 0x00
#define BPP_LDO_SUSPEND 0x02
#define BPP_LDO_OFF 0x03
+#define EFUSE_CTL 0xFC30
+#define EFUSE_ADD 0xFC31
#define SYS_VER 0xFC32
+#define EFUSE_DATAL 0xFC34
+#define EFUSE_DATAH 0xFC35
#define CARD_PULL_CTL1 0xFD60
#define CARD_PULL_CTL2 0xFD61
@@ -552,6 +568,9 @@
#define RBBC1 0xFE2F
#define RBDAT 0xFE30
#define RBCTL 0xFE34
+#define U_AUTO_DMA_EN_MASK 0x20
+#define U_AUTO_DMA_DISABLE 0x00
+#define RB_FLUSH 0x80
#define CFGADDR0 0xFE35
#define CFGADDR1 0xFE36
#define CFGDATA0 0xFE37
@@ -580,6 +599,8 @@
#define LTR_LATENCY_MODE_HW 0
#define LTR_LATENCY_MODE_SW BIT(6)
#define OBFF_CFG 0xFE4C
+#define OBFF_EN_MASK 0x03
+#define OBFF_DISABLE 0x00
#define CDRESUMECTL 0xFE52
#define WAKE_SEL_CTL 0xFE54
@@ -594,6 +615,7 @@
#define FORCE_ASPM_L0_EN 0x01
#define FORCE_ASPM_NO_ASPM 0x00
#define PM_CLK_FORCE_CTL 0xFE58
+#define CLK_PM_EN 0x01
#define FUNC_FORCE_CTL 0xFE59
#define FUNC_FORCE_UPME_XMT_DBG 0x02
#define PERST_GLITCH_WIDTH 0xFE5C
@@ -619,14 +641,23 @@
#define LDO_PWR_SEL 0xFE78
#define L1SUB_CONFIG1 0xFE8D
+#define AUX_CLK_ACTIVE_SEL_MASK 0x01
+#define MAC_CKSW_DONE 0x00
#define L1SUB_CONFIG2 0xFE8E
#define L1SUB_AUTO_CFG 0x02
#define L1SUB_CONFIG3 0xFE8F
#define L1OFF_MBIAS2_EN_5250 BIT(7)
#define DUMMY_REG_RESET_0 0xFE90
+#define IC_VERSION_MASK 0x0F
+#define REG_VREF 0xFE97
+#define PWD_SUSPND_EN 0x10
+#define RTS5260_DMA_RST_CTL_0 0xFEBF
+#define RTS5260_DMA_RST 0x80
+#define RTS5260_ADMA3_RST 0x40
#define AUTOLOAD_CFG_BASE 0xFF00
+#define RELINK_TIME_MASK 0x01
#define PETXCFG 0xFF03
#define FORCE_CLKREQ_DELINK_MASK BIT(7)
#define FORCE_CLKREQ_LOW 0x80
@@ -666,15 +697,24 @@
#define LDO_DV18_CFG 0xFF70
#define LDO_DV18_SR_MASK 0xC0
#define LDO_DV18_SR_DF 0x40
+#define DV331812_MASK 0x70
+#define DV331812_33 0x70
+#define DV331812_17 0x30
#define LDO_CONFIG2 0xFF71
#define LDO_D3318_MASK 0x07
#define LDO_D3318_33V 0x07
#define LDO_D3318_18V 0x02
+#define DV331812_VDD1 0x04
+#define DV331812_POWERON 0x08
+#define DV331812_POWEROFF 0x00
#define LDO_VCC_CFG0 0xFF72
#define LDO_VCC_LMTVTH_MASK 0x30
#define LDO_VCC_LMTVTH_2A 0x10
+/*RTS5260*/
+#define RTS5260_DVCC_TUNE_MASK 0x70
+#define RTS5260_DVCC_33 0x70
#define LDO_VCC_CFG1 0xFF73
#define LDO_VCC_REF_TUNE_MASK 0x30
@@ -683,6 +723,10 @@
#define LDO_VCC_1V8 0x04
#define LDO_VCC_3V3 0x07
#define LDO_VCC_LMT_EN 0x08
+/*RTS5260*/
+#define LDO_POW_SDVDD1_MASK 0x08
+#define LDO_POW_SDVDD1_ON 0x08
+#define LDO_POW_SDVDD1_OFF 0x00
#define LDO_VIO_CFG 0xFF75
#define LDO_VIO_SR_MASK 0xC0
@@ -710,6 +754,160 @@
#define SD_VIO_LDO_1V8 0x40
#define SD_VIO_LDO_3V3 0x70
+#define RTS5260_AUTOLOAD_CFG4 0xFF7F
+#define RTS5260_MIMO_DISABLE 0x8A
+
+#define RTS5260_REG_GPIO_CTL0 0xFC1A
+#define RTS5260_REG_GPIO_MASK 0x01
+#define RTS5260_REG_GPIO_ON 0x01
+#define RTS5260_REG_GPIO_OFF 0x00
+
+#define PWR_GLOBAL_CTRL 0xF200
+#define PCIE_L1_2_EN 0x0C
+#define PCIE_L1_1_EN 0x0A
+#define PCIE_L1_0_EN 0x09
+#define PWR_FE_CTL 0xF201
+#define PCIE_L1_2_PD_FE_EN 0x0C
+#define PCIE_L1_1_PD_FE_EN 0x0A
+#define PCIE_L1_0_PD_FE_EN 0x09
+#define CFG_PCIE_APHY_OFF_0 0xF204
+#define CFG_PCIE_APHY_OFF_0_DEFAULT 0xBF
+#define CFG_PCIE_APHY_OFF_1 0xF205
+#define CFG_PCIE_APHY_OFF_1_DEFAULT 0xFF
+#define CFG_PCIE_APHY_OFF_2 0xF206
+#define CFG_PCIE_APHY_OFF_2_DEFAULT 0x01
+#define CFG_PCIE_APHY_OFF_3 0xF207
+#define CFG_PCIE_APHY_OFF_3_DEFAULT 0x00
+#define CFG_L1_0_PCIE_MAC_RET_VALUE 0xF20C
+#define CFG_L1_0_PCIE_DPHY_RET_VALUE 0xF20E
+#define CFG_L1_0_SYS_RET_VALUE 0xF210
+#define CFG_L1_0_CRC_MISC_RET_VALUE 0xF212
+#define CFG_L1_0_CRC_SD30_RET_VALUE 0xF214
+#define CFG_L1_0_CRC_SD40_RET_VALUE 0xF216
+#define CFG_LP_FPWM_VALUE 0xF219
+#define CFG_LP_FPWM_VALUE_DEFAULT 0x18
+#define PWC_CDR 0xF253
+#define PWC_CDR_DEFAULT 0x03
+#define CFG_L1_0_RET_VALUE_DEFAULT 0x1B
+#define CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT 0x0C
+
+/* OCPCTL */
+#define SD_DETECT_EN 0x08
+#define SD_OCP_INT_EN 0x04
+#define SD_OCP_INT_CLR 0x02
+#define SD_OC_CLR 0x01
+
+#define SDVIO_DETECT_EN (1 << 7)
+#define SDVIO_OCP_INT_EN (1 << 6)
+#define SDVIO_OCP_INT_CLR (1 << 5)
+#define SDVIO_OC_CLR (1 << 4)
+
+/* OCPSTAT */
+#define SD_OCP_DETECT 0x08
+#define SD_OC_NOW 0x04
+#define SD_OC_EVER 0x02
+
+#define SDVIO_OC_NOW (1 << 6)
+#define SDVIO_OC_EVER (1 << 5)
+
+#define REG_OCPCTL 0xFD6A
+#define REG_OCPSTAT 0xFD6E
+#define REG_OCPGLITCH 0xFD6C
+#define REG_OCPPARA1 0xFD6B
+#define REG_OCPPARA2 0xFD6D
+
+/* rts5260 DV3318 OCP-related registers */
+#define REG_DV3318_OCPCTL 0xFD89
+#define DV3318_OCP_TIME_MASK 0xF0
+#define DV3318_DETECT_EN 0x08
+#define DV3318_OCP_INT_EN 0x04
+#define DV3318_OCP_INT_CLR 0x02
+#define DV3318_OCP_CLR 0x01
+
+#define REG_DV3318_OCPSTAT 0xFD8A
+#define DV3318_OCP_GlITCH_TIME_MASK 0xF0
+#define DV3318_OCP_DETECT 0x08
+#define DV3318_OCP_NOW 0x04
+#define DV3318_OCP_EVER 0x02
+
+#define SD_OCP_GLITCH_MASK 0x0F
+
+/* OCPPARA1 */
+#define SDVIO_OCP_TIME_60 0x00
+#define SDVIO_OCP_TIME_100 0x10
+#define SDVIO_OCP_TIME_200 0x20
+#define SDVIO_OCP_TIME_400 0x30
+#define SDVIO_OCP_TIME_600 0x40
+#define SDVIO_OCP_TIME_800 0x50
+#define SDVIO_OCP_TIME_1100 0x60
+#define SDVIO_OCP_TIME_MASK 0x70
+
+#define SD_OCP_TIME_60 0x00
+#define SD_OCP_TIME_100 0x01
+#define SD_OCP_TIME_200 0x02
+#define SD_OCP_TIME_400 0x03
+#define SD_OCP_TIME_600 0x04
+#define SD_OCP_TIME_800 0x05
+#define SD_OCP_TIME_1100 0x06
+#define SD_OCP_TIME_MASK 0x07
+
+/* OCPPARA2 */
+#define SDVIO_OCP_THD_190 0x00
+#define SDVIO_OCP_THD_250 0x10
+#define SDVIO_OCP_THD_320 0x20
+#define SDVIO_OCP_THD_380 0x30
+#define SDVIO_OCP_THD_440 0x40
+#define SDVIO_OCP_THD_500 0x50
+#define SDVIO_OCP_THD_570 0x60
+#define SDVIO_OCP_THD_630 0x70
+#define SDVIO_OCP_THD_MASK 0x70
+
+#define SD_OCP_THD_450 0x00
+#define SD_OCP_THD_550 0x01
+#define SD_OCP_THD_650 0x02
+#define SD_OCP_THD_750 0x03
+#define SD_OCP_THD_850 0x04
+#define SD_OCP_THD_950 0x05
+#define SD_OCP_THD_1050 0x06
+#define SD_OCP_THD_1150 0x07
+#define SD_OCP_THD_MASK 0x07
+
+#define SDVIO_OCP_GLITCH_MASK 0xF0
+#define SDVIO_OCP_GLITCH_NONE 0x00
+#define SDVIO_OCP_GLITCH_50U 0x10
+#define SDVIO_OCP_GLITCH_100U 0x20
+#define SDVIO_OCP_GLITCH_200U 0x30
+#define SDVIO_OCP_GLITCH_600U 0x40
+#define SDVIO_OCP_GLITCH_800U 0x50
+#define SDVIO_OCP_GLITCH_1M 0x60
+#define SDVIO_OCP_GLITCH_2M 0x70
+#define SDVIO_OCP_GLITCH_3M 0x80
+#define SDVIO_OCP_GLITCH_4M 0x90
+#define SDVIO_OCP_GLIVCH_5M 0xA0
+#define SDVIO_OCP_GLITCH_6M 0xB0
+#define SDVIO_OCP_GLITCH_7M 0xC0
+#define SDVIO_OCP_GLITCH_8M 0xD0
+#define SDVIO_OCP_GLITCH_9M 0xE0
+#define SDVIO_OCP_GLITCH_10M 0xF0
+
+#define SD_OCP_GLITCH_MASK 0x0F
+#define SD_OCP_GLITCH_NONE 0x00
+#define SD_OCP_GLITCH_50U 0x01
+#define SD_OCP_GLITCH_100U 0x02
+#define SD_OCP_GLITCH_200U 0x03
+#define SD_OCP_GLITCH_600U 0x04
+#define SD_OCP_GLITCH_800U 0x05
+#define SD_OCP_GLITCH_1M 0x06
+#define SD_OCP_GLITCH_2M 0x07
+#define SD_OCP_GLITCH_3M 0x08
+#define SD_OCP_GLITCH_4M 0x09
+#define SD_OCP_GLIVCH_5M 0x0A
+#define SD_OCP_GLITCH_6M 0x0B
+#define SD_OCP_GLITCH_7M 0x0C
+#define SD_OCP_GLITCH_8M 0x0D
+#define SD_OCP_GLITCH_9M 0x0E
+#define SD_OCP_GLITCH_10M 0x0F
+
/* Phy register */
#define PHY_PCR 0x00
#define PHY_PCR_FORCE_CODE 0xB000
@@ -856,6 +1054,7 @@
#define PCR_ASPM_SETTING_REG1 0x160
#define PCR_ASPM_SETTING_REG2 0x168
+#define PCR_ASPM_SETTING_5260 0x178
#define PCR_SETTING_REG1 0x724
#define PCR_SETTING_REG2 0x814
@@ -889,6 +1088,7 @@ struct pcr_ops {
int (*conv_clk_and_div_n)(int clk, int dir);
void (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state);
+ void (*stop_cmd)(struct rtsx_pcr *pcr);
void (*set_aspm)(struct rtsx_pcr *pcr, bool enable);
int (*set_ltr_latency)(struct rtsx_pcr *pcr, u32 latency);
@@ -896,6 +1096,12 @@ struct pcr_ops {
void (*set_l1off_cfg_sub_d0)(struct rtsx_pcr *pcr, int active);
void (*full_on)(struct rtsx_pcr *pcr);
void (*power_saving)(struct rtsx_pcr *pcr);
+ void (*enable_ocp)(struct rtsx_pcr *pcr);
+ void (*disable_ocp)(struct rtsx_pcr *pcr);
+ void (*init_ocp)(struct rtsx_pcr *pcr);
+ void (*process_ocp)(struct rtsx_pcr *pcr);
+ int (*get_ocpstat)(struct rtsx_pcr *pcr, u8 *val);
+ void (*clear_ocpstat)(struct rtsx_pcr *pcr);
};
enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN};
@@ -934,6 +1140,9 @@ enum dev_aspm_mode {
* @l1_snooze_delay: l1 snooze delay
* @ltr_l1off_sspwrgate: ltr l1off sspwrgate
* @ltr_l1off_snooze_sspwrgate: ltr l1off snooze sspwrgate
+ * @ocp_en: enable ocp flag
+ * @sd_400mA_ocp_thd: 400mA ocp thd
+ * @sd_800mA_ocp_thd: 800mA ocp thd
*/
struct rtsx_cr_option {
u32 dev_flags;
@@ -948,6 +1157,19 @@ struct rtsx_cr_option {
u32 l1_snooze_delay;
u8 ltr_l1off_sspwrgate;
u8 ltr_l1off_snooze_sspwrgate;
+ bool ocp_en;
+ u8 sd_400mA_ocp_thd;
+ u8 sd_800mA_ocp_thd;
+};
+
+/*
+ * struct rtsx_hw_param - card reader hardware param
+ * @interrupt_en: indicate which interrutp enable
+ * @ocp_glitch: ocp glitch time
+ */
+struct rtsx_hw_param {
+ u32 interrupt_en;
+ u8 ocp_glitch;
};
#define rtsx_set_dev_flag(cr, flag) \
@@ -962,6 +1184,7 @@ struct rtsx_pcr {
unsigned int id;
int pcie_cap;
struct rtsx_cr_option option;
+ struct rtsx_hw_param hw_param;
/* pci resources */
unsigned long addr;
@@ -1041,12 +1264,15 @@ struct rtsx_pcr {
struct rtsx_slot *slots;
u8 dma_error_count;
+ u8 ocp_stat;
+ u8 ocp_stat2;
};
#define PID_524A 0x524A
-#define PID_5249 0x5249
-#define PID_5250 0x5250
+#define PID_5249 0x5249
+#define PID_5250 0x5250
#define PID_525A 0x525A
+#define PID_5260 0x5260
#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
#define PCI_VID(pcr) ((pcr)->pci->vendor)
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 8:50 [PATCH] staging: rtsx: Add support for RTS5260 rui_feng
@ 2017-10-13 9:26 ` Greg KH
2017-10-13 9:54 ` Lee Jones
2017-10-13 18:28 ` Mario Limonciello
1 sibling, 1 reply; 13+ messages in thread
From: Greg KH @ 2017-10-13 9:26 UTC (permalink / raw)
To: rui_feng; +Cc: lee.jones, linux-kernel, devel, ricky_wu
On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> From: rui_feng <rui_feng@realsil.com.cn>
>
> Add support for new chip rts5260.
> In order to support rts5260,the definitions of some internal
> registers and workflow have to be modified and are different from its
> predecessors and OCP function is added for RTS5260.
> So we need this patch to ensure RTS5260 can work.
>
> Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
Your from and signed-off-by name does not match :(
> ---
> drivers/mfd/Makefile | 4 +
> drivers/mfd/rtsx_pcr.c | 127 ++++++-
> drivers/mfd/rtsx_pcr.h | 12 +
> drivers/staging/Kconfig | 2 +
> drivers/staging/rts5260/Kconfig | 6 +
> drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> drivers/staging/rts5260/rts5260.h | 45 +++
> include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
I do not see a reason why this is a staging driver. Where is the TODO
file listing what needs to be done to get it out of staging? Why can it
not just go into the "real" part of the kernel?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 9:26 ` Greg KH
@ 2017-10-13 9:54 ` Lee Jones
2017-10-13 9:59 ` Greg KH
0 siblings, 1 reply; 13+ messages in thread
From: Lee Jones @ 2017-10-13 9:54 UTC (permalink / raw)
To: Greg KH; +Cc: rui_feng, linux-kernel, devel, ricky_wu
On Fri, 13 Oct 2017, Greg KH wrote:
> On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> > From: rui_feng <rui_feng@realsil.com.cn>
> >
> > Add support for new chip rts5260.
> > In order to support rts5260,the definitions of some internal
> > registers and workflow have to be modified and are different from its
> > predecessors and OCP function is added for RTS5260.
> > So we need this patch to ensure RTS5260 can work.
> >
> > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
>
> Your from and signed-off-by name does not match :(
>
> > ---
> > drivers/mfd/Makefile | 4 +
> > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > drivers/mfd/rtsx_pcr.h | 12 +
> > drivers/staging/Kconfig | 2 +
> > drivers/staging/rts5260/Kconfig | 6 +
> > drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> > drivers/staging/rts5260/rts5260.h | 45 +++
> > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
>
> I do not see a reason why this is a staging driver. Where is the TODO
> file listing what needs to be done to get it out of staging? Why can it
> not just go into the "real" part of the kernel?
It's not a staging driver. Rui's focus appears to be to have this
driver accepted into Mainline by hook or by crock. He's tried MFD,
Misc and now Staging!
Background:
There are a number of drivers in this family which currently reside in
MFD. These were accepted before my time. After a recent review I've
made the decision that these aren't MFD drivers at all.
MFD drivers are ones which aid in registering and setting up shared
resources for sub-devices which reside on the same piece of silicon.
This driver does basically none of that. Instead it *is* the (what we
describe above as) sub-device. It does everything.
In the absence of a subsystem which covers this type of device, I
suggested Misk as a good location to place these drivers.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 9:54 ` Lee Jones
@ 2017-10-13 9:59 ` Greg KH
2017-10-13 10:11 ` Lee Jones
2017-10-16 5:58 ` 冯锐
0 siblings, 2 replies; 13+ messages in thread
From: Greg KH @ 2017-10-13 9:59 UTC (permalink / raw)
To: Lee Jones; +Cc: devel, ricky_wu, linux-kernel, rui_feng
On Fri, Oct 13, 2017 at 10:54:22AM +0100, Lee Jones wrote:
> On Fri, 13 Oct 2017, Greg KH wrote:
>
> > On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> > > From: rui_feng <rui_feng@realsil.com.cn>
> > >
> > > Add support for new chip rts5260.
> > > In order to support rts5260,the definitions of some internal
> > > registers and workflow have to be modified and are different from its
> > > predecessors and OCP function is added for RTS5260.
> > > So we need this patch to ensure RTS5260 can work.
> > >
> > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> >
> > Your from and signed-off-by name does not match :(
> >
> > > ---
> > > drivers/mfd/Makefile | 4 +
> > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > drivers/mfd/rtsx_pcr.h | 12 +
> > > drivers/staging/Kconfig | 2 +
> > > drivers/staging/rts5260/Kconfig | 6 +
> > > drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> >
> > I do not see a reason why this is a staging driver. Where is the TODO
> > file listing what needs to be done to get it out of staging? Why can it
> > not just go into the "real" part of the kernel?
>
> It's not a staging driver. Rui's focus appears to be to have this
> driver accepted into Mainline by hook or by crock. He's tried MFD,
> Misc and now Staging!
Yeah, I've watched it too :)
> Background:
>
> There are a number of drivers in this family which currently reside in
> MFD. These were accepted before my time. After a recent review I've
> made the decision that these aren't MFD drivers at all.
>
> MFD drivers are ones which aid in registering and setting up shared
> resources for sub-devices which reside on the same piece of silicon.
> This driver does basically none of that. Instead it *is* the (what we
> describe above as) sub-device. It does everything.
I agree with your assessment.
> In the absence of a subsystem which covers this type of device, I
> suggested Misk as a good location to place these drivers.
What type of device is this thing? I can't seem to figure that out. If
we can determine that, then we can find the proper place for it in the
kernel.
Rui, what does this hardware do? What is the interface between the
hardware and userspace that this driver is creating?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 9:59 ` Greg KH
@ 2017-10-13 10:11 ` Lee Jones
2017-10-13 10:21 ` Greg KH
2017-10-16 5:58 ` 冯锐
1 sibling, 1 reply; 13+ messages in thread
From: Lee Jones @ 2017-10-13 10:11 UTC (permalink / raw)
To: Greg KH; +Cc: devel, ricky_wu, linux-kernel, rui_feng
On Fri, 13 Oct 2017, Greg KH wrote:
> On Fri, Oct 13, 2017 at 10:54:22AM +0100, Lee Jones wrote:
> > On Fri, 13 Oct 2017, Greg KH wrote:
> >
> > > On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> > > > From: rui_feng <rui_feng@realsil.com.cn>
> > > >
> > > > Add support for new chip rts5260.
> > > > In order to support rts5260,the definitions of some internal
> > > > registers and workflow have to be modified and are different from its
> > > > predecessors and OCP function is added for RTS5260.
> > > > So we need this patch to ensure RTS5260 can work.
> > > >
> > > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > >
> > > Your from and signed-off-by name does not match :(
> > >
> > > > ---
> > > > drivers/mfd/Makefile | 4 +
> > > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > > drivers/mfd/rtsx_pcr.h | 12 +
> > > > drivers/staging/Kconfig | 2 +
> > > > drivers/staging/rts5260/Kconfig | 6 +
> > > > drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> > > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > >
> > > I do not see a reason why this is a staging driver. Where is the TODO
> > > file listing what needs to be done to get it out of staging? Why can it
> > > not just go into the "real" part of the kernel?
> >
> > It's not a staging driver. Rui's focus appears to be to have this
> > driver accepted into Mainline by hook or by crock. He's tried MFD,
> > Misc and now Staging!
>
> Yeah, I've watched it too :)
>
> > Background:
> >
> > There are a number of drivers in this family which currently reside in
> > MFD. These were accepted before my time. After a recent review I've
> > made the decision that these aren't MFD drivers at all.
> >
> > MFD drivers are ones which aid in registering and setting up shared
> > resources for sub-devices which reside on the same piece of silicon.
> > This driver does basically none of that. Instead it *is* the (what we
> > describe above as) sub-device. It does everything.
>
> I agree with your assessment.
>
> > In the absence of a subsystem which covers this type of device, I
> > suggested Misk as a good location to place these drivers.
Sorry, that should have been "Misc"
> What type of device is this thing? I can't seem to figure that out. If
> we can determine that, then we can find the proper place for it in the
> kernel.
It's a card (MMC, (u)SD, etc) reader.
> Rui, what does this hardware do? What is the interface between the
> hardware and userspace that this driver is creating?
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 10:11 ` Lee Jones
@ 2017-10-13 10:21 ` Greg KH
2017-10-13 10:30 ` 答复: " 冯锐
0 siblings, 1 reply; 13+ messages in thread
From: Greg KH @ 2017-10-13 10:21 UTC (permalink / raw)
To: Lee Jones; +Cc: devel, ricky_wu, linux-kernel, rui_feng
On Fri, Oct 13, 2017 at 11:11:15AM +0100, Lee Jones wrote:
> On Fri, 13 Oct 2017, Greg KH wrote:
>
> > On Fri, Oct 13, 2017 at 10:54:22AM +0100, Lee Jones wrote:
> > > On Fri, 13 Oct 2017, Greg KH wrote:
> > >
> > > > On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> > > > > From: rui_feng <rui_feng@realsil.com.cn>
> > > > >
> > > > > Add support for new chip rts5260.
> > > > > In order to support rts5260,the definitions of some internal
> > > > > registers and workflow have to be modified and are different from its
> > > > > predecessors and OCP function is added for RTS5260.
> > > > > So we need this patch to ensure RTS5260 can work.
> > > > >
> > > > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > > >
> > > > Your from and signed-off-by name does not match :(
> > > >
> > > > > ---
> > > > > drivers/mfd/Makefile | 4 +
> > > > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > > > drivers/mfd/rtsx_pcr.h | 12 +
> > > > > drivers/staging/Kconfig | 2 +
> > > > > drivers/staging/rts5260/Kconfig | 6 +
> > > > > drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> > > > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > > >
> > > > I do not see a reason why this is a staging driver. Where is the TODO
> > > > file listing what needs to be done to get it out of staging? Why can it
> > > > not just go into the "real" part of the kernel?
> > >
> > > It's not a staging driver. Rui's focus appears to be to have this
> > > driver accepted into Mainline by hook or by crock. He's tried MFD,
> > > Misc and now Staging!
> >
> > Yeah, I've watched it too :)
> >
> > > Background:
> > >
> > > There are a number of drivers in this family which currently reside in
> > > MFD. These were accepted before my time. After a recent review I've
> > > made the decision that these aren't MFD drivers at all.
> > >
> > > MFD drivers are ones which aid in registering and setting up shared
> > > resources for sub-devices which reside on the same piece of silicon.
> > > This driver does basically none of that. Instead it *is* the (what we
> > > describe above as) sub-device. It does everything.
> >
> > I agree with your assessment.
> >
> > > In the absence of a subsystem which covers this type of device, I
> > > suggested Misk as a good location to place these drivers.
>
> Sorry, that should have been "Misc"
>
> > What type of device is this thing? I can't seem to figure that out. If
> > we can determine that, then we can find the proper place for it in the
> > kernel.
>
> It's a card (MMC, (u)SD, etc) reader.
Ok, how does it hook up to the hardware to talk to the reader?
And we have other card readers in drivers/misc/ so maybe that is the
right place for it, depending on the api to the hardware.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* 答复: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 10:21 ` Greg KH
@ 2017-10-13 10:30 ` 冯锐
0 siblings, 0 replies; 13+ messages in thread
From: 冯锐 @ 2017-10-13 10:30 UTC (permalink / raw)
To: Greg KH, Lee Jones; +Cc: devel, ricky_wu, linux-kernel, 王炜
Loop Wei Wang
> On Fri, Oct 13, 2017 at 11:11:15AM +0100, Lee Jones wrote:
> > On Fri, 13 Oct 2017, Greg KH wrote:
> >
> > > On Fri, Oct 13, 2017 at 10:54:22AM +0100, Lee Jones wrote:
> > > > On Fri, 13 Oct 2017, Greg KH wrote:
> > > >
> > > > > On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn
> wrote:
> > > > > > From: rui_feng <rui_feng@realsil.com.cn>
> > > > > >
> > > > > > Add support for new chip rts5260.
> > > > > > In order to support rts5260,the definitions of some internal
> > > > > > registers and workflow have to be modified and are different
> > > > > > from its predecessors and OCP function is added for RTS5260.
> > > > > > So we need this patch to ensure RTS5260 can work.
> > > > > >
> > > > > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > > > >
> > > > > Your from and signed-off-by name does not match :(
> > > > >
> > > > > > ---
> > > > > > drivers/mfd/Makefile | 4 +
> > > > > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > > > > drivers/mfd/rtsx_pcr.h | 12 +
> > > > > > drivers/staging/Kconfig | 2 +
> > > > > > drivers/staging/rts5260/Kconfig | 6 +
> > > > > > drivers/staging/rts5260/rts5260.c | 748
> > > > > > ++++++++++++++++++++++++++++++++++++++
> > > > > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > > > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > > > >
> > > > > I do not see a reason why this is a staging driver. Where is
> > > > > the TODO file listing what needs to be done to get it out of
> > > > > staging? Why can it not just go into the "real" part of the kernel?
> > > >
> > > > It's not a staging driver. Rui's focus appears to be to have this
> > > > driver accepted into Mainline by hook or by crock. He's tried
> > > > MFD, Misc and now Staging!
> > >
> > > Yeah, I've watched it too :)
> > >
> > > > Background:
> > > >
> > > > There are a number of drivers in this family which currently
> > > > reside in MFD. These were accepted before my time. After a
> > > > recent review I've made the decision that these aren't MFD drivers at all.
> > > >
> > > > MFD drivers are ones which aid in registering and setting up
> > > > shared resources for sub-devices which reside on the same piece of
> silicon.
> > > > This driver does basically none of that. Instead it *is* the
> > > > (what we describe above as) sub-device. It does everything.
> > >
> > > I agree with your assessment.
> > >
> > > > In the absence of a subsystem which covers this type of device, I
> > > > suggested Misk as a good location to place these drivers.
> >
> > Sorry, that should have been "Misc"
> >
> > > What type of device is this thing? I can't seem to figure that out.
> > > If we can determine that, then we can find the proper place for it
> > > in the kernel.
> >
> > It's a card (MMC, (u)SD, etc) reader.
>
> Ok, how does it hook up to the hardware to talk to the reader?
>
> And we have other card readers in drivers/misc/ so maybe that is the right
> place for it, depending on the api to the hardware.
>
> thanks,
>
> greg k-h
>
> ------Please consider the environment before printing this e-mail.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: staging: rtsx: Add support for RTS5260
2017-10-13 8:50 [PATCH] staging: rtsx: Add support for RTS5260 rui_feng
2017-10-13 9:26 ` Greg KH
@ 2017-10-13 18:28 ` Mario Limonciello
2017-10-13 21:15 ` Lee Jones
1 sibling, 1 reply; 13+ messages in thread
From: Mario Limonciello @ 2017-10-13 18:28 UTC (permalink / raw)
To: rui_feng, lee.jones, gregkh, linux-kernel, devel; +Cc: ricky_wu, wei_wang
On 10/13/2017 03:50 AM, rui_feng@realsil.com.cn wrote:
> From: rui_feng <rui_feng@realsil.com.cn>
>
> Add support for new chip rts5260.
> In order to support rts5260,the definitions of some internal
> registers and workflow have to be modified and are different from its
> predecessors and OCP function is added for RTS5260.
> So we need this patch to ensure RTS5260 can work.
>
> Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> ---
> drivers/mfd/Makefile | 4 +
> drivers/mfd/rtsx_pcr.c | 127 ++++++-
> drivers/mfd/rtsx_pcr.h | 12 +
> drivers/staging/Kconfig | 2 +
> drivers/staging/rts5260/Kconfig | 6 +
> drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> drivers/staging/rts5260/rts5260.h | 45 +++
> include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> 8 files changed, 1173 insertions(+), 5 deletions(-)
> create mode 100644 drivers/staging/rts5260/Kconfig
> create mode 100644 drivers/staging/rts5260/rts5260.c
> create mode 100644 drivers/staging/rts5260/rts5260.h
>
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 080793b..93edc5b 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -18,6 +18,10 @@ obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
> obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
>
> rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
> +ifneq ($(CONFIG_RTS5260), )
> +ccflags-y += -DCONFIG_RTS5260
> +rtsx_pci-objs += ../staging/rts5260/rts5260.o
> +endif
> obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
> obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
>
> diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
> index 7c87485..1917125 100644
> --- a/drivers/mfd/rtsx_pcr.c
> +++ b/drivers/mfd/rtsx_pcr.c
> @@ -62,6 +62,9 @@
> { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
> { PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
> { PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
> +#ifdef CONFIG_RTS5260
> + { PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 },
> +#endif
> { 0, }
> };
>
> @@ -334,6 +337,9 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
>
> void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
> {
> + if (pcr->ops->stop_cmd)
> + return pcr->ops->stop_cmd(pcr);
> +
> rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
> rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
>
> @@ -826,7 +832,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
> return err;
>
> /* Wait SSC clock stable */
> - udelay(10);
> + udelay(SSC_CLOCK_STABLE_WAIT);
> err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
> if (err < 0)
> return err;
> @@ -963,6 +969,20 @@ static void rtsx_pci_card_detect(struct work_struct *work)
> pcr->slots[RTSX_MS_CARD].p_dev);
> }
>
> +void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
> +{
> + if (pcr->ops->process_ocp)
> + pcr->ops->process_ocp(pcr);
> +}
> +
> +int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
> +{
> + if (pcr->option.ocp_en)
> + rtsx_pci_process_ocp(pcr);
> +
> + return 0;
> +}
> +
> static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
> {
> struct rtsx_pcr *pcr = dev_id;
> @@ -987,6 +1007,9 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
>
> int_reg &= (pcr->bier | 0x7FFFFF);
>
> + if (int_reg & SD_OC_INT)
> + rtsx_pci_process_ocp_interrupt(pcr);
> +
> if (int_reg & SD_INT) {
> if (int_reg & SD_EXIST) {
> pcr->card_inserted |= SD_EXIST;
> @@ -1119,6 +1142,102 @@ static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
> }
> #endif
>
> +void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
> +{
> + u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
> +
> + if (pcr->ops->enable_ocp)
> + pcr->ops->enable_ocp(pcr);
> + else
> + rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
> +
> +}
> +
> +void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
> +{
> + u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
> +
> + if (pcr->ops->disable_ocp)
> + pcr->ops->disable_ocp(pcr);
> + else
> + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> +}
> +
> +void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
> +{
> + if (pcr->ops->init_ocp) {
> + pcr->ops->init_ocp(pcr);
> + } else {
> + struct rtsx_cr_option *option = &(pcr->option);
> +
> + if (option->ocp_en) {
> + u8 val = option->sd_400mA_ocp_thd;
> +
> + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
> + rtsx_pci_write_register(pcr, REG_OCPPARA1,
> + SD_OCP_TIME_MASK, SD_OCP_TIME_800);
> + rtsx_pci_write_register(pcr, REG_OCPPARA2,
> + SD_OCP_THD_MASK, val);
> + rtsx_pci_write_register(pcr, REG_OCPGLITCH,
> + SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch);
> + rtsx_pci_enable_ocp(pcr);
> + } else {
> + /* OC power down */
> + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
> + OC_POWER_DOWN);
> + }
> + }
> +}
> +
> +int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
> +{
> + if (pcr->ops->get_ocpstat)
> + return pcr->ops->get_ocpstat(pcr, val);
> + else
> + return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
> +}
> +
> +void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
> +{
> + if (pcr->ops->clear_ocpstat) {
> + pcr->ops->clear_ocpstat(pcr);
> + } else {
> + u8 mask = SD_OCP_INT_CLR | SD_OC_CLR;
> + u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
> +
> + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
> + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> + }
> +}
> +
> +int sd_power_off_card3v3(struct rtsx_pcr *pcr)
> +{
> + rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
> + MS_CLK_EN | SD40_CLK_EN, 0);
> + rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
> +
> + rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
> +
> + msleep(50);
> +
> + rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
> +
> + return 0;
> +}
> +
> +int ms_power_off_card3v3(struct rtsx_pcr *pcr)
> +{
> + rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
> + MS_CLK_EN | SD40_CLK_EN, 0);
> +
> + rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
> +
> + rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
> + rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
> +
> + return 0;
> +}
> +
> static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
> {
> int err;
> @@ -1189,6 +1308,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
> case PID_5250:
> case PID_524A:
> case PID_525A:
> + case PID_5260:
> rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1);
> break;
> default:
> @@ -1265,6 +1385,11 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
> case 0x5286:
> rtl8402_init_params(pcr);
> break;
> +#ifdef CONFIG_RTS5260
> + case 0x5260:
> + rts5260_init_params(pcr);
> + break;
> +#endif
> }
>
> pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
> diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h
> index ec784e0..59090e1 100644
> --- a/drivers/mfd/rtsx_pcr.h
> +++ b/drivers/mfd/rtsx_pcr.h
> @@ -44,6 +44,8 @@
> #define ASPM_MASK_NEG 0xFC
> #define MASK_8_BIT_DEF 0xFF
>
> +#define SSC_CLOCK_STABLE_WAIT 130
> +
> 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);
>
> @@ -57,6 +59,9 @@
> void rts524a_init_params(struct rtsx_pcr *pcr);
> void rts525a_init_params(struct rtsx_pcr *pcr);
> void rtl8411b_init_params(struct rtsx_pcr *pcr);
> +#ifdef CONFIG_RTS5260
> +void rts5260_init_params(struct rtsx_pcr *pcr);
> +#endif
>
> static inline u8 map_sd_drive(int idx)
> {
> @@ -99,5 +104,12 @@ static inline u8 map_sd_drive(int idx)
> int rtsx_gops_pm_reset(struct rtsx_pcr *pcr);
> int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency);
> int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val);
> +void rtsx_pci_init_ocp(struct rtsx_pcr *pcr);
> +void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr);
> +void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr);
> +int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val);
> +void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr);
> +int sd_power_off_card3v3(struct rtsx_pcr *pcr);
> +int ms_power_off_card3v3(struct rtsx_pcr *pcr);
>
> #endif
> diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
> index ef28a1c..1b27245 100644
> --- a/drivers/staging/Kconfig
> +++ b/drivers/staging/Kconfig
> @@ -42,6 +42,8 @@ source "drivers/staging/rtl8188eu/Kconfig"
>
> source "drivers/staging/rts5208/Kconfig"
>
> +source "drivers/staging/rts5260/Kconfig"
> +
> source "drivers/staging/octeon/Kconfig"
>
> source "drivers/staging/octeon-usb/Kconfig"
> diff --git a/drivers/staging/rts5260/Kconfig b/drivers/staging/rts5260/Kconfig
> new file mode 100644
> index 0000000..5b7d328
> --- /dev/null
> +++ b/drivers/staging/rts5260/Kconfig
> @@ -0,0 +1,6 @@
> +config RTS5260
> + tristate "Realtek PCI-E Card Reader RTS5260 support"
> + help
> + Say Y here to include driver code to support the Realtek
> + PCI-E card reader rts5260.
> +
> diff --git a/drivers/staging/rts5260/rts5260.c b/drivers/staging/rts5260/rts5260.c
> new file mode 100644
> index 0000000..8dc22a67a
> --- /dev/null
> +++ b/drivers/staging/rts5260/rts5260.c
> @@ -0,0 +1,748 @@
> +/* Driver for Realtek PCI-Express card reader
> + *
> + * Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2, or (at your option) any
> + * later version.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, see <http://www.gnu.org/licenses/>.
> + *
> + * Author:
> + * Steven FENG <steven_feng@realsil.com.cn>
> + * Rui FENG <rui_feng@realsil.com.cn>
> + * Wei WANG <wei_wang@realsil.com.cn>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/mfd/rtsx_pci.h>
> +
> +#include "rts5260.h"
> +#include "../../mfd/rtsx_pcr.h"
> +
> +static u8 rts5260_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 rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
> +{
> + u8 driving_3v3[6][3] = {
> + {0x94, 0x94, 0x94},
> + {0x11, 0x11, 0x18},
> + {0x55, 0x55, 0x5C},
> + {0x94, 0x94, 0x94},
> + {0x94, 0x94, 0x94},
> + {0xFF, 0xFF, 0xFF},
> + };
> + u8 driving_1v8[6][3] = {
> + {0x9A, 0x89, 0x89},
> + {0xC4, 0xC4, 0xC4},
> + {0x3C, 0x3C, 0x3C},
> + {0x9B, 0x99, 0x99},
> + {0x9A, 0x89, 0x89},
> + {0xFE, 0xFE, 0xFE},
> + };
> + 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_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
> + 0xFF, driving[drive_sel][0]);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
> + 0xFF, driving[drive_sel][1]);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
> + 0xFF, driving[drive_sel][2]);
> +}
> +
> +static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
> +{
> + u32 reg;
> +
> + rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
> + pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
> +
> + if (!rtsx_vendor_setting_valid(reg)) {
> + pcr_dbg(pcr, "skip fetch vendor setting\n");
> + return;
> + }
> +
> + pcr->aspm_en = rtsx_reg_to_aspm(reg);
> + pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
> + pcr->card_drive_sel &= 0x3F;
> + pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
> +
> + rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
> + pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
> + pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
> + if (rtsx_reg_check_reverse_socket(reg))
> + pcr->flags |= PCR_REVERSE_SOCKET;
> +}
> +
> +static void rtsx_base_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, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN);
> +}
> +
> +static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
> +{
> + return rtsx_pci_write_register(pcr, OLT_LED_CTL,
> + LED_SHINE_MASK, LED_SHINE_EN);
> +}
> +
> +static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
> +{
> + return rtsx_pci_write_register(pcr, OLT_LED_CTL,
> + LED_SHINE_MASK, LED_SHINE_DISABLE);
> +}
> +
> +static int rts5260_turn_on_led(struct rtsx_pcr *pcr)
> +{
> + return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0,
> + RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_ON);
> +}
> +
> +static int rts5260_turn_off_led(struct rtsx_pcr *pcr)
> +{
> + return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0,
> + RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_OFF);
> +}
> +
> +/* 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 rts5260_sd_pull_ctl_enable_tbl[] = {
> + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
> + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
> + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
> + RTSX_REG_PAIR(CARD_PULL_CTL4, 0xAA),
> + 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 rts5260_sd_pull_ctl_disable_tbl[] = {
> + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
> + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
> + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
> + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
> + 0,
> +};
> +
> +/* MS Pull Control Enable:
> + * MS CD ==> pull up
> + * others ==> pull down
> + */
> +static const u32 rts5260_ms_pull_ctl_enable_tbl[] = {
> + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
> + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
> + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
> + 0,
> +};
> +
> +/* MS Pull Control Disable:
> + * MS CD ==> pull up
> + * others ==> pull down
> + */
> +static const u32 rts5260_ms_pull_ctl_disable_tbl[] = {
> + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
> + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
> + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
> + 0,
> +};
> +
> +static int 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 rts5260_card_power_on(struct rtsx_pcr *pcr, int card)
> +{
> + int err = 0;
> + struct rtsx_cr_option *option = &pcr->option;
> +
> + 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);
> +
> + msleep(20);
> +
> + if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
> + pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
> + sd_set_sample_push_timing_sd30(pcr);
> +
> + /* Initialize SD_CFG1 register */
> + rtsx_pci_write_register(pcr, SD_CFG1, 0xFF,
> + SD_CLK_DIVIDE_128 | SD_20_MODE);
> +
> + 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);
> +
> + rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, 0);
> +
> + return err;
> +}
> +
> +static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
> +{
> + switch (voltage) {
> + case OUTPUT_3V3:
> + rtsx_pci_write_register(pcr, LDO_CONFIG2,
> + DV331812_VDD1, DV331812_VDD1);
> + rtsx_pci_write_register(pcr, LDO_DV18_CFG,
> + DV331812_MASK, DV331812_33);
> + rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
> + break;
> + case OUTPUT_1V8:
> + rtsx_pci_write_register(pcr, LDO_CONFIG2,
> + DV331812_VDD1, DV331812_VDD1);
> + rtsx_pci_write_register(pcr, LDO_DV18_CFG,
> + DV331812_MASK, DV331812_17);
> + rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
> + SD_IO_USING_1V8);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /* set pad drive */
> + rtsx_pci_init_cmd(pcr);
> + rts5260_fill_driving(pcr, voltage);
> + return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> +}
> +
> +static void rts5260_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 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_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;
> +}
> +
> +static void rts5260_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, 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);
> +
> + rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
> + RTS5260_DV331812_OCP_THD_MASK,
> + RTS5260_DV331812_OCP_THD_210);
> +
> + mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
> + val = pcr->hw_param.ocp_glitch;
> + rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
> +
> + 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);
> + }
> +}
> +
> +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)
> +{
> + 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);
> +}
> +
> +int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
> +{
> + return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
> +}
> +
> +int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val)
> +{
> + return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val);
> +}
> +
> +void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
> +{
> + u8 mask = 0;
> + 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,
> + DV3318_OCP_INT_CLR | DV3318_OCP_CLR,
> + DV3318_OCP_INT_CLR | DV3318_OCP_CLR);
> + udelay(10);
> + rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
> + rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
> + DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0);
> +}
> +
> +void rts5260_process_ocp(struct rtsx_pcr *pcr)
> +{
> + if (!pcr->option.ocp_en)
> + return;
> +
> + rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
> + rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
> + if (pcr->card_exist & SD_EXIST)
> + sd_power_off_card3v3(pcr);
> + else if (pcr->card_exist & MS_EXIST)
> + 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);
> + 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);
> + }
> +}
> +
> +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,
> + AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE);
> + /* Rest L1SUB Config */
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CLK_FORCE_CTL,
> + CLK_PM_EN, CLK_PM_EN);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWD_SUSPEND_EN, 0xFF, 0xFF);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
> + PWR_GATE_EN, PWR_GATE_EN);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, REG_VREF,
> + PWD_SUSPND_EN, PWD_SUSPND_EN);
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RBCTL,
> + U_AUTO_DMA_EN_MASK, U_AUTO_DMA_DISABLE);
> +
> + if (pcr->flags & PCR_REVERSE_SOCKET)
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
> + else
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
> +
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG,
> + OBFF_EN_MASK, OBFF_DISABLE);
> +
> + err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
> + if (err < 0)
> + return err;
> +
> + return 0;
> +}
> +
> +static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)
> +{
> + int lss_l1_1, lss_l1_2;
> +
> + lss_l1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN)
> + | rtsx_check_dev_flag(pcr, PM_L1_1_EN);
> + lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN)
> + | rtsx_check_dev_flag(pcr, PM_L1_2_EN);
> +
> + if (lss_l1_2) {
> + 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, PWR_FE_CTL,
> + 0xFF, PCIE_L1_2_PD_FE_EN);
> + } else if (lss_l1_1) {
> + pcr_dbg(pcr, "Set parameters for L1.1.");
> + rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
> + 0xFF, PCIE_L1_1_EN);
> + rtsx_pci_write_register(pcr, PWR_FE_CTL,
> + 0xFF, PCIE_L1_1_PD_FE_EN);
> + } else {
> + pcr_dbg(pcr, "Set parameters for L1.");
> + rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
> + 0xFF, PCIE_L1_0_EN);
> + rtsx_pci_write_register(pcr, PWR_FE_CTL,
> + 0xFF, PCIE_L1_0_PD_FE_EN);
> + }
> +
> + rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_DPHY_RET_VALUE,
> + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_MAC_RET_VALUE,
> + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD30_RET_VALUE,
> + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD40_RET_VALUE,
> + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_L1_0_SYS_RET_VALUE,
> + 0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
> + /*Option cut APHY*/
> + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_0,
> + 0xFF, CFG_PCIE_APHY_OFF_0_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_1,
> + 0xFF, CFG_PCIE_APHY_OFF_1_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_2,
> + 0xFF, CFG_PCIE_APHY_OFF_2_DEFAULT);
> + rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_3,
> + 0xFF, CFG_PCIE_APHY_OFF_3_DEFAULT);
> + /*CDR DEC*/
> + rtsx_pci_write_register(pcr, PWC_CDR, 0xFF, PWC_CDR_DEFAULT);
> + /*PWMPFM*/
> + rtsx_pci_write_register(pcr, CFG_LP_FPWM_VALUE,
> + 0xFF, CFG_LP_FPWM_VALUE_DEFAULT);
> + /*No Power Saving WA*/
> + rtsx_pci_write_register(pcr, CFG_L1_0_CRC_MISC_RET_VALUE,
> + 0xFF, CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT);
> +}
> +
> +static void rts5260_init_from_cfg(struct rtsx_pcr *pcr)
> +{
> + struct rtsx_cr_option *option = &pcr->option;
> + u32 lval;
> +
> + rtsx_pci_read_config_dword(pcr, PCR_ASPM_SETTING_5260, &lval);
> +
> + if (lval & ASPM_L1_1_EN_MASK)
> + rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
> +
> + if (lval & ASPM_L1_2_EN_MASK)
> + rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
> +
> + if (lval & PM_L1_1_EN_MASK)
> + rtsx_set_dev_flag(pcr, PM_L1_1_EN);
> +
> + if (lval & PM_L1_2_EN_MASK)
> + rtsx_set_dev_flag(pcr, PM_L1_2_EN);
> +
> + rts5260_pwr_saving_setting(pcr);
> +
> + if (option->ltr_en) {
> + u16 val;
> +
> + pcie_capability_read_word(pcr->pci, 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 rts5260_extra_init_hw(struct rtsx_pcr *pcr)
> +{
> + struct rtsx_cr_option *option = &pcr->option;
> +
> + /* Set mcu_cnt to 7 to ensure data can be sampled properly */
> + rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07);
> + rtsx_pci_write_register(pcr, SSC_DIV_N_0, 0xFF, 0x5D);
> +
> + rts5260_init_from_cfg(pcr);
> +
> + /* force no MDIO*/
> + rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4,
> + 0xFF, RTS5260_MIMO_DISABLE);
> + /*Modify SDVCC Tune Default Parameters!*/
> + rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
> + RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
> +
> + rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
> +
> + rts5260_init_hw(pcr);
> +
> + /*
> + * 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_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
> + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
> + else
> + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
> + FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);
> +
> + return 0;
> +}
> +
> +void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable)
> +{
> + struct rtsx_cr_option *option = &pcr->option;
> + u8 val = 0;
> +
> + if (pcr->aspm_enabled == enable)
> + return;
> +
> + if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) {
> + if (enable)
> + val = pcr->aspm_en;
> + rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
> + ASPM_MASK_NEG, val);
> + } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) {
> + u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0;
> +
> + if (!enable)
> + val = FORCE_ASPM_CTL0;
> + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
> + }
> +
> + pcr->aspm_enabled = enable;
> +}
> +
> +static void rts5260_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active)
> +{
> + struct rtsx_cr_option *option = &pcr->option;
> + u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR);
> + int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST);
> + 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;
> + }
> +
> + if (aspm_L1_1 || aspm_L1_2) {
> + if (rtsx_check_dev_flag(pcr,
> + LTR_L1SS_PWR_GATE_CHECK_CARD_EN)) {
> + if (card_exist)
> + val &= ~L1OFF_MBIAS2_EN_5250;
> + else
> + val |= L1OFF_MBIAS2_EN_5250;
> + }
> + }
> + rtsx_set_l1off_sub(pcr, val);
> +}
> +
> +static const struct pcr_ops rts5260_pcr_ops = {
> + .fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
> + .turn_on_led = rts5260_turn_on_led,
> + .turn_off_led = rts5260_turn_off_led,
> + .extra_init_hw = rts5260_extra_init_hw,
> + .enable_auto_blink = rtsx_base_enable_auto_blink,
> + .disable_auto_blink = rtsx_base_disable_auto_blink,
> + .card_power_on = rts5260_card_power_on,
> + .card_power_off = rts5260_card_power_off,
> + .switch_output_voltage = rts5260_switch_output_voltage,
> + .force_power_down = rtsx_base_force_power_down,
> + .stop_cmd = rts5260_stop_cmd,
> + .set_aspm = rts5260_set_aspm,
> + .set_l1off_cfg_sub_d0 = rts5260_set_l1off_cfg_sub_d0,
> + .enable_ocp = rts5260_enable_ocp,
> + .disable_ocp = rts5260_disable_ocp,
> + .init_ocp = rts5260_init_ocp,
> + .process_ocp = rts5260_process_ocp,
> + .get_ocpstat = rts5260_get_ocpstat,
> + .clear_ocpstat = rts5260_clear_ocpstat,
> +};
> +
> +void rts5260_init_params(struct rtsx_pcr *pcr)
> +{
> + struct rtsx_cr_option *option = &pcr->option;
> + struct rtsx_hw_param *hw_param = &pcr->hw_param;
> +
> + pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
> + pcr->num_slots = 2;
> +
> + pcr->flags = 0;
> + pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
> + pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
> + pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
> + pcr->aspm_en = ASPM_L1_EN;
> + pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
> + pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
> +
> + pcr->ic_version = rts5260_get_ic_version(pcr);
> + pcr->sd_pull_ctl_enable_tbl = rts5260_sd_pull_ctl_enable_tbl;
> + pcr->sd_pull_ctl_disable_tbl = rts5260_sd_pull_ctl_disable_tbl;
> + pcr->ms_pull_ctl_enable_tbl = rts5260_ms_pull_ctl_enable_tbl;
> + pcr->ms_pull_ctl_disable_tbl = rts5260_ms_pull_ctl_disable_tbl;
> +
> + pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
> +
> + pcr->ops = &rts5260_pcr_ops;
> +
> + 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->dev_aspm_mode = DEV_ASPM_DYNAMIC;
> + option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF;
> + option->ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF;
> + option->ltr_l1off_snooze_sspwrgate =
> + LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF;
> +
> + 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;
> + option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
> + option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
> +}
> diff --git a/drivers/staging/rts5260/rts5260.h b/drivers/staging/rts5260/rts5260.h
> new file mode 100644
> index 0000000..ff20eff
> --- /dev/null
> +++ b/drivers/staging/rts5260/rts5260.h
> @@ -0,0 +1,45 @@
> +#ifndef __RTS5260_H__
> +#define __RTS5260_H__
> +
> +#define RTS5260_DVCC_CTRL 0xFF73
> +#define RTS5260_DVCC_OCP_EN (0x01 << 7)
> +#define RTS5260_DVCC_OCP_THD_MASK (0x07 << 4)
> +#define RTS5260_DVCC_POWERON (0x01 << 3)
> +#define RTS5260_DVCC_OCP_CL_EN (0x01 << 2)
> +
> +#define RTS5260_DVIO_CTRL 0xFF75
> +#define RTS5260_DVIO_OCP_EN (0x01 << 7)
> +#define RTS5260_DVIO_OCP_THD_MASK (0x07 << 4)
> +#define RTS5260_DVIO_POWERON (0x01 << 3)
> +#define RTS5260_DVIO_OCP_CL_EN (0x01 << 2)
> +
> +#define RTS5260_DV331812_CFG 0xFF71
> +#define RTS5260_DV331812_OCP_EN (0x01 << 7)
> +#define RTS5260_DV331812_OCP_THD_MASK (0x07 << 4)
> +#define RTS5260_DV331812_POWERON (0x01 << 3)
> +#define RTS5260_DV331812_SEL (0x01 << 2)
> +#define RTS5260_DV331812_VDD1 (0x01 << 2)
> +#define RTS5260_DV331812_VDD2 (0x00 << 2)
> +
> +#define RTS5260_DV331812_OCP_THD_120 (0x00 << 4)
> +#define RTS5260_DV331812_OCP_THD_140 (0x01 << 4)
> +#define RTS5260_DV331812_OCP_THD_160 (0x02 << 4)
> +#define RTS5260_DV331812_OCP_THD_180 (0x03 << 4)
> +#define RTS5260_DV331812_OCP_THD_210 (0x04 << 4)
> +#define RTS5260_DV331812_OCP_THD_240 (0x05 << 4)
> +#define RTS5260_DV331812_OCP_THD_270 (0x06 << 4)
> +#define RTS5260_DV331812_OCP_THD_300 (0x07 << 4)
> +
> +#define RTS5260_DVIO_OCP_THD_250 (0x00 << 4)
> +#define RTS5260_DVIO_OCP_THD_300 (0x01 << 4)
> +#define RTS5260_DVIO_OCP_THD_350 (0x02 << 4)
> +#define RTS5260_DVIO_OCP_THD_400 (0x03 << 4)
> +#define RTS5260_DVIO_OCP_THD_450 (0x04 << 4)
> +#define RTS5260_DVIO_OCP_THD_500 (0x05 << 4)
> +#define RTS5260_DVIO_OCP_THD_550 (0x06 << 4)
> +#define RTS5260_DVIO_OCP_THD_600 (0x07 << 4)
> +
> +#define RTS5260_DVCC_OCP_THD_550 (0x00 << 4)
> +#define RTS5260_DVCC_OCP_THD_970 (0x05 << 4)
> +
> +#endif
> diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
> index 57e23ad..d086acc 100644
> --- a/include/linux/mfd/rtsx_pci.h
> +++ b/include/linux/mfd/rtsx_pci.h
> @@ -203,6 +203,7 @@
> #define SD_DDR_MODE 0x04
> #define SD_30_MODE 0x08
> #define SD_CLK_DIVIDE_MASK 0xC0
> +#define SD_MODE_SELECT_MASK 0x0C
> #define SD_CFG2 0xFDA1
> #define SD_CALCULATE_CRC7 0x00
> #define SD_NO_CALCULATE_CRC7 0x80
> @@ -226,6 +227,7 @@
> #define SD_RSP_TYPE_R6 0x01
> #define SD_RSP_TYPE_R7 0x01
> #define SD_CFG3 0xFDA2
> +#define SD30_CLK_END_EN 0x10
> #define SD_RSP_80CLK_TIMEOUT_EN 0x01
>
> #define SD_STAT1 0xFDA3
> @@ -309,6 +311,12 @@
>
> #define SD_DATA_STATE 0xFDB6
> #define SD_DATA_IDLE 0x80
> +#define REG_SD_STOP_SDCLK_CFG 0xFDB8
> +#define SD30_CLK_STOP_CFG_EN 0x04
> +#define SD30_CLK_STOP_CFG1 0x02
> +#define SD30_CLK_STOP_CFG0 0x01
> +#define REG_PRE_RW_MODE 0xFD70
> +#define EN_INFINITE_MODE 0x01
>
> #define SRCTL 0xFC13
>
> @@ -433,6 +441,7 @@
> #define CARD_CLK_EN 0xFD69
> #define SD_CLK_EN 0x04
> #define MS_CLK_EN 0x08
> +#define SD40_CLK_EN 0x10
> #define SDIO_CTRL 0xFD6B
> #define CD_PAD_CTL 0xFD73
> #define CD_DISABLE_MASK 0x07
> @@ -452,8 +461,8 @@
> #define FPDCTL 0xFC00
> #define SSC_POWER_DOWN 0x01
> #define SD_OC_POWER_DOWN 0x02
> -#define ALL_POWER_DOWN 0x07
> -#define OC_POWER_DOWN 0x06
> +#define ALL_POWER_DOWN 0x03
> +#define OC_POWER_DOWN 0x02
> #define PDINFO 0xFC01
>
> #define CLK_CTL 0xFC02
> @@ -489,6 +498,9 @@
>
> #define FPGA_PULL_CTL 0xFC1D
> #define OLT_LED_CTL 0xFC1E
> +#define LED_SHINE_MASK 0x08
> +#define LED_SHINE_EN 0x08
> +#define LED_SHINE_DISABLE 0x00
> #define GPIO_CTL 0xFC1F
>
> #define LDO_CTL 0xFC1E
> @@ -510,7 +522,11 @@
> #define BPP_LDO_ON 0x00
> #define BPP_LDO_SUSPEND 0x02
> #define BPP_LDO_OFF 0x03
> +#define EFUSE_CTL 0xFC30
> +#define EFUSE_ADD 0xFC31
> #define SYS_VER 0xFC32
> +#define EFUSE_DATAL 0xFC34
> +#define EFUSE_DATAH 0xFC35
>
> #define CARD_PULL_CTL1 0xFD60
> #define CARD_PULL_CTL2 0xFD61
> @@ -552,6 +568,9 @@
> #define RBBC1 0xFE2F
> #define RBDAT 0xFE30
> #define RBCTL 0xFE34
> +#define U_AUTO_DMA_EN_MASK 0x20
> +#define U_AUTO_DMA_DISABLE 0x00
> +#define RB_FLUSH 0x80
> #define CFGADDR0 0xFE35
> #define CFGADDR1 0xFE36
> #define CFGDATA0 0xFE37
> @@ -580,6 +599,8 @@
> #define LTR_LATENCY_MODE_HW 0
> #define LTR_LATENCY_MODE_SW BIT(6)
> #define OBFF_CFG 0xFE4C
> +#define OBFF_EN_MASK 0x03
> +#define OBFF_DISABLE 0x00
>
> #define CDRESUMECTL 0xFE52
> #define WAKE_SEL_CTL 0xFE54
> @@ -594,6 +615,7 @@
> #define FORCE_ASPM_L0_EN 0x01
> #define FORCE_ASPM_NO_ASPM 0x00
> #define PM_CLK_FORCE_CTL 0xFE58
> +#define CLK_PM_EN 0x01
> #define FUNC_FORCE_CTL 0xFE59
> #define FUNC_FORCE_UPME_XMT_DBG 0x02
> #define PERST_GLITCH_WIDTH 0xFE5C
> @@ -619,14 +641,23 @@
> #define LDO_PWR_SEL 0xFE78
>
> #define L1SUB_CONFIG1 0xFE8D
> +#define AUX_CLK_ACTIVE_SEL_MASK 0x01
> +#define MAC_CKSW_DONE 0x00
> #define L1SUB_CONFIG2 0xFE8E
> #define L1SUB_AUTO_CFG 0x02
> #define L1SUB_CONFIG3 0xFE8F
> #define L1OFF_MBIAS2_EN_5250 BIT(7)
>
> #define DUMMY_REG_RESET_0 0xFE90
> +#define IC_VERSION_MASK 0x0F
>
> +#define REG_VREF 0xFE97
> +#define PWD_SUSPND_EN 0x10
> +#define RTS5260_DMA_RST_CTL_0 0xFEBF
> +#define RTS5260_DMA_RST 0x80
> +#define RTS5260_ADMA3_RST 0x40
> #define AUTOLOAD_CFG_BASE 0xFF00
> +#define RELINK_TIME_MASK 0x01
> #define PETXCFG 0xFF03
> #define FORCE_CLKREQ_DELINK_MASK BIT(7)
> #define FORCE_CLKREQ_LOW 0x80
> @@ -666,15 +697,24 @@
> #define LDO_DV18_CFG 0xFF70
> #define LDO_DV18_SR_MASK 0xC0
> #define LDO_DV18_SR_DF 0x40
> +#define DV331812_MASK 0x70
> +#define DV331812_33 0x70
> +#define DV331812_17 0x30
>
> #define LDO_CONFIG2 0xFF71
> #define LDO_D3318_MASK 0x07
> #define LDO_D3318_33V 0x07
> #define LDO_D3318_18V 0x02
> +#define DV331812_VDD1 0x04
> +#define DV331812_POWERON 0x08
> +#define DV331812_POWEROFF 0x00
>
> #define LDO_VCC_CFG0 0xFF72
> #define LDO_VCC_LMTVTH_MASK 0x30
> #define LDO_VCC_LMTVTH_2A 0x10
> +/*RTS5260*/
> +#define RTS5260_DVCC_TUNE_MASK 0x70
> +#define RTS5260_DVCC_33 0x70
>
> #define LDO_VCC_CFG1 0xFF73
> #define LDO_VCC_REF_TUNE_MASK 0x30
> @@ -683,6 +723,10 @@
> #define LDO_VCC_1V8 0x04
> #define LDO_VCC_3V3 0x07
> #define LDO_VCC_LMT_EN 0x08
> +/*RTS5260*/
> +#define LDO_POW_SDVDD1_MASK 0x08
> +#define LDO_POW_SDVDD1_ON 0x08
> +#define LDO_POW_SDVDD1_OFF 0x00
>
> #define LDO_VIO_CFG 0xFF75
> #define LDO_VIO_SR_MASK 0xC0
> @@ -710,6 +754,160 @@
> #define SD_VIO_LDO_1V8 0x40
> #define SD_VIO_LDO_3V3 0x70
>
> +#define RTS5260_AUTOLOAD_CFG4 0xFF7F
> +#define RTS5260_MIMO_DISABLE 0x8A
> +
> +#define RTS5260_REG_GPIO_CTL0 0xFC1A
> +#define RTS5260_REG_GPIO_MASK 0x01
> +#define RTS5260_REG_GPIO_ON 0x01
> +#define RTS5260_REG_GPIO_OFF 0x00
> +
> +#define PWR_GLOBAL_CTRL 0xF200
> +#define PCIE_L1_2_EN 0x0C
> +#define PCIE_L1_1_EN 0x0A
> +#define PCIE_L1_0_EN 0x09
> +#define PWR_FE_CTL 0xF201
> +#define PCIE_L1_2_PD_FE_EN 0x0C
> +#define PCIE_L1_1_PD_FE_EN 0x0A
> +#define PCIE_L1_0_PD_FE_EN 0x09
> +#define CFG_PCIE_APHY_OFF_0 0xF204
> +#define CFG_PCIE_APHY_OFF_0_DEFAULT 0xBF
> +#define CFG_PCIE_APHY_OFF_1 0xF205
> +#define CFG_PCIE_APHY_OFF_1_DEFAULT 0xFF
> +#define CFG_PCIE_APHY_OFF_2 0xF206
> +#define CFG_PCIE_APHY_OFF_2_DEFAULT 0x01
> +#define CFG_PCIE_APHY_OFF_3 0xF207
> +#define CFG_PCIE_APHY_OFF_3_DEFAULT 0x00
> +#define CFG_L1_0_PCIE_MAC_RET_VALUE 0xF20C
> +#define CFG_L1_0_PCIE_DPHY_RET_VALUE 0xF20E
> +#define CFG_L1_0_SYS_RET_VALUE 0xF210
> +#define CFG_L1_0_CRC_MISC_RET_VALUE 0xF212
> +#define CFG_L1_0_CRC_SD30_RET_VALUE 0xF214
> +#define CFG_L1_0_CRC_SD40_RET_VALUE 0xF216
> +#define CFG_LP_FPWM_VALUE 0xF219
> +#define CFG_LP_FPWM_VALUE_DEFAULT 0x18
> +#define PWC_CDR 0xF253
> +#define PWC_CDR_DEFAULT 0x03
> +#define CFG_L1_0_RET_VALUE_DEFAULT 0x1B
> +#define CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT 0x0C
> +
> +/* OCPCTL */
> +#define SD_DETECT_EN 0x08
> +#define SD_OCP_INT_EN 0x04
> +#define SD_OCP_INT_CLR 0x02
> +#define SD_OC_CLR 0x01
> +
> +#define SDVIO_DETECT_EN (1 << 7)
> +#define SDVIO_OCP_INT_EN (1 << 6)
> +#define SDVIO_OCP_INT_CLR (1 << 5)
> +#define SDVIO_OC_CLR (1 << 4)
> +
> +/* OCPSTAT */
> +#define SD_OCP_DETECT 0x08
> +#define SD_OC_NOW 0x04
> +#define SD_OC_EVER 0x02
> +
> +#define SDVIO_OC_NOW (1 << 6)
> +#define SDVIO_OC_EVER (1 << 5)
> +
> +#define REG_OCPCTL 0xFD6A
> +#define REG_OCPSTAT 0xFD6E
> +#define REG_OCPGLITCH 0xFD6C
> +#define REG_OCPPARA1 0xFD6B
> +#define REG_OCPPARA2 0xFD6D
> +
> +/* rts5260 DV3318 OCP-related registers */
> +#define REG_DV3318_OCPCTL 0xFD89
> +#define DV3318_OCP_TIME_MASK 0xF0
> +#define DV3318_DETECT_EN 0x08
> +#define DV3318_OCP_INT_EN 0x04
> +#define DV3318_OCP_INT_CLR 0x02
> +#define DV3318_OCP_CLR 0x01
> +
> +#define REG_DV3318_OCPSTAT 0xFD8A
> +#define DV3318_OCP_GlITCH_TIME_MASK 0xF0
> +#define DV3318_OCP_DETECT 0x08
> +#define DV3318_OCP_NOW 0x04
> +#define DV3318_OCP_EVER 0x02
> +
> +#define SD_OCP_GLITCH_MASK 0x0F
> +
> +/* OCPPARA1 */
> +#define SDVIO_OCP_TIME_60 0x00
> +#define SDVIO_OCP_TIME_100 0x10
> +#define SDVIO_OCP_TIME_200 0x20
> +#define SDVIO_OCP_TIME_400 0x30
> +#define SDVIO_OCP_TIME_600 0x40
> +#define SDVIO_OCP_TIME_800 0x50
> +#define SDVIO_OCP_TIME_1100 0x60
> +#define SDVIO_OCP_TIME_MASK 0x70
> +
> +#define SD_OCP_TIME_60 0x00
> +#define SD_OCP_TIME_100 0x01
> +#define SD_OCP_TIME_200 0x02
> +#define SD_OCP_TIME_400 0x03
> +#define SD_OCP_TIME_600 0x04
> +#define SD_OCP_TIME_800 0x05
> +#define SD_OCP_TIME_1100 0x06
> +#define SD_OCP_TIME_MASK 0x07
> +
> +/* OCPPARA2 */
> +#define SDVIO_OCP_THD_190 0x00
> +#define SDVIO_OCP_THD_250 0x10
> +#define SDVIO_OCP_THD_320 0x20
> +#define SDVIO_OCP_THD_380 0x30
> +#define SDVIO_OCP_THD_440 0x40
> +#define SDVIO_OCP_THD_500 0x50
> +#define SDVIO_OCP_THD_570 0x60
> +#define SDVIO_OCP_THD_630 0x70
> +#define SDVIO_OCP_THD_MASK 0x70
> +
> +#define SD_OCP_THD_450 0x00
> +#define SD_OCP_THD_550 0x01
> +#define SD_OCP_THD_650 0x02
> +#define SD_OCP_THD_750 0x03
> +#define SD_OCP_THD_850 0x04
> +#define SD_OCP_THD_950 0x05
> +#define SD_OCP_THD_1050 0x06
> +#define SD_OCP_THD_1150 0x07
> +#define SD_OCP_THD_MASK 0x07
> +
> +#define SDVIO_OCP_GLITCH_MASK 0xF0
> +#define SDVIO_OCP_GLITCH_NONE 0x00
> +#define SDVIO_OCP_GLITCH_50U 0x10
> +#define SDVIO_OCP_GLITCH_100U 0x20
> +#define SDVIO_OCP_GLITCH_200U 0x30
> +#define SDVIO_OCP_GLITCH_600U 0x40
> +#define SDVIO_OCP_GLITCH_800U 0x50
> +#define SDVIO_OCP_GLITCH_1M 0x60
> +#define SDVIO_OCP_GLITCH_2M 0x70
> +#define SDVIO_OCP_GLITCH_3M 0x80
> +#define SDVIO_OCP_GLITCH_4M 0x90
> +#define SDVIO_OCP_GLIVCH_5M 0xA0
> +#define SDVIO_OCP_GLITCH_6M 0xB0
> +#define SDVIO_OCP_GLITCH_7M 0xC0
> +#define SDVIO_OCP_GLITCH_8M 0xD0
> +#define SDVIO_OCP_GLITCH_9M 0xE0
> +#define SDVIO_OCP_GLITCH_10M 0xF0
> +
> +#define SD_OCP_GLITCH_MASK 0x0F
> +#define SD_OCP_GLITCH_NONE 0x00
> +#define SD_OCP_GLITCH_50U 0x01
> +#define SD_OCP_GLITCH_100U 0x02
> +#define SD_OCP_GLITCH_200U 0x03
> +#define SD_OCP_GLITCH_600U 0x04
> +#define SD_OCP_GLITCH_800U 0x05
> +#define SD_OCP_GLITCH_1M 0x06
> +#define SD_OCP_GLITCH_2M 0x07
> +#define SD_OCP_GLITCH_3M 0x08
> +#define SD_OCP_GLITCH_4M 0x09
> +#define SD_OCP_GLIVCH_5M 0x0A
> +#define SD_OCP_GLITCH_6M 0x0B
> +#define SD_OCP_GLITCH_7M 0x0C
> +#define SD_OCP_GLITCH_8M 0x0D
> +#define SD_OCP_GLITCH_9M 0x0E
> +#define SD_OCP_GLITCH_10M 0x0F
> +
> /* Phy register */
> #define PHY_PCR 0x00
> #define PHY_PCR_FORCE_CODE 0xB000
> @@ -856,6 +1054,7 @@
>
> #define PCR_ASPM_SETTING_REG1 0x160
> #define PCR_ASPM_SETTING_REG2 0x168
> +#define PCR_ASPM_SETTING_5260 0x178
>
> #define PCR_SETTING_REG1 0x724
> #define PCR_SETTING_REG2 0x814
> @@ -889,6 +1088,7 @@ struct pcr_ops {
> int (*conv_clk_and_div_n)(int clk, int dir);
> void (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
> void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state);
> + void (*stop_cmd)(struct rtsx_pcr *pcr);
>
> void (*set_aspm)(struct rtsx_pcr *pcr, bool enable);
> int (*set_ltr_latency)(struct rtsx_pcr *pcr, u32 latency);
> @@ -896,6 +1096,12 @@ struct pcr_ops {
> void (*set_l1off_cfg_sub_d0)(struct rtsx_pcr *pcr, int active);
> void (*full_on)(struct rtsx_pcr *pcr);
> void (*power_saving)(struct rtsx_pcr *pcr);
> + void (*enable_ocp)(struct rtsx_pcr *pcr);
> + void (*disable_ocp)(struct rtsx_pcr *pcr);
> + void (*init_ocp)(struct rtsx_pcr *pcr);
> + void (*process_ocp)(struct rtsx_pcr *pcr);
> + int (*get_ocpstat)(struct rtsx_pcr *pcr, u8 *val);
> + void (*clear_ocpstat)(struct rtsx_pcr *pcr);
> };
>
> enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN};
> @@ -934,6 +1140,9 @@ enum dev_aspm_mode {
> * @l1_snooze_delay: l1 snooze delay
> * @ltr_l1off_sspwrgate: ltr l1off sspwrgate
> * @ltr_l1off_snooze_sspwrgate: ltr l1off snooze sspwrgate
> + * @ocp_en: enable ocp flag
> + * @sd_400mA_ocp_thd: 400mA ocp thd
> + * @sd_800mA_ocp_thd: 800mA ocp thd
> */
> struct rtsx_cr_option {
> u32 dev_flags;
> @@ -948,6 +1157,19 @@ struct rtsx_cr_option {
> u32 l1_snooze_delay;
> u8 ltr_l1off_sspwrgate;
> u8 ltr_l1off_snooze_sspwrgate;
> + bool ocp_en;
> + u8 sd_400mA_ocp_thd;
> + u8 sd_800mA_ocp_thd;
> +};
> +
> +/*
> + * struct rtsx_hw_param - card reader hardware param
> + * @interrupt_en: indicate which interrutp enable
> + * @ocp_glitch: ocp glitch time
> + */
> +struct rtsx_hw_param {
> + u32 interrupt_en;
> + u8 ocp_glitch;
> };
>
> #define rtsx_set_dev_flag(cr, flag) \
> @@ -962,6 +1184,7 @@ struct rtsx_pcr {
> unsigned int id;
> int pcie_cap;
> struct rtsx_cr_option option;
> + struct rtsx_hw_param hw_param;
>
> /* pci resources */
> unsigned long addr;
> @@ -1041,12 +1264,15 @@ struct rtsx_pcr {
> struct rtsx_slot *slots;
>
> u8 dma_error_count;
> + u8 ocp_stat;
> + u8 ocp_stat2;
> };
>
> #define PID_524A 0x524A
> -#define PID_5249 0x5249
> -#define PID_5250 0x5250
> +#define PID_5249 0x5249
> +#define PID_5250 0x5250
> #define PID_525A 0x525A
> +#define PID_5260 0x5260
>
> #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
> #define PCI_VID(pcr) ((pcr)->pci->vendor)
> There are a number of drivers in this family which currently reside in
> MFD. These were accepted before my time. After a recent review I've
> made the decision that these aren't MFD drivers at all.
If all these other similar drivers don't belong in MFD, why are they
still there? Have they been moved in -next?
As recently as last month I still see patches being accepted into
MFD regarding Realtek card readers.
https://patchwork.kernel.org/patch/9941753/
I miss how it's reasonable to expect the submitter who is adding support
for new HW that is similar to other hardware in the past to be able to
know where to put it if this change hasn't already happened.
What's actually wrong with accepting it in MFD like the other drivers
similar to it and then moving them all at once when the right place
is figured out?
Then its much clearer for future drivers similar to this one that they
live in the new place (misc, or wherever makes sense).
It seems like it would be the same result but with less pain.
> Ok, how does it hook up to the hardware to talk to the reader?
This particular case its PCIe. I don't know if their chip is
used in any other packages, but I wouldn't be surprised if so.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: staging: rtsx: Add support for RTS5260
2017-10-13 18:28 ` Mario Limonciello
@ 2017-10-13 21:15 ` Lee Jones
2017-10-16 20:38 ` Mario.Limonciello
0 siblings, 1 reply; 13+ messages in thread
From: Lee Jones @ 2017-10-13 21:15 UTC (permalink / raw)
To: Mario Limonciello
Cc: rui_feng, gregkh, linux-kernel, devel, ricky_wu, wei_wang
On Fri, 13 Oct 2017, Mario Limonciello wrote:
> On 10/13/2017 03:50 AM, rui_feng@realsil.com.cn wrote:
> > From: rui_feng <rui_feng@realsil.com.cn>
> >
> > Add support for new chip rts5260.
> > In order to support rts5260,the definitions of some internal
> > registers and workflow have to be modified and are different from its
> > predecessors and OCP function is added for RTS5260.
> > So we need this patch to ensure RTS5260 can work.
> >
> > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > ---
> > drivers/mfd/Makefile | 4 +
> > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > drivers/mfd/rtsx_pcr.h | 12 +
> > drivers/staging/Kconfig | 2 +
> > drivers/staging/rts5260/Kconfig | 6 +
> > drivers/staging/rts5260/rts5260.c | 748 ++++++++++++++++++++++++++++++++++++++
> > drivers/staging/rts5260/rts5260.h | 45 +++
> > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > 8 files changed, 1173 insertions(+), 5 deletions(-)
> > create mode 100644 drivers/staging/rts5260/Kconfig
> > create mode 100644 drivers/staging/rts5260/rts5260.c
> > create mode 100644 drivers/staging/rts5260/rts5260.h
[nearly 1000 lines snipped]
Wow, that's a lot of scrolling to get to your reply!
It would be helpful if you'd please snip your replies in the future.
> > There are a number of drivers in this family which currently reside in
> > MFD. These were accepted before my time. After a recent review I've
> > made the decision that these aren't MFD drivers at all.
>
> If all these other similar drivers don't belong in MFD, why are they
> still there? Have they been moved in -next?
No effort has been made to move them yet. We still don't have a
suitable home for them. That's what we're discussing.
> As recently as last month I still see patches being accepted into
> MFD regarding Realtek card readers.
>
> https://patchwork.kernel.org/patch/9941753/
Changes to existing drivers, yes.
I only noticed what was going on when this new driver was submitted.
I'm now not accepting new ones.
> I miss how it's reasonable to expect the submitter who is adding support
> for new HW that is similar to other hardware in the past to be able to
> know where to put it if this change hasn't already happened.
It's perfectly reasonable to reject a new driver which doesn't
belong.
> What's actually wrong with accepting it in MFD like the other drivers
> similar to it and then moving them all at once when the right place
> is figured out?
Because it removes the incentive for someone to take the initiative and
move them. I can't work with promises. Too many times I've heard "if
you just accept this patch, I'll do XYZ as a subsequent piece of
work", then move on. They are either never seen again, or we have the
same conversation when they attempt to submit something else. Things
don't get done that way.
> Then its much clearer for future drivers similar to this one that they
> live in the new place (misc, or wherever makes sense).
I've I would have accepted the original patch into MFD, we would not
be having this conversation, people like yourself and Greg would not
be aware and (the chances are - just going by previous experience
here) nothing would have changed/improved.
> It seems like it would be the same result but with less pain.
That cannot be guaranteed.
If people's words would have been their bond in the past, I would have
more trust and the world would be a nicer place. :)
> > Ok, how does it hook up to the hardware to talk to the reader?
>
> This particular case its PCIe. I don't know if their chip is
> used in any other packages, but I wouldn't be surprised if so.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 13+ messages in thread
* 答复: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-13 9:59 ` Greg KH
2017-10-13 10:11 ` Lee Jones
@ 2017-10-16 5:58 ` 冯锐
2017-10-16 7:45 ` Greg KH
1 sibling, 1 reply; 13+ messages in thread
From: 冯锐 @ 2017-10-16 5:58 UTC (permalink / raw)
To: Greg KH, Lee Jones; +Cc: devel, ricky_wu, linux-kernel
> On Fri, Oct 13, 2017 at 10:54:22AM +0100, Lee Jones wrote:
> > On Fri, 13 Oct 2017, Greg KH wrote:
> >
> > > On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> > > > From: rui_feng <rui_feng@realsil.com.cn>
> > > >
> > > > Add support for new chip rts5260.
> > > > In order to support rts5260,the definitions of some internal
> > > > registers and workflow have to be modified and are different from
> > > > its predecessors and OCP function is added for RTS5260.
> > > > So we need this patch to ensure RTS5260 can work.
> > > >
> > > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > >
> > > Your from and signed-off-by name does not match :(
> > >
> > > > ---
> > > > drivers/mfd/Makefile | 4 +
> > > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > > drivers/mfd/rtsx_pcr.h | 12 +
> > > > drivers/staging/Kconfig | 2 +
> > > > drivers/staging/rts5260/Kconfig | 6 +
> > > > drivers/staging/rts5260/rts5260.c | 748
> > > > ++++++++++++++++++++++++++++++++++++++
> > > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > >
> > > I do not see a reason why this is a staging driver. Where is the
> > > TODO file listing what needs to be done to get it out of staging?
> > > Why can it not just go into the "real" part of the kernel?
> >
> > It's not a staging driver. Rui's focus appears to be to have this
> > driver accepted into Mainline by hook or by crock. He's tried MFD,
> > Misc and now Staging!
>
> Yeah, I've watched it too :)
>
> > Background:
> >
> > There are a number of drivers in this family which currently reside in
> > MFD. These were accepted before my time. After a recent review I've
> > made the decision that these aren't MFD drivers at all.
> >
> > MFD drivers are ones which aid in registering and setting up shared
> > resources for sub-devices which reside on the same piece of silicon.
> > This driver does basically none of that. Instead it *is* the (what we
> > describe above as) sub-device. It does everything.
>
> I agree with your assessment.
>
> > In the absence of a subsystem which covers this type of device, I
> > suggested Misk as a good location to place these drivers.
>
> What type of device is this thing? I can't seem to figure that out. If we can
> determine that, then we can find the proper place for it in the kernel.
>
> Rui, what does this hardware do? What is the interface between the
> hardware and userspace that this driver is creating?
>
This driver is a pcie driver, it bridge mmc subsystem and memstick subsystem, and it does not deal with userspace.
> thanks,
>
> greg k-h
>
> ------Please consider the environment before printing this e-mail.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: 答复: [PATCH] staging: rtsx: Add support for RTS5260
2017-10-16 5:58 ` 冯锐
@ 2017-10-16 7:45 ` Greg KH
0 siblings, 0 replies; 13+ messages in thread
From: Greg KH @ 2017-10-16 7:45 UTC (permalink / raw)
To: 冯锐; +Cc: Lee Jones, devel, ricky_wu, linux-kernel
On Mon, Oct 16, 2017 at 05:58:12AM +0000, 冯锐 wrote:
> > On Fri, Oct 13, 2017 at 10:54:22AM +0100, Lee Jones wrote:
> > > On Fri, 13 Oct 2017, Greg KH wrote:
> > >
> > > > On Fri, Oct 13, 2017 at 04:50:35PM +0800, rui_feng@realsil.com.cn wrote:
> > > > > From: rui_feng <rui_feng@realsil.com.cn>
> > > > >
> > > > > Add support for new chip rts5260.
> > > > > In order to support rts5260,the definitions of some internal
> > > > > registers and workflow have to be modified and are different from
> > > > > its predecessors and OCP function is added for RTS5260.
> > > > > So we need this patch to ensure RTS5260 can work.
> > > > >
> > > > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > > >
> > > > Your from and signed-off-by name does not match :(
> > > >
> > > > > ---
> > > > > drivers/mfd/Makefile | 4 +
> > > > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > > > drivers/mfd/rtsx_pcr.h | 12 +
> > > > > drivers/staging/Kconfig | 2 +
> > > > > drivers/staging/rts5260/Kconfig | 6 +
> > > > > drivers/staging/rts5260/rts5260.c | 748
> > > > > ++++++++++++++++++++++++++++++++++++++
> > > > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > > >
> > > > I do not see a reason why this is a staging driver. Where is the
> > > > TODO file listing what needs to be done to get it out of staging?
> > > > Why can it not just go into the "real" part of the kernel?
> > >
> > > It's not a staging driver. Rui's focus appears to be to have this
> > > driver accepted into Mainline by hook or by crock. He's tried MFD,
> > > Misc and now Staging!
> >
> > Yeah, I've watched it too :)
> >
> > > Background:
> > >
> > > There are a number of drivers in this family which currently reside in
> > > MFD. These were accepted before my time. After a recent review I've
> > > made the decision that these aren't MFD drivers at all.
> > >
> > > MFD drivers are ones which aid in registering and setting up shared
> > > resources for sub-devices which reside on the same piece of silicon.
> > > This driver does basically none of that. Instead it *is* the (what we
> > > describe above as) sub-device. It does everything.
> >
> > I agree with your assessment.
> >
> > > In the absence of a subsystem which covers this type of device, I
> > > suggested Misk as a good location to place these drivers.
> >
> > What type of device is this thing? I can't seem to figure that out. If we can
> > determine that, then we can find the proper place for it in the kernel.
> >
> > Rui, what does this hardware do? What is the interface between the
> > hardware and userspace that this driver is creating?
> >
> This driver is a pcie driver, it bridge mmc subsystem and memstick
> subsystem, and it does not deal with userspace.
Ok, sounds like drivers/misc/ is a good place for it.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 13+ messages in thread
* RE: staging: rtsx: Add support for RTS5260
2017-10-13 21:15 ` Lee Jones
@ 2017-10-16 20:38 ` Mario.Limonciello
2017-10-23 9:18 ` Lee Jones
0 siblings, 1 reply; 13+ messages in thread
From: Mario.Limonciello @ 2017-10-16 20:38 UTC (permalink / raw)
To: lee.jones; +Cc: rui_feng, gregkh, linux-kernel, devel, ricky_wu, wei_wang
> -----Original Message-----
> From: Lee Jones [mailto:lee.jones@linaro.org]
> Sent: Friday, October 13, 2017 4:15 PM
> To: Limonciello, Mario <Mario_Limonciello@Dell.com>
> Cc: rui_feng@realsil.com.cn; gregkh@linuxfoundation.org; linux-
> kernel@vger.kernel.org; devel@driverdev.osuosl.org; ricky_wu@realtek.com;
> wei_wang@realsil.com.cn
> Subject: Re: staging: rtsx: Add support for RTS5260
>
> On Fri, 13 Oct 2017, Mario Limonciello wrote:
> > On 10/13/2017 03:50 AM, rui_feng@realsil.com.cn wrote:
> > > From: rui_feng <rui_feng@realsil.com.cn>
> > >
> > > Add support for new chip rts5260.
> > > In order to support rts5260,the definitions of some internal
> > > registers and workflow have to be modified and are different from its
> > > predecessors and OCP function is added for RTS5260.
> > > So we need this patch to ensure RTS5260 can work.
> > >
> > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > > ---
> > > drivers/mfd/Makefile | 4 +
> > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > drivers/mfd/rtsx_pcr.h | 12 +
> > > drivers/staging/Kconfig | 2 +
> > > drivers/staging/rts5260/Kconfig | 6 +
> > > drivers/staging/rts5260/rts5260.c | 748
> ++++++++++++++++++++++++++++++++++++++
> > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > > 8 files changed, 1173 insertions(+), 5 deletions(-)
> > > create mode 100644 drivers/staging/rts5260/Kconfig
> > > create mode 100644 drivers/staging/rts5260/rts5260.c
> > > create mode 100644 drivers/staging/rts5260/rts5260.h
>
> [nearly 1000 lines snipped]
>
> Wow, that's a lot of scrolling to get to your reply!
>
> It would be helpful if you'd please snip your replies in the future.
Yes, sorry about that.
>
> > > There are a number of drivers in this family which currently reside in
> > > MFD. These were accepted before my time. After a recent review I've
> > > made the decision that these aren't MFD drivers at all.
> >
> > If all these other similar drivers don't belong in MFD, why are they
> > still there? Have they been moved in -next?
>
> No effort has been made to move them yet. We still don't have a
> suitable home for them. That's what we're discussing.
I see that on a part of this thread I wasn't on CC that drivers/misc
was decided.
>
> > As recently as last month I still see patches being accepted into
> > MFD regarding Realtek card readers.
> >
> > https://patchwork.kernel.org/patch/9941753/
>
> Changes to existing drivers, yes.
>
> I only noticed what was going on when this new driver was submitted.
>
> I'm now not accepting new ones.
>
> > I miss how it's reasonable to expect the submitter who is adding support
> > for new HW that is similar to other hardware in the past to be able to
> > know where to put it if this change hasn't already happened.
>
> It's perfectly reasonable to reject a new driver which doesn't
> belong.
>
> > What's actually wrong with accepting it in MFD like the other drivers
> > similar to it and then moving them all at once when the right place
> > is figured out?
>
> Because it removes the incentive for someone to take the initiative and
> move them. I can't work with promises. Too many times I've heard "if
> you just accept this patch, I'll do XYZ as a subsequent piece of
> work", then move on. They are either never seen again, or we have the
> same conversation when they attempt to submit something else. Things
> don't get done that way.
>
> > Then its much clearer for future drivers similar to this one that they
> > live in the new place (misc, or wherever makes sense).
>
> I've I would have accepted the original patch into MFD, we would not
> be having this conversation, people like yourself and Greg would not
> be aware and (the chances are - just going by previous experience
> here) nothing would have changed/improved.
>
> > It seems like it would be the same result but with less pain.
>
> That cannot be guaranteed.
>
> If people's words would have been their bond in the past, I would have
> more trust and the world would be a nicer place. :)
>
Thanks for answering each of my points and explaining. With strangers
that you don't work with regularly, trust absolutely needs to built.
I noticed that Realtek submitted the driver to misc/ but didn't move
the rest of the stuff in the series over the weekend.
I understand then that the ask would be to instead do 2 patch series:
1) Move the Realtek card reader drivers that are currently in
drivers/mfd/ over to drivers/misc.
Move all the stuff in include/mfd headers related to these realtek
devices over to a Realtek specific include/misc header
2) Submit this driver as into the new location.
I believe it should also be done relative to your -next tree since
as I mentioned before there was some things already targeted at
4.15.
So if that aligns to your expectations I believe their submission into
misc from this weekend should be discarded for now until they submit
the change to move the existing drivers as well.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: staging: rtsx: Add support for RTS5260
2017-10-16 20:38 ` Mario.Limonciello
@ 2017-10-23 9:18 ` Lee Jones
0 siblings, 0 replies; 13+ messages in thread
From: Lee Jones @ 2017-10-23 9:18 UTC (permalink / raw)
To: Mario.Limonciello
Cc: rui_feng, gregkh, linux-kernel, devel, ricky_wu, wei_wang
On Mon, 16 Oct 2017, Mario.Limonciello@dell.com wrote:
> > -----Original Message-----
> > From: Lee Jones [mailto:lee.jones@linaro.org]
> > Sent: Friday, October 13, 2017 4:15 PM
> > To: Limonciello, Mario <Mario_Limonciello@Dell.com>
> > Cc: rui_feng@realsil.com.cn; gregkh@linuxfoundation.org; linux-
> > kernel@vger.kernel.org; devel@driverdev.osuosl.org; ricky_wu@realtek.com;
> > wei_wang@realsil.com.cn
> > Subject: Re: staging: rtsx: Add support for RTS5260
> >
> > On Fri, 13 Oct 2017, Mario Limonciello wrote:
> > > On 10/13/2017 03:50 AM, rui_feng@realsil.com.cn wrote:
> > > > From: rui_feng <rui_feng@realsil.com.cn>
> > > >
> > > > Add support for new chip rts5260.
> > > > In order to support rts5260,the definitions of some internal
> > > > registers and workflow have to be modified and are different from its
> > > > predecessors and OCP function is added for RTS5260.
> > > > So we need this patch to ensure RTS5260 can work.
> > > >
> > > > Signed-off-by: Rui Feng <rui_feng@realsil.com.cn>
> > > > ---
> > > > drivers/mfd/Makefile | 4 +
> > > > drivers/mfd/rtsx_pcr.c | 127 ++++++-
> > > > drivers/mfd/rtsx_pcr.h | 12 +
> > > > drivers/staging/Kconfig | 2 +
> > > > drivers/staging/rts5260/Kconfig | 6 +
> > > > drivers/staging/rts5260/rts5260.c | 748
> > ++++++++++++++++++++++++++++++++++++++
> > > > drivers/staging/rts5260/rts5260.h | 45 +++
> > > > include/linux/mfd/rtsx_pci.h | 234 +++++++++++-
> > > > 8 files changed, 1173 insertions(+), 5 deletions(-)
> > > > create mode 100644 drivers/staging/rts5260/Kconfig
> > > > create mode 100644 drivers/staging/rts5260/rts5260.c
> > > > create mode 100644 drivers/staging/rts5260/rts5260.h
> >
> > [nearly 1000 lines snipped]
> >
> > Wow, that's a lot of scrolling to get to your reply!
> >
> > It would be helpful if you'd please snip your replies in the future.
>
> Yes, sorry about that.
>
> >
> > > > There are a number of drivers in this family which currently reside in
> > > > MFD. These were accepted before my time. After a recent review I've
> > > > made the decision that these aren't MFD drivers at all.
> > >
> > > If all these other similar drivers don't belong in MFD, why are they
> > > still there? Have they been moved in -next?
> >
> > No effort has been made to move them yet. We still don't have a
> > suitable home for them. That's what we're discussing.
>
> I see that on a part of this thread I wasn't on CC that drivers/misc
> was decided.
>
> >
> > > As recently as last month I still see patches being accepted into
> > > MFD regarding Realtek card readers.
> > >
> > > https://patchwork.kernel.org/patch/9941753/
> >
> > Changes to existing drivers, yes.
> >
> > I only noticed what was going on when this new driver was submitted.
> >
> > I'm now not accepting new ones.
> >
> > > I miss how it's reasonable to expect the submitter who is adding support
> > > for new HW that is similar to other hardware in the past to be able to
> > > know where to put it if this change hasn't already happened.
> >
> > It's perfectly reasonable to reject a new driver which doesn't
> > belong.
> >
> > > What's actually wrong with accepting it in MFD like the other drivers
> > > similar to it and then moving them all at once when the right place
> > > is figured out?
> >
> > Because it removes the incentive for someone to take the initiative and
> > move them. I can't work with promises. Too many times I've heard "if
> > you just accept this patch, I'll do XYZ as a subsequent piece of
> > work", then move on. They are either never seen again, or we have the
> > same conversation when they attempt to submit something else. Things
> > don't get done that way.
> >
> > > Then its much clearer for future drivers similar to this one that they
> > > live in the new place (misc, or wherever makes sense).
> >
> > I've I would have accepted the original patch into MFD, we would not
> > be having this conversation, people like yourself and Greg would not
> > be aware and (the chances are - just going by previous experience
> > here) nothing would have changed/improved.
> >
> > > It seems like it would be the same result but with less pain.
> >
> > That cannot be guaranteed.
> >
> > If people's words would have been their bond in the past, I would have
> > more trust and the world would be a nicer place. :)
> >
>
> Thanks for answering each of my points and explaining. With strangers
> that you don't work with regularly, trust absolutely needs to built.
>
> I noticed that Realtek submitted the driver to misc/ but didn't move
> the rest of the stuff in the series over the weekend.
>
> I understand then that the ask would be to instead do 2 patch series:
> 1) Move the Realtek card reader drivers that are currently in
> drivers/mfd/ over to drivers/misc.
> Move all the stuff in include/mfd headers related to these realtek
> devices over to a Realtek specific include/misc header
> 2) Submit this driver as into the new location.
>
> I believe it should also be done relative to your -next tree since
> as I mentioned before there was some things already targeted at
> 4.15.
>
> So if that aligns to your expectations I believe their submission into
> misc from this weekend should be discarded for now until they submit
> the change to move the existing drivers as well.
Apologies for the delay, I was on vacation last week.
You're absolutely right. Looks like the wheels are in motion:
https://patchwork.kernel.org/patch/10015855/
Thanks for taking an interest.
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2017-10-23 9:18 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-13 8:50 [PATCH] staging: rtsx: Add support for RTS5260 rui_feng
2017-10-13 9:26 ` Greg KH
2017-10-13 9:54 ` Lee Jones
2017-10-13 9:59 ` Greg KH
2017-10-13 10:11 ` Lee Jones
2017-10-13 10:21 ` Greg KH
2017-10-13 10:30 ` 答复: " 冯锐
2017-10-16 5:58 ` 冯锐
2017-10-16 7:45 ` Greg KH
2017-10-13 18:28 ` Mario Limonciello
2017-10-13 21:15 ` Lee Jones
2017-10-16 20:38 ` Mario.Limonciello
2017-10-23 9:18 ` Lee Jones
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.