.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* Driver for Realtek PCI-Express card reader |
---|
2 | 3 | * |
---|
3 | 4 | * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms of the GNU General Public License as published by the |
---|
7 | | - * Free Software Foundation; either version 2, or (at your option) any |
---|
8 | | - * later version. |
---|
9 | | - * |
---|
10 | | - * This program is distributed in the hope that it will be useful, but |
---|
11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
13 | | - * General Public License for more details. |
---|
14 | | - * |
---|
15 | | - * You should have received a copy of the GNU General Public License along |
---|
16 | | - * with this program; if not, see <http://www.gnu.org/licenses/>. |
---|
17 | 5 | * |
---|
18 | 6 | * Author: |
---|
19 | 7 | * Wei WANG <wei_wang@realsil.com.cn> |
---|
.. | .. |
---|
34 | 22 | #include <asm/unaligned.h> |
---|
35 | 23 | |
---|
36 | 24 | #include "rtsx_pcr.h" |
---|
| 25 | +#include "rts5261.h" |
---|
| 26 | +#include "rts5228.h" |
---|
37 | 27 | |
---|
38 | 28 | static bool msi_en = true; |
---|
39 | 29 | module_param(msi_en, bool, S_IRUGO | S_IWUSR); |
---|
.. | .. |
---|
45 | 35 | static struct mfd_cell rtsx_pcr_cells[] = { |
---|
46 | 36 | [RTSX_SD_CARD] = { |
---|
47 | 37 | .name = DRV_NAME_RTSX_PCI_SDMMC, |
---|
48 | | - }, |
---|
49 | | - [RTSX_MS_CARD] = { |
---|
50 | | - .name = DRV_NAME_RTSX_PCI_MS, |
---|
51 | 38 | }, |
---|
52 | 39 | }; |
---|
53 | 40 | |
---|
.. | .. |
---|
63 | 50 | { PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
---|
64 | 51 | { PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
---|
65 | 52 | { PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
---|
| 53 | + { PCI_DEVICE(0x10EC, 0x5261), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
---|
| 54 | + { PCI_DEVICE(0x10EC, 0x5228), PCI_CLASS_OTHERS << 16, 0xFF0000 }, |
---|
66 | 55 | { 0, } |
---|
67 | 56 | }; |
---|
68 | 57 | |
---|
69 | 58 | MODULE_DEVICE_TABLE(pci, rtsx_pci_ids); |
---|
70 | 59 | |
---|
71 | | -static inline void rtsx_pci_enable_aspm(struct rtsx_pcr *pcr) |
---|
72 | | -{ |
---|
73 | | - rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL, |
---|
74 | | - 0xFC, pcr->aspm_en); |
---|
75 | | -} |
---|
76 | | - |
---|
77 | 60 | static inline void rtsx_pci_disable_aspm(struct rtsx_pcr *pcr) |
---|
78 | 61 | { |
---|
79 | | - rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL, |
---|
80 | | - 0xFC, 0); |
---|
| 62 | + pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, |
---|
| 63 | + PCI_EXP_LNKCTL_ASPMC, 0); |
---|
81 | 64 | } |
---|
82 | 65 | |
---|
83 | 66 | static int rtsx_comm_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency) |
---|
.. | .. |
---|
98 | 81 | |
---|
99 | 82 | int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency) |
---|
100 | 83 | { |
---|
101 | | - if (pcr->ops->set_ltr_latency) |
---|
102 | | - return pcr->ops->set_ltr_latency(pcr, latency); |
---|
103 | | - else |
---|
104 | | - return rtsx_comm_set_ltr_latency(pcr, latency); |
---|
| 84 | + return rtsx_comm_set_ltr_latency(pcr, latency); |
---|
105 | 85 | } |
---|
106 | 86 | |
---|
107 | 87 | static void rtsx_comm_set_aspm(struct rtsx_pcr *pcr, bool enable) |
---|
108 | 88 | { |
---|
109 | | - struct rtsx_cr_option *option = &pcr->option; |
---|
110 | | - |
---|
111 | 89 | if (pcr->aspm_enabled == enable) |
---|
112 | 90 | return; |
---|
113 | 91 | |
---|
114 | | - if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) { |
---|
115 | | - if (enable) |
---|
116 | | - rtsx_pci_enable_aspm(pcr); |
---|
117 | | - else |
---|
118 | | - rtsx_pci_disable_aspm(pcr); |
---|
119 | | - } else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) { |
---|
120 | | - u8 mask = FORCE_ASPM_VAL_MASK; |
---|
121 | | - u8 val = 0; |
---|
122 | | - |
---|
123 | | - if (enable) |
---|
124 | | - val = pcr->aspm_en; |
---|
125 | | - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val); |
---|
126 | | - } |
---|
| 92 | + pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, |
---|
| 93 | + PCI_EXP_LNKCTL_ASPMC, |
---|
| 94 | + enable ? pcr->aspm_en : 0); |
---|
127 | 95 | |
---|
128 | 96 | pcr->aspm_enabled = enable; |
---|
129 | 97 | } |
---|
.. | .. |
---|
167 | 135 | |
---|
168 | 136 | static void rtsx_pm_full_on(struct rtsx_pcr *pcr) |
---|
169 | 137 | { |
---|
170 | | - if (pcr->ops->full_on) |
---|
171 | | - pcr->ops->full_on(pcr); |
---|
172 | | - else |
---|
173 | | - rtsx_comm_pm_full_on(pcr); |
---|
| 138 | + rtsx_comm_pm_full_on(pcr); |
---|
174 | 139 | } |
---|
175 | 140 | |
---|
176 | 141 | void rtsx_pci_start_run(struct rtsx_pcr *pcr) |
---|
.. | .. |
---|
243 | 208 | int err, i, finished = 0; |
---|
244 | 209 | u8 tmp; |
---|
245 | 210 | |
---|
246 | | - rtsx_pci_init_cmd(pcr); |
---|
247 | | - |
---|
248 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA0, 0xFF, (u8)val); |
---|
249 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA1, 0xFF, (u8)(val >> 8)); |
---|
250 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr); |
---|
251 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x81); |
---|
252 | | - |
---|
253 | | - err = rtsx_pci_send_cmd(pcr, 100); |
---|
254 | | - if (err < 0) |
---|
255 | | - return err; |
---|
| 211 | + rtsx_pci_write_register(pcr, PHYDATA0, 0xFF, (u8)val); |
---|
| 212 | + rtsx_pci_write_register(pcr, PHYDATA1, 0xFF, (u8)(val >> 8)); |
---|
| 213 | + rtsx_pci_write_register(pcr, PHYADDR, 0xFF, addr); |
---|
| 214 | + rtsx_pci_write_register(pcr, PHYRWCTL, 0xFF, 0x81); |
---|
256 | 215 | |
---|
257 | 216 | for (i = 0; i < 100000; i++) { |
---|
258 | 217 | err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp); |
---|
.. | .. |
---|
284 | 243 | { |
---|
285 | 244 | int err, i, finished = 0; |
---|
286 | 245 | u16 data; |
---|
287 | | - u8 *ptr, tmp; |
---|
| 246 | + u8 tmp, val1, val2; |
---|
288 | 247 | |
---|
289 | | - rtsx_pci_init_cmd(pcr); |
---|
290 | | - |
---|
291 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr); |
---|
292 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x80); |
---|
293 | | - |
---|
294 | | - err = rtsx_pci_send_cmd(pcr, 100); |
---|
295 | | - if (err < 0) |
---|
296 | | - return err; |
---|
| 248 | + rtsx_pci_write_register(pcr, PHYADDR, 0xFF, addr); |
---|
| 249 | + rtsx_pci_write_register(pcr, PHYRWCTL, 0xFF, 0x80); |
---|
297 | 250 | |
---|
298 | 251 | for (i = 0; i < 100000; i++) { |
---|
299 | 252 | err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp); |
---|
.. | .. |
---|
309 | 262 | if (!finished) |
---|
310 | 263 | return -ETIMEDOUT; |
---|
311 | 264 | |
---|
312 | | - rtsx_pci_init_cmd(pcr); |
---|
313 | | - |
---|
314 | | - rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA0, 0, 0); |
---|
315 | | - rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA1, 0, 0); |
---|
316 | | - |
---|
317 | | - err = rtsx_pci_send_cmd(pcr, 100); |
---|
318 | | - if (err < 0) |
---|
319 | | - return err; |
---|
320 | | - |
---|
321 | | - ptr = rtsx_pci_get_cmd_data(pcr); |
---|
322 | | - data = ((u16)ptr[1] << 8) | ptr[0]; |
---|
| 265 | + rtsx_pci_read_register(pcr, PHYDATA0, &val1); |
---|
| 266 | + rtsx_pci_read_register(pcr, PHYDATA1, &val2); |
---|
| 267 | + data = val1 | (val2 << 8); |
---|
323 | 268 | |
---|
324 | 269 | if (val) |
---|
325 | 270 | *val = data; |
---|
.. | .. |
---|
453 | 398 | |
---|
454 | 399 | if (end) |
---|
455 | 400 | option |= RTSX_SG_END; |
---|
456 | | - val = ((u64)addr << 32) | ((u64)len << 12) | option; |
---|
457 | 401 | |
---|
| 402 | + if ((PCI_PID(pcr) == PID_5261) || (PCI_PID(pcr) == PID_5228)) { |
---|
| 403 | + if (len > 0xFFFF) |
---|
| 404 | + val = ((u64)addr << 32) | (((u64)len & 0xFFFF) << 16) |
---|
| 405 | + | (((u64)len >> 16) << 6) | option; |
---|
| 406 | + else |
---|
| 407 | + val = ((u64)addr << 32) | ((u64)len << 16) | option; |
---|
| 408 | + } else { |
---|
| 409 | + val = ((u64)addr << 32) | ((u64)len << 12) | option; |
---|
| 410 | + } |
---|
458 | 411 | put_unaligned_le64(val, ptr); |
---|
459 | 412 | pcr->sgi++; |
---|
460 | 413 | } |
---|
.. | .. |
---|
699 | 652 | else |
---|
700 | 653 | return -EINVAL; |
---|
701 | 654 | |
---|
702 | | - |
---|
703 | 655 | return rtsx_pci_set_pull_ctl(pcr, tbl); |
---|
704 | 656 | } |
---|
705 | 657 | EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable); |
---|
706 | 658 | |
---|
707 | 659 | static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr) |
---|
708 | 660 | { |
---|
709 | | - pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN; |
---|
| 661 | + struct rtsx_hw_param *hw_param = &pcr->hw_param; |
---|
| 662 | + |
---|
| 663 | + pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN |
---|
| 664 | + | hw_param->interrupt_en; |
---|
710 | 665 | |
---|
711 | 666 | if (pcr->num_slots > 1) |
---|
712 | 667 | pcr->bier |= MS_INT_EN; |
---|
.. | .. |
---|
746 | 701 | [RTSX_SSC_DEPTH_500K] = SSC_DEPTH_500K, |
---|
747 | 702 | [RTSX_SSC_DEPTH_250K] = SSC_DEPTH_250K, |
---|
748 | 703 | }; |
---|
| 704 | + |
---|
| 705 | + if (PCI_PID(pcr) == PID_5261) |
---|
| 706 | + return rts5261_pci_switch_clock(pcr, card_clock, |
---|
| 707 | + ssc_depth, initial_mode, double_clk, vpclk); |
---|
| 708 | + if (PCI_PID(pcr) == PID_5228) |
---|
| 709 | + return rts5228_pci_switch_clock(pcr, card_clock, |
---|
| 710 | + ssc_depth, initial_mode, double_clk, vpclk); |
---|
749 | 711 | |
---|
750 | 712 | if (initial_mode) { |
---|
751 | 713 | /* We use 250k(around) here, in initial stage */ |
---|
.. | .. |
---|
972 | 934 | |
---|
973 | 935 | static void rtsx_pci_process_ocp(struct rtsx_pcr *pcr) |
---|
974 | 936 | { |
---|
975 | | - if (pcr->ops->process_ocp) |
---|
| 937 | + if (pcr->ops->process_ocp) { |
---|
976 | 938 | pcr->ops->process_ocp(pcr); |
---|
| 939 | + } else { |
---|
| 940 | + if (!pcr->option.ocp_en) |
---|
| 941 | + return; |
---|
| 942 | + rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat); |
---|
| 943 | + if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { |
---|
| 944 | + rtsx_pci_card_power_off(pcr, RTSX_SD_CARD); |
---|
| 945 | + rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); |
---|
| 946 | + rtsx_pci_clear_ocpstat(pcr); |
---|
| 947 | + pcr->ocp_stat = 0; |
---|
| 948 | + } |
---|
| 949 | + } |
---|
977 | 950 | } |
---|
978 | 951 | |
---|
979 | 952 | static int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr) |
---|
.. | .. |
---|
1042 | 1015 | } |
---|
1043 | 1016 | } |
---|
1044 | 1017 | |
---|
1045 | | - if (pcr->card_inserted || pcr->card_removed) |
---|
| 1018 | + if ((pcr->card_inserted || pcr->card_removed) && !(int_reg & SD_OC_INT)) |
---|
1046 | 1019 | schedule_delayed_work(&pcr->carddet_work, |
---|
1047 | 1020 | msecs_to_jiffies(200)); |
---|
1048 | 1021 | |
---|
.. | .. |
---|
1099 | 1072 | |
---|
1100 | 1073 | static void rtsx_pm_power_saving(struct rtsx_pcr *pcr) |
---|
1101 | 1074 | { |
---|
1102 | | - if (pcr->ops->power_saving) |
---|
1103 | | - pcr->ops->power_saving(pcr); |
---|
1104 | | - else |
---|
1105 | | - rtsx_comm_pm_power_saving(pcr); |
---|
| 1075 | + rtsx_comm_pm_power_saving(pcr); |
---|
1106 | 1076 | } |
---|
1107 | 1077 | |
---|
1108 | 1078 | static void rtsx_pci_idle_work(struct work_struct *work) |
---|
.. | .. |
---|
1126 | 1096 | mutex_unlock(&pcr->pcr_mutex); |
---|
1127 | 1097 | } |
---|
1128 | 1098 | |
---|
1129 | | -#ifdef CONFIG_PM |
---|
1130 | | -static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state) |
---|
| 1099 | +static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) |
---|
| 1100 | +{ |
---|
| 1101 | + /* Set relink_time to 0 */ |
---|
| 1102 | + rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0); |
---|
| 1103 | + rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0); |
---|
| 1104 | + rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, |
---|
| 1105 | + RELINK_TIME_MASK, 0); |
---|
| 1106 | + |
---|
| 1107 | + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, |
---|
| 1108 | + D3_DELINK_MODE_EN, D3_DELINK_MODE_EN); |
---|
| 1109 | + |
---|
| 1110 | + rtsx_pci_write_register(pcr, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN); |
---|
| 1111 | +} |
---|
| 1112 | + |
---|
| 1113 | +static void __maybe_unused rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state) |
---|
1131 | 1114 | { |
---|
1132 | 1115 | if (pcr->ops->turn_off_led) |
---|
1133 | 1116 | pcr->ops->turn_off_led(pcr); |
---|
.. | .. |
---|
1140 | 1123 | |
---|
1141 | 1124 | if (pcr->ops->force_power_down) |
---|
1142 | 1125 | pcr->ops->force_power_down(pcr, pm_state); |
---|
| 1126 | + else |
---|
| 1127 | + rtsx_base_force_power_down(pcr, pm_state); |
---|
1143 | 1128 | } |
---|
1144 | | -#endif |
---|
1145 | 1129 | |
---|
1146 | 1130 | void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr) |
---|
1147 | 1131 | { |
---|
1148 | 1132 | u8 val = SD_OCP_INT_EN | SD_DETECT_EN; |
---|
1149 | 1133 | |
---|
1150 | | - if (pcr->ops->enable_ocp) |
---|
| 1134 | + if (pcr->ops->enable_ocp) { |
---|
1151 | 1135 | pcr->ops->enable_ocp(pcr); |
---|
1152 | | - else |
---|
| 1136 | + } else { |
---|
| 1137 | + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0); |
---|
1153 | 1138 | rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); |
---|
| 1139 | + } |
---|
1154 | 1140 | |
---|
1155 | 1141 | } |
---|
1156 | 1142 | |
---|
.. | .. |
---|
1158 | 1144 | { |
---|
1159 | 1145 | u8 mask = SD_OCP_INT_EN | SD_DETECT_EN; |
---|
1160 | 1146 | |
---|
1161 | | - if (pcr->ops->disable_ocp) |
---|
| 1147 | + if (pcr->ops->disable_ocp) { |
---|
1162 | 1148 | pcr->ops->disable_ocp(pcr); |
---|
1163 | | - else |
---|
| 1149 | + } else { |
---|
1164 | 1150 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); |
---|
| 1151 | + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, |
---|
| 1152 | + OC_POWER_DOWN); |
---|
| 1153 | + } |
---|
1165 | 1154 | } |
---|
1166 | 1155 | |
---|
1167 | 1156 | void rtsx_pci_init_ocp(struct rtsx_pcr *pcr) |
---|
.. | .. |
---|
1172 | 1161 | struct rtsx_cr_option *option = &(pcr->option); |
---|
1173 | 1162 | |
---|
1174 | 1163 | if (option->ocp_en) { |
---|
1175 | | - u8 val = option->sd_400mA_ocp_thd; |
---|
| 1164 | + u8 val = option->sd_800mA_ocp_thd; |
---|
1176 | 1165 | |
---|
1177 | 1166 | rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0); |
---|
1178 | 1167 | rtsx_pci_write_register(pcr, REG_OCPPARA1, |
---|
.. | .. |
---|
1182 | 1171 | rtsx_pci_write_register(pcr, REG_OCPGLITCH, |
---|
1183 | 1172 | SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch); |
---|
1184 | 1173 | rtsx_pci_enable_ocp(pcr); |
---|
1185 | | - } else { |
---|
1186 | | - /* OC power down */ |
---|
1187 | | - rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, |
---|
1188 | | - OC_POWER_DOWN); |
---|
1189 | 1174 | } |
---|
1190 | 1175 | } |
---|
1191 | 1176 | } |
---|
.. | .. |
---|
1207 | 1192 | u8 val = SD_OCP_INT_CLR | SD_OC_CLR; |
---|
1208 | 1193 | |
---|
1209 | 1194 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val); |
---|
| 1195 | + udelay(100); |
---|
1210 | 1196 | rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); |
---|
1211 | 1197 | } |
---|
| 1198 | +} |
---|
| 1199 | + |
---|
| 1200 | +void rtsx_pci_enable_oobs_polling(struct rtsx_pcr *pcr) |
---|
| 1201 | +{ |
---|
| 1202 | + u16 val; |
---|
| 1203 | + |
---|
| 1204 | + if ((PCI_PID(pcr) != PID_525A) && (PCI_PID(pcr) != PID_5260)) { |
---|
| 1205 | + rtsx_pci_read_phy_register(pcr, 0x01, &val); |
---|
| 1206 | + val |= 1<<9; |
---|
| 1207 | + rtsx_pci_write_phy_register(pcr, 0x01, val); |
---|
| 1208 | + } |
---|
| 1209 | + rtsx_pci_write_register(pcr, REG_CFG_OOBS_OFF_TIMER, 0xFF, 0x32); |
---|
| 1210 | + rtsx_pci_write_register(pcr, REG_CFG_OOBS_ON_TIMER, 0xFF, 0x05); |
---|
| 1211 | + rtsx_pci_write_register(pcr, REG_CFG_VCM_ON_TIMER, 0xFF, 0x83); |
---|
| 1212 | + rtsx_pci_write_register(pcr, REG_CFG_OOBS_POLLING, 0xFF, 0xDE); |
---|
| 1213 | + |
---|
| 1214 | +} |
---|
| 1215 | + |
---|
| 1216 | +void rtsx_pci_disable_oobs_polling(struct rtsx_pcr *pcr) |
---|
| 1217 | +{ |
---|
| 1218 | + u16 val; |
---|
| 1219 | + |
---|
| 1220 | + if ((PCI_PID(pcr) != PID_525A) && (PCI_PID(pcr) != PID_5260)) { |
---|
| 1221 | + rtsx_pci_read_phy_register(pcr, 0x01, &val); |
---|
| 1222 | + val &= ~(1<<9); |
---|
| 1223 | + rtsx_pci_write_phy_register(pcr, 0x01, val); |
---|
| 1224 | + } |
---|
| 1225 | + rtsx_pci_write_register(pcr, REG_CFG_VCM_ON_TIMER, 0xFF, 0x03); |
---|
| 1226 | + rtsx_pci_write_register(pcr, REG_CFG_OOBS_POLLING, 0xFF, 0x00); |
---|
| 1227 | + |
---|
1212 | 1228 | } |
---|
1213 | 1229 | |
---|
1214 | 1230 | int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr) |
---|
.. | .. |
---|
1216 | 1232 | rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN | |
---|
1217 | 1233 | MS_CLK_EN | SD40_CLK_EN, 0); |
---|
1218 | 1234 | rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); |
---|
1219 | | - |
---|
1220 | 1235 | rtsx_pci_card_power_off(pcr, RTSX_SD_CARD); |
---|
1221 | 1236 | |
---|
1222 | 1237 | msleep(50); |
---|
.. | .. |
---|
1241 | 1256 | |
---|
1242 | 1257 | static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) |
---|
1243 | 1258 | { |
---|
| 1259 | + struct pci_dev *pdev = pcr->pci; |
---|
1244 | 1260 | int err; |
---|
1245 | 1261 | |
---|
1246 | | - pcr->pcie_cap = pci_find_capability(pcr->pci, PCI_CAP_ID_EXP); |
---|
| 1262 | + if (PCI_PID(pcr) == PID_5228) |
---|
| 1263 | + rtsx_pci_write_register(pcr, RTS5228_LDO1_CFG1, RTS5228_LDO1_SR_TIME_MASK, |
---|
| 1264 | + RTS5228_LDO1_SR_0_5); |
---|
| 1265 | + |
---|
1247 | 1266 | rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr); |
---|
1248 | 1267 | |
---|
1249 | 1268 | rtsx_pci_enable_bus_int(pcr); |
---|
1250 | 1269 | |
---|
1251 | 1270 | /* Power on SSC */ |
---|
1252 | | - err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0); |
---|
| 1271 | + if (PCI_PID(pcr) == PID_5261) { |
---|
| 1272 | + /* Gating real mcu clock */ |
---|
| 1273 | + err = rtsx_pci_write_register(pcr, RTS5261_FW_CFG1, |
---|
| 1274 | + RTS5261_MCU_CLOCK_GATING, 0); |
---|
| 1275 | + err = rtsx_pci_write_register(pcr, RTS5261_REG_FPDCTL, |
---|
| 1276 | + SSC_POWER_DOWN, 0); |
---|
| 1277 | + } else { |
---|
| 1278 | + err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0); |
---|
| 1279 | + } |
---|
1253 | 1280 | if (err < 0) |
---|
1254 | 1281 | return err; |
---|
1255 | 1282 | |
---|
.. | .. |
---|
1279 | 1306 | /* Enable SSC Clock */ |
---|
1280 | 1307 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, |
---|
1281 | 1308 | 0xFF, SSC_8X_EN | SSC_SEL_4M); |
---|
1282 | | - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12); |
---|
| 1309 | + if (PCI_PID(pcr) == PID_5261) |
---|
| 1310 | + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, |
---|
| 1311 | + RTS5261_SSC_DEPTH_2M); |
---|
| 1312 | + else if (PCI_PID(pcr) == PID_5228) |
---|
| 1313 | + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, |
---|
| 1314 | + RTS5228_SSC_DEPTH_2M); |
---|
| 1315 | + else |
---|
| 1316 | + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12); |
---|
| 1317 | + |
---|
1283 | 1318 | /* Disable cd_pwr_save */ |
---|
1284 | 1319 | rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x16, 0x10); |
---|
1285 | 1320 | /* Clear Link Ready Interrupt */ |
---|
.. | .. |
---|
1310 | 1345 | case PID_524A: |
---|
1311 | 1346 | case PID_525A: |
---|
1312 | 1347 | case PID_5260: |
---|
| 1348 | + case PID_5261: |
---|
| 1349 | + case PID_5228: |
---|
1313 | 1350 | rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1); |
---|
1314 | 1351 | break; |
---|
1315 | 1352 | default: |
---|
1316 | 1353 | break; |
---|
1317 | 1354 | } |
---|
1318 | 1355 | |
---|
| 1356 | + /*init ocp*/ |
---|
| 1357 | + rtsx_pci_init_ocp(pcr); |
---|
| 1358 | + |
---|
1319 | 1359 | /* Enable clk_request_n to enable clock power management */ |
---|
1320 | | - rtsx_pci_write_config_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL + 1, 1); |
---|
| 1360 | + pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, |
---|
| 1361 | + PCI_EXP_LNKCTL_CLKREQ_EN); |
---|
1321 | 1362 | /* Enter L1 when host tx idle */ |
---|
1322 | | - rtsx_pci_write_config_byte(pcr, 0x70F, 0x5B); |
---|
| 1363 | + pci_write_config_byte(pdev, 0x70F, 0x5B); |
---|
1323 | 1364 | |
---|
1324 | 1365 | if (pcr->ops->extra_init_hw) { |
---|
1325 | 1366 | err = pcr->ops->extra_init_hw(pcr); |
---|
.. | .. |
---|
1386 | 1427 | case 0x5286: |
---|
1387 | 1428 | rtl8402_init_params(pcr); |
---|
1388 | 1429 | break; |
---|
| 1430 | + |
---|
1389 | 1431 | case 0x5260: |
---|
1390 | 1432 | rts5260_init_params(pcr); |
---|
| 1433 | + break; |
---|
| 1434 | + |
---|
| 1435 | + case 0x5261: |
---|
| 1436 | + rts5261_init_params(pcr); |
---|
| 1437 | + break; |
---|
| 1438 | + |
---|
| 1439 | + case 0x5228: |
---|
| 1440 | + rts5228_init_params(pcr); |
---|
1391 | 1441 | break; |
---|
1392 | 1442 | } |
---|
1393 | 1443 | |
---|
.. | .. |
---|
1476 | 1526 | bar = 1; |
---|
1477 | 1527 | len = pci_resource_len(pcidev, bar); |
---|
1478 | 1528 | base = pci_resource_start(pcidev, bar); |
---|
1479 | | - pcr->remap_addr = ioremap_nocache(base, len); |
---|
| 1529 | + pcr->remap_addr = ioremap(base, len); |
---|
1480 | 1530 | if (!pcr->remap_addr) { |
---|
1481 | 1531 | ret = -ENOMEM; |
---|
1482 | | - goto free_handle; |
---|
| 1532 | + goto free_idr; |
---|
1483 | 1533 | } |
---|
1484 | 1534 | |
---|
1485 | 1535 | pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev), |
---|
.. | .. |
---|
1541 | 1591 | pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); |
---|
1542 | 1592 | unmap: |
---|
1543 | 1593 | iounmap(pcr->remap_addr); |
---|
| 1594 | +free_idr: |
---|
| 1595 | + spin_lock(&rtsx_pci_lock); |
---|
| 1596 | + idr_remove(&rtsx_pci_idr, pcr->id); |
---|
| 1597 | + spin_unlock(&rtsx_pci_lock); |
---|
1544 | 1598 | free_handle: |
---|
1545 | 1599 | kfree(handle); |
---|
1546 | 1600 | free_pcr: |
---|
.. | .. |
---|
1594 | 1648 | pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device); |
---|
1595 | 1649 | } |
---|
1596 | 1650 | |
---|
1597 | | -#ifdef CONFIG_PM |
---|
1598 | | - |
---|
1599 | | -static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state) |
---|
| 1651 | +static int __maybe_unused rtsx_pci_suspend(struct device *dev_d) |
---|
1600 | 1652 | { |
---|
| 1653 | + struct pci_dev *pcidev = to_pci_dev(dev_d); |
---|
1601 | 1654 | struct pcr_handle *handle; |
---|
1602 | 1655 | struct rtsx_pcr *pcr; |
---|
1603 | 1656 | |
---|
.. | .. |
---|
1613 | 1666 | |
---|
1614 | 1667 | rtsx_pci_power_off(pcr, HOST_ENTER_S3); |
---|
1615 | 1668 | |
---|
1616 | | - pci_save_state(pcidev); |
---|
1617 | | - pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0); |
---|
1618 | | - pci_disable_device(pcidev); |
---|
1619 | | - pci_set_power_state(pcidev, pci_choose_state(pcidev, state)); |
---|
| 1669 | + device_wakeup_disable(dev_d); |
---|
1620 | 1670 | |
---|
1621 | 1671 | mutex_unlock(&pcr->pcr_mutex); |
---|
1622 | 1672 | return 0; |
---|
1623 | 1673 | } |
---|
1624 | 1674 | |
---|
1625 | | -static int rtsx_pci_resume(struct pci_dev *pcidev) |
---|
| 1675 | +static int __maybe_unused rtsx_pci_resume(struct device *dev_d) |
---|
1626 | 1676 | { |
---|
| 1677 | + struct pci_dev *pcidev = to_pci_dev(dev_d); |
---|
1627 | 1678 | struct pcr_handle *handle; |
---|
1628 | 1679 | struct rtsx_pcr *pcr; |
---|
1629 | 1680 | int ret = 0; |
---|
.. | .. |
---|
1634 | 1685 | pcr = handle->pcr; |
---|
1635 | 1686 | |
---|
1636 | 1687 | mutex_lock(&pcr->pcr_mutex); |
---|
1637 | | - |
---|
1638 | | - pci_set_power_state(pcidev, PCI_D0); |
---|
1639 | | - pci_restore_state(pcidev); |
---|
1640 | | - ret = pci_enable_device(pcidev); |
---|
1641 | | - if (ret) |
---|
1642 | | - goto out; |
---|
1643 | | - pci_set_master(pcidev); |
---|
1644 | 1688 | |
---|
1645 | 1689 | ret = rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00); |
---|
1646 | 1690 | if (ret) |
---|
.. | .. |
---|
1656 | 1700 | mutex_unlock(&pcr->pcr_mutex); |
---|
1657 | 1701 | return ret; |
---|
1658 | 1702 | } |
---|
| 1703 | + |
---|
| 1704 | +#ifdef CONFIG_PM |
---|
1659 | 1705 | |
---|
1660 | 1706 | static void rtsx_pci_shutdown(struct pci_dev *pcidev) |
---|
1661 | 1707 | { |
---|
.. | .. |
---|
1676 | 1722 | |
---|
1677 | 1723 | #else /* CONFIG_PM */ |
---|
1678 | 1724 | |
---|
1679 | | -#define rtsx_pci_suspend NULL |
---|
1680 | | -#define rtsx_pci_resume NULL |
---|
1681 | 1725 | #define rtsx_pci_shutdown NULL |
---|
1682 | 1726 | |
---|
1683 | 1727 | #endif /* CONFIG_PM */ |
---|
| 1728 | + |
---|
| 1729 | +static SIMPLE_DEV_PM_OPS(rtsx_pci_pm_ops, rtsx_pci_suspend, rtsx_pci_resume); |
---|
1684 | 1730 | |
---|
1685 | 1731 | static struct pci_driver rtsx_pci_driver = { |
---|
1686 | 1732 | .name = DRV_NAME_RTSX_PCI, |
---|
1687 | 1733 | .id_table = rtsx_pci_ids, |
---|
1688 | 1734 | .probe = rtsx_pci_probe, |
---|
1689 | 1735 | .remove = rtsx_pci_remove, |
---|
1690 | | - .suspend = rtsx_pci_suspend, |
---|
1691 | | - .resume = rtsx_pci_resume, |
---|
| 1736 | + .driver.pm = &rtsx_pci_pm_ops, |
---|
1692 | 1737 | .shutdown = rtsx_pci_shutdown, |
---|
1693 | 1738 | }; |
---|
1694 | 1739 | module_pci_driver(rtsx_pci_driver); |
---|