cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rts5229.c (7412B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* Driver for Realtek PCI-Express card reader
      3 *
      4 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
      5 *
      6 * Author:
      7 *   Wei WANG <wei_wang@realsil.com.cn>
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/delay.h>
     12#include <linux/rtsx_pci.h>
     13
     14#include "rtsx_pcr.h"
     15
     16static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr)
     17{
     18	u8 val;
     19
     20	rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
     21	return val & 0x0F;
     22}
     23
     24static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
     25{
     26	struct pci_dev *pdev = pcr->pci;
     27	u32 reg;
     28
     29	pci_read_config_dword(pdev, PCR_SETTING_REG1, &reg);
     30	pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
     31
     32	if (!rtsx_vendor_setting_valid(reg))
     33		return;
     34
     35	pcr->aspm_en = rtsx_reg_to_aspm(reg);
     36	pcr->sd30_drive_sel_1v8 =
     37		map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg));
     38	pcr->card_drive_sel &= 0x3F;
     39	pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
     40
     41	pci_read_config_dword(pdev, PCR_SETTING_REG2, &reg);
     42	pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
     43	pcr->sd30_drive_sel_3v3 =
     44		map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg));
     45}
     46
     47static void rts5229_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
     48{
     49	rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
     50}
     51
     52static int rts5229_extra_init_hw(struct rtsx_pcr *pcr)
     53{
     54	rtsx_pci_init_cmd(pcr);
     55
     56	/* Configure GPIO as output */
     57	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
     58	/* Reset ASPM state to default value */
     59	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
     60	/* Force CLKREQ# PIN to drive 0 to request clock */
     61	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
     62	/* Switch LDO3318 source from DV33 to card_3v3 */
     63	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
     64	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
     65	/* LED shine disabled, set initial shine cycle period */
     66	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
     67	/* Configure driving */
     68	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
     69			0xFF, pcr->sd30_drive_sel_3v3);
     70
     71	return rtsx_pci_send_cmd(pcr, 100);
     72}
     73
     74static int rts5229_optimize_phy(struct rtsx_pcr *pcr)
     75{
     76	/* Optimize RX sensitivity */
     77	return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42);
     78}
     79
     80static int rts5229_turn_on_led(struct rtsx_pcr *pcr)
     81{
     82	return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
     83}
     84
     85static int rts5229_turn_off_led(struct rtsx_pcr *pcr)
     86{
     87	return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
     88}
     89
     90static int rts5229_enable_auto_blink(struct rtsx_pcr *pcr)
     91{
     92	return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
     93}
     94
     95static int rts5229_disable_auto_blink(struct rtsx_pcr *pcr)
     96{
     97	return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
     98}
     99
    100static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card)
    101{
    102	int err;
    103
    104	rtsx_pci_init_cmd(pcr);
    105	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
    106			SD_POWER_MASK, SD_PARTIAL_POWER_ON);
    107	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
    108			LDO3318_PWR_MASK, 0x02);
    109	err = rtsx_pci_send_cmd(pcr, 100);
    110	if (err < 0)
    111		return err;
    112
    113	/* To avoid too large in-rush current */
    114	udelay(150);
    115
    116	rtsx_pci_init_cmd(pcr);
    117	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
    118			SD_POWER_MASK, SD_POWER_ON);
    119	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
    120			LDO3318_PWR_MASK, 0x06);
    121	return rtsx_pci_send_cmd(pcr, 100);
    122}
    123
    124static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card)
    125{
    126	rtsx_pci_init_cmd(pcr);
    127	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
    128			SD_POWER_MASK | PMOS_STRG_MASK,
    129			SD_POWER_OFF | PMOS_STRG_400mA);
    130	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
    131			LDO3318_PWR_MASK, 0x00);
    132	return rtsx_pci_send_cmd(pcr, 100);
    133}
    134
    135static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
    136{
    137	int err;
    138
    139	if (voltage == OUTPUT_3V3) {
    140		err = rtsx_pci_write_register(pcr,
    141				SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3);
    142		if (err < 0)
    143			return err;
    144		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24);
    145		if (err < 0)
    146			return err;
    147	} else if (voltage == OUTPUT_1V8) {
    148		err = rtsx_pci_write_register(pcr,
    149				SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8);
    150		if (err < 0)
    151			return err;
    152		err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24);
    153		if (err < 0)
    154			return err;
    155	} else {
    156		return -EINVAL;
    157	}
    158
    159	return 0;
    160}
    161
    162static const struct pcr_ops rts5229_pcr_ops = {
    163	.fetch_vendor_settings = rts5229_fetch_vendor_settings,
    164	.extra_init_hw = rts5229_extra_init_hw,
    165	.optimize_phy = rts5229_optimize_phy,
    166	.turn_on_led = rts5229_turn_on_led,
    167	.turn_off_led = rts5229_turn_off_led,
    168	.enable_auto_blink = rts5229_enable_auto_blink,
    169	.disable_auto_blink = rts5229_disable_auto_blink,
    170	.card_power_on = rts5229_card_power_on,
    171	.card_power_off = rts5229_card_power_off,
    172	.switch_output_voltage = rts5229_switch_output_voltage,
    173	.cd_deglitch = NULL,
    174	.conv_clk_and_div_n = NULL,
    175	.force_power_down = rts5229_force_power_down,
    176};
    177
    178/* SD Pull Control Enable:
    179 *     SD_DAT[3:0] ==> pull up
    180 *     SD_CD       ==> pull up
    181 *     SD_WP       ==> pull up
    182 *     SD_CMD      ==> pull up
    183 *     SD_CLK      ==> pull down
    184 */
    185static const u32 rts5229_sd_pull_ctl_enable_tbl1[] = {
    186	RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
    187	RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
    188	0,
    189};
    190
    191/* For RTS5229 version C */
    192static const u32 rts5229_sd_pull_ctl_enable_tbl2[] = {
    193	RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
    194	RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD9),
    195	0,
    196};
    197
    198/* SD Pull Control Disable:
    199 *     SD_DAT[3:0] ==> pull down
    200 *     SD_CD       ==> pull up
    201 *     SD_WP       ==> pull down
    202 *     SD_CMD      ==> pull down
    203 *     SD_CLK      ==> pull down
    204 */
    205static const u32 rts5229_sd_pull_ctl_disable_tbl1[] = {
    206	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
    207	RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
    208	0,
    209};
    210
    211/* For RTS5229 version C */
    212static const u32 rts5229_sd_pull_ctl_disable_tbl2[] = {
    213	RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
    214	RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE5),
    215	0,
    216};
    217
    218/* MS Pull Control Enable:
    219 *     MS CD       ==> pull up
    220 *     others      ==> pull down
    221 */
    222static const u32 rts5229_ms_pull_ctl_enable_tbl[] = {
    223	RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
    224	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
    225	0,
    226};
    227
    228/* MS Pull Control Disable:
    229 *     MS CD       ==> pull up
    230 *     others      ==> pull down
    231 */
    232static const u32 rts5229_ms_pull_ctl_disable_tbl[] = {
    233	RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
    234	RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
    235	0,
    236};
    237
    238void rts5229_init_params(struct rtsx_pcr *pcr)
    239{
    240	pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
    241	pcr->num_slots = 2;
    242	pcr->ops = &rts5229_pcr_ops;
    243
    244	pcr->flags = 0;
    245	pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
    246	pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B;
    247	pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D;
    248	pcr->aspm_en = ASPM_L1_EN;
    249	pcr->aspm_mode = ASPM_MODE_CFG;
    250	pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15);
    251	pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 6, 6);
    252
    253	pcr->ic_version = rts5229_get_ic_version(pcr);
    254	if (pcr->ic_version == IC_VER_C) {
    255		pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2;
    256		pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl2;
    257	} else {
    258		pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl1;
    259		pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl1;
    260	}
    261	pcr->ms_pull_ctl_enable_tbl = rts5229_ms_pull_ctl_enable_tbl;
    262	pcr->ms_pull_ctl_disable_tbl = rts5229_ms_pull_ctl_disable_tbl;
    263}