diff options
-rw-r--r-- | drivers/mfd/rtl8411.c | 77 | ||||
-rw-r--r-- | drivers/mfd/rts5209.c | 48 | ||||
-rw-r--r-- | drivers/mfd/rts5227.c | 91 | ||||
-rw-r--r-- | drivers/mfd/rts5229.c | 38 | ||||
-rw-r--r-- | drivers/mfd/rts5249.c | 90 | ||||
-rw-r--r-- | drivers/mfd/rtsx_pcr.c | 26 | ||||
-rw-r--r-- | drivers/mfd/rtsx_pcr.h | 29 | ||||
-rw-r--r-- | include/linux/mfd/rtsx_pci.h | 34 |
8 files changed, 365 insertions, 68 deletions
diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c index c436bf27e78d..5a68c9bdeddf 100644 --- a/drivers/mfd/rtl8411.c +++ b/drivers/mfd/rtl8411.c | |||
@@ -47,19 +47,70 @@ static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr) | |||
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | 49 | ||
50 | static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr) | ||
51 | { | ||
52 | u32 reg1; | ||
53 | u8 reg3; | ||
54 | |||
55 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®1); | ||
56 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1); | ||
57 | |||
58 | if (!rtsx_vendor_setting_valid(reg1)) | ||
59 | return; | ||
60 | |||
61 | pcr->aspm_en = rtsx_reg_to_aspm(reg1); | ||
62 | pcr->sd30_drive_sel_1v8 = | ||
63 | map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg1)); | ||
64 | pcr->card_drive_sel &= 0x3F; | ||
65 | pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1); | ||
66 | |||
67 | rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, ®3); | ||
68 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3); | ||
69 | pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3); | ||
70 | } | ||
71 | |||
72 | static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr) | ||
73 | { | ||
74 | u32 reg; | ||
75 | |||
76 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); | ||
77 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); | ||
78 | |||
79 | if (!rtsx_vendor_setting_valid(reg)) | ||
80 | return; | ||
81 | |||
82 | pcr->aspm_en = rtsx_reg_to_aspm(reg); | ||
83 | pcr->sd30_drive_sel_1v8 = | ||
84 | map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg)); | ||
85 | pcr->sd30_drive_sel_3v3 = | ||
86 | map_sd_drive(rtl8411b_reg_to_sd30_drive_sel_3v3(reg)); | ||
87 | } | ||
88 | |||
50 | static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr) | 89 | static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr) |
51 | { | 90 | { |
52 | return rtsx_pci_write_register(pcr, CD_PAD_CTL, | 91 | rtsx_pci_init_cmd(pcr); |
92 | |||
93 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL, | ||
94 | 0xFF, pcr->sd30_drive_sel_3v3); | ||
95 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL, | ||
53 | CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); | 96 | CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); |
97 | |||
98 | return rtsx_pci_send_cmd(pcr, 100); | ||
54 | } | 99 | } |
55 | 100 | ||
56 | static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr) | 101 | static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr) |
57 | { | 102 | { |
58 | if (rtl8411b_is_qfn48(pcr)) | 103 | rtsx_pci_init_cmd(pcr); |
59 | rtsx_pci_write_register(pcr, CARD_PULL_CTL3, 0xFF, 0xF5); | ||
60 | 104 | ||
61 | return rtsx_pci_write_register(pcr, CD_PAD_CTL, | 105 | if (rtl8411b_is_qfn48(pcr)) |
106 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
107 | CARD_PULL_CTL3, 0xFF, 0xF5); | ||
108 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL, | ||
109 | 0xFF, pcr->sd30_drive_sel_3v3); | ||
110 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CD_PAD_CTL, | ||
62 | CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); | 111 | CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); |
112 | |||
113 | return rtsx_pci_send_cmd(pcr, 100); | ||
63 | } | 114 | } |
64 | 115 | ||
65 | static int rtl8411_turn_on_led(struct rtsx_pcr *pcr) | 116 | static int rtl8411_turn_on_led(struct rtsx_pcr *pcr) |
@@ -141,13 +192,13 @@ static int rtl8411_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
141 | mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK; | 192 | mask = (BPP_REG_TUNED18 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_MASK; |
142 | if (voltage == OUTPUT_3V3) { | 193 | if (voltage == OUTPUT_3V3) { |
143 | err = rtsx_pci_write_register(pcr, | 194 | err = rtsx_pci_write_register(pcr, |
144 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); | 195 | SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3); |
145 | if (err < 0) | 196 | if (err < 0) |
146 | return err; | 197 | return err; |
147 | val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3; | 198 | val = (BPP_ASIC_3V3 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_3V3; |
148 | } else if (voltage == OUTPUT_1V8) { | 199 | } else if (voltage == OUTPUT_1V8) { |
149 | err = rtsx_pci_write_register(pcr, | 200 | err = rtsx_pci_write_register(pcr, |
150 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); | 201 | SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8); |
151 | if (err < 0) | 202 | if (err < 0) |
152 | return err; | 203 | return err; |
153 | val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8; | 204 | val = (BPP_ASIC_1V8 << BPP_TUNED18_SHIFT_8411) | BPP_PAD_1V8; |
@@ -222,6 +273,7 @@ static int rtl8411_conv_clk_and_div_n(int input, int dir) | |||
222 | } | 273 | } |
223 | 274 | ||
224 | static const struct pcr_ops rtl8411_pcr_ops = { | 275 | static const struct pcr_ops rtl8411_pcr_ops = { |
276 | .fetch_vendor_settings = rtl8411_fetch_vendor_settings, | ||
225 | .extra_init_hw = rtl8411_extra_init_hw, | 277 | .extra_init_hw = rtl8411_extra_init_hw, |
226 | .optimize_phy = NULL, | 278 | .optimize_phy = NULL, |
227 | .turn_on_led = rtl8411_turn_on_led, | 279 | .turn_on_led = rtl8411_turn_on_led, |
@@ -236,6 +288,7 @@ static const struct pcr_ops rtl8411_pcr_ops = { | |||
236 | }; | 288 | }; |
237 | 289 | ||
238 | static const struct pcr_ops rtl8411b_pcr_ops = { | 290 | static const struct pcr_ops rtl8411b_pcr_ops = { |
291 | .fetch_vendor_settings = rtl8411b_fetch_vendor_settings, | ||
239 | .extra_init_hw = rtl8411b_extra_init_hw, | 292 | .extra_init_hw = rtl8411b_extra_init_hw, |
240 | .optimize_phy = NULL, | 293 | .optimize_phy = NULL, |
241 | .turn_on_led = rtl8411_turn_on_led, | 294 | .turn_on_led = rtl8411_turn_on_led, |
@@ -385,6 +438,12 @@ void rtl8411_init_params(struct rtsx_pcr *pcr) | |||
385 | pcr->num_slots = 2; | 438 | pcr->num_slots = 2; |
386 | pcr->ops = &rtl8411_pcr_ops; | 439 | pcr->ops = &rtl8411_pcr_ops; |
387 | 440 | ||
441 | pcr->flags = 0; | ||
442 | pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT; | ||
443 | pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; | ||
444 | pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; | ||
445 | pcr->aspm_en = ASPM_L1_EN; | ||
446 | |||
388 | pcr->ic_version = rtl8411_get_ic_version(pcr); | 447 | pcr->ic_version = rtl8411_get_ic_version(pcr); |
389 | pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl; | 448 | pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl; |
390 | pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl; | 449 | pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl; |
@@ -398,6 +457,12 @@ void rtl8411b_init_params(struct rtsx_pcr *pcr) | |||
398 | pcr->num_slots = 2; | 457 | pcr->num_slots = 2; |
399 | pcr->ops = &rtl8411b_pcr_ops; | 458 | pcr->ops = &rtl8411b_pcr_ops; |
400 | 459 | ||
460 | pcr->flags = 0; | ||
461 | pcr->card_drive_sel = RTL8411_CARD_DRIVE_DEFAULT; | ||
462 | pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; | ||
463 | pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; | ||
464 | pcr->aspm_en = ASPM_L1_EN; | ||
465 | |||
401 | pcr->ic_version = rtl8411_get_ic_version(pcr); | 466 | pcr->ic_version = rtl8411_get_ic_version(pcr); |
402 | 467 | ||
403 | if (rtl8411b_is_qfn48(pcr)) { | 468 | if (rtl8411b_is_qfn48(pcr)) { |
diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c index ec78d9fb0879..2170449bd7e5 100644 --- a/drivers/mfd/rts5209.c +++ b/drivers/mfd/rts5209.c | |||
@@ -34,18 +34,28 @@ static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr) | |||
34 | return val & 0x0F; | 34 | return val & 0x0F; |
35 | } | 35 | } |
36 | 36 | ||
37 | static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr) | 37 | static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr) |
38 | { | 38 | { |
39 | u32 val; | 39 | u32 reg; |
40 | 40 | ||
41 | rtsx_pci_read_config_dword(pcr, 0x724, &val); | 41 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); |
42 | dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val); | 42 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); |
43 | 43 | ||
44 | if (!(val & 0x80)) { | 44 | if (rts5209_vendor_setting1_valid(reg)) { |
45 | if (val & 0x08) | 45 | if (rts5209_reg_check_ms_pmos(reg)) |
46 | pcr->ms_pmos = false; | 46 | pcr->flags |= PCR_MS_PMOS; |
47 | else | 47 | pcr->aspm_en = rts5209_reg_to_aspm(reg); |
48 | pcr->ms_pmos = true; | 48 | } |
49 | |||
50 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®); | ||
51 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); | ||
52 | |||
53 | if (rts5209_vendor_setting2_valid(reg)) { | ||
54 | pcr->sd30_drive_sel_1v8 = | ||
55 | rts5209_reg_to_sd30_drive_sel_1v8(reg); | ||
56 | pcr->sd30_drive_sel_3v3 = | ||
57 | rts5209_reg_to_sd30_drive_sel_3v3(reg); | ||
58 | pcr->card_drive_sel = rts5209_reg_to_card_drive_sel(reg); | ||
49 | } | 59 | } |
50 | } | 60 | } |
51 | 61 | ||
@@ -57,6 +67,9 @@ static int rts5209_extra_init_hw(struct rtsx_pcr *pcr) | |||
57 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03); | 67 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03); |
58 | /* Configure GPIO as output */ | 68 | /* Configure GPIO as output */ |
59 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03); | 69 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03); |
70 | /* Configure driving */ | ||
71 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL, | ||
72 | 0xFF, pcr->sd30_drive_sel_3v3); | ||
60 | 73 | ||
61 | return rtsx_pci_send_cmd(pcr, 100); | 74 | return rtsx_pci_send_cmd(pcr, 100); |
62 | } | 75 | } |
@@ -95,7 +108,7 @@ static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card) | |||
95 | partial_pwr_on = SD_PARTIAL_POWER_ON; | 108 | partial_pwr_on = SD_PARTIAL_POWER_ON; |
96 | pwr_on = SD_POWER_ON; | 109 | pwr_on = SD_POWER_ON; |
97 | 110 | ||
98 | if (pcr->ms_pmos && (card == RTSX_MS_CARD)) { | 111 | if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) { |
99 | pwr_mask = MS_POWER_MASK; | 112 | pwr_mask = MS_POWER_MASK; |
100 | partial_pwr_on = MS_PARTIAL_POWER_ON; | 113 | partial_pwr_on = MS_PARTIAL_POWER_ON; |
101 | pwr_on = MS_POWER_ON; | 114 | pwr_on = MS_POWER_ON; |
@@ -131,7 +144,7 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) | |||
131 | pwr_mask = SD_POWER_MASK; | 144 | pwr_mask = SD_POWER_MASK; |
132 | pwr_off = SD_POWER_OFF; | 145 | pwr_off = SD_POWER_OFF; |
133 | 146 | ||
134 | if (pcr->ms_pmos && (card == RTSX_MS_CARD)) { | 147 | if ((pcr->flags & PCR_MS_PMOS) && (card == RTSX_MS_CARD)) { |
135 | pwr_mask = MS_POWER_MASK; | 148 | pwr_mask = MS_POWER_MASK; |
136 | pwr_off = MS_POWER_OFF; | 149 | pwr_off = MS_POWER_OFF; |
137 | } | 150 | } |
@@ -140,7 +153,7 @@ static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) | |||
140 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, | 153 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, |
141 | pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA); | 154 | pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA); |
142 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, | 155 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, |
143 | LDO3318_PWR_MASK, 0X06); | 156 | LDO3318_PWR_MASK, 0x06); |
144 | return rtsx_pci_send_cmd(pcr, 100); | 157 | return rtsx_pci_send_cmd(pcr, 100); |
145 | } | 158 | } |
146 | 159 | ||
@@ -150,7 +163,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
150 | 163 | ||
151 | if (voltage == OUTPUT_3V3) { | 164 | if (voltage == OUTPUT_3V3) { |
152 | err = rtsx_pci_write_register(pcr, | 165 | err = rtsx_pci_write_register(pcr, |
153 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); | 166 | SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3); |
154 | if (err < 0) | 167 | if (err < 0) |
155 | return err; | 168 | return err; |
156 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | 169 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); |
@@ -158,7 +171,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
158 | return err; | 171 | return err; |
159 | } else if (voltage == OUTPUT_1V8) { | 172 | } else if (voltage == OUTPUT_1V8) { |
160 | err = rtsx_pci_write_register(pcr, | 173 | err = rtsx_pci_write_register(pcr, |
161 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); | 174 | SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8); |
162 | if (err < 0) | 175 | if (err < 0) |
163 | return err; | 176 | return err; |
164 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); | 177 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); |
@@ -172,6 +185,7 @@ static int rts5209_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
172 | } | 185 | } |
173 | 186 | ||
174 | static const struct pcr_ops rts5209_pcr_ops = { | 187 | static const struct pcr_ops rts5209_pcr_ops = { |
188 | .fetch_vendor_settings = rts5209_fetch_vendor_settings, | ||
175 | .extra_init_hw = rts5209_extra_init_hw, | 189 | .extra_init_hw = rts5209_extra_init_hw, |
176 | .optimize_phy = rts5209_optimize_phy, | 190 | .optimize_phy = rts5209_optimize_phy, |
177 | .turn_on_led = rts5209_turn_on_led, | 191 | .turn_on_led = rts5209_turn_on_led, |
@@ -242,7 +256,11 @@ void rts5209_init_params(struct rtsx_pcr *pcr) | |||
242 | pcr->num_slots = 2; | 256 | pcr->num_slots = 2; |
243 | pcr->ops = &rts5209_pcr_ops; | 257 | pcr->ops = &rts5209_pcr_ops; |
244 | 258 | ||
245 | rts5209_init_vendor_cfg(pcr); | 259 | pcr->flags = 0; |
260 | pcr->card_drive_sel = RTS5209_CARD_DRIVE_DEFAULT; | ||
261 | pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; | ||
262 | pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; | ||
263 | pcr->aspm_en = ASPM_L1_EN; | ||
246 | 264 | ||
247 | pcr->ic_version = rts5209_get_ic_version(pcr); | 265 | pcr->ic_version = rts5209_get_ic_version(pcr); |
248 | pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl; | 266 | pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl; |
diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c index fc831dcb1480..c3181d71fedd 100644 --- a/drivers/mfd/rts5227.c +++ b/drivers/mfd/rts5227.c | |||
@@ -29,6 +29,60 @@ | |||
29 | 29 | ||
30 | #include "rtsx_pcr.h" | 30 | #include "rtsx_pcr.h" |
31 | 31 | ||
32 | static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage) | ||
33 | { | ||
34 | u8 driving_3v3[4][3] = { | ||
35 | {0x13, 0x13, 0x13}, | ||
36 | {0x96, 0x96, 0x96}, | ||
37 | {0x7F, 0x7F, 0x7F}, | ||
38 | {0x96, 0x96, 0x96}, | ||
39 | }; | ||
40 | u8 driving_1v8[4][3] = { | ||
41 | {0x99, 0x99, 0x99}, | ||
42 | {0xAA, 0xAA, 0xAA}, | ||
43 | {0xFE, 0xFE, 0xFE}, | ||
44 | {0xB3, 0xB3, 0xB3}, | ||
45 | }; | ||
46 | u8 (*driving)[3], drive_sel; | ||
47 | |||
48 | if (voltage == OUTPUT_3V3) { | ||
49 | driving = driving_3v3; | ||
50 | drive_sel = pcr->sd30_drive_sel_3v3; | ||
51 | } else { | ||
52 | driving = driving_1v8; | ||
53 | drive_sel = pcr->sd30_drive_sel_1v8; | ||
54 | } | ||
55 | |||
56 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, | ||
57 | 0xFF, driving[drive_sel][0]); | ||
58 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, | ||
59 | 0xFF, driving[drive_sel][1]); | ||
60 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, | ||
61 | 0xFF, driving[drive_sel][2]); | ||
62 | } | ||
63 | |||
64 | static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr) | ||
65 | { | ||
66 | u32 reg; | ||
67 | |||
68 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); | ||
69 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); | ||
70 | |||
71 | if (!rtsx_vendor_setting_valid(reg)) | ||
72 | return; | ||
73 | |||
74 | pcr->aspm_en = rtsx_reg_to_aspm(reg); | ||
75 | pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg); | ||
76 | pcr->card_drive_sel &= 0x3F; | ||
77 | pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg); | ||
78 | |||
79 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®); | ||
80 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); | ||
81 | pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg); | ||
82 | if (rtsx_reg_check_reverse_socket(reg)) | ||
83 | pcr->flags |= PCR_REVERSE_SOCKET; | ||
84 | } | ||
85 | |||
32 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) | 86 | static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) |
33 | { | 87 | { |
34 | u16 cap; | 88 | u16 cap; |
@@ -48,17 +102,15 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) | |||
48 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3); | 102 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LTR_CTL, 0xFF, 0xA3); |
49 | /* Configure OBFF */ | 103 | /* Configure OBFF */ |
50 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03); | 104 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG, 0x03, 0x03); |
51 | /* Configure force_clock_req | 105 | /* Configure driving */ |
52 | * Maybe We should define 0xFF03 as some name | 106 | rts5227_fill_driving(pcr, OUTPUT_3V3); |
53 | */ | 107 | /* Configure force_clock_req */ |
54 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, 0xFF03, 0x08, 0x08); | 108 | if (pcr->flags & PCR_REVERSE_SOCKET) |
55 | /* Correct driving */ | 109 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, |
56 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 110 | AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8); |
57 | SD30_CLK_DRIVE_SEL, 0xFF, 0x96); | 111 | else |
58 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 112 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, |
59 | SD30_CMD_DRIVE_SEL, 0xFF, 0x96); | 113 | AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88); |
60 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | ||
61 | SD30_DAT_DRIVE_SEL, 0xFF, 0x96); | ||
62 | 114 | ||
63 | return rtsx_pci_send_cmd(pcr, 100); | 115 | return rtsx_pci_send_cmd(pcr, 100); |
64 | } | 116 | } |
@@ -131,13 +183,11 @@ static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card) | |||
131 | static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | 183 | static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) |
132 | { | 184 | { |
133 | int err; | 185 | int err; |
134 | u8 drive_sel; | ||
135 | 186 | ||
136 | if (voltage == OUTPUT_3V3) { | 187 | if (voltage == OUTPUT_3V3) { |
137 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | 188 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); |
138 | if (err < 0) | 189 | if (err < 0) |
139 | return err; | 190 | return err; |
140 | drive_sel = 0x96; | ||
141 | } else if (voltage == OUTPUT_1V8) { | 191 | } else if (voltage == OUTPUT_1V8) { |
142 | err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02); | 192 | err = rtsx_pci_write_phy_register(pcr, 0x11, 0x3C02); |
143 | if (err < 0) | 193 | if (err < 0) |
@@ -145,23 +195,18 @@ static int rts5227_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
145 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24); | 195 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C80 | 0x24); |
146 | if (err < 0) | 196 | if (err < 0) |
147 | return err; | 197 | return err; |
148 | drive_sel = 0xB3; | ||
149 | } else { | 198 | } else { |
150 | return -EINVAL; | 199 | return -EINVAL; |
151 | } | 200 | } |
152 | 201 | ||
153 | /* set pad drive */ | 202 | /* set pad drive */ |
154 | rtsx_pci_init_cmd(pcr); | 203 | rtsx_pci_init_cmd(pcr); |
155 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, | 204 | rts5227_fill_driving(pcr, voltage); |
156 | 0xFF, drive_sel); | ||
157 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, | ||
158 | 0xFF, drive_sel); | ||
159 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, | ||
160 | 0xFF, drive_sel); | ||
161 | return rtsx_pci_send_cmd(pcr, 100); | 205 | return rtsx_pci_send_cmd(pcr, 100); |
162 | } | 206 | } |
163 | 207 | ||
164 | static const struct pcr_ops rts5227_pcr_ops = { | 208 | static const struct pcr_ops rts5227_pcr_ops = { |
209 | .fetch_vendor_settings = rts5227_fetch_vendor_settings, | ||
165 | .extra_init_hw = rts5227_extra_init_hw, | 210 | .extra_init_hw = rts5227_extra_init_hw, |
166 | .optimize_phy = rts5227_optimize_phy, | 211 | .optimize_phy = rts5227_optimize_phy, |
167 | .turn_on_led = rts5227_turn_on_led, | 212 | .turn_on_led = rts5227_turn_on_led, |
@@ -227,6 +272,12 @@ void rts5227_init_params(struct rtsx_pcr *pcr) | |||
227 | pcr->num_slots = 2; | 272 | pcr->num_slots = 2; |
228 | pcr->ops = &rts5227_pcr_ops; | 273 | pcr->ops = &rts5227_pcr_ops; |
229 | 274 | ||
275 | pcr->flags = 0; | ||
276 | pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT; | ||
277 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; | ||
278 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; | ||
279 | pcr->aspm_en = ASPM_L1_EN; | ||
280 | |||
230 | pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl; | 281 | pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl; |
231 | pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl; | 282 | pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl; |
232 | pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl; | 283 | pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl; |
diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c index 58af4dbe3586..7a1ad6dd2917 100644 --- a/drivers/mfd/rts5229.c +++ b/drivers/mfd/rts5229.c | |||
@@ -34,6 +34,28 @@ static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr) | |||
34 | return val & 0x0F; | 34 | return val & 0x0F; |
35 | } | 35 | } |
36 | 36 | ||
37 | static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr) | ||
38 | { | ||
39 | u32 reg; | ||
40 | |||
41 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); | ||
42 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); | ||
43 | |||
44 | if (!rtsx_vendor_setting_valid(reg)) | ||
45 | return; | ||
46 | |||
47 | pcr->aspm_en = rtsx_reg_to_aspm(reg); | ||
48 | pcr->sd30_drive_sel_1v8 = | ||
49 | map_sd_drive(rtsx_reg_to_sd30_drive_sel_1v8(reg)); | ||
50 | pcr->card_drive_sel &= 0x3F; | ||
51 | pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg); | ||
52 | |||
53 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®); | ||
54 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); | ||
55 | pcr->sd30_drive_sel_3v3 = | ||
56 | map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg)); | ||
57 | } | ||
58 | |||
37 | static int rts5229_extra_init_hw(struct rtsx_pcr *pcr) | 59 | static int rts5229_extra_init_hw(struct rtsx_pcr *pcr) |
38 | { | 60 | { |
39 | rtsx_pci_init_cmd(pcr); | 61 | rtsx_pci_init_cmd(pcr); |
@@ -45,6 +67,9 @@ static int rts5229_extra_init_hw(struct rtsx_pcr *pcr) | |||
45 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); | 67 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); |
46 | /* LED shine disabled, set initial shine cycle period */ | 68 | /* LED shine disabled, set initial shine cycle period */ |
47 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); | 69 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); |
70 | /* Configure driving */ | ||
71 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL, | ||
72 | 0xFF, pcr->sd30_drive_sel_3v3); | ||
48 | 73 | ||
49 | return rtsx_pci_send_cmd(pcr, 100); | 74 | return rtsx_pci_send_cmd(pcr, 100); |
50 | } | 75 | } |
@@ -110,7 +135,7 @@ static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card) | |||
110 | SD_POWER_MASK | PMOS_STRG_MASK, | 135 | SD_POWER_MASK | PMOS_STRG_MASK, |
111 | SD_POWER_OFF | PMOS_STRG_400mA); | 136 | SD_POWER_OFF | PMOS_STRG_400mA); |
112 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, | 137 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, |
113 | LDO3318_PWR_MASK, 0X00); | 138 | LDO3318_PWR_MASK, 0x00); |
114 | return rtsx_pci_send_cmd(pcr, 100); | 139 | return rtsx_pci_send_cmd(pcr, 100); |
115 | } | 140 | } |
116 | 141 | ||
@@ -120,7 +145,7 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
120 | 145 | ||
121 | if (voltage == OUTPUT_3V3) { | 146 | if (voltage == OUTPUT_3V3) { |
122 | err = rtsx_pci_write_register(pcr, | 147 | err = rtsx_pci_write_register(pcr, |
123 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_D); | 148 | SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_3v3); |
124 | if (err < 0) | 149 | if (err < 0) |
125 | return err; | 150 | return err; |
126 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); | 151 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); |
@@ -128,7 +153,7 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
128 | return err; | 153 | return err; |
129 | } else if (voltage == OUTPUT_1V8) { | 154 | } else if (voltage == OUTPUT_1V8) { |
130 | err = rtsx_pci_write_register(pcr, | 155 | err = rtsx_pci_write_register(pcr, |
131 | SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); | 156 | SD30_DRIVE_SEL, 0x07, pcr->sd30_drive_sel_1v8); |
132 | if (err < 0) | 157 | if (err < 0) |
133 | return err; | 158 | return err; |
134 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); | 159 | err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); |
@@ -142,6 +167,7 @@ static int rts5229_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
142 | } | 167 | } |
143 | 168 | ||
144 | static const struct pcr_ops rts5229_pcr_ops = { | 169 | static const struct pcr_ops rts5229_pcr_ops = { |
170 | .fetch_vendor_settings = rts5229_fetch_vendor_settings, | ||
145 | .extra_init_hw = rts5229_extra_init_hw, | 171 | .extra_init_hw = rts5229_extra_init_hw, |
146 | .optimize_phy = rts5229_optimize_phy, | 172 | .optimize_phy = rts5229_optimize_phy, |
147 | .turn_on_led = rts5229_turn_on_led, | 173 | .turn_on_led = rts5229_turn_on_led, |
@@ -221,6 +247,12 @@ void rts5229_init_params(struct rtsx_pcr *pcr) | |||
221 | pcr->num_slots = 2; | 247 | pcr->num_slots = 2; |
222 | pcr->ops = &rts5229_pcr_ops; | 248 | pcr->ops = &rts5229_pcr_ops; |
223 | 249 | ||
250 | pcr->flags = 0; | ||
251 | pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT; | ||
252 | pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; | ||
253 | pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; | ||
254 | pcr->aspm_en = ASPM_L1_EN; | ||
255 | |||
224 | pcr->ic_version = rts5229_get_ic_version(pcr); | 256 | pcr->ic_version = rts5229_get_ic_version(pcr); |
225 | if (pcr->ic_version == IC_VER_C) { | 257 | if (pcr->ic_version == IC_VER_C) { |
226 | pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2; | 258 | pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2; |
diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c index 15dc848bc081..d5db182f35db 100644 --- a/drivers/mfd/rts5249.c +++ b/drivers/mfd/rts5249.c | |||
@@ -34,6 +34,60 @@ static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr) | |||
34 | return val & 0x0F; | 34 | return val & 0x0F; |
35 | } | 35 | } |
36 | 36 | ||
37 | static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage) | ||
38 | { | ||
39 | u8 driving_3v3[4][3] = { | ||
40 | {0x11, 0x11, 0x11}, | ||
41 | {0x55, 0x55, 0x5C}, | ||
42 | {0x99, 0x99, 0x92}, | ||
43 | {0x99, 0x99, 0x92}, | ||
44 | }; | ||
45 | u8 driving_1v8[4][3] = { | ||
46 | {0x3C, 0x3C, 0x3C}, | ||
47 | {0xB3, 0xB3, 0xB3}, | ||
48 | {0xFE, 0xFE, 0xFE}, | ||
49 | {0xC4, 0xC4, 0xC4}, | ||
50 | }; | ||
51 | u8 (*driving)[3], drive_sel; | ||
52 | |||
53 | if (voltage == OUTPUT_3V3) { | ||
54 | driving = driving_3v3; | ||
55 | drive_sel = pcr->sd30_drive_sel_3v3; | ||
56 | } else { | ||
57 | driving = driving_1v8; | ||
58 | drive_sel = pcr->sd30_drive_sel_1v8; | ||
59 | } | ||
60 | |||
61 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, | ||
62 | 0xFF, driving[drive_sel][0]); | ||
63 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, | ||
64 | 0xFF, driving[drive_sel][1]); | ||
65 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, | ||
66 | 0xFF, driving[drive_sel][2]); | ||
67 | } | ||
68 | |||
69 | static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr) | ||
70 | { | ||
71 | u32 reg; | ||
72 | |||
73 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®); | ||
74 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg); | ||
75 | |||
76 | if (!rtsx_vendor_setting_valid(reg)) | ||
77 | return; | ||
78 | |||
79 | pcr->aspm_en = rtsx_reg_to_aspm(reg); | ||
80 | pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg); | ||
81 | pcr->card_drive_sel &= 0x3F; | ||
82 | pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg); | ||
83 | |||
84 | rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®); | ||
85 | dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); | ||
86 | pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg); | ||
87 | if (rtsx_reg_check_reverse_socket(reg)) | ||
88 | pcr->flags |= PCR_REVERSE_SOCKET; | ||
89 | } | ||
90 | |||
37 | static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) | 91 | static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) |
38 | { | 92 | { |
39 | rtsx_pci_init_cmd(pcr); | 93 | rtsx_pci_init_cmd(pcr); |
@@ -45,13 +99,14 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) | |||
45 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); | 99 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); |
46 | /* LED shine disabled, set initial shine cycle period */ | 100 | /* LED shine disabled, set initial shine cycle period */ |
47 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); | 101 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); |
48 | /* Correct driving */ | 102 | /* Configure driving */ |
49 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 103 | rts5249_fill_driving(pcr, OUTPUT_3V3); |
50 | SD30_CLK_DRIVE_SEL, 0xFF, 0x99); | 104 | if (pcr->flags & PCR_REVERSE_SOCKET) |
51 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 105 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, |
52 | SD30_CMD_DRIVE_SEL, 0xFF, 0x99); | 106 | AUTOLOAD_CFG_BASE + 3, 0xB0, 0xB0); |
53 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, | 107 | else |
54 | SD30_DAT_DRIVE_SEL, 0xFF, 0x92); | 108 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, |
109 | AUTOLOAD_CFG_BASE + 3, 0xB0, 0x80); | ||
55 | 110 | ||
56 | return rtsx_pci_send_cmd(pcr, 100); | 111 | return rtsx_pci_send_cmd(pcr, 100); |
57 | } | 112 | } |
@@ -129,15 +184,11 @@ static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card) | |||
129 | static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | 184 | static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) |
130 | { | 185 | { |
131 | int err; | 186 | int err; |
132 | u8 clk_drive, cmd_drive, dat_drive; | ||
133 | 187 | ||
134 | if (voltage == OUTPUT_3V3) { | 188 | if (voltage == OUTPUT_3V3) { |
135 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24); | 189 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24); |
136 | if (err < 0) | 190 | if (err < 0) |
137 | return err; | 191 | return err; |
138 | clk_drive = 0x99; | ||
139 | cmd_drive = 0x99; | ||
140 | dat_drive = 0x92; | ||
141 | } else if (voltage == OUTPUT_1V8) { | 192 | } else if (voltage == OUTPUT_1V8) { |
142 | err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02); | 193 | err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02); |
143 | if (err < 0) | 194 | if (err < 0) |
@@ -145,25 +196,18 @@ static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage) | |||
145 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24); | 196 | err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24); |
146 | if (err < 0) | 197 | if (err < 0) |
147 | return err; | 198 | return err; |
148 | clk_drive = 0xb3; | ||
149 | cmd_drive = 0xb3; | ||
150 | dat_drive = 0xb3; | ||
151 | } else { | 199 | } else { |
152 | return -EINVAL; | 200 | return -EINVAL; |
153 | } | 201 | } |
154 | 202 | ||
155 | /* set pad drive */ | 203 | /* set pad drive */ |
156 | rtsx_pci_init_cmd(pcr); | 204 | rtsx_pci_init_cmd(pcr); |
157 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL, | 205 | rts5249_fill_driving(pcr, voltage); |
158 | 0xFF, clk_drive); | ||
159 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL, | ||
160 | 0xFF, cmd_drive); | ||
161 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL, | ||
162 | 0xFF, dat_drive); | ||
163 | return rtsx_pci_send_cmd(pcr, 100); | 206 | return rtsx_pci_send_cmd(pcr, 100); |
164 | } | 207 | } |
165 | 208 | ||
166 | static const struct pcr_ops rts5249_pcr_ops = { | 209 | static const struct pcr_ops rts5249_pcr_ops = { |
210 | .fetch_vendor_settings = rts5249_fetch_vendor_settings, | ||
167 | .extra_init_hw = rts5249_extra_init_hw, | 211 | .extra_init_hw = rts5249_extra_init_hw, |
168 | .optimize_phy = rts5249_optimize_phy, | 212 | .optimize_phy = rts5249_optimize_phy, |
169 | .turn_on_led = rts5249_turn_on_led, | 213 | .turn_on_led = rts5249_turn_on_led, |
@@ -233,6 +277,12 @@ void rts5249_init_params(struct rtsx_pcr *pcr) | |||
233 | pcr->num_slots = 2; | 277 | pcr->num_slots = 2; |
234 | pcr->ops = &rts5249_pcr_ops; | 278 | pcr->ops = &rts5249_pcr_ops; |
235 | 279 | ||
280 | pcr->flags = 0; | ||
281 | pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT; | ||
282 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C; | ||
283 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; | ||
284 | pcr->aspm_en = ASPM_L1_EN; | ||
285 | |||
236 | pcr->ic_version = rts5249_get_ic_version(pcr); | 286 | pcr->ic_version = rts5249_get_ic_version(pcr); |
237 | pcr->sd_pull_ctl_enable_tbl = rts5249_sd_pull_ctl_enable_tbl; | 287 | pcr->sd_pull_ctl_enable_tbl = rts5249_sd_pull_ctl_enable_tbl; |
238 | pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl; | 288 | pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl; |
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index dd186c4103c1..e06d6b0d55f6 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -73,6 +73,9 @@ void rtsx_pci_start_run(struct rtsx_pcr *pcr) | |||
73 | pcr->state = PDEV_STAT_RUN; | 73 | pcr->state = PDEV_STAT_RUN; |
74 | if (pcr->ops->enable_auto_blink) | 74 | if (pcr->ops->enable_auto_blink) |
75 | pcr->ops->enable_auto_blink(pcr); | 75 | pcr->ops->enable_auto_blink(pcr); |
76 | |||
77 | if (pcr->aspm_en) | ||
78 | rtsx_pci_write_config_byte(pcr, LCTLR, 0); | ||
76 | } | 79 | } |
77 | 80 | ||
78 | mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200)); | 81 | mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200)); |
@@ -717,7 +720,7 @@ int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card) | |||
717 | [RTSX_MS_CARD] = MS_EXIST | 720 | [RTSX_MS_CARD] = MS_EXIST |
718 | }; | 721 | }; |
719 | 722 | ||
720 | if (!pcr->ms_pmos) { | 723 | if (!(pcr->flags & PCR_MS_PMOS)) { |
721 | /* When using single PMOS, accessing card is not permitted | 724 | /* When using single PMOS, accessing card is not permitted |
722 | * if the existing card is not the designated one. | 725 | * if the existing card is not the designated one. |
723 | */ | 726 | */ |
@@ -918,6 +921,9 @@ static void rtsx_pci_idle_work(struct work_struct *work) | |||
918 | if (pcr->ops->turn_off_led) | 921 | if (pcr->ops->turn_off_led) |
919 | pcr->ops->turn_off_led(pcr); | 922 | pcr->ops->turn_off_led(pcr); |
920 | 923 | ||
924 | if (pcr->aspm_en) | ||
925 | rtsx_pci_write_config_byte(pcr, LCTLR, pcr->aspm_en); | ||
926 | |||
921 | mutex_unlock(&pcr->pcr_mutex); | 927 | mutex_unlock(&pcr->pcr_mutex); |
922 | } | 928 | } |
923 | 929 | ||
@@ -956,8 +962,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) | |||
956 | /* Reset delink mode */ | 962 | /* Reset delink mode */ |
957 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0); | 963 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0); |
958 | /* Card driving select */ | 964 | /* Card driving select */ |
959 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL, | 965 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DRIVE_SEL, |
960 | 0x07, DRIVER_TYPE_D); | 966 | 0xFF, pcr->card_drive_sel); |
961 | /* Enable SSC Clock */ | 967 | /* Enable SSC Clock */ |
962 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, | 968 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, |
963 | 0xFF, SSC_8X_EN | SSC_SEL_4M); | 969 | 0xFF, SSC_8X_EN | SSC_SEL_4M); |
@@ -989,6 +995,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) | |||
989 | if (err < 0) | 995 | if (err < 0) |
990 | return err; | 996 | return err; |
991 | 997 | ||
998 | rtsx_pci_write_config_byte(pcr, LCTLR, 0); | ||
999 | |||
992 | /* Enable clk_request_n to enable clock power management */ | 1000 | /* Enable clk_request_n to enable clock power management */ |
993 | rtsx_pci_write_config_byte(pcr, 0x81, 1); | 1001 | rtsx_pci_write_config_byte(pcr, 0x81, 1); |
994 | /* Enter L1 when host tx idle */ | 1002 | /* Enter L1 when host tx idle */ |
@@ -1053,6 +1061,18 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) | |||
1053 | if (!pcr->slots) | 1061 | if (!pcr->slots) |
1054 | return -ENOMEM; | 1062 | return -ENOMEM; |
1055 | 1063 | ||
1064 | if (pcr->ops->fetch_vendor_settings) | ||
1065 | pcr->ops->fetch_vendor_settings(pcr); | ||
1066 | |||
1067 | dev_dbg(&(pcr->pci->dev), "pcr->aspm_en = 0x%x\n", pcr->aspm_en); | ||
1068 | dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_1v8 = 0x%x\n", | ||
1069 | pcr->sd30_drive_sel_1v8); | ||
1070 | dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_3v3 = 0x%x\n", | ||
1071 | pcr->sd30_drive_sel_3v3); | ||
1072 | dev_dbg(&(pcr->pci->dev), "pcr->card_drive_sel = 0x%x\n", | ||
1073 | pcr->card_drive_sel); | ||
1074 | dev_dbg(&(pcr->pci->dev), "pcr->flags = 0x%x\n", pcr->flags); | ||
1075 | |||
1056 | pcr->state = PDEV_STAT_IDLE; | 1076 | pcr->state = PDEV_STAT_IDLE; |
1057 | err = rtsx_pci_init_hw(pcr); | 1077 | err = rtsx_pci_init_hw(pcr); |
1058 | if (err < 0) { | 1078 | if (err < 0) { |
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h index c0cac7e8972f..7a1b87a250a5 100644 --- a/drivers/mfd/rtsx_pcr.h +++ b/drivers/mfd/rtsx_pcr.h | |||
@@ -35,4 +35,33 @@ void rts5227_init_params(struct rtsx_pcr *pcr); | |||
35 | void rts5249_init_params(struct rtsx_pcr *pcr); | 35 | void rts5249_init_params(struct rtsx_pcr *pcr); |
36 | void rtl8411b_init_params(struct rtsx_pcr *pcr); | 36 | void rtl8411b_init_params(struct rtsx_pcr *pcr); |
37 | 37 | ||
38 | static inline u8 map_sd_drive(int idx) | ||
39 | { | ||
40 | u8 sd_drive[4] = { | ||
41 | 0x01, /* Type D */ | ||
42 | 0x02, /* Type C */ | ||
43 | 0x05, /* Type A */ | ||
44 | 0x03 /* Type B */ | ||
45 | }; | ||
46 | |||
47 | return sd_drive[idx]; | ||
48 | } | ||
49 | |||
50 | #define rtsx_vendor_setting_valid(reg) (!((reg) & 0x1000000)) | ||
51 | #define rts5209_vendor_setting1_valid(reg) (!((reg) & 0x80)) | ||
52 | #define rts5209_vendor_setting2_valid(reg) ((reg) & 0x80) | ||
53 | |||
54 | #define rtsx_reg_to_aspm(reg) (((reg) >> 28) & 0x03) | ||
55 | #define rtsx_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 26) & 0x03) | ||
56 | #define rtsx_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x03) | ||
57 | #define rtsx_reg_to_card_drive_sel(reg) ((((reg) >> 25) & 0x01) << 6) | ||
58 | #define rtsx_reg_check_reverse_socket(reg) ((reg) & 0x4000) | ||
59 | #define rts5209_reg_to_aspm(reg) (((reg) >> 5) & 0x03) | ||
60 | #define rts5209_reg_check_ms_pmos(reg) (!((reg) & 0x08)) | ||
61 | #define rts5209_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 3) & 0x07) | ||
62 | #define rts5209_reg_to_sd30_drive_sel_3v3(reg) ((reg) & 0x07) | ||
63 | #define rts5209_reg_to_card_drive_sel(reg) ((reg) >> 8) | ||
64 | #define rtl8411_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x07) | ||
65 | #define rtl8411b_reg_to_sd30_drive_sel_3v3(reg) ((reg) & 0x03) | ||
66 | |||
38 | #endif | 67 | #endif |
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 7a9f7089435d..9cba73703704 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h | |||
@@ -184,11 +184,26 @@ | |||
184 | #define CARD_SHARE_BAROSSA_SD 0x01 | 184 | #define CARD_SHARE_BAROSSA_SD 0x01 |
185 | #define CARD_SHARE_BAROSSA_MS 0x02 | 185 | #define CARD_SHARE_BAROSSA_MS 0x02 |
186 | 186 | ||
187 | /* CARD_DRIVE_SEL */ | ||
188 | #define MS_DRIVE_8mA (0x01 << 6) | ||
189 | #define MMC_DRIVE_8mA (0x01 << 4) | ||
190 | #define XD_DRIVE_8mA (0x01 << 2) | ||
191 | #define GPIO_DRIVE_8mA 0x01 | ||
192 | #define RTS5209_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | MMC_DRIVE_8mA |\ | ||
193 | XD_DRIVE_8mA | GPIO_DRIVE_8mA) | ||
194 | #define RTL8411_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | MMC_DRIVE_8mA |\ | ||
195 | XD_DRIVE_8mA) | ||
196 | #define RTSX_CARD_DRIVE_DEFAULT (MS_DRIVE_8mA | GPIO_DRIVE_8mA) | ||
197 | |||
187 | /* SD30_DRIVE_SEL */ | 198 | /* SD30_DRIVE_SEL */ |
188 | #define DRIVER_TYPE_A 0x05 | 199 | #define DRIVER_TYPE_A 0x05 |
189 | #define DRIVER_TYPE_B 0x03 | 200 | #define DRIVER_TYPE_B 0x03 |
190 | #define DRIVER_TYPE_C 0x02 | 201 | #define DRIVER_TYPE_C 0x02 |
191 | #define DRIVER_TYPE_D 0x01 | 202 | #define DRIVER_TYPE_D 0x01 |
203 | #define CFG_DRIVER_TYPE_A 0x02 | ||
204 | #define CFG_DRIVER_TYPE_B 0x03 | ||
205 | #define CFG_DRIVER_TYPE_C 0x01 | ||
206 | #define CFG_DRIVER_TYPE_D 0x00 | ||
192 | 207 | ||
193 | /* FPDCTL */ | 208 | /* FPDCTL */ |
194 | #define SSC_POWER_DOWN 0x01 | 209 | #define SSC_POWER_DOWN 0x01 |
@@ -684,6 +699,8 @@ | |||
684 | 699 | ||
685 | #define DUMMY_REG_RESET_0 0xFE90 | 700 | #define DUMMY_REG_RESET_0 0xFE90 |
686 | 701 | ||
702 | #define AUTOLOAD_CFG_BASE 0xFF00 | ||
703 | |||
687 | /* Memory mapping */ | 704 | /* Memory mapping */ |
688 | #define SRAM_BASE 0xE600 | 705 | #define SRAM_BASE 0xE600 |
689 | #define RBUF_BASE 0xF400 | 706 | #define RBUF_BASE 0xF400 |
@@ -726,6 +743,11 @@ | |||
726 | #define PHY_FLD4 0x1E | 743 | #define PHY_FLD4 0x1E |
727 | #define PHY_DUM_REG 0x1F | 744 | #define PHY_DUM_REG 0x1F |
728 | 745 | ||
746 | #define LCTLR 0x80 | ||
747 | #define PCR_SETTING_REG1 0x724 | ||
748 | #define PCR_SETTING_REG2 0x814 | ||
749 | #define PCR_SETTING_REG3 0x747 | ||
750 | |||
729 | #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) | 751 | #define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) |
730 | 752 | ||
731 | struct rtsx_pcr; | 753 | struct rtsx_pcr; |
@@ -747,6 +769,7 @@ struct pcr_ops { | |||
747 | u8 voltage); | 769 | u8 voltage); |
748 | unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr); | 770 | unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr); |
749 | int (*conv_clk_and_div_n)(int clk, int dir); | 771 | int (*conv_clk_and_div_n)(int clk, int dir); |
772 | void (*fetch_vendor_settings)(struct rtsx_pcr *pcr); | ||
750 | }; | 773 | }; |
751 | 774 | ||
752 | enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN}; | 775 | enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN}; |
@@ -788,7 +811,6 @@ struct rtsx_pcr { | |||
788 | struct completion *finish_me; | 811 | struct completion *finish_me; |
789 | 812 | ||
790 | unsigned int cur_clock; | 813 | unsigned int cur_clock; |
791 | bool ms_pmos; | ||
792 | bool remove_pci; | 814 | bool remove_pci; |
793 | bool msi_en; | 815 | bool msi_en; |
794 | 816 | ||
@@ -806,6 +828,16 @@ struct rtsx_pcr { | |||
806 | #define IC_VER_D 3 | 828 | #define IC_VER_D 3 |
807 | u8 ic_version; | 829 | u8 ic_version; |
808 | 830 | ||
831 | u8 sd30_drive_sel_1v8; | ||
832 | u8 sd30_drive_sel_3v3; | ||
833 | u8 card_drive_sel; | ||
834 | #define ASPM_L1_EN 0x02 | ||
835 | u8 aspm_en; | ||
836 | |||
837 | #define PCR_MS_PMOS (1 << 0) | ||
838 | #define PCR_REVERSE_SOCKET (1 << 1) | ||
839 | u32 flags; | ||
840 | |||
809 | const u32 *sd_pull_ctl_enable_tbl; | 841 | const u32 *sd_pull_ctl_enable_tbl; |
810 | const u32 *sd_pull_ctl_disable_tbl; | 842 | const u32 *sd_pull_ctl_disable_tbl; |
811 | const u32 *ms_pull_ctl_enable_tbl; | 843 | const u32 *ms_pull_ctl_enable_tbl; |