Commit c0e5f4e7 authored by Rui Feng's avatar Rui Feng Committed by Greg Kroah-Hartman

misc: rtsx: Add support for RTS5261

Add support for new chip rts5261.
In order to support rts5261, the definitions of some internal registers
and workflow have to be modified and are different from its predecessors.
So we need this patch to ensure RTS5261 can work.
Signed-off-by: default avatarRui Feng <rui_feng@realsil.com.cn>
Link: https://lore.kernel.org/r/1571645105-5028-1-git-send-email-rui_feng@realsil.com.cnSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c6bf3842
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_MISC_ALCOR_PCI) += alcor_pci.o obj-$(CONFIG_MISC_ALCOR_PCI) += alcor_pci.o
obj-$(CONFIG_MISC_RTSX_PCI) += rtsx_pci.o obj-$(CONFIG_MISC_RTSX_PCI) += rtsx_pci.o
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o rts5260.o rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o rts5260.o rts5261.o
obj-$(CONFIG_MISC_RTSX_USB) += rtsx_usb.o obj-$(CONFIG_MISC_RTSX_USB) += rtsx_usb.o
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/* Driver for Realtek PCI-Express card reader
*
* Copyright(c) 2018-2019 Realtek Semiconductor Corp. All rights reserved.
*
* Author:
* Rui FENG <rui_feng@realsil.com.cn>
* Wei WANG <wei_wang@realsil.com.cn>
*/
#ifndef RTS5261_H
#define RTS5261_H
/*New add*/
#define rts5261_vendor_setting_valid(reg) ((reg) & 0x010000)
#define rts5261_reg_to_aspm(reg) (((reg) >> 28) ^ 0x03)
#define rts5261_reg_check_reverse_socket(reg) ((reg) & 0x04)
#define rts5261_reg_to_card_drive_sel(reg) ((((reg) >> 6) & 0x01) << 6)
#define rts5261_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 22) ^ 0x03)
#define rts5261_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 16) ^ 0x03)
#define RTS5261_AUTOLOAD_CFG0 0xFF7B
#define RTS5261_AUTOLOAD_CFG1 0xFF7C
#define RTS5261_AUTOLOAD_CFG2 0xFF7D
#define RTS5261_AUTOLOAD_CFG3 0xFF7E
#define RTS5261_AUTOLOAD_CFG4 0xFF7F
#define RTS5261_FORCE_PRSNT_LOW (1 << 6)
#define RTS5261_AUX_CLK_16M_EN (1 << 5)
#define RTS5261_REG_VREF 0xFE97
#define RTS5261_PWD_SUSPND_EN (1 << 4)
#define RTS5261_PAD_H3L1 0xFF79
#define PAD_GPIO_H3L1 (1 << 3)
/* SSC_CTL2 0xFC12 */
#define RTS5261_SSC_DEPTH_MASK 0x07
#define RTS5261_SSC_DEPTH_DISALBE 0x00
#define RTS5261_SSC_DEPTH_8M 0x01
#define RTS5261_SSC_DEPTH_4M 0x02
#define RTS5261_SSC_DEPTH_2M 0x03
#define RTS5261_SSC_DEPTH_1M 0x04
#define RTS5261_SSC_DEPTH_512K 0x05
#define RTS5261_SSC_DEPTH_256K 0x06
#define RTS5261_SSC_DEPTH_128K 0x07
/* efuse control register*/
#define RTS5261_EFUSE_CTL 0xFC30
#define RTS5261_EFUSE_ENABLE 0x80
/* EFUSE_MODE: 0=READ 1=PROGRAM */
#define RTS5261_EFUSE_MODE_MASK 0x40
#define RTS5261_EFUSE_PROGRAM 0x40
#define RTS5261_EFUSE_ADDR 0xFC31
#define RTS5261_EFUSE_ADDR_MASK 0x3F
#define RTS5261_EFUSE_WRITE_DATA 0xFC32
#define RTS5261_EFUSE_READ_DATA 0xFC34
/* DMACTL 0xFE2C */
#define RTS5261_DMA_PACK_SIZE_MASK 0xF0
/* FW config info register */
#define RTS5261_FW_CFG_INFO0 0xFF50
#define RTS5261_FW_EXPRESS_TEST_MASK (0x01<<0)
#define RTS5261_FW_EA_MODE_MASK (0x01<<5)
/* FW config register */
#define RTS5261_FW_CFG0 0xFF54
#define RTS5261_FW_ENTER_EXPRESS (0x01<<0)
#define RTS5261_FW_CFG1 0xFF55
#define RTS5261_SYS_CLK_SEL_MCU_CLK (0x01<<7)
#define RTS5261_CRC_CLK_SEL_MCU_CLK (0x01<<6)
#define RTS5261_FAKE_MCU_CLOCK_GATING (0x01<<5)
/*MCU_bus_mode_sel: 0=real 8051 1=fake mcu*/
#define RTS5261_MCU_BUS_SEL_MASK (0x01<<4)
/*MCU_clock_sel:VerA 00=aux16M 01=aux400K 1x=REFCLK100M*/
/*MCU_clock_sel:VerB 00=aux400K 01=aux16M 10=REFCLK100M*/
#define RTS5261_MCU_CLOCK_SEL_MASK (0x03<<2)
#define RTS5261_MCU_CLOCK_SEL_16M (0x01<<2)
#define RTS5261_MCU_CLOCK_GATING (0x01<<1)
#define RTS5261_DRIVER_ENABLE_FW (0x01<<0)
/* FW status register */
#define RTS5261_FW_STATUS 0xFF56
#define RTS5261_EXPRESS_LINK_FAIL_MASK (0x01<<7)
/* FW control register */
#define RTS5261_FW_CTL 0xFF5F
#define RTS5261_INFORM_RTD3_COLD (0x01<<5)
#define RTS5261_REG_FPDCTL 0xFF60
#define RTS5261_REG_LDO12_CFG 0xFF6E
#define RTS5261_LDO12_VO_TUNE_MASK (0x07<<1)
#define RTS5261_LDO12_115 (0x03<<1)
#define RTS5261_LDO12_120 (0x04<<1)
#define RTS5261_LDO12_125 (0x05<<1)
#define RTS5261_LDO12_130 (0x06<<1)
#define RTS5261_LDO12_135 (0x07<<1)
/* LDO control register */
#define RTS5261_CARD_PWR_CTL 0xFD50
#define RTS5261_SD_CLK_ISO (0x01<<7)
#define RTS5261_PAD_SD_DAT_FW_CTRL (0x01<<6)
#define RTS5261_PUPDC (0x01<<5)
#define RTS5261_SD_CMD_ISO (0x01<<4)
#define RTS5261_SD_DAT_ISO_MASK (0x0F<<0)
#define RTS5261_LDO1233318_POW_CTL 0xFF70
#define RTS5261_LDO3318_POWERON (0x01<<3)
#define RTS5261_LDO3_POWERON (0x01<<2)
#define RTS5261_LDO2_POWERON (0x01<<1)
#define RTS5261_LDO1_POWERON (0x01<<0)
#define RTS5261_LDO_POWERON_MASK (0x0F<<0)
#define RTS5261_DV3318_CFG 0xFF71
#define RTS5261_DV3318_TUNE_MASK (0x07<<4)
#define RTS5261_DV3318_18 (0x02<<4)
#define RTS5261_DV3318_19 (0x04<<4)
#define RTS5261_DV3318_33 (0x07<<4)
#define RTS5261_LDO1_CFG0 0xFF72
#define RTS5261_LDO1_OCP_THD_MASK (0x07<<5)
#define RTS5261_LDO1_OCP_EN (0x01<<4)
#define RTS5261_LDO1_OCP_LMT_THD_MASK (0x03<<2)
#define RTS5261_LDO1_OCP_LMT_EN (0x01<<1)
/* CRD6603-433 190319 request changed */
#define RTS5261_LDO1_OCP_THD_740 (0x00<<5)
#define RTS5261_LDO1_OCP_THD_800 (0x01<<5)
#define RTS5261_LDO1_OCP_THD_860 (0x02<<5)
#define RTS5261_LDO1_OCP_THD_920 (0x03<<5)
#define RTS5261_LDO1_OCP_THD_980 (0x04<<5)
#define RTS5261_LDO1_OCP_THD_1040 (0x05<<5)
#define RTS5261_LDO1_OCP_THD_1100 (0x06<<5)
#define RTS5261_LDO1_OCP_THD_1160 (0x07<<5)
#define RTS5261_LDO1_LMT_THD_450 (0x00<<2)
#define RTS5261_LDO1_LMT_THD_1000 (0x01<<2)
#define RTS5261_LDO1_LMT_THD_1500 (0x02<<2)
#define RTS5261_LDO1_LMT_THD_2000 (0x03<<2)
#define RTS5261_LDO1_CFG1 0xFF73
#define RTS5261_LDO1_TUNE_MASK (0x07<<1)
#define RTS5261_LDO1_18 (0x05<<1)
#define RTS5261_LDO1_33 (0x07<<1)
#define RTS5261_LDO1_PWD_MASK (0x01<<0)
#define RTS5261_LDO2_CFG0 0xFF74
#define RTS5261_LDO2_OCP_THD_MASK (0x07<<5)
#define RTS5261_LDO2_OCP_EN (0x01<<4)
#define RTS5261_LDO2_OCP_LMT_THD_MASK (0x03<<2)
#define RTS5261_LDO2_OCP_LMT_EN (0x01<<1)
#define RTS5261_LDO2_OCP_THD_620 (0x00<<5)
#define RTS5261_LDO2_OCP_THD_650 (0x01<<5)
#define RTS5261_LDO2_OCP_THD_680 (0x02<<5)
#define RTS5261_LDO2_OCP_THD_720 (0x03<<5)
#define RTS5261_LDO2_OCP_THD_750 (0x04<<5)
#define RTS5261_LDO2_OCP_THD_780 (0x05<<5)
#define RTS5261_LDO2_OCP_THD_810 (0x06<<5)
#define RTS5261_LDO2_OCP_THD_840 (0x07<<5)
#define RTS5261_LDO2_CFG1 0xFF75
#define RTS5261_LDO2_TUNE_MASK (0x07<<1)
#define RTS5261_LDO2_18 (0x05<<1)
#define RTS5261_LDO2_33 (0x07<<1)
#define RTS5261_LDO2_PWD_MASK (0x01<<0)
#define RTS5261_LDO3_CFG0 0xFF76
#define RTS5261_LDO3_OCP_THD_MASK (0x07<<5)
#define RTS5261_LDO3_OCP_EN (0x01<<4)
#define RTS5261_LDO3_OCP_LMT_THD_MASK (0x03<<2)
#define RTS5261_LDO3_OCP_LMT_EN (0x01<<1)
#define RTS5261_LDO3_OCP_THD_620 (0x00<<5)
#define RTS5261_LDO3_OCP_THD_650 (0x01<<5)
#define RTS5261_LDO3_OCP_THD_680 (0x02<<5)
#define RTS5261_LDO3_OCP_THD_720 (0x03<<5)
#define RTS5261_LDO3_OCP_THD_750 (0x04<<5)
#define RTS5261_LDO3_OCP_THD_780 (0x05<<5)
#define RTS5261_LDO3_OCP_THD_810 (0x06<<5)
#define RTS5261_LDO3_OCP_THD_840 (0x07<<5)
#define RTS5261_LDO3_CFG1 0xFF77
#define RTS5261_LDO3_TUNE_MASK (0x07<<1)
#define RTS5261_LDO3_18 (0x05<<1)
#define RTS5261_LDO3_33 (0x07<<1)
#define RTS5261_LDO3_PWD_MASK (0x01<<0)
#define RTS5261_REG_PME_FORCE_CTL 0xFF78
#define FORCE_PM_CONTROL 0x20
#define FORCE_PM_VALUE 0x10
#define REG_EFUSE_BYPASS 0x08
#define REG_EFUSE_POR 0x04
#define REG_EFUSE_POWER_MASK 0x03
#define REG_EFUSE_POWERON 0x03
#define REG_EFUSE_POWEROFF 0x00
/* Single LUN, support SD/SD EXPRESS */
#define DEFAULT_SINGLE 0
#define SD_LUN 1
#define SD_EXPRESS_LUN 2
/* For Change_FPGA_SSCClock Function */
#define MULTIPLY_BY_1 0x00
#define MULTIPLY_BY_2 0x01
#define MULTIPLY_BY_3 0x02
#define MULTIPLY_BY_4 0x03
#define MULTIPLY_BY_5 0x04
#define MULTIPLY_BY_6 0x05
#define MULTIPLY_BY_7 0x06
#define MULTIPLY_BY_8 0x07
#define MULTIPLY_BY_9 0x08
#define MULTIPLY_BY_10 0x09
#define DIVIDE_BY_2 0x01
#define DIVIDE_BY_3 0x02
#define DIVIDE_BY_4 0x03
#define DIVIDE_BY_5 0x04
#define DIVIDE_BY_6 0x05
#define DIVIDE_BY_7 0x06
#define DIVIDE_BY_8 0x07
#define DIVIDE_BY_9 0x08
#define DIVIDE_BY_10 0x09
int rts5261_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
#endif /* RTS5261_H */
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "rtsx_pcr.h" #include "rtsx_pcr.h"
#include "rts5261.h"
static bool msi_en = true; static bool msi_en = true;
module_param(msi_en, bool, S_IRUGO | S_IWUSR); module_param(msi_en, bool, S_IRUGO | S_IWUSR);
...@@ -34,9 +35,6 @@ static struct mfd_cell rtsx_pcr_cells[] = { ...@@ -34,9 +35,6 @@ static struct mfd_cell rtsx_pcr_cells[] = {
[RTSX_SD_CARD] = { [RTSX_SD_CARD] = {
.name = DRV_NAME_RTSX_PCI_SDMMC, .name = DRV_NAME_RTSX_PCI_SDMMC,
}, },
[RTSX_MS_CARD] = {
.name = DRV_NAME_RTSX_PCI_MS,
},
}; };
static const struct pci_device_id rtsx_pci_ids[] = { static const struct pci_device_id rtsx_pci_ids[] = {
...@@ -51,6 +49,7 @@ static const struct pci_device_id rtsx_pci_ids[] = { ...@@ -51,6 +49,7 @@ static const struct pci_device_id rtsx_pci_ids[] = {
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5261), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ 0, } { 0, }
}; };
...@@ -438,8 +437,16 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr, ...@@ -438,8 +437,16 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
if (end) if (end)
option |= RTSX_SG_END; option |= RTSX_SG_END;
val = ((u64)addr << 32) | ((u64)len << 12) | option;
if (PCI_PID(pcr) == PID_5261) {
if (len > 0xFFFF)
val = ((u64)addr << 32) | (((u64)len & 0xFFFF) << 16)
| (((u64)len >> 16) << 6) | option;
else
val = ((u64)addr << 32) | ((u64)len << 16) | option;
} else {
val = ((u64)addr << 32) | ((u64)len << 12) | option;
}
put_unaligned_le64(val, ptr); put_unaligned_le64(val, ptr);
pcr->sgi++; pcr->sgi++;
} }
...@@ -684,7 +691,6 @@ int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card) ...@@ -684,7 +691,6 @@ int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card)
else else
return -EINVAL; return -EINVAL;
return rtsx_pci_set_pull_ctl(pcr, tbl); return rtsx_pci_set_pull_ctl(pcr, tbl);
} }
EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable); EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable);
...@@ -735,6 +741,10 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, ...@@ -735,6 +741,10 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
[RTSX_SSC_DEPTH_250K] = SSC_DEPTH_250K, [RTSX_SSC_DEPTH_250K] = SSC_DEPTH_250K,
}; };
if (PCI_PID(pcr) == PID_5261)
return rts5261_pci_switch_clock(pcr, card_clock,
ssc_depth, initial_mode, double_clk, vpclk);
if (initial_mode) { if (initial_mode) {
/* We use 250k(around) here, in initial stage */ /* We use 250k(around) here, in initial stage */
clk_divider = SD_CLK_DIVIDE_128; clk_divider = SD_CLK_DIVIDE_128;
...@@ -1253,7 +1263,15 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) ...@@ -1253,7 +1263,15 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
rtsx_pci_enable_bus_int(pcr); rtsx_pci_enable_bus_int(pcr);
/* Power on SSC */ /* Power on SSC */
err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0); if (PCI_PID(pcr) == PID_5261) {
/* Gating real mcu clock */
err = rtsx_pci_write_register(pcr, RTS5261_FW_CFG1,
RTS5261_MCU_CLOCK_GATING, 0);
err = rtsx_pci_write_register(pcr, RTS5261_REG_FPDCTL,
SSC_POWER_DOWN, 0);
} else {
err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0);
}
if (err < 0) if (err < 0)
return err; return err;
...@@ -1283,7 +1301,12 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) ...@@ -1283,7 +1301,12 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
/* Enable SSC Clock */ /* Enable SSC Clock */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1,
0xFF, SSC_8X_EN | SSC_SEL_4M); 0xFF, SSC_8X_EN | SSC_SEL_4M);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12); if (PCI_PID(pcr) == PID_5261)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF,
RTS5261_SSC_DEPTH_2M);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12);
/* Disable cd_pwr_save */ /* Disable cd_pwr_save */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x16, 0x10); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x16, 0x10);
/* Clear Link Ready Interrupt */ /* Clear Link Ready Interrupt */
...@@ -1314,6 +1337,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) ...@@ -1314,6 +1337,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
case PID_524A: case PID_524A:
case PID_525A: case PID_525A:
case PID_5260: case PID_5260:
case PID_5261:
rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1); rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1);
break; break;
default: default:
...@@ -1393,9 +1417,14 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) ...@@ -1393,9 +1417,14 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
case 0x5286: case 0x5286:
rtl8402_init_params(pcr); rtl8402_init_params(pcr);
break; break;
case 0x5260: case 0x5260:
rts5260_init_params(pcr); rts5260_init_params(pcr);
break; break;
case 0x5261:
rts5261_init_params(pcr);
break;
} }
pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n", pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
......
...@@ -53,6 +53,7 @@ void rts524a_init_params(struct rtsx_pcr *pcr); ...@@ -53,6 +53,7 @@ void rts524a_init_params(struct rtsx_pcr *pcr);
void rts525a_init_params(struct rtsx_pcr *pcr); void rts525a_init_params(struct rtsx_pcr *pcr);
void rtl8411b_init_params(struct rtsx_pcr *pcr); void rtl8411b_init_params(struct rtsx_pcr *pcr);
void rts5260_init_params(struct rtsx_pcr *pcr); void rts5260_init_params(struct rtsx_pcr *pcr);
void rts5261_init_params(struct rtsx_pcr *pcr);
static inline u8 map_sd_drive(int idx) static inline u8 map_sd_drive(int idx)
{ {
......
...@@ -1262,6 +1262,7 @@ struct rtsx_pcr { ...@@ -1262,6 +1262,7 @@ struct rtsx_pcr {
#define PID_5250 0x5250 #define PID_5250 0x5250
#define PID_525A 0x525A #define PID_525A 0x525A
#define PID_5260 0x5260 #define PID_5260 0x5260
#define PID_5261 0x5261
#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid)) #define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
#define PCI_VID(pcr) ((pcr)->pci->vendor) #define PCI_VID(pcr) ((pcr)->pci->vendor)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment