Commit | Line | Data |
---|---|---|
97fb5e8d | 1 | // SPDX-License-Identifier: GPL-2.0-only |
0eb0d9f4 GD |
2 | /* |
3 | * drivers/mmc/host/sdhci-msm.c - Qualcomm SDHCI Platform driver | |
4 | * | |
5 | * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. | |
0eb0d9f4 GD |
6 | */ |
7 | ||
8 | #include <linux/module.h> | |
0eb0d9f4 | 9 | #include <linux/delay.h> |
415b5a75 | 10 | #include <linux/mmc/mmc.h> |
67e6db11 | 11 | #include <linux/pm_runtime.h> |
0472f8d3 | 12 | #include <linux/pm_opp.h> |
415b5a75 | 13 | #include <linux/slab.h> |
cc392c58 | 14 | #include <linux/iopoll.h> |
ac06fba1 | 15 | #include <linux/regulator/consumer.h> |
b4fc8278 | 16 | #include <linux/interconnect.h> |
c62da8a8 | 17 | #include <linux/of.h> |
b5c833b7 | 18 | #include <linux/pinctrl/consumer.h> |
3e5a8e84 | 19 | #include <linux/reset.h> |
0eb0d9f4 | 20 | |
c7eed31e AV |
21 | #include <soc/qcom/ice.h> |
22 | ||
08b863bb | 23 | #include "sdhci-cqhci.h" |
0eb0d9f4 | 24 | #include "sdhci-pltfm.h" |
87a8df0d | 25 | #include "cqhci.h" |
0eb0d9f4 | 26 | |
3a3ad3e9 GD |
27 | #define CORE_MCI_VERSION 0x50 |
28 | #define CORE_VERSION_MAJOR_SHIFT 28 | |
29 | #define CORE_VERSION_MAJOR_MASK (0xf << CORE_VERSION_MAJOR_SHIFT) | |
30 | #define CORE_VERSION_MINOR_MASK 0xff | |
31 | ||
52884f8f BA |
32 | #define CORE_MCI_GENERICS 0x70 |
33 | #define SWITCHABLE_SIGNALING_VOLTAGE BIT(29) | |
34 | ||
0eb0d9f4 GD |
35 | #define HC_MODE_EN 0x1 |
36 | #define CORE_POWER 0x0 | |
37 | #define CORE_SW_RST BIT(7) | |
ff06ce41 | 38 | #define FF_CLK_SW_RST_DIS BIT(13) |
0eb0d9f4 | 39 | |
ad81d387 GD |
40 | #define CORE_PWRCTL_BUS_OFF BIT(0) |
41 | #define CORE_PWRCTL_BUS_ON BIT(1) | |
42 | #define CORE_PWRCTL_IO_LOW BIT(2) | |
43 | #define CORE_PWRCTL_IO_HIGH BIT(3) | |
44 | #define CORE_PWRCTL_BUS_SUCCESS BIT(0) | |
92a21738 | 45 | #define CORE_PWRCTL_BUS_FAIL BIT(1) |
ad81d387 | 46 | #define CORE_PWRCTL_IO_SUCCESS BIT(2) |
92a21738 | 47 | #define CORE_PWRCTL_IO_FAIL BIT(3) |
ad81d387 GD |
48 | #define REQ_BUS_OFF BIT(0) |
49 | #define REQ_BUS_ON BIT(1) | |
50 | #define REQ_IO_LOW BIT(2) | |
51 | #define REQ_IO_HIGH BIT(3) | |
52 | #define INT_MASK 0xf | |
415b5a75 GD |
53 | #define MAX_PHASES 16 |
54 | #define CORE_DLL_LOCK BIT(7) | |
02e4293d | 55 | #define CORE_DDR_DLL_LOCK BIT(11) |
415b5a75 GD |
56 | #define CORE_DLL_EN BIT(16) |
57 | #define CORE_CDR_EN BIT(17) | |
58 | #define CORE_CK_OUT_EN BIT(18) | |
59 | #define CORE_CDR_EXT_EN BIT(19) | |
60 | #define CORE_DLL_PDN BIT(29) | |
61 | #define CORE_DLL_RST BIT(30) | |
cc392c58 | 62 | #define CORE_CMD_DAT_TRACK_SEL BIT(0) |
415b5a75 | 63 | |
02e4293d | 64 | #define CORE_DDR_CAL_EN BIT(0) |
83736352 VG |
65 | #define CORE_FLL_CYCLE_CNT BIT(18) |
66 | #define CORE_DLL_CLOCK_DISABLE BIT(21) | |
67 | ||
5c30f340 VB |
68 | #define DLL_USR_CTL_POR_VAL 0x10800 |
69 | #define ENABLE_DLL_LOCK_STATUS BIT(26) | |
70 | #define FINE_TUNE_MODE_EN BIT(27) | |
71 | #define BIAS_OK_SIGNAL BIT(29) | |
72 | ||
04816e67 SG |
73 | #define DLL_CONFIG_3_LOW_FREQ_VAL 0x08 |
74 | #define DLL_CONFIG_3_HIGH_FREQ_VAL 0x10 | |
75 | ||
946932d9 | 76 | #define CORE_VENDOR_SPEC_POR_VAL 0xa9c |
415b5a75 | 77 | #define CORE_CLK_PWRSAVE BIT(1) |
ff06ce41 VG |
78 | #define CORE_HC_MCLK_SEL_DFLT (2 << 8) |
79 | #define CORE_HC_MCLK_SEL_HS400 (3 << 8) | |
80 | #define CORE_HC_MCLK_SEL_MASK (3 << 8) | |
946932d9 VB |
81 | #define CORE_IO_PAD_PWR_SWITCH_EN BIT(15) |
82 | #define CORE_IO_PAD_PWR_SWITCH BIT(16) | |
ff06ce41 VG |
83 | #define CORE_HC_SELECT_IN_EN BIT(18) |
84 | #define CORE_HC_SELECT_IN_HS400 (6 << 19) | |
85 | #define CORE_HC_SELECT_IN_MASK (7 << 19) | |
415b5a75 | 86 | |
946932d9 VB |
87 | #define CORE_3_0V_SUPPORT BIT(25) |
88 | #define CORE_1_8V_SUPPORT BIT(26) | |
5c132323 | 89 | #define CORE_VOLT_SUPPORT (CORE_3_0V_SUPPORT | CORE_1_8V_SUPPORT) |
ac06fba1 | 90 | |
cc392c58 RH |
91 | #define CORE_CSR_CDC_CTLR_CFG0 0x130 |
92 | #define CORE_SW_TRIG_FULL_CALIB BIT(16) | |
93 | #define CORE_HW_AUTOCAL_ENA BIT(17) | |
94 | ||
95 | #define CORE_CSR_CDC_CTLR_CFG1 0x134 | |
96 | #define CORE_CSR_CDC_CAL_TIMER_CFG0 0x138 | |
97 | #define CORE_TIMER_ENA BIT(16) | |
98 | ||
99 | #define CORE_CSR_CDC_CAL_TIMER_CFG1 0x13C | |
100 | #define CORE_CSR_CDC_REFCOUNT_CFG 0x140 | |
101 | #define CORE_CSR_CDC_COARSE_CAL_CFG 0x144 | |
102 | #define CORE_CDC_OFFSET_CFG 0x14C | |
103 | #define CORE_CSR_CDC_DELAY_CFG 0x150 | |
104 | #define CORE_CDC_SLAVE_DDA_CFG 0x160 | |
105 | #define CORE_CSR_CDC_STATUS0 0x164 | |
106 | #define CORE_CALIBRATION_DONE BIT(0) | |
107 | ||
108 | #define CORE_CDC_ERROR_CODE_MASK 0x7000000 | |
109 | ||
110 | #define CORE_CSR_CDC_GEN_CFG 0x178 | |
111 | #define CORE_CDC_SWITCH_BYPASS_OFF BIT(0) | |
112 | #define CORE_CDC_SWITCH_RC_EN BIT(1) | |
113 | ||
cc392c58 | 114 | #define CORE_CDC_T4_DLY_SEL BIT(0) |
44bf2312 | 115 | #define CORE_CMDIN_RCLK_EN BIT(1) |
cc392c58 | 116 | #define CORE_START_CDC_TRAFFIC BIT(6) |
bc99266b | 117 | |
02e4293d RH |
118 | #define CORE_PWRSAVE_DLL BIT(3) |
119 | ||
fa56ac97 | 120 | #define DDR_CONFIG_POR_VAL 0x80040873 |
cc392c58 | 121 | |
3a3ad3e9 | 122 | |
abf270e5 | 123 | #define INVALID_TUNING_PHASE -1 |
80031bde | 124 | #define SDHCI_MSM_MIN_CLOCK 400000 |
ff06ce41 | 125 | #define CORE_FREQ_100MHZ (100 * 1000 * 1000) |
80031bde | 126 | |
415b5a75 GD |
127 | #define CDR_SELEXT_SHIFT 20 |
128 | #define CDR_SELEXT_MASK (0xf << CDR_SELEXT_SHIFT) | |
129 | #define CMUX_SHIFT_PHASE_SHIFT 24 | |
130 | #define CMUX_SHIFT_PHASE_MASK (7 << CMUX_SHIFT_PHASE_SHIFT) | |
131 | ||
67e6db11 | 132 | #define MSM_MMC_AUTOSUSPEND_DELAY_MS 50 |
c0309b38 VV |
133 | |
134 | /* Timeout value to avoid infinite waiting for pwr_irq */ | |
135 | #define MSM_PWR_IRQ_TIMEOUT_MS 5000 | |
136 | ||
92a21738 VB |
137 | /* Max load for eMMC Vdd-io supply */ |
138 | #define MMC_VQMMC_MAX_LOAD_UA 325000 | |
139 | ||
bc99266b SL |
140 | #define msm_host_readl(msm_host, host, offset) \ |
141 | msm_host->var_ops->msm_readl_relaxed(host, offset) | |
142 | ||
143 | #define msm_host_writel(msm_host, val, host, offset) \ | |
144 | msm_host->var_ops->msm_writel_relaxed(val, host, offset) | |
145 | ||
87a8df0d RH |
146 | /* CQHCI vendor specific registers */ |
147 | #define CQHCI_VENDOR_CFG1 0xA00 | |
148 | #define CQHCI_VENDOR_DIS_RST_ON_CQ_EN (0x3 << 13) | |
149 | ||
f1535888 SL |
150 | struct sdhci_msm_offset { |
151 | u32 core_hc_mode; | |
152 | u32 core_mci_data_cnt; | |
153 | u32 core_mci_status; | |
154 | u32 core_mci_fifo_cnt; | |
155 | u32 core_mci_version; | |
156 | u32 core_generics; | |
157 | u32 core_testbus_config; | |
158 | u32 core_testbus_sel2_bit; | |
159 | u32 core_testbus_ena; | |
160 | u32 core_testbus_sel2; | |
161 | u32 core_pwrctl_status; | |
162 | u32 core_pwrctl_mask; | |
163 | u32 core_pwrctl_clear; | |
164 | u32 core_pwrctl_ctl; | |
165 | u32 core_sdcc_debug_reg; | |
166 | u32 core_dll_config; | |
167 | u32 core_dll_status; | |
168 | u32 core_vendor_spec; | |
169 | u32 core_vendor_spec_adma_err_addr0; | |
170 | u32 core_vendor_spec_adma_err_addr1; | |
171 | u32 core_vendor_spec_func2; | |
172 | u32 core_vendor_spec_capabilities0; | |
173 | u32 core_ddr_200_cfg; | |
174 | u32 core_vendor_spec3; | |
175 | u32 core_dll_config_2; | |
fa56ac97 VB |
176 | u32 core_dll_config_3; |
177 | u32 core_ddr_config_old; /* Applicable to sdcc minor ver < 0x49 */ | |
f1535888 | 178 | u32 core_ddr_config; |
5c30f340 | 179 | u32 core_dll_usr_ctl; /* Present on SDCC5.1 onwards */ |
f1535888 SL |
180 | }; |
181 | ||
182 | static const struct sdhci_msm_offset sdhci_msm_v5_offset = { | |
183 | .core_mci_data_cnt = 0x35c, | |
184 | .core_mci_status = 0x324, | |
185 | .core_mci_fifo_cnt = 0x308, | |
186 | .core_mci_version = 0x318, | |
187 | .core_generics = 0x320, | |
188 | .core_testbus_config = 0x32c, | |
189 | .core_testbus_sel2_bit = 3, | |
190 | .core_testbus_ena = (1 << 31), | |
191 | .core_testbus_sel2 = (1 << 3), | |
192 | .core_pwrctl_status = 0x240, | |
193 | .core_pwrctl_mask = 0x244, | |
194 | .core_pwrctl_clear = 0x248, | |
195 | .core_pwrctl_ctl = 0x24c, | |
196 | .core_sdcc_debug_reg = 0x358, | |
197 | .core_dll_config = 0x200, | |
198 | .core_dll_status = 0x208, | |
199 | .core_vendor_spec = 0x20c, | |
200 | .core_vendor_spec_adma_err_addr0 = 0x214, | |
201 | .core_vendor_spec_adma_err_addr1 = 0x218, | |
202 | .core_vendor_spec_func2 = 0x210, | |
203 | .core_vendor_spec_capabilities0 = 0x21c, | |
204 | .core_ddr_200_cfg = 0x224, | |
205 | .core_vendor_spec3 = 0x250, | |
206 | .core_dll_config_2 = 0x254, | |
fa56ac97 VB |
207 | .core_dll_config_3 = 0x258, |
208 | .core_ddr_config = 0x25c, | |
5c30f340 | 209 | .core_dll_usr_ctl = 0x388, |
f1535888 SL |
210 | }; |
211 | ||
212 | static const struct sdhci_msm_offset sdhci_msm_mci_offset = { | |
213 | .core_hc_mode = 0x78, | |
214 | .core_mci_data_cnt = 0x30, | |
215 | .core_mci_status = 0x34, | |
216 | .core_mci_fifo_cnt = 0x44, | |
217 | .core_mci_version = 0x050, | |
218 | .core_generics = 0x70, | |
219 | .core_testbus_config = 0x0cc, | |
220 | .core_testbus_sel2_bit = 4, | |
221 | .core_testbus_ena = (1 << 3), | |
222 | .core_testbus_sel2 = (1 << 4), | |
223 | .core_pwrctl_status = 0xdc, | |
224 | .core_pwrctl_mask = 0xe0, | |
225 | .core_pwrctl_clear = 0xe4, | |
226 | .core_pwrctl_ctl = 0xe8, | |
227 | .core_sdcc_debug_reg = 0x124, | |
228 | .core_dll_config = 0x100, | |
229 | .core_dll_status = 0x108, | |
230 | .core_vendor_spec = 0x10c, | |
231 | .core_vendor_spec_adma_err_addr0 = 0x114, | |
232 | .core_vendor_spec_adma_err_addr1 = 0x118, | |
233 | .core_vendor_spec_func2 = 0x110, | |
234 | .core_vendor_spec_capabilities0 = 0x11c, | |
235 | .core_ddr_200_cfg = 0x184, | |
236 | .core_vendor_spec3 = 0x1b0, | |
237 | .core_dll_config_2 = 0x1b4, | |
fa56ac97 VB |
238 | .core_ddr_config_old = 0x1b8, |
239 | .core_ddr_config = 0x1bc, | |
f1535888 SL |
240 | }; |
241 | ||
6ed4bb43 VV |
242 | struct sdhci_msm_variant_ops { |
243 | u32 (*msm_readl_relaxed)(struct sdhci_host *host, u32 offset); | |
244 | void (*msm_writel_relaxed)(u32 val, struct sdhci_host *host, | |
245 | u32 offset); | |
246 | }; | |
247 | ||
248 | /* | |
249 | * From V5, register spaces have changed. Wrap this info in a structure | |
250 | * and choose the data_structure based on version info mentioned in DT. | |
251 | */ | |
252 | struct sdhci_msm_variant_info { | |
253 | bool mci_removed; | |
21f1e2d4 | 254 | bool restore_dll_config; |
6ed4bb43 VV |
255 | const struct sdhci_msm_variant_ops *var_ops; |
256 | const struct sdhci_msm_offset *offset; | |
257 | }; | |
258 | ||
0eb0d9f4 GD |
259 | struct sdhci_msm_host { |
260 | struct platform_device *pdev; | |
261 | void __iomem *core_mem; /* MSM SDCC mapped address */ | |
ad81d387 | 262 | int pwr_irq; /* power irq */ |
0eb0d9f4 | 263 | struct clk *bus_clk; /* SDHC bus voter clock */ |
83736352 | 264 | struct clk *xo_clk; /* TCXO clk needed for FLL feature of cm_dll*/ |
c7eed31e AV |
265 | /* core, iface, cal and sleep clocks */ |
266 | struct clk_bulk_data bulk_clks[4]; | |
267 | #ifdef CONFIG_MMC_CRYPTO | |
268 | struct qcom_ice *ice; | |
269 | #endif | |
edc609fd | 270 | unsigned long clk_rate; |
0eb0d9f4 | 271 | struct mmc_host *mmc; |
83736352 | 272 | bool use_14lpp_dll_reset; |
ff06ce41 VG |
273 | bool tuning_done; |
274 | bool calibration_done; | |
abf270e5 | 275 | u8 saved_tuning_phase; |
02e4293d | 276 | bool use_cdclp533; |
c0309b38 VV |
277 | u32 curr_pwr_state; |
278 | u32 curr_io_level; | |
279 | wait_queue_head_t pwr_irq_wait; | |
280 | bool pwr_irq_flag; | |
ac06fba1 | 281 | u32 caps_0; |
6ed4bb43 | 282 | bool mci_removed; |
21f1e2d4 | 283 | bool restore_dll_config; |
6ed4bb43 VV |
284 | const struct sdhci_msm_variant_ops *var_ops; |
285 | const struct sdhci_msm_offset *offset; | |
a89e7bcb LP |
286 | bool use_cdr; |
287 | u32 transfer_mode; | |
fa56ac97 | 288 | bool updated_ddr_cfg; |
5c30f340 | 289 | bool uses_tassadar_dll; |
03591160 | 290 | u32 dll_config; |
1dfbe3ff | 291 | u32 ddr_config; |
92a21738 | 292 | bool vqmmc_enabled; |
0eb0d9f4 GD |
293 | }; |
294 | ||
bc99266b SL |
295 | static const struct sdhci_msm_offset *sdhci_priv_msm_offset(struct sdhci_host *host) |
296 | { | |
297 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
298 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
299 | ||
300 | return msm_host->offset; | |
301 | } | |
302 | ||
6ed4bb43 VV |
303 | /* |
304 | * APIs to read/write to vendor specific registers which were there in the | |
305 | * core_mem region before MCI was removed. | |
306 | */ | |
307 | static u32 sdhci_msm_mci_variant_readl_relaxed(struct sdhci_host *host, | |
308 | u32 offset) | |
309 | { | |
310 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
311 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
312 | ||
313 | return readl_relaxed(msm_host->core_mem + offset); | |
314 | } | |
315 | ||
316 | static u32 sdhci_msm_v5_variant_readl_relaxed(struct sdhci_host *host, | |
317 | u32 offset) | |
318 | { | |
319 | return readl_relaxed(host->ioaddr + offset); | |
320 | } | |
321 | ||
322 | static void sdhci_msm_mci_variant_writel_relaxed(u32 val, | |
323 | struct sdhci_host *host, u32 offset) | |
324 | { | |
325 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
326 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
327 | ||
328 | writel_relaxed(val, msm_host->core_mem + offset); | |
329 | } | |
330 | ||
331 | static void sdhci_msm_v5_variant_writel_relaxed(u32 val, | |
332 | struct sdhci_host *host, u32 offset) | |
333 | { | |
334 | writel_relaxed(val, host->ioaddr + offset); | |
335 | } | |
336 | ||
f16c8fd4 | 337 | static unsigned int msm_get_clock_mult_for_bus_mode(struct sdhci_host *host) |
0fb8a3d4 RH |
338 | { |
339 | struct mmc_ios ios = host->mmc->ios; | |
340 | /* | |
341 | * The SDHC requires internal clock frequency to be double the | |
342 | * actual clock that will be set for DDR mode. The controller | |
343 | * uses the faster clock(100/400MHz) for some of its parts and | |
344 | * send the actual required clock (50/200MHz) to the card. | |
345 | */ | |
346 | if (ios.timing == MMC_TIMING_UHS_DDR50 || | |
347 | ios.timing == MMC_TIMING_MMC_DDR52 || | |
d7507aa1 RH |
348 | ios.timing == MMC_TIMING_MMC_HS400 || |
349 | host->flags & SDHCI_HS400_TUNING) | |
f16c8fd4 DA |
350 | return 2; |
351 | return 1; | |
0fb8a3d4 RH |
352 | } |
353 | ||
354 | static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host, | |
355 | unsigned int clock) | |
356 | { | |
357 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
358 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
359 | struct mmc_ios curr_ios = host->mmc->ios; | |
e4bf91f6 | 360 | struct clk *core_clk = msm_host->bulk_clks[0].clk; |
a8cd989e | 361 | unsigned long achieved_rate; |
f16c8fd4 DA |
362 | unsigned int desired_rate; |
363 | unsigned int mult; | |
0fb8a3d4 RH |
364 | int rc; |
365 | ||
f16c8fd4 DA |
366 | mult = msm_get_clock_mult_for_bus_mode(host); |
367 | desired_rate = clock * mult; | |
368 | rc = dev_pm_opp_set_rate(mmc_dev(host->mmc), desired_rate); | |
0fb8a3d4 RH |
369 | if (rc) { |
370 | pr_err("%s: Failed to set clock at rate %u at timing %d\n", | |
f16c8fd4 | 371 | mmc_hostname(host->mmc), desired_rate, curr_ios.timing); |
0fb8a3d4 RH |
372 | return; |
373 | } | |
a8cd989e DA |
374 | |
375 | /* | |
376 | * Qualcomm clock drivers by default round clock _up_ if they can't | |
377 | * make the requested rate. This is not good for SD. Yell if we | |
378 | * encounter it. | |
379 | */ | |
380 | achieved_rate = clk_get_rate(core_clk); | |
f16c8fd4 | 381 | if (achieved_rate > desired_rate) |
a8cd989e | 382 | pr_warn("%s: Card appears overclocked; req %u Hz, actual %lu Hz\n", |
f16c8fd4 DA |
383 | mmc_hostname(host->mmc), desired_rate, achieved_rate); |
384 | host->mmc->actual_clock = achieved_rate / mult; | |
385 | ||
386 | /* Stash the rate we requested to use in sdhci_msm_runtime_resume() */ | |
387 | msm_host->clk_rate = desired_rate; | |
a8cd989e | 388 | |
0fb8a3d4 | 389 | pr_debug("%s: Setting clock at rate %lu at timing %d\n", |
a8cd989e | 390 | mmc_hostname(host->mmc), achieved_rate, curr_ios.timing); |
0fb8a3d4 RH |
391 | } |
392 | ||
0eb0d9f4 | 393 | /* Platform specific tuning */ |
415b5a75 GD |
394 | static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll) |
395 | { | |
396 | u32 wait_cnt = 50; | |
397 | u8 ck_out_en; | |
398 | struct mmc_host *mmc = host->mmc; | |
bc99266b SL |
399 | const struct sdhci_msm_offset *msm_offset = |
400 | sdhci_priv_msm_offset(host); | |
415b5a75 GD |
401 | |
402 | /* Poll for CK_OUT_EN bit. max. poll time = 50us */ | |
bc99266b SL |
403 | ck_out_en = !!(readl_relaxed(host->ioaddr + |
404 | msm_offset->core_dll_config) & CORE_CK_OUT_EN); | |
415b5a75 GD |
405 | |
406 | while (ck_out_en != poll) { | |
407 | if (--wait_cnt == 0) { | |
408 | dev_err(mmc_dev(mmc), "%s: CK_OUT_EN bit is not %d\n", | |
409 | mmc_hostname(mmc), poll); | |
410 | return -ETIMEDOUT; | |
411 | } | |
412 | udelay(1); | |
413 | ||
bc99266b SL |
414 | ck_out_en = !!(readl_relaxed(host->ioaddr + |
415 | msm_offset->core_dll_config) & CORE_CK_OUT_EN); | |
415b5a75 GD |
416 | } |
417 | ||
418 | return 0; | |
419 | } | |
420 | ||
421 | static int msm_config_cm_dll_phase(struct sdhci_host *host, u8 phase) | |
422 | { | |
423 | int rc; | |
424 | static const u8 grey_coded_phase_table[] = { | |
425 | 0x0, 0x1, 0x3, 0x2, 0x6, 0x7, 0x5, 0x4, | |
426 | 0xc, 0xd, 0xf, 0xe, 0xa, 0xb, 0x9, 0x8 | |
427 | }; | |
428 | unsigned long flags; | |
429 | u32 config; | |
430 | struct mmc_host *mmc = host->mmc; | |
bc99266b SL |
431 | const struct sdhci_msm_offset *msm_offset = |
432 | sdhci_priv_msm_offset(host); | |
415b5a75 | 433 | |
abf270e5 RH |
434 | if (phase > 0xf) |
435 | return -EINVAL; | |
436 | ||
415b5a75 GD |
437 | spin_lock_irqsave(&host->lock, flags); |
438 | ||
bc99266b | 439 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
440 | config &= ~(CORE_CDR_EN | CORE_CK_OUT_EN); |
441 | config |= (CORE_CDR_EXT_EN | CORE_DLL_EN); | |
bc99266b | 442 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
443 | |
444 | /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '0' */ | |
445 | rc = msm_dll_poll_ck_out_en(host, 0); | |
446 | if (rc) | |
447 | goto err_out; | |
448 | ||
449 | /* | |
450 | * Write the selected DLL clock output phase (0 ... 15) | |
451 | * to CDR_SELEXT bit field of DLL_CONFIG register. | |
452 | */ | |
bc99266b | 453 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
454 | config &= ~CDR_SELEXT_MASK; |
455 | config |= grey_coded_phase_table[phase] << CDR_SELEXT_SHIFT; | |
bc99266b | 456 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config); |
415b5a75 | 457 | |
bc99266b | 458 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config); |
29301f40 | 459 | config |= CORE_CK_OUT_EN; |
bc99266b | 460 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
461 | |
462 | /* Wait until CK_OUT_EN bit of DLL_CONFIG register becomes '1' */ | |
463 | rc = msm_dll_poll_ck_out_en(host, 1); | |
464 | if (rc) | |
465 | goto err_out; | |
466 | ||
bc99266b | 467 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
468 | config |= CORE_CDR_EN; |
469 | config &= ~CORE_CDR_EXT_EN; | |
bc99266b | 470 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
471 | goto out; |
472 | ||
473 | err_out: | |
474 | dev_err(mmc_dev(mmc), "%s: Failed to set DLL phase: %d\n", | |
475 | mmc_hostname(mmc), phase); | |
476 | out: | |
477 | spin_unlock_irqrestore(&host->lock, flags); | |
478 | return rc; | |
479 | } | |
480 | ||
481 | /* | |
482 | * Find out the greatest range of consecuitive selected | |
483 | * DLL clock output phases that can be used as sampling | |
484 | * setting for SD3.0 UHS-I card read operation (in SDR104 | |
ff06ce41 VG |
485 | * timing mode) or for eMMC4.5 card read operation (in |
486 | * HS400/HS200 timing mode). | |
415b5a75 GD |
487 | * Select the 3/4 of the range and configure the DLL with the |
488 | * selected DLL clock output phase. | |
489 | */ | |
490 | ||
491 | static int msm_find_most_appropriate_phase(struct sdhci_host *host, | |
492 | u8 *phase_table, u8 total_phases) | |
493 | { | |
494 | int ret; | |
495 | u8 ranges[MAX_PHASES][MAX_PHASES] = { {0}, {0} }; | |
496 | u8 phases_per_row[MAX_PHASES] = { 0 }; | |
497 | int row_index = 0, col_index = 0, selected_row_index = 0, curr_max = 0; | |
498 | int i, cnt, phase_0_raw_index = 0, phase_15_raw_index = 0; | |
499 | bool phase_0_found = false, phase_15_found = false; | |
500 | struct mmc_host *mmc = host->mmc; | |
501 | ||
502 | if (!total_phases || (total_phases > MAX_PHASES)) { | |
503 | dev_err(mmc_dev(mmc), "%s: Invalid argument: total_phases=%d\n", | |
504 | mmc_hostname(mmc), total_phases); | |
505 | return -EINVAL; | |
506 | } | |
507 | ||
508 | for (cnt = 0; cnt < total_phases; cnt++) { | |
509 | ranges[row_index][col_index] = phase_table[cnt]; | |
510 | phases_per_row[row_index] += 1; | |
511 | col_index++; | |
512 | ||
513 | if ((cnt + 1) == total_phases) { | |
514 | continue; | |
515 | /* check if next phase in phase_table is consecutive or not */ | |
516 | } else if ((phase_table[cnt] + 1) != phase_table[cnt + 1]) { | |
517 | row_index++; | |
518 | col_index = 0; | |
519 | } | |
520 | } | |
521 | ||
522 | if (row_index >= MAX_PHASES) | |
523 | return -EINVAL; | |
524 | ||
525 | /* Check if phase-0 is present in first valid window? */ | |
526 | if (!ranges[0][0]) { | |
527 | phase_0_found = true; | |
528 | phase_0_raw_index = 0; | |
529 | /* Check if cycle exist between 2 valid windows */ | |
530 | for (cnt = 1; cnt <= row_index; cnt++) { | |
531 | if (phases_per_row[cnt]) { | |
532 | for (i = 0; i < phases_per_row[cnt]; i++) { | |
533 | if (ranges[cnt][i] == 15) { | |
534 | phase_15_found = true; | |
535 | phase_15_raw_index = cnt; | |
536 | break; | |
537 | } | |
538 | } | |
539 | } | |
540 | } | |
541 | } | |
542 | ||
543 | /* If 2 valid windows form cycle then merge them as single window */ | |
544 | if (phase_0_found && phase_15_found) { | |
545 | /* number of phases in raw where phase 0 is present */ | |
546 | u8 phases_0 = phases_per_row[phase_0_raw_index]; | |
547 | /* number of phases in raw where phase 15 is present */ | |
548 | u8 phases_15 = phases_per_row[phase_15_raw_index]; | |
549 | ||
550 | if (phases_0 + phases_15 >= MAX_PHASES) | |
551 | /* | |
552 | * If there are more than 1 phase windows then total | |
553 | * number of phases in both the windows should not be | |
554 | * more than or equal to MAX_PHASES. | |
555 | */ | |
556 | return -EINVAL; | |
557 | ||
558 | /* Merge 2 cyclic windows */ | |
559 | i = phases_15; | |
560 | for (cnt = 0; cnt < phases_0; cnt++) { | |
561 | ranges[phase_15_raw_index][i] = | |
562 | ranges[phase_0_raw_index][cnt]; | |
563 | if (++i >= MAX_PHASES) | |
564 | break; | |
565 | } | |
566 | ||
567 | phases_per_row[phase_0_raw_index] = 0; | |
568 | phases_per_row[phase_15_raw_index] = phases_15 + phases_0; | |
569 | } | |
570 | ||
571 | for (cnt = 0; cnt <= row_index; cnt++) { | |
572 | if (phases_per_row[cnt] > curr_max) { | |
573 | curr_max = phases_per_row[cnt]; | |
574 | selected_row_index = cnt; | |
575 | } | |
576 | } | |
577 | ||
578 | i = (curr_max * 3) / 4; | |
579 | if (i) | |
580 | i--; | |
581 | ||
582 | ret = ranges[selected_row_index][i]; | |
583 | ||
584 | if (ret >= MAX_PHASES) { | |
585 | ret = -EINVAL; | |
586 | dev_err(mmc_dev(mmc), "%s: Invalid phase selected=%d\n", | |
587 | mmc_hostname(mmc), ret); | |
588 | } | |
589 | ||
590 | return ret; | |
591 | } | |
592 | ||
593 | static inline void msm_cm_dll_set_freq(struct sdhci_host *host) | |
0eb0d9f4 | 594 | { |
415b5a75 | 595 | u32 mclk_freq = 0, config; |
bc99266b SL |
596 | const struct sdhci_msm_offset *msm_offset = |
597 | sdhci_priv_msm_offset(host); | |
415b5a75 GD |
598 | |
599 | /* Program the MCLK value to MCLK_FREQ bit field */ | |
600 | if (host->clock <= 112000000) | |
601 | mclk_freq = 0; | |
602 | else if (host->clock <= 125000000) | |
603 | mclk_freq = 1; | |
604 | else if (host->clock <= 137000000) | |
605 | mclk_freq = 2; | |
606 | else if (host->clock <= 150000000) | |
607 | mclk_freq = 3; | |
608 | else if (host->clock <= 162000000) | |
609 | mclk_freq = 4; | |
610 | else if (host->clock <= 175000000) | |
611 | mclk_freq = 5; | |
612 | else if (host->clock <= 187000000) | |
613 | mclk_freq = 6; | |
614 | else if (host->clock <= 200000000) | |
615 | mclk_freq = 7; | |
616 | ||
bc99266b | 617 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
618 | config &= ~CMUX_SHIFT_PHASE_MASK; |
619 | config |= mclk_freq << CMUX_SHIFT_PHASE_SHIFT; | |
bc99266b | 620 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config); |
415b5a75 GD |
621 | } |
622 | ||
623 | /* Initialize the DLL (Programmable Delay Line) */ | |
624 | static int msm_init_cm_dll(struct sdhci_host *host) | |
625 | { | |
626 | struct mmc_host *mmc = host->mmc; | |
83736352 VG |
627 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
628 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
415b5a75 | 629 | int wait_cnt = 50; |
5e6b6651 | 630 | unsigned long flags, xo_clk = 0; |
29301f40 | 631 | u32 config; |
bc99266b SL |
632 | const struct sdhci_msm_offset *msm_offset = |
633 | msm_host->offset; | |
415b5a75 | 634 | |
5e6b6651 JRO |
635 | if (msm_host->use_14lpp_dll_reset && !IS_ERR_OR_NULL(msm_host->xo_clk)) |
636 | xo_clk = clk_get_rate(msm_host->xo_clk); | |
637 | ||
415b5a75 GD |
638 | spin_lock_irqsave(&host->lock, flags); |
639 | ||
0eb0d9f4 | 640 | /* |
415b5a75 GD |
641 | * Make sure that clock is always enabled when DLL |
642 | * tuning is in progress. Keeping PWRSAVE ON may | |
643 | * turn off the clock. | |
0eb0d9f4 | 644 | */ |
bc99266b | 645 | config = readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec); |
29301f40 | 646 | config &= ~CORE_CLK_PWRSAVE; |
bc99266b | 647 | writel_relaxed(config, host->ioaddr + msm_offset->core_vendor_spec); |
415b5a75 | 648 | |
3ec2d511 VB |
649 | if (msm_host->dll_config) |
650 | writel_relaxed(msm_host->dll_config, | |
651 | host->ioaddr + msm_offset->core_dll_config); | |
03591160 | 652 | |
83736352 | 653 | if (msm_host->use_14lpp_dll_reset) { |
bc99266b SL |
654 | config = readl_relaxed(host->ioaddr + |
655 | msm_offset->core_dll_config); | |
83736352 | 656 | config &= ~CORE_CK_OUT_EN; |
bc99266b SL |
657 | writel_relaxed(config, host->ioaddr + |
658 | msm_offset->core_dll_config); | |
83736352 | 659 | |
bc99266b SL |
660 | config = readl_relaxed(host->ioaddr + |
661 | msm_offset->core_dll_config_2); | |
83736352 | 662 | config |= CORE_DLL_CLOCK_DISABLE; |
bc99266b SL |
663 | writel_relaxed(config, host->ioaddr + |
664 | msm_offset->core_dll_config_2); | |
83736352 VG |
665 | } |
666 | ||
bc99266b SL |
667 | config = readl_relaxed(host->ioaddr + |
668 | msm_offset->core_dll_config); | |
29301f40 | 669 | config |= CORE_DLL_RST; |
bc99266b SL |
670 | writel_relaxed(config, host->ioaddr + |
671 | msm_offset->core_dll_config); | |
415b5a75 | 672 | |
bc99266b SL |
673 | config = readl_relaxed(host->ioaddr + |
674 | msm_offset->core_dll_config); | |
29301f40 | 675 | config |= CORE_DLL_PDN; |
bc99266b SL |
676 | writel_relaxed(config, host->ioaddr + |
677 | msm_offset->core_dll_config); | |
03591160 SG |
678 | |
679 | if (!msm_host->dll_config) | |
680 | msm_cm_dll_set_freq(host); | |
415b5a75 | 681 | |
83736352 VG |
682 | if (msm_host->use_14lpp_dll_reset && |
683 | !IS_ERR_OR_NULL(msm_host->xo_clk)) { | |
684 | u32 mclk_freq = 0; | |
685 | ||
bc99266b SL |
686 | config = readl_relaxed(host->ioaddr + |
687 | msm_offset->core_dll_config_2); | |
83736352 VG |
688 | config &= CORE_FLL_CYCLE_CNT; |
689 | if (config) | |
690 | mclk_freq = DIV_ROUND_CLOSEST_ULL((host->clock * 8), | |
5e6b6651 | 691 | xo_clk); |
83736352 VG |
692 | else |
693 | mclk_freq = DIV_ROUND_CLOSEST_ULL((host->clock * 4), | |
5e6b6651 | 694 | xo_clk); |
83736352 | 695 | |
bc99266b SL |
696 | config = readl_relaxed(host->ioaddr + |
697 | msm_offset->core_dll_config_2); | |
83736352 VG |
698 | config &= ~(0xFF << 10); |
699 | config |= mclk_freq << 10; | |
700 | ||
bc99266b SL |
701 | writel_relaxed(config, host->ioaddr + |
702 | msm_offset->core_dll_config_2); | |
83736352 VG |
703 | /* wait for 5us before enabling DLL clock */ |
704 | udelay(5); | |
705 | } | |
706 | ||
bc99266b SL |
707 | config = readl_relaxed(host->ioaddr + |
708 | msm_offset->core_dll_config); | |
29301f40 | 709 | config &= ~CORE_DLL_RST; |
bc99266b SL |
710 | writel_relaxed(config, host->ioaddr + |
711 | msm_offset->core_dll_config); | |
415b5a75 | 712 | |
bc99266b SL |
713 | config = readl_relaxed(host->ioaddr + |
714 | msm_offset->core_dll_config); | |
29301f40 | 715 | config &= ~CORE_DLL_PDN; |
bc99266b SL |
716 | writel_relaxed(config, host->ioaddr + |
717 | msm_offset->core_dll_config); | |
415b5a75 | 718 | |
83736352 | 719 | if (msm_host->use_14lpp_dll_reset) { |
03591160 SG |
720 | if (!msm_host->dll_config) |
721 | msm_cm_dll_set_freq(host); | |
bc99266b SL |
722 | config = readl_relaxed(host->ioaddr + |
723 | msm_offset->core_dll_config_2); | |
83736352 | 724 | config &= ~CORE_DLL_CLOCK_DISABLE; |
bc99266b SL |
725 | writel_relaxed(config, host->ioaddr + |
726 | msm_offset->core_dll_config_2); | |
83736352 VG |
727 | } |
728 | ||
5c30f340 VB |
729 | /* |
730 | * Configure DLL user control register to enable DLL status. | |
731 | * This setting is applicable to SDCC v5.1 onwards only. | |
732 | */ | |
733 | if (msm_host->uses_tassadar_dll) { | |
734 | config = DLL_USR_CTL_POR_VAL | FINE_TUNE_MODE_EN | | |
735 | ENABLE_DLL_LOCK_STATUS | BIAS_OK_SIGNAL; | |
736 | writel_relaxed(config, host->ioaddr + | |
737 | msm_offset->core_dll_usr_ctl); | |
04816e67 SG |
738 | |
739 | config = readl_relaxed(host->ioaddr + | |
740 | msm_offset->core_dll_config_3); | |
741 | config &= ~0xFF; | |
742 | if (msm_host->clk_rate < 150000000) | |
743 | config |= DLL_CONFIG_3_LOW_FREQ_VAL; | |
744 | else | |
745 | config |= DLL_CONFIG_3_HIGH_FREQ_VAL; | |
746 | writel_relaxed(config, host->ioaddr + | |
747 | msm_offset->core_dll_config_3); | |
5c30f340 VB |
748 | } |
749 | ||
bc99266b SL |
750 | config = readl_relaxed(host->ioaddr + |
751 | msm_offset->core_dll_config); | |
29301f40 | 752 | config |= CORE_DLL_EN; |
bc99266b SL |
753 | writel_relaxed(config, host->ioaddr + |
754 | msm_offset->core_dll_config); | |
415b5a75 | 755 | |
bc99266b SL |
756 | config = readl_relaxed(host->ioaddr + |
757 | msm_offset->core_dll_config); | |
29301f40 | 758 | config |= CORE_CK_OUT_EN; |
bc99266b SL |
759 | writel_relaxed(config, host->ioaddr + |
760 | msm_offset->core_dll_config); | |
415b5a75 GD |
761 | |
762 | /* Wait until DLL_LOCK bit of DLL_STATUS register becomes '1' */ | |
bc99266b | 763 | while (!(readl_relaxed(host->ioaddr + msm_offset->core_dll_status) & |
415b5a75 GD |
764 | CORE_DLL_LOCK)) { |
765 | /* max. wait for 50us sec for LOCK bit to be set */ | |
766 | if (--wait_cnt == 0) { | |
767 | dev_err(mmc_dev(mmc), "%s: DLL failed to LOCK\n", | |
768 | mmc_hostname(mmc)); | |
769 | spin_unlock_irqrestore(&host->lock, flags); | |
770 | return -ETIMEDOUT; | |
771 | } | |
772 | udelay(1); | |
773 | } | |
774 | ||
775 | spin_unlock_irqrestore(&host->lock, flags); | |
0eb0d9f4 GD |
776 | return 0; |
777 | } | |
778 | ||
b54aaa8a RH |
779 | static void msm_hc_select_default(struct sdhci_host *host) |
780 | { | |
781 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
782 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
783 | u32 config; | |
bc99266b SL |
784 | const struct sdhci_msm_offset *msm_offset = |
785 | msm_host->offset; | |
b54aaa8a RH |
786 | |
787 | if (!msm_host->use_cdclp533) { | |
788 | config = readl_relaxed(host->ioaddr + | |
bc99266b | 789 | msm_offset->core_vendor_spec3); |
b54aaa8a RH |
790 | config &= ~CORE_PWRSAVE_DLL; |
791 | writel_relaxed(config, host->ioaddr + | |
bc99266b | 792 | msm_offset->core_vendor_spec3); |
b54aaa8a RH |
793 | } |
794 | ||
bc99266b | 795 | config = readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec); |
b54aaa8a RH |
796 | config &= ~CORE_HC_MCLK_SEL_MASK; |
797 | config |= CORE_HC_MCLK_SEL_DFLT; | |
bc99266b | 798 | writel_relaxed(config, host->ioaddr + msm_offset->core_vendor_spec); |
b54aaa8a RH |
799 | |
800 | /* | |
801 | * Disable HC_SELECT_IN to be able to use the UHS mode select | |
802 | * configuration from Host Control2 register for all other | |
803 | * modes. | |
804 | * Write 0 to HC_SELECT_IN and HC_SELECT_IN_EN field | |
805 | * in VENDOR_SPEC_FUNC | |
806 | */ | |
bc99266b | 807 | config = readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec); |
b54aaa8a RH |
808 | config &= ~CORE_HC_SELECT_IN_EN; |
809 | config &= ~CORE_HC_SELECT_IN_MASK; | |
bc99266b | 810 | writel_relaxed(config, host->ioaddr + msm_offset->core_vendor_spec); |
b54aaa8a RH |
811 | |
812 | /* | |
813 | * Make sure above writes impacting free running MCLK are completed | |
814 | * before changing the clk_rate at GCC. | |
815 | */ | |
816 | wmb(); | |
817 | } | |
818 | ||
819 | static void msm_hc_select_hs400(struct sdhci_host *host) | |
820 | { | |
821 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
822 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
44bf2312 | 823 | struct mmc_ios ios = host->mmc->ios; |
b54aaa8a RH |
824 | u32 config, dll_lock; |
825 | int rc; | |
bc99266b SL |
826 | const struct sdhci_msm_offset *msm_offset = |
827 | msm_host->offset; | |
b54aaa8a RH |
828 | |
829 | /* Select the divided clock (free running MCLK/2) */ | |
bc99266b | 830 | config = readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec); |
b54aaa8a RH |
831 | config &= ~CORE_HC_MCLK_SEL_MASK; |
832 | config |= CORE_HC_MCLK_SEL_HS400; | |
833 | ||
bc99266b | 834 | writel_relaxed(config, host->ioaddr + msm_offset->core_vendor_spec); |
b54aaa8a RH |
835 | /* |
836 | * Select HS400 mode using the HC_SELECT_IN from VENDOR SPEC | |
837 | * register | |
838 | */ | |
44bf2312 RH |
839 | if ((msm_host->tuning_done || ios.enhanced_strobe) && |
840 | !msm_host->calibration_done) { | |
bc99266b SL |
841 | config = readl_relaxed(host->ioaddr + |
842 | msm_offset->core_vendor_spec); | |
b54aaa8a RH |
843 | config |= CORE_HC_SELECT_IN_HS400; |
844 | config |= CORE_HC_SELECT_IN_EN; | |
bc99266b SL |
845 | writel_relaxed(config, host->ioaddr + |
846 | msm_offset->core_vendor_spec); | |
b54aaa8a RH |
847 | } |
848 | if (!msm_host->clk_rate && !msm_host->use_cdclp533) { | |
849 | /* | |
850 | * Poll on DLL_LOCK or DDR_DLL_LOCK bits in | |
bc99266b | 851 | * core_dll_status to be set. This should get set |
b54aaa8a RH |
852 | * within 15 us at 200 MHz. |
853 | */ | |
854 | rc = readl_relaxed_poll_timeout(host->ioaddr + | |
bc99266b | 855 | msm_offset->core_dll_status, |
b54aaa8a RH |
856 | dll_lock, |
857 | (dll_lock & | |
858 | (CORE_DLL_LOCK | | |
859 | CORE_DDR_DLL_LOCK)), 10, | |
860 | 1000); | |
861 | if (rc == -ETIMEDOUT) | |
862 | pr_err("%s: Unable to get DLL_LOCK/DDR_DLL_LOCK, dll_status: 0x%08x\n", | |
863 | mmc_hostname(host->mmc), dll_lock); | |
864 | } | |
865 | /* | |
866 | * Make sure above writes impacting free running MCLK are completed | |
867 | * before changing the clk_rate at GCC. | |
868 | */ | |
869 | wmb(); | |
870 | } | |
871 | ||
872 | /* | |
873 | * sdhci_msm_hc_select_mode :- In general all timing modes are | |
874 | * controlled via UHS mode select in Host Control2 register. | |
875 | * eMMC specific HS200/HS400 doesn't have their respective modes | |
876 | * defined here, hence we use these values. | |
877 | * | |
878 | * HS200 - SDR104 (Since they both are equivalent in functionality) | |
879 | * HS400 - This involves multiple configurations | |
880 | * Initially SDR104 - when tuning is required as HS200 | |
881 | * Then when switching to DDR @ 400MHz (HS400) we use | |
882 | * the vendor specific HC_SELECT_IN to control the mode. | |
883 | * | |
884 | * In addition to controlling the modes we also need to select the | |
885 | * correct input clock for DLL depending on the mode. | |
886 | * | |
887 | * HS400 - divided clock (free running MCLK/2) | |
888 | * All other modes - default (free running MCLK) | |
889 | */ | |
30de038d | 890 | static void sdhci_msm_hc_select_mode(struct sdhci_host *host) |
b54aaa8a RH |
891 | { |
892 | struct mmc_ios ios = host->mmc->ios; | |
893 | ||
d7507aa1 RH |
894 | if (ios.timing == MMC_TIMING_MMC_HS400 || |
895 | host->flags & SDHCI_HS400_TUNING) | |
b54aaa8a RH |
896 | msm_hc_select_hs400(host); |
897 | else | |
898 | msm_hc_select_default(host); | |
899 | } | |
900 | ||
cc392c58 RH |
901 | static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host) |
902 | { | |
903 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
904 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
905 | u32 config, calib_done; | |
906 | int ret; | |
bc99266b SL |
907 | const struct sdhci_msm_offset *msm_offset = |
908 | msm_host->offset; | |
cc392c58 RH |
909 | |
910 | pr_debug("%s: %s: Enter\n", mmc_hostname(host->mmc), __func__); | |
911 | ||
912 | /* | |
913 | * Retuning in HS400 (DDR mode) will fail, just reset the | |
914 | * tuning block and restore the saved tuning phase. | |
915 | */ | |
916 | ret = msm_init_cm_dll(host); | |
917 | if (ret) | |
918 | goto out; | |
919 | ||
920 | /* Set the selected phase in delay line hw block */ | |
921 | ret = msm_config_cm_dll_phase(host, msm_host->saved_tuning_phase); | |
922 | if (ret) | |
923 | goto out; | |
924 | ||
bc99266b | 925 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config); |
cc392c58 | 926 | config |= CORE_CMD_DAT_TRACK_SEL; |
bc99266b | 927 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config); |
cc392c58 | 928 | |
bc99266b | 929 | config = readl_relaxed(host->ioaddr + msm_offset->core_ddr_200_cfg); |
cc392c58 | 930 | config &= ~CORE_CDC_T4_DLY_SEL; |
bc99266b | 931 | writel_relaxed(config, host->ioaddr + msm_offset->core_ddr_200_cfg); |
cc392c58 RH |
932 | |
933 | config = readl_relaxed(host->ioaddr + CORE_CSR_CDC_GEN_CFG); | |
934 | config &= ~CORE_CDC_SWITCH_BYPASS_OFF; | |
935 | writel_relaxed(config, host->ioaddr + CORE_CSR_CDC_GEN_CFG); | |
936 | ||
937 | config = readl_relaxed(host->ioaddr + CORE_CSR_CDC_GEN_CFG); | |
938 | config |= CORE_CDC_SWITCH_RC_EN; | |
939 | writel_relaxed(config, host->ioaddr + CORE_CSR_CDC_GEN_CFG); | |
940 | ||
bc99266b | 941 | config = readl_relaxed(host->ioaddr + msm_offset->core_ddr_200_cfg); |
cc392c58 | 942 | config &= ~CORE_START_CDC_TRAFFIC; |
bc99266b | 943 | writel_relaxed(config, host->ioaddr + msm_offset->core_ddr_200_cfg); |
cc392c58 | 944 | |
543c576d | 945 | /* Perform CDC Register Initialization Sequence */ |
cc392c58 RH |
946 | |
947 | writel_relaxed(0x11800EC, host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
948 | writel_relaxed(0x3011111, host->ioaddr + CORE_CSR_CDC_CTLR_CFG1); | |
949 | writel_relaxed(0x1201000, host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG0); | |
950 | writel_relaxed(0x4, host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG1); | |
951 | writel_relaxed(0xCB732020, host->ioaddr + CORE_CSR_CDC_REFCOUNT_CFG); | |
952 | writel_relaxed(0xB19, host->ioaddr + CORE_CSR_CDC_COARSE_CAL_CFG); | |
083c9aa0 | 953 | writel_relaxed(0x4E2, host->ioaddr + CORE_CSR_CDC_DELAY_CFG); |
cc392c58 RH |
954 | writel_relaxed(0x0, host->ioaddr + CORE_CDC_OFFSET_CFG); |
955 | writel_relaxed(0x16334, host->ioaddr + CORE_CDC_SLAVE_DDA_CFG); | |
956 | ||
957 | /* CDC HW Calibration */ | |
958 | ||
959 | config = readl_relaxed(host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
960 | config |= CORE_SW_TRIG_FULL_CALIB; | |
961 | writel_relaxed(config, host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
962 | ||
963 | config = readl_relaxed(host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
964 | config &= ~CORE_SW_TRIG_FULL_CALIB; | |
965 | writel_relaxed(config, host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
966 | ||
967 | config = readl_relaxed(host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
968 | config |= CORE_HW_AUTOCAL_ENA; | |
969 | writel_relaxed(config, host->ioaddr + CORE_CSR_CDC_CTLR_CFG0); | |
970 | ||
971 | config = readl_relaxed(host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG0); | |
972 | config |= CORE_TIMER_ENA; | |
973 | writel_relaxed(config, host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG0); | |
974 | ||
975 | ret = readl_relaxed_poll_timeout(host->ioaddr + CORE_CSR_CDC_STATUS0, | |
976 | calib_done, | |
977 | (calib_done & CORE_CALIBRATION_DONE), | |
978 | 1, 50); | |
979 | ||
980 | if (ret == -ETIMEDOUT) { | |
981 | pr_err("%s: %s: CDC calibration was not completed\n", | |
982 | mmc_hostname(host->mmc), __func__); | |
983 | goto out; | |
984 | } | |
985 | ||
986 | ret = readl_relaxed(host->ioaddr + CORE_CSR_CDC_STATUS0) | |
987 | & CORE_CDC_ERROR_CODE_MASK; | |
988 | if (ret) { | |
989 | pr_err("%s: %s: CDC error code %d\n", | |
990 | mmc_hostname(host->mmc), __func__, ret); | |
991 | ret = -EINVAL; | |
992 | goto out; | |
993 | } | |
994 | ||
bc99266b | 995 | config = readl_relaxed(host->ioaddr + msm_offset->core_ddr_200_cfg); |
cc392c58 | 996 | config |= CORE_START_CDC_TRAFFIC; |
bc99266b | 997 | writel_relaxed(config, host->ioaddr + msm_offset->core_ddr_200_cfg); |
cc392c58 RH |
998 | out: |
999 | pr_debug("%s: %s: Exit, ret %d\n", mmc_hostname(host->mmc), | |
1000 | __func__, ret); | |
1001 | return ret; | |
1002 | } | |
1003 | ||
02e4293d RH |
1004 | static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host) |
1005 | { | |
44bf2312 | 1006 | struct mmc_host *mmc = host->mmc; |
fa56ac97 | 1007 | u32 dll_status, config, ddr_cfg_offset; |
02e4293d | 1008 | int ret; |
fa56ac97 VB |
1009 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1010 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
bc99266b SL |
1011 | const struct sdhci_msm_offset *msm_offset = |
1012 | sdhci_priv_msm_offset(host); | |
02e4293d RH |
1013 | |
1014 | pr_debug("%s: %s: Enter\n", mmc_hostname(host->mmc), __func__); | |
1015 | ||
1016 | /* | |
bc99266b | 1017 | * Currently the core_ddr_config register defaults to desired |
02e4293d RH |
1018 | * configuration on reset. Currently reprogramming the power on |
1019 | * reset (POR) value in case it might have been modified by | |
1020 | * bootloaders. In the future, if this changes, then the desired | |
1021 | * values will need to be programmed appropriately. | |
1022 | */ | |
fa56ac97 VB |
1023 | if (msm_host->updated_ddr_cfg) |
1024 | ddr_cfg_offset = msm_offset->core_ddr_config; | |
1025 | else | |
1026 | ddr_cfg_offset = msm_offset->core_ddr_config_old; | |
1dfbe3ff | 1027 | writel_relaxed(msm_host->ddr_config, host->ioaddr + ddr_cfg_offset); |
02e4293d | 1028 | |
44bf2312 | 1029 | if (mmc->ios.enhanced_strobe) { |
bc99266b SL |
1030 | config = readl_relaxed(host->ioaddr + |
1031 | msm_offset->core_ddr_200_cfg); | |
44bf2312 | 1032 | config |= CORE_CMDIN_RCLK_EN; |
bc99266b SL |
1033 | writel_relaxed(config, host->ioaddr + |
1034 | msm_offset->core_ddr_200_cfg); | |
44bf2312 RH |
1035 | } |
1036 | ||
bc99266b | 1037 | config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config_2); |
02e4293d | 1038 | config |= CORE_DDR_CAL_EN; |
bc99266b | 1039 | writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config_2); |
02e4293d | 1040 | |
bc99266b SL |
1041 | ret = readl_relaxed_poll_timeout(host->ioaddr + |
1042 | msm_offset->core_dll_status, | |
1043 | dll_status, | |
1044 | (dll_status & CORE_DDR_DLL_LOCK), | |
1045 | 10, 1000); | |
02e4293d RH |
1046 | |
1047 | if (ret == -ETIMEDOUT) { | |
1048 | pr_err("%s: %s: CM_DLL_SDC4 calibration was not completed\n", | |
1049 | mmc_hostname(host->mmc), __func__); | |
1050 | goto out; | |
1051 | } | |
1052 | ||
219c02ca RH |
1053 | /* |
1054 | * Set CORE_PWRSAVE_DLL bit in CORE_VENDOR_SPEC3. | |
1055 | * When MCLK is gated OFF, it is not gated for less than 0.5us | |
1056 | * and MCLK must be switched on for at-least 1us before DATA | |
1057 | * starts coming. Controllers with 14lpp and later tech DLL cannot | |
1058 | * guarantee above requirement. So PWRSAVE_DLL should not be | |
1059 | * turned on for host controllers using this DLL. | |
1060 | */ | |
1061 | if (!msm_host->use_14lpp_dll_reset) { | |
1062 | config = readl_relaxed(host->ioaddr + | |
1063 | msm_offset->core_vendor_spec3); | |
1064 | config |= CORE_PWRSAVE_DLL; | |
1065 | writel_relaxed(config, host->ioaddr + | |
1066 | msm_offset->core_vendor_spec3); | |
1067 | } | |
02e4293d RH |
1068 | |
1069 | /* | |
1070 | * Drain writebuffer to ensure above DLL calibration | |
1071 | * and PWRSAVE DLL is enabled. | |
1072 | */ | |
1073 | wmb(); | |
1074 | out: | |
1075 | pr_debug("%s: %s: Exit, ret %d\n", mmc_hostname(host->mmc), | |
1076 | __func__, ret); | |
1077 | return ret; | |
1078 | } | |
1079 | ||
1080 | static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host) | |
1081 | { | |
1082 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1083 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
44bf2312 | 1084 | struct mmc_host *mmc = host->mmc; |
02e4293d RH |
1085 | int ret; |
1086 | u32 config; | |
bc99266b SL |
1087 | const struct sdhci_msm_offset *msm_offset = |
1088 | msm_host->offset; | |
02e4293d RH |
1089 | |
1090 | pr_debug("%s: %s: Enter\n", mmc_hostname(host->mmc), __func__); | |
1091 | ||
1092 | /* | |
1093 | * Retuning in HS400 (DDR mode) will fail, just reset the | |
1094 | * tuning block and restore the saved tuning phase. | |
1095 | */ | |
1096 | ret = msm_init_cm_dll(host); | |
1097 | if (ret) | |
1098 | goto out; | |
1099 | ||
44bf2312 RH |
1100 | if (!mmc->ios.enhanced_strobe) { |
1101 | /* Set the selected phase in delay line hw block */ | |
1102 | ret = msm_config_cm_dll_phase(host, | |
1103 | msm_host->saved_tuning_phase); | |
1104 | if (ret) | |
1105 | goto out; | |
bc99266b SL |
1106 | config = readl_relaxed(host->ioaddr + |
1107 | msm_offset->core_dll_config); | |
44bf2312 | 1108 | config |= CORE_CMD_DAT_TRACK_SEL; |
bc99266b SL |
1109 | writel_relaxed(config, host->ioaddr + |
1110 | msm_offset->core_dll_config); | |
44bf2312 | 1111 | } |
02e4293d | 1112 | |
02e4293d RH |
1113 | if (msm_host->use_cdclp533) |
1114 | ret = sdhci_msm_cdclp533_calibration(host); | |
1115 | else | |
1116 | ret = sdhci_msm_cm_dll_sdc4_calibration(host); | |
1117 | out: | |
1118 | pr_debug("%s: %s: Exit, ret %d\n", mmc_hostname(host->mmc), | |
1119 | __func__, ret); | |
1120 | return ret; | |
1121 | } | |
1122 | ||
21f1e2d4 VB |
1123 | static bool sdhci_msm_is_tuning_needed(struct sdhci_host *host) |
1124 | { | |
1125 | struct mmc_ios *ios = &host->mmc->ios; | |
1126 | ||
1127 | /* | |
1128 | * Tuning is required for SDR104, HS200 and HS400 cards and | |
1129 | * if clock frequency is greater than 100MHz in these modes. | |
1130 | */ | |
1131 | if (host->clock <= CORE_FREQ_100MHZ || | |
1132 | !(ios->timing == MMC_TIMING_MMC_HS400 || | |
1133 | ios->timing == MMC_TIMING_MMC_HS200 || | |
1134 | ios->timing == MMC_TIMING_UHS_SDR104) || | |
1135 | ios->enhanced_strobe) | |
1136 | return false; | |
1137 | ||
1138 | return true; | |
1139 | } | |
1140 | ||
1141 | static int sdhci_msm_restore_sdr_dll_config(struct sdhci_host *host) | |
1142 | { | |
1143 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1144 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
1145 | int ret; | |
1146 | ||
1147 | /* | |
1148 | * SDR DLL comes into picture only for timing modes which needs | |
1149 | * tuning. | |
1150 | */ | |
1151 | if (!sdhci_msm_is_tuning_needed(host)) | |
1152 | return 0; | |
1153 | ||
1154 | /* Reset the tuning block */ | |
1155 | ret = msm_init_cm_dll(host); | |
1156 | if (ret) | |
1157 | return ret; | |
1158 | ||
1159 | /* Restore the tuning block */ | |
1160 | ret = msm_config_cm_dll_phase(host, msm_host->saved_tuning_phase); | |
1161 | ||
1162 | return ret; | |
1163 | } | |
1164 | ||
a89e7bcb LP |
1165 | static void sdhci_msm_set_cdr(struct sdhci_host *host, bool enable) |
1166 | { | |
1167 | const struct sdhci_msm_offset *msm_offset = sdhci_priv_msm_offset(host); | |
1168 | u32 config, oldconfig = readl_relaxed(host->ioaddr + | |
1169 | msm_offset->core_dll_config); | |
1170 | ||
1171 | config = oldconfig; | |
1172 | if (enable) { | |
1173 | config |= CORE_CDR_EN; | |
1174 | config &= ~CORE_CDR_EXT_EN; | |
1175 | } else { | |
1176 | config &= ~CORE_CDR_EN; | |
1177 | config |= CORE_CDR_EXT_EN; | |
1178 | } | |
1179 | ||
1180 | if (config != oldconfig) { | |
1181 | writel_relaxed(config, host->ioaddr + | |
1182 | msm_offset->core_dll_config); | |
1183 | } | |
1184 | } | |
1185 | ||
4436c535 | 1186 | static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) |
415b5a75 | 1187 | { |
4436c535 | 1188 | struct sdhci_host *host = mmc_priv(mmc); |
9d5dcefb | 1189 | int tuning_seq_cnt = 10; |
33d73935 | 1190 | u8 phase, tuned_phases[16], tuned_phase_cnt = 0; |
415b5a75 | 1191 | int rc; |
415b5a75 | 1192 | struct mmc_ios ios = host->mmc->ios; |
abf270e5 RH |
1193 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1194 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
415b5a75 | 1195 | |
a89e7bcb LP |
1196 | if (!sdhci_msm_is_tuning_needed(host)) { |
1197 | msm_host->use_cdr = false; | |
1198 | sdhci_msm_set_cdr(host, false); | |
415b5a75 | 1199 | return 0; |
a89e7bcb LP |
1200 | } |
1201 | ||
1202 | /* Clock-Data-Recovery used to dynamically adjust RX sampling point */ | |
1203 | msm_host->use_cdr = true; | |
415b5a75 | 1204 | |
9253d710 VB |
1205 | /* |
1206 | * Clear tuning_done flag before tuning to ensure proper | |
1207 | * HS400 settings. | |
1208 | */ | |
1209 | msm_host->tuning_done = 0; | |
1210 | ||
d7507aa1 RH |
1211 | /* |
1212 | * For HS400 tuning in HS200 timing requires: | |
1213 | * - select MCLK/2 in VENDOR_SPEC | |
1214 | * - program MCLK to 400MHz (or nearest supported) in GCC | |
1215 | */ | |
1216 | if (host->flags & SDHCI_HS400_TUNING) { | |
1217 | sdhci_msm_hc_select_mode(host); | |
1218 | msm_set_clock_rate_for_bus_mode(host, ios.clock); | |
4436c535 | 1219 | host->flags &= ~SDHCI_HS400_TUNING; |
d7507aa1 RH |
1220 | } |
1221 | ||
415b5a75 GD |
1222 | retry: |
1223 | /* First of all reset the tuning block */ | |
1224 | rc = msm_init_cm_dll(host); | |
1225 | if (rc) | |
33d73935 | 1226 | return rc; |
415b5a75 GD |
1227 | |
1228 | phase = 0; | |
1229 | do { | |
415b5a75 GD |
1230 | /* Set the phase in delay line hw block */ |
1231 | rc = msm_config_cm_dll_phase(host, phase); | |
1232 | if (rc) | |
33d73935 | 1233 | return rc; |
415b5a75 | 1234 | |
9979dbe5 | 1235 | rc = mmc_send_tuning(mmc, opcode, NULL); |
33d73935 | 1236 | if (!rc) { |
415b5a75 GD |
1237 | /* Tuning is successful at this tuning point */ |
1238 | tuned_phases[tuned_phase_cnt++] = phase; | |
1239 | dev_dbg(mmc_dev(mmc), "%s: Found good phase = %d\n", | |
1240 | mmc_hostname(mmc), phase); | |
1241 | } | |
1242 | } while (++phase < ARRAY_SIZE(tuned_phases)); | |
1243 | ||
1244 | if (tuned_phase_cnt) { | |
9d5dcefb DA |
1245 | if (tuned_phase_cnt == ARRAY_SIZE(tuned_phases)) { |
1246 | /* | |
1247 | * All phases valid is _almost_ as bad as no phases | |
1248 | * valid. Probably all phases are not really reliable | |
1249 | * but we didn't detect where the unreliable place is. | |
1250 | * That means we'll essentially be guessing and hoping | |
1251 | * we get a good phase. Better to try a few times. | |
1252 | */ | |
1253 | dev_dbg(mmc_dev(mmc), "%s: All phases valid; try again\n", | |
1254 | mmc_hostname(mmc)); | |
1255 | if (--tuning_seq_cnt) { | |
1256 | tuned_phase_cnt = 0; | |
1257 | goto retry; | |
1258 | } | |
1259 | } | |
1260 | ||
415b5a75 GD |
1261 | rc = msm_find_most_appropriate_phase(host, tuned_phases, |
1262 | tuned_phase_cnt); | |
1263 | if (rc < 0) | |
33d73935 | 1264 | return rc; |
415b5a75 GD |
1265 | else |
1266 | phase = rc; | |
1267 | ||
1268 | /* | |
1269 | * Finally set the selected phase in delay | |
1270 | * line hw block. | |
1271 | */ | |
1272 | rc = msm_config_cm_dll_phase(host, phase); | |
1273 | if (rc) | |
33d73935 | 1274 | return rc; |
21f1e2d4 | 1275 | msm_host->saved_tuning_phase = phase; |
415b5a75 GD |
1276 | dev_dbg(mmc_dev(mmc), "%s: Setting the tuning phase to %d\n", |
1277 | mmc_hostname(mmc), phase); | |
1278 | } else { | |
1279 | if (--tuning_seq_cnt) | |
1280 | goto retry; | |
1281 | /* Tuning failed */ | |
1282 | dev_dbg(mmc_dev(mmc), "%s: No tuning point found\n", | |
1283 | mmc_hostname(mmc)); | |
1284 | rc = -EIO; | |
1285 | } | |
1286 | ||
ff06ce41 VG |
1287 | if (!rc) |
1288 | msm_host->tuning_done = true; | |
415b5a75 GD |
1289 | return rc; |
1290 | } | |
1291 | ||
db9bd163 RH |
1292 | /* |
1293 | * sdhci_msm_hs400 - Calibrate the DLL for HS400 bus speed mode operation. | |
44bf2312 | 1294 | * This needs to be done for both tuning and enhanced_strobe mode. |
db9bd163 RH |
1295 | * DLL operation is only needed for clock > 100MHz. For clock <= 100MHz |
1296 | * fixed feedback clock is used. | |
1297 | */ | |
1298 | static void sdhci_msm_hs400(struct sdhci_host *host, struct mmc_ios *ios) | |
1299 | { | |
1300 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1301 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
1302 | int ret; | |
1303 | ||
1304 | if (host->clock > CORE_FREQ_100MHZ && | |
44bf2312 RH |
1305 | (msm_host->tuning_done || ios->enhanced_strobe) && |
1306 | !msm_host->calibration_done) { | |
db9bd163 RH |
1307 | ret = sdhci_msm_hs400_dll_calibration(host); |
1308 | if (!ret) | |
1309 | msm_host->calibration_done = true; | |
1310 | else | |
1311 | pr_err("%s: Failed to calibrate DLL for hs400 mode (%d)\n", | |
1312 | mmc_hostname(host->mmc), ret); | |
1313 | } | |
1314 | } | |
1315 | ||
ee320674 RH |
1316 | static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host, |
1317 | unsigned int uhs) | |
1318 | { | |
1319 | struct mmc_host *mmc = host->mmc; | |
ff06ce41 VG |
1320 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1321 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
ee320674 | 1322 | u16 ctrl_2; |
ff06ce41 | 1323 | u32 config; |
bc99266b SL |
1324 | const struct sdhci_msm_offset *msm_offset = |
1325 | msm_host->offset; | |
ee320674 RH |
1326 | |
1327 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | |
1328 | /* Select Bus Speed Mode for host */ | |
1329 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; | |
1330 | switch (uhs) { | |
1331 | case MMC_TIMING_UHS_SDR12: | |
1332 | ctrl_2 |= SDHCI_CTRL_UHS_SDR12; | |
1333 | break; | |
1334 | case MMC_TIMING_UHS_SDR25: | |
1335 | ctrl_2 |= SDHCI_CTRL_UHS_SDR25; | |
1336 | break; | |
1337 | case MMC_TIMING_UHS_SDR50: | |
1338 | ctrl_2 |= SDHCI_CTRL_UHS_SDR50; | |
1339 | break; | |
ff06ce41 | 1340 | case MMC_TIMING_MMC_HS400: |
ee320674 RH |
1341 | case MMC_TIMING_MMC_HS200: |
1342 | case MMC_TIMING_UHS_SDR104: | |
1343 | ctrl_2 |= SDHCI_CTRL_UHS_SDR104; | |
1344 | break; | |
1345 | case MMC_TIMING_UHS_DDR50: | |
1346 | case MMC_TIMING_MMC_DDR52: | |
1347 | ctrl_2 |= SDHCI_CTRL_UHS_DDR50; | |
1348 | break; | |
1349 | } | |
1350 | ||
1351 | /* | |
1352 | * When clock frequency is less than 100MHz, the feedback clock must be | |
1353 | * provided and DLL must not be used so that tuning can be skipped. To | |
1354 | * provide feedback clock, the mode selection can be any value less | |
1355 | * than 3'b011 in bits [2:0] of HOST CONTROL2 register. | |
1356 | */ | |
ff06ce41 VG |
1357 | if (host->clock <= CORE_FREQ_100MHZ) { |
1358 | if (uhs == MMC_TIMING_MMC_HS400 || | |
1359 | uhs == MMC_TIMING_MMC_HS200 || | |
1360 | uhs == MMC_TIMING_UHS_SDR104) | |
1361 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; | |
1362 | /* | |
1363 | * DLL is not required for clock <= 100MHz | |
1364 | * Thus, make sure DLL it is disabled when not required | |
1365 | */ | |
bc99266b SL |
1366 | config = readl_relaxed(host->ioaddr + |
1367 | msm_offset->core_dll_config); | |
ff06ce41 | 1368 | config |= CORE_DLL_RST; |
bc99266b SL |
1369 | writel_relaxed(config, host->ioaddr + |
1370 | msm_offset->core_dll_config); | |
ff06ce41 | 1371 | |
bc99266b SL |
1372 | config = readl_relaxed(host->ioaddr + |
1373 | msm_offset->core_dll_config); | |
ff06ce41 | 1374 | config |= CORE_DLL_PDN; |
bc99266b SL |
1375 | writel_relaxed(config, host->ioaddr + |
1376 | msm_offset->core_dll_config); | |
ff06ce41 VG |
1377 | |
1378 | /* | |
1379 | * The DLL needs to be restored and CDCLP533 recalibrated | |
1380 | * when the clock frequency is set back to 400MHz. | |
1381 | */ | |
1382 | msm_host->calibration_done = false; | |
1383 | } | |
ee320674 RH |
1384 | |
1385 | dev_dbg(mmc_dev(mmc), "%s: clock=%u uhs=%u ctrl_2=0x%x\n", | |
1386 | mmc_hostname(host->mmc), host->clock, uhs, ctrl_2); | |
1387 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); | |
cc392c58 | 1388 | |
db9bd163 RH |
1389 | if (mmc->ios.timing == MMC_TIMING_MMC_HS400) |
1390 | sdhci_msm_hs400(host, &mmc->ios); | |
ee320674 RH |
1391 | } |
1392 | ||
b5c833b7 VB |
1393 | static int sdhci_msm_set_pincfg(struct sdhci_msm_host *msm_host, bool level) |
1394 | { | |
1395 | struct platform_device *pdev = msm_host->pdev; | |
1396 | int ret; | |
1397 | ||
1398 | if (level) | |
1399 | ret = pinctrl_pm_select_default_state(&pdev->dev); | |
1400 | else | |
1401 | ret = pinctrl_pm_select_sleep_state(&pdev->dev); | |
1402 | ||
1403 | return ret; | |
1404 | } | |
1405 | ||
92a21738 VB |
1406 | static int sdhci_msm_set_vmmc(struct mmc_host *mmc) |
1407 | { | |
1408 | if (IS_ERR(mmc->supply.vmmc)) | |
1409 | return 0; | |
1410 | ||
1411 | return mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd); | |
1412 | } | |
1413 | ||
1414 | static int msm_toggle_vqmmc(struct sdhci_msm_host *msm_host, | |
1415 | struct mmc_host *mmc, bool level) | |
1416 | { | |
1417 | int ret; | |
1418 | struct mmc_ios ios; | |
1419 | ||
1420 | if (msm_host->vqmmc_enabled == level) | |
1421 | return 0; | |
1422 | ||
1423 | if (level) { | |
1424 | /* Set the IO voltage regulator to default voltage level */ | |
1425 | if (msm_host->caps_0 & CORE_3_0V_SUPPORT) | |
1426 | ios.signal_voltage = MMC_SIGNAL_VOLTAGE_330; | |
1427 | else if (msm_host->caps_0 & CORE_1_8V_SUPPORT) | |
1428 | ios.signal_voltage = MMC_SIGNAL_VOLTAGE_180; | |
1429 | ||
1430 | if (msm_host->caps_0 & CORE_VOLT_SUPPORT) { | |
1431 | ret = mmc_regulator_set_vqmmc(mmc, &ios); | |
1432 | if (ret < 0) { | |
1433 | dev_err(mmc_dev(mmc), "%s: vqmmc set volgate failed: %d\n", | |
1434 | mmc_hostname(mmc), ret); | |
1435 | goto out; | |
1436 | } | |
1437 | } | |
1438 | ret = regulator_enable(mmc->supply.vqmmc); | |
1439 | } else { | |
1440 | ret = regulator_disable(mmc->supply.vqmmc); | |
1441 | } | |
1442 | ||
1443 | if (ret) | |
1444 | dev_err(mmc_dev(mmc), "%s: vqmm %sable failed: %d\n", | |
1445 | mmc_hostname(mmc), level ? "en":"dis", ret); | |
1446 | else | |
1447 | msm_host->vqmmc_enabled = level; | |
1448 | out: | |
1449 | return ret; | |
1450 | } | |
1451 | ||
1452 | static int msm_config_vqmmc_mode(struct sdhci_msm_host *msm_host, | |
1453 | struct mmc_host *mmc, bool hpm) | |
1454 | { | |
1455 | int load, ret; | |
1456 | ||
1457 | load = hpm ? MMC_VQMMC_MAX_LOAD_UA : 0; | |
1458 | ret = regulator_set_load(mmc->supply.vqmmc, load); | |
1459 | if (ret) | |
1460 | dev_err(mmc_dev(mmc), "%s: vqmmc set load failed: %d\n", | |
1461 | mmc_hostname(mmc), ret); | |
1462 | return ret; | |
1463 | } | |
1464 | ||
1465 | static int sdhci_msm_set_vqmmc(struct sdhci_msm_host *msm_host, | |
1466 | struct mmc_host *mmc, bool level) | |
1467 | { | |
1468 | int ret; | |
1469 | bool always_on; | |
1470 | ||
1471 | if (IS_ERR(mmc->supply.vqmmc) || | |
1472 | (mmc->ios.power_mode == MMC_POWER_UNDEFINED)) | |
1473 | return 0; | |
1474 | /* | |
1475 | * For eMMC don't turn off Vqmmc, Instead just configure it in LPM | |
1476 | * and HPM modes by setting the corresponding load. | |
1477 | * | |
1478 | * Till eMMC is initialized (i.e. always_on == 0), just turn on/off | |
1479 | * Vqmmc. Vqmmc gets turned off only if init fails and mmc_power_off | |
1480 | * gets invoked. Once eMMC is initialized (i.e. always_on == 1), | |
1481 | * Vqmmc should remain ON, So just set the load instead of turning it | |
1482 | * off/on. | |
1483 | */ | |
1484 | always_on = !mmc_card_is_removable(mmc) && | |
1485 | mmc->card && mmc_card_mmc(mmc->card); | |
1486 | ||
1487 | if (always_on) | |
1488 | ret = msm_config_vqmmc_mode(msm_host, mmc, level); | |
1489 | else | |
1490 | ret = msm_toggle_vqmmc(msm_host, mmc, level); | |
1491 | ||
1492 | return ret; | |
1493 | } | |
1494 | ||
c0309b38 VV |
1495 | static inline void sdhci_msm_init_pwr_irq_wait(struct sdhci_msm_host *msm_host) |
1496 | { | |
1497 | init_waitqueue_head(&msm_host->pwr_irq_wait); | |
1498 | } | |
1499 | ||
1500 | static inline void sdhci_msm_complete_pwr_irq_wait( | |
1501 | struct sdhci_msm_host *msm_host) | |
1502 | { | |
1503 | wake_up(&msm_host->pwr_irq_wait); | |
1504 | } | |
1505 | ||
1506 | /* | |
1507 | * sdhci_msm_check_power_status API should be called when registers writes | |
1508 | * which can toggle sdhci IO bus ON/OFF or change IO lines HIGH/LOW happens. | |
1509 | * To what state the register writes will change the IO lines should be passed | |
1510 | * as the argument req_type. This API will check whether the IO line's state | |
1511 | * is already the expected state and will wait for power irq only if | |
27d8a86a | 1512 | * power irq is expected to be triggered based on the current IO line state |
c0309b38 VV |
1513 | * and expected IO line state. |
1514 | */ | |
1515 | static void sdhci_msm_check_power_status(struct sdhci_host *host, u32 req_type) | |
1516 | { | |
1517 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1518 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
1519 | bool done = false; | |
bc99266b SL |
1520 | u32 val = SWITCHABLE_SIGNALING_VOLTAGE; |
1521 | const struct sdhci_msm_offset *msm_offset = | |
1522 | msm_host->offset; | |
c0309b38 VV |
1523 | |
1524 | pr_debug("%s: %s: request %d curr_pwr_state %x curr_io_level %x\n", | |
1525 | mmc_hostname(host->mmc), __func__, req_type, | |
1526 | msm_host->curr_pwr_state, msm_host->curr_io_level); | |
1527 | ||
52884f8f BA |
1528 | /* |
1529 | * The power interrupt will not be generated for signal voltage | |
1530 | * switches if SWITCHABLE_SIGNALING_VOLTAGE in MCI_GENERICS is not set. | |
bc99266b SL |
1531 | * Since sdhci-msm-v5, this bit has been removed and SW must consider |
1532 | * it as always set. | |
52884f8f | 1533 | */ |
bc99266b SL |
1534 | if (!msm_host->mci_removed) |
1535 | val = msm_host_readl(msm_host, host, | |
1536 | msm_offset->core_generics); | |
52884f8f BA |
1537 | if ((req_type & REQ_IO_HIGH || req_type & REQ_IO_LOW) && |
1538 | !(val & SWITCHABLE_SIGNALING_VOLTAGE)) { | |
1539 | return; | |
1540 | } | |
1541 | ||
c0309b38 VV |
1542 | /* |
1543 | * The IRQ for request type IO High/LOW will be generated when - | |
1544 | * there is a state change in 1.8V enable bit (bit 3) of | |
1545 | * SDHCI_HOST_CONTROL2 register. The reset state of that bit is 0 | |
1546 | * which indicates 3.3V IO voltage. So, when MMC core layer tries | |
1547 | * to set it to 3.3V before card detection happens, the | |
1548 | * IRQ doesn't get triggered as there is no state change in this bit. | |
1549 | * The driver already handles this case by changing the IO voltage | |
1550 | * level to high as part of controller power up sequence. Hence, check | |
1551 | * for host->pwr to handle a case where IO voltage high request is | |
1552 | * issued even before controller power up. | |
1553 | */ | |
1554 | if ((req_type & REQ_IO_HIGH) && !host->pwr) { | |
1555 | pr_debug("%s: do not wait for power IRQ that never comes, req_type: %d\n", | |
1556 | mmc_hostname(host->mmc), req_type); | |
1557 | return; | |
1558 | } | |
1559 | if ((req_type & msm_host->curr_pwr_state) || | |
1560 | (req_type & msm_host->curr_io_level)) | |
1561 | done = true; | |
1562 | /* | |
1563 | * This is needed here to handle cases where register writes will | |
1564 | * not change the current bus state or io level of the controller. | |
1565 | * In this case, no power irq will be triggerred and we should | |
1566 | * not wait. | |
1567 | */ | |
1568 | if (!done) { | |
1569 | if (!wait_event_timeout(msm_host->pwr_irq_wait, | |
1570 | msm_host->pwr_irq_flag, | |
1571 | msecs_to_jiffies(MSM_PWR_IRQ_TIMEOUT_MS))) | |
9ccfa817 AB |
1572 | dev_warn(&msm_host->pdev->dev, |
1573 | "%s: pwr_irq for req: (%d) timed out\n", | |
1574 | mmc_hostname(host->mmc), req_type); | |
c0309b38 VV |
1575 | } |
1576 | pr_debug("%s: %s: request %d done\n", mmc_hostname(host->mmc), | |
1577 | __func__, req_type); | |
1578 | } | |
1579 | ||
401b2d06 ST |
1580 | static void sdhci_msm_dump_pwr_ctrl_regs(struct sdhci_host *host) |
1581 | { | |
1582 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1583 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
bc99266b SL |
1584 | const struct sdhci_msm_offset *msm_offset = |
1585 | msm_host->offset; | |
401b2d06 ST |
1586 | |
1587 | pr_err("%s: PWRCTL_STATUS: 0x%08x | PWRCTL_MASK: 0x%08x | PWRCTL_CTL: 0x%08x\n", | |
bc99266b SL |
1588 | mmc_hostname(host->mmc), |
1589 | msm_host_readl(msm_host, host, msm_offset->core_pwrctl_status), | |
1590 | msm_host_readl(msm_host, host, msm_offset->core_pwrctl_mask), | |
1591 | msm_host_readl(msm_host, host, msm_offset->core_pwrctl_ctl)); | |
401b2d06 ST |
1592 | } |
1593 | ||
1594 | static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) | |
ad81d387 GD |
1595 | { |
1596 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1597 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
92a21738 | 1598 | struct mmc_host *mmc = host->mmc; |
ad81d387 | 1599 | u32 irq_status, irq_ack = 0; |
92a21738 | 1600 | int retry = 10, ret; |
ac06fba1 | 1601 | u32 pwr_state = 0, io_level = 0; |
5c132323 | 1602 | u32 config; |
bc99266b | 1603 | const struct sdhci_msm_offset *msm_offset = msm_host->offset; |
ad81d387 | 1604 | |
bc99266b SL |
1605 | irq_status = msm_host_readl(msm_host, host, |
1606 | msm_offset->core_pwrctl_status); | |
ad81d387 GD |
1607 | irq_status &= INT_MASK; |
1608 | ||
bc99266b SL |
1609 | msm_host_writel(msm_host, irq_status, host, |
1610 | msm_offset->core_pwrctl_clear); | |
ad81d387 | 1611 | |
401b2d06 ST |
1612 | /* |
1613 | * There is a rare HW scenario where the first clear pulse could be | |
1614 | * lost when actual reset and clear/read of status register is | |
1615 | * happening at a time. Hence, retry for at least 10 times to make | |
1616 | * sure status register is cleared. Otherwise, this will result in | |
1617 | * a spurious power IRQ resulting in system instability. | |
1618 | */ | |
bc99266b SL |
1619 | while (irq_status & msm_host_readl(msm_host, host, |
1620 | msm_offset->core_pwrctl_status)) { | |
401b2d06 ST |
1621 | if (retry == 0) { |
1622 | pr_err("%s: Timedout clearing (0x%x) pwrctl status register\n", | |
1623 | mmc_hostname(host->mmc), irq_status); | |
1624 | sdhci_msm_dump_pwr_ctrl_regs(host); | |
1625 | WARN_ON(1); | |
1626 | break; | |
1627 | } | |
bc99266b SL |
1628 | msm_host_writel(msm_host, irq_status, host, |
1629 | msm_offset->core_pwrctl_clear); | |
401b2d06 ST |
1630 | retry--; |
1631 | udelay(10); | |
1632 | } | |
1633 | ||
c0309b38 VV |
1634 | /* Handle BUS ON/OFF*/ |
1635 | if (irq_status & CORE_PWRCTL_BUS_ON) { | |
1636 | pwr_state = REQ_BUS_ON; | |
1637 | io_level = REQ_IO_HIGH; | |
c0309b38 VV |
1638 | } |
1639 | if (irq_status & CORE_PWRCTL_BUS_OFF) { | |
1640 | pwr_state = REQ_BUS_OFF; | |
1641 | io_level = REQ_IO_LOW; | |
c0309b38 | 1642 | } |
92a21738 VB |
1643 | |
1644 | if (pwr_state) { | |
1645 | ret = sdhci_msm_set_vmmc(mmc); | |
1646 | if (!ret) | |
1647 | ret = sdhci_msm_set_vqmmc(msm_host, mmc, | |
1648 | pwr_state & REQ_BUS_ON); | |
b5c833b7 VB |
1649 | if (!ret) |
1650 | ret = sdhci_msm_set_pincfg(msm_host, | |
1651 | pwr_state & REQ_BUS_ON); | |
92a21738 VB |
1652 | if (!ret) |
1653 | irq_ack |= CORE_PWRCTL_BUS_SUCCESS; | |
1654 | else | |
1655 | irq_ack |= CORE_PWRCTL_BUS_FAIL; | |
1656 | } | |
1657 | ||
c0309b38 | 1658 | /* Handle IO LOW/HIGH */ |
92a21738 | 1659 | if (irq_status & CORE_PWRCTL_IO_LOW) |
c0309b38 | 1660 | io_level = REQ_IO_LOW; |
92a21738 VB |
1661 | |
1662 | if (irq_status & CORE_PWRCTL_IO_HIGH) | |
c0309b38 | 1663 | io_level = REQ_IO_HIGH; |
92a21738 VB |
1664 | |
1665 | if (io_level) | |
c0309b38 | 1666 | irq_ack |= CORE_PWRCTL_IO_SUCCESS; |
92a21738 VB |
1667 | |
1668 | if (io_level && !IS_ERR(mmc->supply.vqmmc) && !pwr_state) { | |
1669 | ret = mmc_regulator_set_vqmmc(mmc, &mmc->ios); | |
1670 | if (ret < 0) { | |
1671 | dev_err(mmc_dev(mmc), "%s: IO_level setting failed(%d). signal_voltage: %d, vdd: %d irq_status: 0x%08x\n", | |
1672 | mmc_hostname(mmc), ret, | |
1673 | mmc->ios.signal_voltage, mmc->ios.vdd, | |
1674 | irq_status); | |
1675 | irq_ack |= CORE_PWRCTL_IO_FAIL; | |
1676 | } | |
c0309b38 | 1677 | } |
ad81d387 GD |
1678 | |
1679 | /* | |
1680 | * The driver has to acknowledge the interrupt, switch voltages and | |
1681 | * report back if it succeded or not to this register. The voltage | |
1682 | * switches are handled by the sdhci core, so just report success. | |
1683 | */ | |
bc99266b SL |
1684 | msm_host_writel(msm_host, irq_ack, host, |
1685 | msm_offset->core_pwrctl_ctl); | |
401b2d06 | 1686 | |
5c132323 VV |
1687 | /* |
1688 | * If we don't have info regarding the voltage levels supported by | |
1689 | * regulators, don't change the IO PAD PWR SWITCH. | |
1690 | */ | |
1691 | if (msm_host->caps_0 & CORE_VOLT_SUPPORT) { | |
1692 | u32 new_config; | |
1693 | /* | |
1694 | * We should unset IO PAD PWR switch only if the register write | |
1695 | * can set IO lines high and the regulator also switches to 3 V. | |
1696 | * Else, we should keep the IO PAD PWR switch set. | |
1697 | * This is applicable to certain targets where eMMC vccq supply | |
1698 | * is only 1.8V. In such targets, even during REQ_IO_HIGH, the | |
1699 | * IO PAD PWR switch must be kept set to reflect actual | |
1700 | * regulator voltage. This way, during initialization of | |
1701 | * controllers with only 1.8V, we will set the IO PAD bit | |
1702 | * without waiting for a REQ_IO_LOW. | |
1703 | */ | |
bc99266b SL |
1704 | config = readl_relaxed(host->ioaddr + |
1705 | msm_offset->core_vendor_spec); | |
5c132323 VV |
1706 | new_config = config; |
1707 | ||
1708 | if ((io_level & REQ_IO_HIGH) && | |
1709 | (msm_host->caps_0 & CORE_3_0V_SUPPORT)) | |
1710 | new_config &= ~CORE_IO_PAD_PWR_SWITCH; | |
1711 | else if ((io_level & REQ_IO_LOW) || | |
1712 | (msm_host->caps_0 & CORE_1_8V_SUPPORT)) | |
1713 | new_config |= CORE_IO_PAD_PWR_SWITCH; | |
1714 | ||
1715 | if (config ^ new_config) | |
bc99266b SL |
1716 | writel_relaxed(new_config, host->ioaddr + |
1717 | msm_offset->core_vendor_spec); | |
5c132323 VV |
1718 | } |
1719 | ||
c0309b38 VV |
1720 | if (pwr_state) |
1721 | msm_host->curr_pwr_state = pwr_state; | |
1722 | if (io_level) | |
1723 | msm_host->curr_io_level = io_level; | |
1724 | ||
92a21738 | 1725 | dev_dbg(mmc_dev(mmc), "%s: %s: Handled IRQ(%d), irq_status=0x%x, ack=0x%x\n", |
401b2d06 ST |
1726 | mmc_hostname(msm_host->mmc), __func__, irq, irq_status, |
1727 | irq_ack); | |
ad81d387 GD |
1728 | } |
1729 | ||
1730 | static irqreturn_t sdhci_msm_pwr_irq(int irq, void *data) | |
1731 | { | |
1732 | struct sdhci_host *host = (struct sdhci_host *)data; | |
c0309b38 VV |
1733 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
1734 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
ad81d387 | 1735 | |
401b2d06 | 1736 | sdhci_msm_handle_pwr_irq(host, irq); |
c0309b38 VV |
1737 | msm_host->pwr_irq_flag = 1; |
1738 | sdhci_msm_complete_pwr_irq_wait(msm_host); | |
1739 | ||
ad81d387 GD |
1740 | |
1741 | return IRQ_HANDLED; | |
1742 | } | |
1743 | ||
80031bde RH |
1744 | static unsigned int sdhci_msm_get_max_clock(struct sdhci_host *host) |
1745 | { | |
1746 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1747 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
e4bf91f6 | 1748 | struct clk *core_clk = msm_host->bulk_clks[0].clk; |
80031bde | 1749 | |
e4bf91f6 | 1750 | return clk_round_rate(core_clk, ULONG_MAX); |
80031bde RH |
1751 | } |
1752 | ||
1753 | static unsigned int sdhci_msm_get_min_clock(struct sdhci_host *host) | |
1754 | { | |
1755 | return SDHCI_MSM_MIN_CLOCK; | |
1756 | } | |
1757 | ||
abf4633a | 1758 | /* |
edc609fd RH |
1759 | * __sdhci_msm_set_clock - sdhci_msm clock control. |
1760 | * | |
1761 | * Description: | |
1762 | * MSM controller does not use internal divider and | |
1763 | * instead directly control the GCC clock as per | |
1764 | * HW recommendation. | |
1765 | **/ | |
30de038d | 1766 | static void __sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) |
edc609fd RH |
1767 | { |
1768 | u16 clk; | |
edc609fd RH |
1769 | |
1770 | sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); | |
1771 | ||
1772 | if (clock == 0) | |
1773 | return; | |
1774 | ||
1775 | /* | |
1776 | * MSM controller do not use clock divider. | |
1777 | * Thus read SDHCI_CLOCK_CONTROL and only enable | |
1778 | * clock with no divider value programmed. | |
1779 | */ | |
1780 | clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); | |
1781 | sdhci_enable_clk(host, clk); | |
1782 | } | |
1783 | ||
1784 | /* sdhci_msm_set_clock - Called with (host->lock) spinlock held. */ | |
1785 | static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock) | |
1786 | { | |
1787 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1788 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
edc609fd RH |
1789 | |
1790 | if (!clock) { | |
f16c8fd4 | 1791 | host->mmc->actual_clock = msm_host->clk_rate = 0; |
edc609fd RH |
1792 | goto out; |
1793 | } | |
1794 | ||
b54aaa8a | 1795 | sdhci_msm_hc_select_mode(host); |
edc609fd | 1796 | |
0fb8a3d4 | 1797 | msm_set_clock_rate_for_bus_mode(host, clock); |
edc609fd RH |
1798 | out: |
1799 | __sdhci_msm_set_clock(host, clock); | |
1800 | } | |
1801 | ||
c93767cf EB |
1802 | /*****************************************************************************\ |
1803 | * * | |
1804 | * Inline Crypto Engine (ICE) support * | |
1805 | * * | |
1806 | \*****************************************************************************/ | |
1807 | ||
1808 | #ifdef CONFIG_MMC_CRYPTO | |
1809 | ||
c93767cf EB |
1810 | static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, |
1811 | struct cqhci_host *cq_host) | |
1812 | { | |
1813 | struct mmc_host *mmc = msm_host->mmc; | |
1814 | struct device *dev = mmc_dev(mmc); | |
c7eed31e | 1815 | struct qcom_ice *ice; |
c93767cf EB |
1816 | |
1817 | if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS)) | |
1818 | return 0; | |
1819 | ||
c7eed31e AV |
1820 | ice = of_qcom_ice_get(dev); |
1821 | if (ice == ERR_PTR(-EOPNOTSUPP)) { | |
1822 | dev_warn(dev, "Disabling inline encryption support\n"); | |
1823 | ice = NULL; | |
c93767cf EB |
1824 | } |
1825 | ||
c7eed31e AV |
1826 | if (IS_ERR_OR_NULL(ice)) |
1827 | return PTR_ERR_OR_ZERO(ice); | |
c93767cf | 1828 | |
c7eed31e | 1829 | msm_host->ice = ice; |
c93767cf | 1830 | mmc->caps2 |= MMC_CAP2_CRYPTO; |
c93767cf | 1831 | |
c93767cf EB |
1832 | return 0; |
1833 | } | |
1834 | ||
c7eed31e | 1835 | static void sdhci_msm_ice_enable(struct sdhci_msm_host *msm_host) |
c93767cf | 1836 | { |
c7eed31e AV |
1837 | if (msm_host->mmc->caps2 & MMC_CAP2_CRYPTO) |
1838 | qcom_ice_enable(msm_host->ice); | |
c93767cf EB |
1839 | } |
1840 | ||
c7eed31e | 1841 | static __maybe_unused int sdhci_msm_ice_resume(struct sdhci_msm_host *msm_host) |
c93767cf | 1842 | { |
c7eed31e AV |
1843 | if (msm_host->mmc->caps2 & MMC_CAP2_CRYPTO) |
1844 | return qcom_ice_resume(msm_host->ice); | |
c93767cf | 1845 | |
c7eed31e | 1846 | return 0; |
c93767cf EB |
1847 | } |
1848 | ||
c7eed31e | 1849 | static __maybe_unused int sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host) |
c93767cf | 1850 | { |
c7eed31e AV |
1851 | if (msm_host->mmc->caps2 & MMC_CAP2_CRYPTO) |
1852 | return qcom_ice_suspend(msm_host->ice); | |
c93767cf | 1853 | |
c7eed31e | 1854 | return 0; |
c93767cf EB |
1855 | } |
1856 | ||
1857 | /* | |
1858 | * Program a key into a QC ICE keyslot, or evict a keyslot. QC ICE requires | |
1859 | * vendor-specific SCM calls for this; it doesn't support the standard way. | |
1860 | */ | |
1861 | static int sdhci_msm_program_key(struct cqhci_host *cq_host, | |
1862 | const union cqhci_crypto_cfg_entry *cfg, | |
1863 | int slot) | |
1864 | { | |
c7eed31e AV |
1865 | struct sdhci_host *host = mmc_priv(cq_host->mmc); |
1866 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1867 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
c93767cf | 1868 | union cqhci_crypto_cap_entry cap; |
c93767cf EB |
1869 | |
1870 | /* Only AES-256-XTS has been tested so far. */ | |
1871 | cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx]; | |
1872 | if (cap.algorithm_id != CQHCI_CRYPTO_ALG_AES_XTS || | |
c7eed31e | 1873 | cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256) |
c93767cf | 1874 | return -EINVAL; |
c93767cf | 1875 | |
c7eed31e AV |
1876 | if (cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE) |
1877 | return qcom_ice_program_key(msm_host->ice, | |
1878 | QCOM_ICE_CRYPTO_ALG_AES_XTS, | |
1879 | QCOM_ICE_CRYPTO_KEY_SIZE_256, | |
1880 | cfg->crypto_key, | |
1881 | cfg->data_unit_size, slot); | |
1882 | else | |
1883 | return qcom_ice_evict_key(msm_host->ice, slot); | |
c93767cf | 1884 | } |
c7eed31e | 1885 | |
c93767cf | 1886 | #else /* CONFIG_MMC_CRYPTO */ |
c93767cf EB |
1887 | |
1888 | static inline int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, | |
1889 | struct cqhci_host *cq_host) | |
1890 | { | |
1891 | return 0; | |
1892 | } | |
1893 | ||
1894 | static inline void sdhci_msm_ice_enable(struct sdhci_msm_host *msm_host) | |
1895 | { | |
1896 | } | |
1897 | ||
c7eed31e | 1898 | static inline __maybe_unused int |
c93767cf EB |
1899 | sdhci_msm_ice_resume(struct sdhci_msm_host *msm_host) |
1900 | { | |
1901 | return 0; | |
1902 | } | |
c7eed31e AV |
1903 | |
1904 | static inline __maybe_unused int | |
1905 | sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host) | |
1906 | { | |
1907 | return 0; | |
1908 | } | |
c93767cf EB |
1909 | #endif /* !CONFIG_MMC_CRYPTO */ |
1910 | ||
87a8df0d RH |
1911 | /*****************************************************************************\ |
1912 | * * | |
1913 | * MSM Command Queue Engine (CQE) * | |
1914 | * * | |
1915 | \*****************************************************************************/ | |
1916 | ||
1917 | static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask) | |
1918 | { | |
1919 | int cmd_error = 0; | |
1920 | int data_error = 0; | |
1921 | ||
1922 | if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error)) | |
1923 | return intmask; | |
1924 | ||
1925 | cqhci_irq(host->mmc, intmask, cmd_error, data_error); | |
1926 | return 0; | |
1927 | } | |
1928 | ||
c93767cf EB |
1929 | static void sdhci_msm_cqe_enable(struct mmc_host *mmc) |
1930 | { | |
1931 | struct sdhci_host *host = mmc_priv(mmc); | |
1932 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1933 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
1934 | ||
1935 | sdhci_cqe_enable(mmc); | |
1936 | sdhci_msm_ice_enable(msm_host); | |
1937 | } | |
1938 | ||
9051db38 | 1939 | static void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery) |
87a8df0d RH |
1940 | { |
1941 | struct sdhci_host *host = mmc_priv(mmc); | |
1942 | unsigned long flags; | |
1943 | u32 ctrl; | |
1944 | ||
1945 | /* | |
1946 | * When CQE is halted, the legacy SDHCI path operates only | |
1947 | * on 16-byte descriptors in 64bit mode. | |
1948 | */ | |
1949 | if (host->flags & SDHCI_USE_64_BIT_DMA) | |
1950 | host->desc_sz = 16; | |
1951 | ||
1952 | spin_lock_irqsave(&host->lock, flags); | |
1953 | ||
1954 | /* | |
1955 | * During CQE command transfers, command complete bit gets latched. | |
1956 | * So s/w should clear command complete interrupt status when CQE is | |
1957 | * either halted or disabled. Otherwise unexpected SDCHI legacy | |
1958 | * interrupt gets triggered when CQE is halted/disabled. | |
1959 | */ | |
1960 | ctrl = sdhci_readl(host, SDHCI_INT_ENABLE); | |
1961 | ctrl |= SDHCI_INT_RESPONSE; | |
1962 | sdhci_writel(host, ctrl, SDHCI_INT_ENABLE); | |
1963 | sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS); | |
1964 | ||
1965 | spin_unlock_irqrestore(&host->lock, flags); | |
1966 | ||
1967 | sdhci_cqe_disable(mmc, recovery); | |
1968 | } | |
1969 | ||
67b13f3e SSB |
1970 | static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) |
1971 | { | |
1972 | u32 count, start = 15; | |
1973 | ||
1974 | __sdhci_set_timeout(host, cmd); | |
1975 | count = sdhci_readb(host, SDHCI_TIMEOUT_CONTROL); | |
1976 | /* | |
1977 | * Update software timeout value if its value is less than hardware data | |
1978 | * timeout value. Qcom SoC hardware data timeout value was calculated | |
1979 | * using 4 * MCLK * 2^(count + 13). where MCLK = 1 / host->clock. | |
1980 | */ | |
1981 | if (cmd && cmd->data && host->clock > 400000 && | |
1982 | host->clock <= 50000000 && | |
1983 | ((1 << (count + start)) > (10 * host->clock))) | |
1984 | host->data_timeout = 22LL * NSEC_PER_SEC; | |
1985 | } | |
1986 | ||
87a8df0d | 1987 | static const struct cqhci_host_ops sdhci_msm_cqhci_ops = { |
c93767cf | 1988 | .enable = sdhci_msm_cqe_enable, |
87a8df0d | 1989 | .disable = sdhci_msm_cqe_disable, |
c93767cf EB |
1990 | #ifdef CONFIG_MMC_CRYPTO |
1991 | .program_key = sdhci_msm_program_key, | |
1992 | #endif | |
87a8df0d RH |
1993 | }; |
1994 | ||
1995 | static int sdhci_msm_cqe_add_host(struct sdhci_host *host, | |
1996 | struct platform_device *pdev) | |
1997 | { | |
1998 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
1999 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
2000 | struct cqhci_host *cq_host; | |
2001 | bool dma64; | |
2002 | u32 cqcfg; | |
2003 | int ret; | |
2004 | ||
2005 | /* | |
2006 | * When CQE is halted, SDHC operates only on 16byte ADMA descriptors. | |
2007 | * So ensure ADMA table is allocated for 16byte descriptors. | |
2008 | */ | |
2009 | if (host->caps & SDHCI_CAN_64BIT) | |
2010 | host->alloc_desc_sz = 16; | |
2011 | ||
2012 | ret = sdhci_setup_host(host); | |
2013 | if (ret) | |
2014 | return ret; | |
2015 | ||
2016 | cq_host = cqhci_pltfm_init(pdev); | |
2017 | if (IS_ERR(cq_host)) { | |
2018 | ret = PTR_ERR(cq_host); | |
2019 | dev_err(&pdev->dev, "cqhci-pltfm init: failed: %d\n", ret); | |
2020 | goto cleanup; | |
2021 | } | |
2022 | ||
2023 | msm_host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD; | |
2024 | cq_host->ops = &sdhci_msm_cqhci_ops; | |
2025 | ||
2026 | dma64 = host->flags & SDHCI_USE_64_BIT_DMA; | |
2027 | ||
c93767cf EB |
2028 | ret = sdhci_msm_ice_init(msm_host, cq_host); |
2029 | if (ret) | |
2030 | goto cleanup; | |
2031 | ||
87a8df0d RH |
2032 | ret = cqhci_init(cq_host, host->mmc, dma64); |
2033 | if (ret) { | |
2034 | dev_err(&pdev->dev, "%s: CQE init: failed (%d)\n", | |
2035 | mmc_hostname(host->mmc), ret); | |
2036 | goto cleanup; | |
2037 | } | |
2038 | ||
2039 | /* Disable cqe reset due to cqe enable signal */ | |
2040 | cqcfg = cqhci_readl(cq_host, CQHCI_VENDOR_CFG1); | |
2041 | cqcfg |= CQHCI_VENDOR_DIS_RST_ON_CQ_EN; | |
2042 | cqhci_writel(cq_host, cqcfg, CQHCI_VENDOR_CFG1); | |
2043 | ||
2044 | /* | |
2045 | * SDHC expects 12byte ADMA descriptors till CQE is enabled. | |
2046 | * So limit desc_sz to 12 so that the data commands that are sent | |
2047 | * during card initialization (before CQE gets enabled) would | |
2048 | * get executed without any issues. | |
2049 | */ | |
2050 | if (host->flags & SDHCI_USE_64_BIT_DMA) | |
2051 | host->desc_sz = 12; | |
2052 | ||
2053 | ret = __sdhci_add_host(host); | |
2054 | if (ret) | |
2055 | goto cleanup; | |
2056 | ||
2057 | dev_info(&pdev->dev, "%s: CQE init: success\n", | |
2058 | mmc_hostname(host->mmc)); | |
2059 | return ret; | |
2060 | ||
2061 | cleanup: | |
2062 | sdhci_cleanup_host(host); | |
2063 | return ret; | |
2064 | } | |
2065 | ||
c0309b38 VV |
2066 | /* |
2067 | * Platform specific register write functions. This is so that, if any | |
2068 | * register write needs to be followed up by platform specific actions, | |
2069 | * they can be added here. These functions can go to sleep when writes | |
2070 | * to certain registers are done. | |
2071 | * These functions are relying on sdhci_set_ios not using spinlock. | |
2072 | */ | |
2073 | static int __sdhci_msm_check_write(struct sdhci_host *host, u16 val, int reg) | |
2074 | { | |
2075 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
2076 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
2077 | u32 req_type = 0; | |
2078 | ||
2079 | switch (reg) { | |
2080 | case SDHCI_HOST_CONTROL2: | |
2081 | req_type = (val & SDHCI_CTRL_VDD_180) ? REQ_IO_LOW : | |
2082 | REQ_IO_HIGH; | |
2083 | break; | |
2084 | case SDHCI_SOFTWARE_RESET: | |
2085 | if (host->pwr && (val & SDHCI_RESET_ALL)) | |
2086 | req_type = REQ_BUS_OFF; | |
2087 | break; | |
2088 | case SDHCI_POWER_CONTROL: | |
2089 | req_type = !val ? REQ_BUS_OFF : REQ_BUS_ON; | |
2090 | break; | |
a89e7bcb LP |
2091 | case SDHCI_TRANSFER_MODE: |
2092 | msm_host->transfer_mode = val; | |
2093 | break; | |
2094 | case SDHCI_COMMAND: | |
2095 | if (!msm_host->use_cdr) | |
2096 | break; | |
2097 | if ((msm_host->transfer_mode & SDHCI_TRNS_READ) && | |
b98e7e8d | 2098 | !mmc_op_tuning(SDHCI_GET_CMD(val))) |
a89e7bcb LP |
2099 | sdhci_msm_set_cdr(host, true); |
2100 | else | |
2101 | sdhci_msm_set_cdr(host, false); | |
2102 | break; | |
c0309b38 VV |
2103 | } |
2104 | ||
2105 | if (req_type) { | |
2106 | msm_host->pwr_irq_flag = 0; | |
2107 | /* | |
2108 | * Since this register write may trigger a power irq, ensure | |
2109 | * all previous register writes are complete by this point. | |
2110 | */ | |
2111 | mb(); | |
2112 | } | |
2113 | return req_type; | |
2114 | } | |
2115 | ||
2116 | /* This function may sleep*/ | |
2117 | static void sdhci_msm_writew(struct sdhci_host *host, u16 val, int reg) | |
2118 | { | |
2119 | u32 req_type = 0; | |
2120 | ||
2121 | req_type = __sdhci_msm_check_write(host, val, reg); | |
2122 | writew_relaxed(val, host->ioaddr + reg); | |
2123 | ||
2124 | if (req_type) | |
2125 | sdhci_msm_check_power_status(host, req_type); | |
2126 | } | |
2127 | ||
2128 | /* This function may sleep*/ | |
2129 | static void sdhci_msm_writeb(struct sdhci_host *host, u8 val, int reg) | |
2130 | { | |
2131 | u32 req_type = 0; | |
2132 | ||
2133 | req_type = __sdhci_msm_check_write(host, val, reg); | |
2134 | ||
2135 | writeb_relaxed(val, host->ioaddr + reg); | |
2136 | ||
2137 | if (req_type) | |
2138 | sdhci_msm_check_power_status(host, req_type); | |
2139 | } | |
2140 | ||
ac06fba1 VV |
2141 | static void sdhci_msm_set_regulator_caps(struct sdhci_msm_host *msm_host) |
2142 | { | |
2143 | struct mmc_host *mmc = msm_host->mmc; | |
2144 | struct regulator *supply = mmc->supply.vqmmc; | |
5c132323 VV |
2145 | u32 caps = 0, config; |
2146 | struct sdhci_host *host = mmc_priv(mmc); | |
bc99266b | 2147 | const struct sdhci_msm_offset *msm_offset = msm_host->offset; |
ac06fba1 VV |
2148 | |
2149 | if (!IS_ERR(mmc->supply.vqmmc)) { | |
2150 | if (regulator_is_supported_voltage(supply, 1700000, 1950000)) | |
2151 | caps |= CORE_1_8V_SUPPORT; | |
2152 | if (regulator_is_supported_voltage(supply, 2700000, 3600000)) | |
2153 | caps |= CORE_3_0V_SUPPORT; | |
2154 | ||
2155 | if (!caps) | |
2156 | pr_warn("%s: 1.8/3V not supported for vqmmc\n", | |
2157 | mmc_hostname(mmc)); | |
2158 | } | |
2159 | ||
5c132323 VV |
2160 | if (caps) { |
2161 | /* | |
2162 | * Set the PAD_PWR_SWITCH_EN bit so that the PAD_PWR_SWITCH | |
2163 | * bit can be used as required later on. | |
2164 | */ | |
2165 | u32 io_level = msm_host->curr_io_level; | |
2166 | ||
bc99266b SL |
2167 | config = readl_relaxed(host->ioaddr + |
2168 | msm_offset->core_vendor_spec); | |
5c132323 VV |
2169 | config |= CORE_IO_PAD_PWR_SWITCH_EN; |
2170 | ||
2171 | if ((io_level & REQ_IO_HIGH) && (caps & CORE_3_0V_SUPPORT)) | |
2172 | config &= ~CORE_IO_PAD_PWR_SWITCH; | |
2173 | else if ((io_level & REQ_IO_LOW) || (caps & CORE_1_8V_SUPPORT)) | |
2174 | config |= CORE_IO_PAD_PWR_SWITCH; | |
2175 | ||
bc99266b SL |
2176 | writel_relaxed(config, |
2177 | host->ioaddr + msm_offset->core_vendor_spec); | |
5c132323 | 2178 | } |
ac06fba1 VV |
2179 | msm_host->caps_0 |= caps; |
2180 | pr_debug("%s: supported caps: 0x%08x\n", mmc_hostname(mmc), caps); | |
2181 | } | |
2182 | ||
92a21738 VB |
2183 | static int sdhci_msm_register_vreg(struct sdhci_msm_host *msm_host) |
2184 | { | |
2185 | int ret; | |
2186 | ||
2187 | ret = mmc_regulator_get_supply(msm_host->mmc); | |
2188 | if (ret) | |
2189 | return ret; | |
2190 | ||
2191 | sdhci_msm_set_regulator_caps(msm_host); | |
2192 | ||
2193 | return 0; | |
2194 | } | |
2195 | ||
2196 | static int sdhci_msm_start_signal_voltage_switch(struct mmc_host *mmc, | |
2197 | struct mmc_ios *ios) | |
2198 | { | |
2199 | struct sdhci_host *host = mmc_priv(mmc); | |
2200 | u16 ctrl, status; | |
2201 | ||
2202 | /* | |
2203 | * Signal Voltage Switching is only applicable for Host Controllers | |
2204 | * v3.00 and above. | |
2205 | */ | |
2206 | if (host->version < SDHCI_SPEC_300) | |
2207 | return 0; | |
2208 | ||
2209 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | |
2210 | ||
2211 | switch (ios->signal_voltage) { | |
2212 | case MMC_SIGNAL_VOLTAGE_330: | |
2213 | if (!(host->flags & SDHCI_SIGNALING_330)) | |
2214 | return -EINVAL; | |
2215 | ||
2216 | /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ | |
2217 | ctrl &= ~SDHCI_CTRL_VDD_180; | |
2218 | break; | |
2219 | case MMC_SIGNAL_VOLTAGE_180: | |
2220 | if (!(host->flags & SDHCI_SIGNALING_180)) | |
2221 | return -EINVAL; | |
2222 | ||
2223 | /* Enable 1.8V Signal Enable in the Host Control2 register */ | |
2224 | ctrl |= SDHCI_CTRL_VDD_180; | |
2225 | break; | |
2226 | ||
2227 | default: | |
2228 | return -EINVAL; | |
2229 | } | |
2230 | ||
2231 | sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); | |
2232 | ||
2233 | /* Wait for 5ms */ | |
2234 | usleep_range(5000, 5500); | |
2235 | ||
2236 | /* regulator output should be stable within 5 ms */ | |
2237 | status = ctrl & SDHCI_CTRL_VDD_180; | |
2238 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | |
2239 | if ((ctrl & SDHCI_CTRL_VDD_180) == status) | |
2240 | return 0; | |
2241 | ||
2242 | dev_warn(mmc_dev(mmc), "%s: Regulator output did not became stable\n", | |
2243 | mmc_hostname(mmc)); | |
2244 | ||
2245 | return -EAGAIN; | |
2246 | } | |
2247 | ||
16d18d89 SG |
2248 | #define DRIVER_NAME "sdhci_msm" |
2249 | #define SDHCI_MSM_DUMP(f, x...) \ | |
2250 | pr_err("%s: " DRIVER_NAME ": " f, mmc_hostname(host->mmc), ## x) | |
2251 | ||
53e888d1 | 2252 | static void sdhci_msm_dump_vendor_regs(struct sdhci_host *host) |
16d18d89 SG |
2253 | { |
2254 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
2255 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
2256 | const struct sdhci_msm_offset *msm_offset = msm_host->offset; | |
2257 | ||
2258 | SDHCI_MSM_DUMP("----------- VENDOR REGISTER DUMP -----------\n"); | |
2259 | ||
2260 | SDHCI_MSM_DUMP( | |
2261 | "DLL sts: 0x%08x | DLL cfg: 0x%08x | DLL cfg2: 0x%08x\n", | |
2262 | readl_relaxed(host->ioaddr + msm_offset->core_dll_status), | |
2263 | readl_relaxed(host->ioaddr + msm_offset->core_dll_config), | |
2264 | readl_relaxed(host->ioaddr + msm_offset->core_dll_config_2)); | |
2265 | SDHCI_MSM_DUMP( | |
2266 | "DLL cfg3: 0x%08x | DLL usr ctl: 0x%08x | DDR cfg: 0x%08x\n", | |
2267 | readl_relaxed(host->ioaddr + msm_offset->core_dll_config_3), | |
2268 | readl_relaxed(host->ioaddr + msm_offset->core_dll_usr_ctl), | |
2269 | readl_relaxed(host->ioaddr + msm_offset->core_ddr_config)); | |
2270 | SDHCI_MSM_DUMP( | |
2271 | "Vndr func: 0x%08x | Vndr func2 : 0x%08x Vndr func3: 0x%08x\n", | |
2272 | readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec), | |
2273 | readl_relaxed(host->ioaddr + | |
2274 | msm_offset->core_vendor_spec_func2), | |
2275 | readl_relaxed(host->ioaddr + msm_offset->core_vendor_spec3)); | |
2276 | } | |
2277 | ||
6ed4bb43 VV |
2278 | static const struct sdhci_msm_variant_ops mci_var_ops = { |
2279 | .msm_readl_relaxed = sdhci_msm_mci_variant_readl_relaxed, | |
2280 | .msm_writel_relaxed = sdhci_msm_mci_variant_writel_relaxed, | |
2281 | }; | |
2282 | ||
2283 | static const struct sdhci_msm_variant_ops v5_var_ops = { | |
2284 | .msm_readl_relaxed = sdhci_msm_v5_variant_readl_relaxed, | |
2285 | .msm_writel_relaxed = sdhci_msm_v5_variant_writel_relaxed, | |
2286 | }; | |
2287 | ||
2288 | static const struct sdhci_msm_variant_info sdhci_msm_mci_var = { | |
6ed4bb43 VV |
2289 | .var_ops = &mci_var_ops, |
2290 | .offset = &sdhci_msm_mci_offset, | |
2291 | }; | |
2292 | ||
2293 | static const struct sdhci_msm_variant_info sdhci_msm_v5_var = { | |
2294 | .mci_removed = true, | |
2295 | .var_ops = &v5_var_ops, | |
2296 | .offset = &sdhci_msm_v5_offset, | |
2297 | }; | |
2298 | ||
21f1e2d4 VB |
2299 | static const struct sdhci_msm_variant_info sdm845_sdhci_var = { |
2300 | .mci_removed = true, | |
2301 | .restore_dll_config = true, | |
2302 | .var_ops = &v5_var_ops, | |
2303 | .offset = &sdhci_msm_v5_offset, | |
2304 | }; | |
2305 | ||
0eb0d9f4 | 2306 | static const struct of_device_id sdhci_msm_dt_match[] = { |
466614a9 | 2307 | /* |
b05cd716 KK |
2308 | * Do not add new variants to the driver which are compatible with |
2309 | * generic ones, unless they need customization. | |
466614a9 | 2310 | */ |
b05cd716 KK |
2311 | {.compatible = "qcom,sdhci-msm-v4", .data = &sdhci_msm_mci_var}, |
2312 | {.compatible = "qcom,sdhci-msm-v5", .data = &sdhci_msm_v5_var}, | |
4de95950 | 2313 | {.compatible = "qcom,sdm670-sdhci", .data = &sdm845_sdhci_var}, |
21f1e2d4 | 2314 | {.compatible = "qcom,sdm845-sdhci", .data = &sdm845_sdhci_var}, |
4dac686b | 2315 | {.compatible = "qcom,sc7180-sdhci", .data = &sdm845_sdhci_var}, |
0eb0d9f4 GD |
2316 | {}, |
2317 | }; | |
2318 | ||
2319 | MODULE_DEVICE_TABLE(of, sdhci_msm_dt_match); | |
2320 | ||
a50396a4 | 2321 | static const struct sdhci_ops sdhci_msm_ops = { |
08b863bb | 2322 | .reset = sdhci_and_cqhci_reset, |
edc609fd | 2323 | .set_clock = sdhci_msm_set_clock, |
80031bde RH |
2324 | .get_min_clock = sdhci_msm_get_min_clock, |
2325 | .get_max_clock = sdhci_msm_get_max_clock, | |
ed1761d7 | 2326 | .set_bus_width = sdhci_set_bus_width, |
ee320674 | 2327 | .set_uhs_signaling = sdhci_msm_set_uhs_signaling, |
c0309b38 VV |
2328 | .write_w = sdhci_msm_writew, |
2329 | .write_b = sdhci_msm_writeb, | |
87a8df0d | 2330 | .irq = sdhci_msm_cqe_irq, |
16d18d89 | 2331 | .dump_vendor_regs = sdhci_msm_dump_vendor_regs, |
92a21738 | 2332 | .set_power = sdhci_set_power_noreg, |
67b13f3e | 2333 | .set_timeout = sdhci_msm_set_timeout, |
0eb0d9f4 GD |
2334 | }; |
2335 | ||
a50396a4 JZ |
2336 | static const struct sdhci_pltfm_data sdhci_msm_pdata = { |
2337 | .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | | |
a0e31428 | 2338 | SDHCI_QUIRK_SINGLE_POWER_WRITE | |
d863cb03 VB |
2339 | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | |
2340 | SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, | |
2341 | ||
a0e31428 | 2342 | .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, |
a50396a4 JZ |
2343 | .ops = &sdhci_msm_ops, |
2344 | }; | |
2345 | ||
1dfbe3ff SG |
2346 | static inline void sdhci_msm_get_of_property(struct platform_device *pdev, |
2347 | struct sdhci_host *host) | |
2348 | { | |
2349 | struct device_node *node = pdev->dev.of_node; | |
2350 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
2351 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
2352 | ||
2353 | if (of_property_read_u32(node, "qcom,ddr-config", | |
2354 | &msm_host->ddr_config)) | |
2355 | msm_host->ddr_config = DDR_CONFIG_POR_VAL; | |
03591160 SG |
2356 | |
2357 | of_property_read_u32(node, "qcom,dll-config", &msm_host->dll_config); | |
e6f9e590 SG |
2358 | |
2359 | if (of_device_is_compatible(node, "qcom,msm8916-sdhci")) | |
2360 | host->quirks2 |= SDHCI_QUIRK2_BROKEN_64_BIT_DMA; | |
1dfbe3ff SG |
2361 | } |
2362 | ||
3e5a8e84 SSB |
2363 | static int sdhci_msm_gcc_reset(struct device *dev, struct sdhci_host *host) |
2364 | { | |
2365 | struct reset_control *reset; | |
2366 | int ret = 0; | |
2367 | ||
2368 | reset = reset_control_get_optional_exclusive(dev, NULL); | |
2369 | if (IS_ERR(reset)) | |
2370 | return dev_err_probe(dev, PTR_ERR(reset), | |
2371 | "unable to acquire core_reset\n"); | |
2372 | ||
2373 | if (!reset) | |
2374 | return ret; | |
2375 | ||
2376 | ret = reset_control_assert(reset); | |
2377 | if (ret) { | |
2378 | reset_control_put(reset); | |
2379 | return dev_err_probe(dev, ret, "core_reset assert failed\n"); | |
2380 | } | |
2381 | ||
2382 | /* | |
2383 | * The hardware requirement for delay between assert/deassert | |
2384 | * is at least 3-4 sleep clock (32.7KHz) cycles, which comes to | |
2385 | * ~125us (4/32768). To be on the safe side add 200us delay. | |
2386 | */ | |
2387 | usleep_range(200, 210); | |
2388 | ||
2389 | ret = reset_control_deassert(reset); | |
2390 | if (ret) { | |
2391 | reset_control_put(reset); | |
2392 | return dev_err_probe(dev, ret, "core_reset deassert failed\n"); | |
2393 | } | |
2394 | ||
2395 | usleep_range(200, 210); | |
2396 | reset_control_put(reset); | |
2397 | ||
2398 | return ret; | |
2399 | } | |
1dfbe3ff | 2400 | |
0eb0d9f4 GD |
2401 | static int sdhci_msm_probe(struct platform_device *pdev) |
2402 | { | |
2403 | struct sdhci_host *host; | |
2404 | struct sdhci_pltfm_host *pltfm_host; | |
2405 | struct sdhci_msm_host *msm_host; | |
e4bf91f6 | 2406 | struct clk *clk; |
0eb0d9f4 | 2407 | int ret; |
3a3ad3e9 | 2408 | u16 host_version, core_minor; |
29301f40 | 2409 | u32 core_version, config; |
3a3ad3e9 | 2410 | u8 core_major; |
bc99266b SL |
2411 | const struct sdhci_msm_offset *msm_offset; |
2412 | const struct sdhci_msm_variant_info *var_info; | |
87a8df0d | 2413 | struct device_node *node = pdev->dev.of_node; |
0eb0d9f4 | 2414 | |
6f699531 | 2415 | host = sdhci_pltfm_init(pdev, &sdhci_msm_pdata, sizeof(*msm_host)); |
0eb0d9f4 GD |
2416 | if (IS_ERR(host)) |
2417 | return PTR_ERR(host); | |
2418 | ||
2a641e53 | 2419 | host->sdma_boundary = 0; |
0eb0d9f4 | 2420 | pltfm_host = sdhci_priv(host); |
6f699531 | 2421 | msm_host = sdhci_pltfm_priv(pltfm_host); |
0eb0d9f4 GD |
2422 | msm_host->mmc = host->mmc; |
2423 | msm_host->pdev = pdev; | |
2424 | ||
2425 | ret = mmc_of_parse(host->mmc); | |
2426 | if (ret) | |
2427 | goto pltfm_free; | |
2428 | ||
bc99266b SL |
2429 | /* |
2430 | * Based on the compatible string, load the required msm host info from | |
2431 | * the data associated with the version info. | |
2432 | */ | |
2433 | var_info = of_device_get_match_data(&pdev->dev); | |
2434 | ||
2435 | msm_host->mci_removed = var_info->mci_removed; | |
21f1e2d4 | 2436 | msm_host->restore_dll_config = var_info->restore_dll_config; |
bc99266b SL |
2437 | msm_host->var_ops = var_info->var_ops; |
2438 | msm_host->offset = var_info->offset; | |
2439 | ||
2440 | msm_offset = msm_host->offset; | |
2441 | ||
0eb0d9f4 | 2442 | sdhci_get_of_property(pdev); |
1dfbe3ff | 2443 | sdhci_msm_get_of_property(pdev, host); |
0eb0d9f4 | 2444 | |
abf270e5 RH |
2445 | msm_host->saved_tuning_phase = INVALID_TUNING_PHASE; |
2446 | ||
3e5a8e84 SSB |
2447 | ret = sdhci_msm_gcc_reset(&pdev->dev, host); |
2448 | if (ret) | |
2449 | goto pltfm_free; | |
2450 | ||
0eb0d9f4 GD |
2451 | /* Setup SDCC bus voter clock. */ |
2452 | msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus"); | |
2453 | if (!IS_ERR(msm_host->bus_clk)) { | |
2454 | /* Vote for max. clk rate for max. performance */ | |
2455 | ret = clk_set_rate(msm_host->bus_clk, INT_MAX); | |
2456 | if (ret) | |
2457 | goto pltfm_free; | |
2458 | ret = clk_prepare_enable(msm_host->bus_clk); | |
2459 | if (ret) | |
2460 | goto pltfm_free; | |
2461 | } | |
2462 | ||
2463 | /* Setup main peripheral bus clock */ | |
e4bf91f6 BA |
2464 | clk = devm_clk_get(&pdev->dev, "iface"); |
2465 | if (IS_ERR(clk)) { | |
2466 | ret = PTR_ERR(clk); | |
2801b95e | 2467 | dev_err(&pdev->dev, "Peripheral clk setup failed (%d)\n", ret); |
0eb0d9f4 GD |
2468 | goto bus_clk_disable; |
2469 | } | |
e4bf91f6 | 2470 | msm_host->bulk_clks[1].clk = clk; |
0eb0d9f4 GD |
2471 | |
2472 | /* Setup SDC MMC clock */ | |
e4bf91f6 BA |
2473 | clk = devm_clk_get(&pdev->dev, "core"); |
2474 | if (IS_ERR(clk)) { | |
2475 | ret = PTR_ERR(clk); | |
0eb0d9f4 | 2476 | dev_err(&pdev->dev, "SDC MMC clk setup failed (%d)\n", ret); |
e4bf91f6 | 2477 | goto bus_clk_disable; |
0eb0d9f4 | 2478 | } |
e4bf91f6 BA |
2479 | msm_host->bulk_clks[0].clk = clk; |
2480 | ||
b4fc8278 P |
2481 | /* Check for optional interconnect paths */ |
2482 | ret = dev_pm_opp_of_find_icc_paths(&pdev->dev, NULL); | |
2483 | if (ret) | |
2484 | goto bus_clk_disable; | |
2485 | ||
411281d2 YL |
2486 | ret = devm_pm_opp_set_clkname(&pdev->dev, "core"); |
2487 | if (ret) | |
0472f8d3 | 2488 | goto bus_clk_disable; |
0472f8d3 RN |
2489 | |
2490 | /* OPP table is optional */ | |
411281d2 | 2491 | ret = devm_pm_opp_of_add_table(&pdev->dev); |
91ca244b | 2492 | if (ret && ret != -ENODEV) { |
c2b613d0 | 2493 | dev_err(&pdev->dev, "Invalid OPP table in Device tree\n"); |
411281d2 | 2494 | goto bus_clk_disable; |
c2b613d0 | 2495 | } |
0472f8d3 | 2496 | |
e4bf91f6 | 2497 | /* Vote for maximum clock rate for maximum performance */ |
0472f8d3 | 2498 | ret = dev_pm_opp_set_rate(&pdev->dev, INT_MAX); |
e4bf91f6 BA |
2499 | if (ret) |
2500 | dev_warn(&pdev->dev, "core clock boost failed\n"); | |
2501 | ||
4946b3af BA |
2502 | clk = devm_clk_get(&pdev->dev, "cal"); |
2503 | if (IS_ERR(clk)) | |
2504 | clk = NULL; | |
2505 | msm_host->bulk_clks[2].clk = clk; | |
2506 | ||
2507 | clk = devm_clk_get(&pdev->dev, "sleep"); | |
2508 | if (IS_ERR(clk)) | |
2509 | clk = NULL; | |
2510 | msm_host->bulk_clks[3].clk = clk; | |
2511 | ||
e4bf91f6 BA |
2512 | ret = clk_bulk_prepare_enable(ARRAY_SIZE(msm_host->bulk_clks), |
2513 | msm_host->bulk_clks); | |
2514 | if (ret) | |
411281d2 | 2515 | goto bus_clk_disable; |
0eb0d9f4 | 2516 | |
83736352 VG |
2517 | /* |
2518 | * xo clock is needed for FLL feature of cm_dll. | |
2519 | * In case if xo clock is not mentioned in DT, warn and proceed. | |
2520 | */ | |
2521 | msm_host->xo_clk = devm_clk_get(&pdev->dev, "xo"); | |
2522 | if (IS_ERR(msm_host->xo_clk)) { | |
2523 | ret = PTR_ERR(msm_host->xo_clk); | |
2524 | dev_warn(&pdev->dev, "TCXO clk not present (%d)\n", ret); | |
2525 | } | |
2526 | ||
bc99266b | 2527 | if (!msm_host->mci_removed) { |
cb064b50 | 2528 | msm_host->core_mem = devm_platform_ioremap_resource(pdev, 1); |
bc99266b | 2529 | if (IS_ERR(msm_host->core_mem)) { |
bc99266b SL |
2530 | ret = PTR_ERR(msm_host->core_mem); |
2531 | goto clk_disable; | |
2532 | } | |
0eb0d9f4 GD |
2533 | } |
2534 | ||
5574ddcc VG |
2535 | /* Reset the vendor spec register to power on reset state */ |
2536 | writel_relaxed(CORE_VENDOR_SPEC_POR_VAL, | |
bc99266b SL |
2537 | host->ioaddr + msm_offset->core_vendor_spec); |
2538 | ||
2539 | if (!msm_host->mci_removed) { | |
2540 | /* Set HC_MODE_EN bit in HC_MODE register */ | |
2541 | msm_host_writel(msm_host, HC_MODE_EN, host, | |
2542 | msm_offset->core_hc_mode); | |
2543 | config = msm_host_readl(msm_host, host, | |
2544 | msm_offset->core_hc_mode); | |
2545 | config |= FF_CLK_SW_RST_DIS; | |
2546 | msm_host_writel(msm_host, config, host, | |
2547 | msm_offset->core_hc_mode); | |
2548 | } | |
ff06ce41 | 2549 | |
0eb0d9f4 GD |
2550 | host_version = readw_relaxed((host->ioaddr + SDHCI_HOST_VERSION)); |
2551 | dev_dbg(&pdev->dev, "Host Version: 0x%x Vendor Version 0x%x\n", | |
2552 | host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >> | |
2553 | SDHCI_VENDOR_VER_SHIFT)); | |
2554 | ||
bc99266b SL |
2555 | core_version = msm_host_readl(msm_host, host, |
2556 | msm_offset->core_mci_version); | |
3a3ad3e9 GD |
2557 | core_major = (core_version & CORE_VERSION_MAJOR_MASK) >> |
2558 | CORE_VERSION_MAJOR_SHIFT; | |
2559 | core_minor = core_version & CORE_VERSION_MINOR_MASK; | |
2560 | dev_dbg(&pdev->dev, "MCI Version: 0x%08x, major: 0x%04x, minor: 0x%02x\n", | |
2561 | core_version, core_major, core_minor); | |
2562 | ||
83736352 VG |
2563 | if (core_major == 1 && core_minor >= 0x42) |
2564 | msm_host->use_14lpp_dll_reset = true; | |
2565 | ||
02e4293d RH |
2566 | /* |
2567 | * SDCC 5 controller with major version 1, minor version 0x34 and later | |
2568 | * with HS 400 mode support will use CM DLL instead of CDC LP 533 DLL. | |
2569 | */ | |
2570 | if (core_major == 1 && core_minor < 0x34) | |
2571 | msm_host->use_cdclp533 = true; | |
2572 | ||
3a3ad3e9 GD |
2573 | /* |
2574 | * Support for some capabilities is not advertised by newer | |
2575 | * controller versions and must be explicitly enabled. | |
2576 | */ | |
2577 | if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12) { | |
29301f40 RH |
2578 | config = readl_relaxed(host->ioaddr + SDHCI_CAPABILITIES); |
2579 | config |= SDHCI_CAN_VDD_300 | SDHCI_CAN_DO_8BIT; | |
2580 | writel_relaxed(config, host->ioaddr + | |
bc99266b | 2581 | msm_offset->core_vendor_spec_capabilities0); |
3a3ad3e9 GD |
2582 | } |
2583 | ||
fa56ac97 VB |
2584 | if (core_major == 1 && core_minor >= 0x49) |
2585 | msm_host->updated_ddr_cfg = true; | |
2586 | ||
8ffbfe43 DB |
2587 | if (core_major == 1 && core_minor >= 0x71) |
2588 | msm_host->uses_tassadar_dll = true; | |
2589 | ||
92a21738 VB |
2590 | ret = sdhci_msm_register_vreg(msm_host); |
2591 | if (ret) | |
2592 | goto clk_disable; | |
2593 | ||
c7ccee22 SJ |
2594 | /* |
2595 | * Power on reset state may trigger power irq if previous status of | |
2596 | * PWRCTL was either BUS_ON or IO_HIGH_V. So before enabling pwr irq | |
2597 | * interrupt in GIC, any pending power irq interrupt should be | |
2598 | * acknowledged. Otherwise power irq interrupt handler would be | |
2599 | * fired prematurely. | |
2600 | */ | |
401b2d06 | 2601 | sdhci_msm_handle_pwr_irq(host, 0); |
c7ccee22 SJ |
2602 | |
2603 | /* | |
2604 | * Ensure that above writes are propogated before interrupt enablement | |
2605 | * in GIC. | |
2606 | */ | |
2607 | mb(); | |
2608 | ||
ad81d387 GD |
2609 | /* Setup IRQ for handling power/voltage tasks with PMIC */ |
2610 | msm_host->pwr_irq = platform_get_irq_byname(pdev, "pwr_irq"); | |
2611 | if (msm_host->pwr_irq < 0) { | |
d1f63f0c | 2612 | ret = msm_host->pwr_irq; |
ad81d387 GD |
2613 | goto clk_disable; |
2614 | } | |
2615 | ||
c0309b38 | 2616 | sdhci_msm_init_pwr_irq_wait(msm_host); |
c7ccee22 | 2617 | /* Enable pwr irq interrupts */ |
bc99266b SL |
2618 | msm_host_writel(msm_host, INT_MASK, host, |
2619 | msm_offset->core_pwrctl_mask); | |
c7ccee22 | 2620 | |
ad81d387 GD |
2621 | ret = devm_request_threaded_irq(&pdev->dev, msm_host->pwr_irq, NULL, |
2622 | sdhci_msm_pwr_irq, IRQF_ONESHOT, | |
2623 | dev_name(&pdev->dev), host); | |
2624 | if (ret) { | |
2625 | dev_err(&pdev->dev, "Request IRQ failed (%d)\n", ret); | |
2626 | goto clk_disable; | |
2627 | } | |
2628 | ||
9d8cb586 VB |
2629 | msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; |
2630 | ||
ed78a03d ST |
2631 | /* Set the timeout value to max possible */ |
2632 | host->max_timeout_count = 0xF; | |
2633 | ||
67e6db11 PG |
2634 | pm_runtime_get_noresume(&pdev->dev); |
2635 | pm_runtime_set_active(&pdev->dev); | |
2636 | pm_runtime_enable(&pdev->dev); | |
2637 | pm_runtime_set_autosuspend_delay(&pdev->dev, | |
2638 | MSM_MMC_AUTOSUSPEND_DELAY_MS); | |
2639 | pm_runtime_use_autosuspend(&pdev->dev); | |
2640 | ||
92a21738 VB |
2641 | host->mmc_host_ops.start_signal_voltage_switch = |
2642 | sdhci_msm_start_signal_voltage_switch; | |
4436c535 | 2643 | host->mmc_host_ops.execute_tuning = sdhci_msm_execute_tuning; |
87a8df0d RH |
2644 | if (of_property_read_bool(node, "supports-cqe")) |
2645 | ret = sdhci_msm_cqe_add_host(host, pdev); | |
2646 | else | |
2647 | ret = sdhci_add_host(host); | |
0eb0d9f4 | 2648 | if (ret) |
67e6db11 PG |
2649 | goto pm_runtime_disable; |
2650 | ||
2651 | pm_runtime_mark_last_busy(&pdev->dev); | |
2652 | pm_runtime_put_autosuspend(&pdev->dev); | |
0eb0d9f4 GD |
2653 | |
2654 | return 0; | |
2655 | ||
67e6db11 PG |
2656 | pm_runtime_disable: |
2657 | pm_runtime_disable(&pdev->dev); | |
2658 | pm_runtime_set_suspended(&pdev->dev); | |
2659 | pm_runtime_put_noidle(&pdev->dev); | |
0eb0d9f4 | 2660 | clk_disable: |
e4bf91f6 BA |
2661 | clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks), |
2662 | msm_host->bulk_clks); | |
0eb0d9f4 GD |
2663 | bus_clk_disable: |
2664 | if (!IS_ERR(msm_host->bus_clk)) | |
2665 | clk_disable_unprepare(msm_host->bus_clk); | |
2666 | pltfm_free: | |
2667 | sdhci_pltfm_free(pdev); | |
2668 | return ret; | |
2669 | } | |
2670 | ||
a7dde463 | 2671 | static void sdhci_msm_remove(struct platform_device *pdev) |
0eb0d9f4 GD |
2672 | { |
2673 | struct sdhci_host *host = platform_get_drvdata(pdev); | |
2674 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
6f699531 | 2675 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); |
0eb0d9f4 GD |
2676 | int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) == |
2677 | 0xffffffff); | |
2678 | ||
2679 | sdhci_remove_host(host, dead); | |
67e6db11 PG |
2680 | |
2681 | pm_runtime_get_sync(&pdev->dev); | |
2682 | pm_runtime_disable(&pdev->dev); | |
2683 | pm_runtime_put_noidle(&pdev->dev); | |
2684 | ||
e4bf91f6 BA |
2685 | clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks), |
2686 | msm_host->bulk_clks); | |
0eb0d9f4 GD |
2687 | if (!IS_ERR(msm_host->bus_clk)) |
2688 | clk_disable_unprepare(msm_host->bus_clk); | |
6f699531 | 2689 | sdhci_pltfm_free(pdev); |
0eb0d9f4 GD |
2690 | } |
2691 | ||
6809a5f7 | 2692 | static __maybe_unused int sdhci_msm_runtime_suspend(struct device *dev) |
67e6db11 PG |
2693 | { |
2694 | struct sdhci_host *host = dev_get_drvdata(dev); | |
2695 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
2696 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
f8def10f MP |
2697 | unsigned long flags; |
2698 | ||
2699 | spin_lock_irqsave(&host->lock, flags); | |
2700 | host->runtime_suspended = true; | |
2701 | spin_unlock_irqrestore(&host->lock, flags); | |
67e6db11 | 2702 | |
0472f8d3 RN |
2703 | /* Drop the performance vote */ |
2704 | dev_pm_opp_set_rate(dev, 0); | |
e4bf91f6 BA |
2705 | clk_bulk_disable_unprepare(ARRAY_SIZE(msm_host->bulk_clks), |
2706 | msm_host->bulk_clks); | |
67e6db11 | 2707 | |
c7eed31e | 2708 | return sdhci_msm_ice_suspend(msm_host); |
67e6db11 PG |
2709 | } |
2710 | ||
6809a5f7 | 2711 | static __maybe_unused int sdhci_msm_runtime_resume(struct device *dev) |
67e6db11 PG |
2712 | { |
2713 | struct sdhci_host *host = dev_get_drvdata(dev); | |
2714 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | |
2715 | struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); | |
f8def10f | 2716 | unsigned long flags; |
21f1e2d4 | 2717 | int ret; |
67e6db11 | 2718 | |
21f1e2d4 | 2719 | ret = clk_bulk_prepare_enable(ARRAY_SIZE(msm_host->bulk_clks), |
e4bf91f6 | 2720 | msm_host->bulk_clks); |
21f1e2d4 VB |
2721 | if (ret) |
2722 | return ret; | |
2723 | /* | |
2724 | * Whenever core-clock is gated dynamically, it's needed to | |
2725 | * restore the SDR DLL settings when the clock is ungated. | |
2726 | */ | |
c93767cf | 2727 | if (msm_host->restore_dll_config && msm_host->clk_rate) { |
0472f8d3 | 2728 | ret = sdhci_msm_restore_sdr_dll_config(host); |
c93767cf EB |
2729 | if (ret) |
2730 | return ret; | |
2731 | } | |
21f1e2d4 | 2732 | |
0472f8d3 RN |
2733 | dev_pm_opp_set_rate(dev, msm_host->clk_rate); |
2734 | ||
f8def10f MP |
2735 | ret = sdhci_msm_ice_resume(msm_host); |
2736 | if (ret) | |
2737 | return ret; | |
2738 | ||
2739 | spin_lock_irqsave(&host->lock, flags); | |
2740 | host->runtime_suspended = false; | |
2741 | spin_unlock_irqrestore(&host->lock, flags); | |
2742 | ||
2743 | return ret; | |
67e6db11 | 2744 | } |
67e6db11 PG |
2745 | |
2746 | static const struct dev_pm_ops sdhci_msm_pm_ops = { | |
2747 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, | |
2748 | pm_runtime_force_resume) | |
2749 | SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, | |
2750 | sdhci_msm_runtime_resume, | |
2751 | NULL) | |
2752 | }; | |
2753 | ||
0eb0d9f4 GD |
2754 | static struct platform_driver sdhci_msm_driver = { |
2755 | .probe = sdhci_msm_probe, | |
a7dde463 | 2756 | .remove_new = sdhci_msm_remove, |
0eb0d9f4 GD |
2757 | .driver = { |
2758 | .name = "sdhci_msm", | |
0eb0d9f4 | 2759 | .of_match_table = sdhci_msm_dt_match, |
67e6db11 | 2760 | .pm = &sdhci_msm_pm_ops, |
8c98644b | 2761 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
0eb0d9f4 GD |
2762 | }, |
2763 | }; | |
2764 | ||
2765 | module_platform_driver(sdhci_msm_driver); | |
2766 | ||
2767 | MODULE_DESCRIPTION("Qualcomm Secure Digital Host Controller Interface driver"); | |
2768 | MODULE_LICENSE("GPL v2"); |