Merge tag 'mmc-v6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[linux-2.6-block.git] / drivers / mmc / host / sdhci-of-dwcmshc.c
CommitLineData
e438cf49
JZ
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for Synopsys DesignWare Cores Mobile Storage Host Controller
4 *
5 * Copyright (C) 2018 Synaptics Incorporated
6 *
7 * Author: Jisheng Zhang <jszhang@kernel.org>
8 */
9
eb81ed51 10#include <linux/acpi.h>
43658a54 11#include <linux/bitfield.h>
e438cf49 12#include <linux/clk.h>
b85c997d 13#include <linux/dma-mapping.h>
08f3dff7 14#include <linux/iopoll.h>
b85c997d 15#include <linux/kernel.h>
e438cf49
JZ
16#include <linux/module.h>
17#include <linux/of.h>
c62da8a8 18#include <linux/platform_device.h>
48fe8fad 19#include <linux/pm_runtime.h>
70f83220 20#include <linux/reset.h>
b85c997d 21#include <linux/sizes.h>
e438cf49
JZ
22
23#include "sdhci-pltfm.h"
24
ca1219c0
JZ
25#define SDHCI_DWCMSHC_ARG2_STUFF GENMASK(31, 16)
26
554232e8
JZ
27/* DWCMSHC specific Mode Select value */
28#define DWCMSHC_CTRL_HS400 0x7
29
08f3dff7
SL
30/* DWC IP vendor area 1 pointer */
31#define DWCMSHC_P_VENDOR_AREA1 0xe8
32#define DWCMSHC_AREA1_MASK GENMASK(11, 0)
33/* Offset inside the vendor area 1 */
34#define DWCMSHC_HOST_CTRL3 0x8
35#define DWCMSHC_EMMC_CONTROL 0x2c
c6f361cb 36#define DWCMSHC_CARD_IS_EMMC BIT(0)
08f3dff7
SL
37#define DWCMSHC_ENHANCED_STROBE BIT(8)
38#define DWCMSHC_EMMC_ATCTRL 0x40
43658a54
DF
39/* Tuning and auto-tuning fields in AT_CTRL_R control register */
40#define AT_CTRL_AT_EN BIT(0) /* autotuning is enabled */
41#define AT_CTRL_CI_SEL BIT(1) /* interval to drive center phase select */
42#define AT_CTRL_SWIN_TH_EN BIT(2) /* sampling window threshold enable */
43#define AT_CTRL_RPT_TUNE_ERR BIT(3) /* enable reporting framing errors */
44#define AT_CTRL_SW_TUNE_EN BIT(4) /* enable software managed tuning */
45#define AT_CTRL_WIN_EDGE_SEL_MASK GENMASK(11, 8) /* bits [11:8] */
46#define AT_CTRL_WIN_EDGE_SEL 0xf /* sampling window edge select */
47#define AT_CTRL_TUNE_CLK_STOP_EN BIT(16) /* clocks stopped during phase code change */
48#define AT_CTRL_PRE_CHANGE_DLY_MASK GENMASK(18, 17) /* bits [18:17] */
49#define AT_CTRL_PRE_CHANGE_DLY 0x1 /* 2-cycle latency */
50#define AT_CTRL_POST_CHANGE_DLY_MASK GENMASK(20, 19) /* bits [20:19] */
51#define AT_CTRL_POST_CHANGE_DLY 0x3 /* 4-cycle latency */
52#define AT_CTRL_SWIN_TH_VAL_MASK GENMASK(31, 24) /* bits [31:24] */
53#define AT_CTRL_SWIN_TH_VAL 0x9 /* sampling window threshold */
08f3dff7 54
017199c2
JZ
55/* Sophgo CV18XX specific Registers */
56#define CV18XX_SDHCI_MSHC_CTRL 0x00
57#define CV18XX_EMMC_FUNC_EN BIT(0)
58#define CV18XX_LATANCY_1T BIT(1)
59#define CV18XX_SDHCI_PHY_TX_RX_DLY 0x40
60#define CV18XX_PHY_TX_DLY_MSK GENMASK(6, 0)
61#define CV18XX_PHY_TX_SRC_MSK GENMASK(9, 8)
62#define CV18XX_PHY_TX_SRC_INVERT_CLK_TX 0x1
63#define CV18XX_PHY_RX_DLY_MSK GENMASK(22, 16)
64#define CV18XX_PHY_RX_SRC_MSK GENMASK(25, 24)
65#define CV18XX_PHY_RX_SRC_INVERT_RX_CLK 0x1
66#define CV18XX_SDHCI_PHY_CONFIG 0x4c
67#define CV18XX_PHY_TX_BPS BIT(0)
68
08f3dff7
SL
69/* Rockchip specific Registers */
70#define DWCMSHC_EMMC_DLL_CTRL 0x800
71#define DWCMSHC_EMMC_DLL_RXCLK 0x804
72#define DWCMSHC_EMMC_DLL_TXCLK 0x808
73#define DWCMSHC_EMMC_DLL_STRBIN 0x80c
c6f361cb 74#define DECMSHC_EMMC_DLL_CMDOUT 0x810
08f3dff7
SL
75#define DWCMSHC_EMMC_DLL_STATUS0 0x840
76#define DWCMSHC_EMMC_DLL_START BIT(0)
77#define DWCMSHC_EMMC_DLL_LOCKED BIT(8)
78#define DWCMSHC_EMMC_DLL_TIMEOUT BIT(9)
79#define DWCMSHC_EMMC_DLL_RXCLK_SRCSEL 29
80#define DWCMSHC_EMMC_DLL_START_POINT 16
81#define DWCMSHC_EMMC_DLL_INC 8
b75a52b0 82#define DWCMSHC_EMMC_DLL_BYPASS BIT(24)
08f3dff7 83#define DWCMSHC_EMMC_DLL_DLYENA BIT(27)
c6f361cb
YZ
84#define DLL_TXCLK_TAPNUM_DEFAULT 0x10
85#define DLL_TXCLK_TAPNUM_90_DEGREES 0xA
08f3dff7 86#define DLL_TXCLK_TAPNUM_FROM_SW BIT(24)
c6f361cb
YZ
87#define DLL_STRBIN_TAPNUM_DEFAULT 0x8
88#define DLL_STRBIN_TAPNUM_FROM_SW BIT(24)
89#define DLL_STRBIN_DELAY_NUM_SEL BIT(26)
90#define DLL_STRBIN_DELAY_NUM_OFFSET 16
91#define DLL_STRBIN_DELAY_NUM_DEFAULT 0x16
08f3dff7
SL
92#define DLL_RXCLK_NO_INVERTER 1
93#define DLL_RXCLK_INVERTER 0
c6f361cb 94#define DLL_CMDOUT_TAPNUM_90_DEGREES 0x8
b75a52b0 95#define DLL_RXCLK_ORI_GATE BIT(31)
c6f361cb
YZ
96#define DLL_CMDOUT_TAPNUM_FROM_SW BIT(24)
97#define DLL_CMDOUT_SRC_CLK_NEG BIT(28)
98#define DLL_CMDOUT_EN_SRC_CLK_NEG BIT(29)
99
08f3dff7
SL
100#define DLL_LOCK_WO_TMOUT(x) \
101 ((((x) & DWCMSHC_EMMC_DLL_LOCKED) == DWCMSHC_EMMC_DLL_LOCKED) && \
102 (((x) & DWCMSHC_EMMC_DLL_TIMEOUT) == 0))
86e1a8e1 103#define RK35xx_MAX_CLKS 3
08f3dff7 104
43658a54
DF
105/* PHY register area pointer */
106#define DWC_MSHC_PTR_PHY_R 0x300
107
108/* PHY general configuration */
109#define PHY_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x00)
110#define PHY_CNFG_RSTN_DEASSERT 0x1 /* Deassert PHY reset */
111#define PHY_CNFG_PAD_SP_MASK GENMASK(19, 16) /* bits [19:16] */
112#define PHY_CNFG_PAD_SP 0x0c /* PMOS TX drive strength */
113#define PHY_CNFG_PAD_SN_MASK GENMASK(23, 20) /* bits [23:20] */
114#define PHY_CNFG_PAD_SN 0x0c /* NMOS TX drive strength */
115
116/* PHY command/response pad settings */
117#define PHY_CMDPAD_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x04)
118
119/* PHY data pad settings */
120#define PHY_DATAPAD_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x06)
121
122/* PHY clock pad settings */
123#define PHY_CLKPAD_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x08)
124
125/* PHY strobe pad settings */
126#define PHY_STBPAD_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x0a)
127
128/* PHY reset pad settings */
129#define PHY_RSTNPAD_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x0c)
130
131/* Bitfields are common for all pad settings */
132#define PHY_PAD_RXSEL_1V8 0x1 /* Receiver type select for 1.8V */
133#define PHY_PAD_RXSEL_3V3 0x2 /* Receiver type select for 3.3V */
134
135#define PHY_PAD_WEAKPULL_MASK GENMASK(4, 3) /* bits [4:3] */
136#define PHY_PAD_WEAKPULL_PULLUP 0x1 /* Weak pull up enabled */
137#define PHY_PAD_WEAKPULL_PULLDOWN 0x2 /* Weak pull down enabled */
138
139#define PHY_PAD_TXSLEW_CTRL_P_MASK GENMASK(8, 5) /* bits [8:5] */
140#define PHY_PAD_TXSLEW_CTRL_P 0x3 /* Slew control for P-Type pad TX */
141#define PHY_PAD_TXSLEW_CTRL_N_MASK GENMASK(12, 9) /* bits [12:9] */
142#define PHY_PAD_TXSLEW_CTRL_N 0x3 /* Slew control for N-Type pad TX */
143
144/* PHY CLK delay line settings */
145#define PHY_SDCLKDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x1d)
146#define PHY_SDCLKDL_CNFG_UPDATE BIT(4) /* set before writing to SDCLKDL_DC */
147
148/* PHY CLK delay line delay code */
149#define PHY_SDCLKDL_DC_R (DWC_MSHC_PTR_PHY_R + 0x1e)
150#define PHY_SDCLKDL_DC_INITIAL 0x40 /* initial delay code */
151#define PHY_SDCLKDL_DC_DEFAULT 0x32 /* default delay code */
152#define PHY_SDCLKDL_DC_HS400 0x18 /* delay code for HS400 mode */
153
154/* PHY drift_cclk_rx delay line configuration setting */
155#define PHY_ATDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x21)
156#define PHY_ATDL_CNFG_INPSEL_MASK GENMASK(3, 2) /* bits [3:2] */
157#define PHY_ATDL_CNFG_INPSEL 0x3 /* delay line input source */
158
159/* PHY DLL control settings */
160#define PHY_DLL_CTRL_R (DWC_MSHC_PTR_PHY_R + 0x24)
161#define PHY_DLL_CTRL_DISABLE 0x0 /* PHY DLL is enabled */
162#define PHY_DLL_CTRL_ENABLE 0x1 /* PHY DLL is disabled */
163
164/* PHY DLL configuration register 1 */
165#define PHY_DLL_CNFG1_R (DWC_MSHC_PTR_PHY_R + 0x25)
166#define PHY_DLL_CNFG1_SLVDLY_MASK GENMASK(5, 4) /* bits [5:4] */
167#define PHY_DLL_CNFG1_SLVDLY 0x2 /* DLL slave update delay input */
168#define PHY_DLL_CNFG1_WAITCYCLE 0x5 /* DLL wait cycle input */
169
170/* PHY DLL configuration register 2 */
171#define PHY_DLL_CNFG2_R (DWC_MSHC_PTR_PHY_R + 0x26)
172#define PHY_DLL_CNFG2_JUMPSTEP 0xa /* DLL jump step input */
173
174/* PHY DLL master and slave delay line configuration settings */
175#define PHY_DLLDL_CNFG_R (DWC_MSHC_PTR_PHY_R + 0x28)
176#define PHY_DLLDL_CNFG_SLV_INPSEL_MASK GENMASK(6, 5) /* bits [6:5] */
177#define PHY_DLLDL_CNFG_SLV_INPSEL 0x3 /* clock source select for slave DL */
178
179#define FLAG_IO_FIXED_1V8 BIT(0)
180
b85c997d
JZ
181#define BOUNDARY_OK(addr, len) \
182 ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))
183
c6f361cb
YZ
184enum dwcmshc_rk_type {
185 DWCMSHC_RK3568,
186 DWCMSHC_RK3588,
187};
188
86e1a8e1 189struct rk35xx_priv {
08f3dff7 190 /* Rockchip specified optional clocks */
86e1a8e1 191 struct clk_bulk_data rockchip_clks[RK35xx_MAX_CLKS];
70f83220 192 struct reset_control *reset;
c6f361cb 193 enum dwcmshc_rk_type devtype;
08f3dff7
SL
194 u8 txclk_tapnum;
195};
196
e438cf49
JZ
197struct dwcmshc_priv {
198 struct clk *bus_clk;
08f3dff7
SL
199 int vendor_specific_area1; /* P_VENDOR_SPECIFIC_AREA reg */
200 void *priv; /* pointer to SoC private stuff */
43658a54
DF
201 u16 delay_line;
202 u16 flags;
e438cf49
JZ
203};
204
b85c997d
JZ
205/*
206 * If DMA addr spans 128MB boundary, we split the DMA transfer into two
207 * so that each DMA transfer doesn't exceed the boundary.
208 */
209static void dwcmshc_adma_write_desc(struct sdhci_host *host, void **desc,
210 dma_addr_t addr, int len, unsigned int cmd)
211{
212 int tmplen, offset;
213
214 if (likely(!len || BOUNDARY_OK(addr, len))) {
215 sdhci_adma_write_desc(host, desc, addr, len, cmd);
216 return;
217 }
218
219 offset = addr & (SZ_128M - 1);
220 tmplen = SZ_128M - offset;
221 sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);
222
223 addr += tmplen;
224 len -= tmplen;
225 sdhci_adma_write_desc(host, desc, addr, len, cmd);
226}
227
eb81ed51
LS
228static unsigned int dwcmshc_get_max_clock(struct sdhci_host *host)
229{
230 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
231
232 if (pltfm_host->clk)
233 return sdhci_pltfm_clk_get_max_clock(host);
234 else
235 return pltfm_host->clock;
236}
237
49502408
VK
238static unsigned int rk35xx_get_max_clock(struct sdhci_host *host)
239{
240 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
241
242 return clk_round_rate(pltfm_host->clk, ULONG_MAX);
243}
244
ca1219c0
JZ
245static void dwcmshc_check_auto_cmd23(struct mmc_host *mmc,
246 struct mmc_request *mrq)
247{
248 struct sdhci_host *host = mmc_priv(mmc);
249
250 /*
251 * No matter V4 is enabled or not, ARGUMENT2 register is 32-bit
252 * block count register which doesn't support stuff bits of
253 * CMD23 argument on dwcmsch host controller.
254 */
255 if (mrq->sbc && (mrq->sbc->arg & SDHCI_DWCMSHC_ARG2_STUFF))
256 host->flags &= ~SDHCI_AUTO_CMD23;
257 else
258 host->flags |= SDHCI_AUTO_CMD23;
259}
260
261static void dwcmshc_request(struct mmc_host *mmc, struct mmc_request *mrq)
262{
263 dwcmshc_check_auto_cmd23(mmc, mrq);
264
265 sdhci_request(mmc, mrq);
266}
267
43658a54
DF
268static void dwcmshc_phy_1_8v_init(struct sdhci_host *host)
269{
270 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
271 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
272 u32 val;
273
274 /* deassert phy reset & set tx drive strength */
275 val = PHY_CNFG_RSTN_DEASSERT;
276 val |= FIELD_PREP(PHY_CNFG_PAD_SP_MASK, PHY_CNFG_PAD_SP);
277 val |= FIELD_PREP(PHY_CNFG_PAD_SN_MASK, PHY_CNFG_PAD_SN);
278 sdhci_writel(host, val, PHY_CNFG_R);
279
280 /* disable delay line */
281 sdhci_writeb(host, PHY_SDCLKDL_CNFG_UPDATE, PHY_SDCLKDL_CNFG_R);
282
283 /* set delay line */
284 sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R);
285 sdhci_writeb(host, PHY_DLL_CNFG2_JUMPSTEP, PHY_DLL_CNFG2_R);
286
287 /* enable delay lane */
288 val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R);
289 val &= ~(PHY_SDCLKDL_CNFG_UPDATE);
290 sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R);
291
292 /* configure phy pads */
293 val = PHY_PAD_RXSEL_1V8;
294 val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLUP);
295 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P);
296 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N);
297 sdhci_writew(host, val, PHY_CMDPAD_CNFG_R);
298 sdhci_writew(host, val, PHY_DATAPAD_CNFG_R);
299 sdhci_writew(host, val, PHY_RSTNPAD_CNFG_R);
300
301 val = FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P);
302 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N);
303 sdhci_writew(host, val, PHY_CLKPAD_CNFG_R);
304
305 val = PHY_PAD_RXSEL_1V8;
306 val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLDOWN);
307 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P);
308 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N);
309 sdhci_writew(host, val, PHY_STBPAD_CNFG_R);
310
311 /* enable data strobe mode */
312 sdhci_writeb(host, FIELD_PREP(PHY_DLLDL_CNFG_SLV_INPSEL_MASK, PHY_DLLDL_CNFG_SLV_INPSEL),
313 PHY_DLLDL_CNFG_R);
314
315 /* enable phy dll */
316 sdhci_writeb(host, PHY_DLL_CTRL_ENABLE, PHY_DLL_CTRL_R);
317}
318
319static void dwcmshc_phy_3_3v_init(struct sdhci_host *host)
320{
321 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
322 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
323 u32 val;
324
325 /* deassert phy reset & set tx drive strength */
326 val = PHY_CNFG_RSTN_DEASSERT;
327 val |= FIELD_PREP(PHY_CNFG_PAD_SP_MASK, PHY_CNFG_PAD_SP);
328 val |= FIELD_PREP(PHY_CNFG_PAD_SN_MASK, PHY_CNFG_PAD_SN);
329 sdhci_writel(host, val, PHY_CNFG_R);
330
331 /* disable delay line */
332 sdhci_writeb(host, PHY_SDCLKDL_CNFG_UPDATE, PHY_SDCLKDL_CNFG_R);
333
334 /* set delay line */
335 sdhci_writeb(host, priv->delay_line, PHY_SDCLKDL_DC_R);
336 sdhci_writeb(host, PHY_DLL_CNFG2_JUMPSTEP, PHY_DLL_CNFG2_R);
337
338 /* enable delay lane */
339 val = sdhci_readb(host, PHY_SDCLKDL_CNFG_R);
340 val &= ~(PHY_SDCLKDL_CNFG_UPDATE);
341 sdhci_writeb(host, val, PHY_SDCLKDL_CNFG_R);
342
343 /* configure phy pads */
344 val = PHY_PAD_RXSEL_3V3;
345 val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLUP);
346 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P);
347 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N);
348 sdhci_writew(host, val, PHY_CMDPAD_CNFG_R);
349 sdhci_writew(host, val, PHY_DATAPAD_CNFG_R);
350 sdhci_writew(host, val, PHY_RSTNPAD_CNFG_R);
351
352 val = FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P);
353 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N);
354 sdhci_writew(host, val, PHY_CLKPAD_CNFG_R);
355
356 val = PHY_PAD_RXSEL_3V3;
357 val |= FIELD_PREP(PHY_PAD_WEAKPULL_MASK, PHY_PAD_WEAKPULL_PULLDOWN);
358 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_P_MASK, PHY_PAD_TXSLEW_CTRL_P);
359 val |= FIELD_PREP(PHY_PAD_TXSLEW_CTRL_N_MASK, PHY_PAD_TXSLEW_CTRL_N);
360 sdhci_writew(host, val, PHY_STBPAD_CNFG_R);
361
362 /* enable phy dll */
363 sdhci_writeb(host, PHY_DLL_CTRL_ENABLE, PHY_DLL_CTRL_R);
364}
365
366static void th1520_sdhci_set_phy(struct sdhci_host *host)
367{
368 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
369 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
370 u32 emmc_caps = MMC_CAP2_NO_SD | MMC_CAP2_NO_SDIO;
371 u16 emmc_ctrl;
372
373 /* Before power on, set PHY configs */
374 if (priv->flags & FLAG_IO_FIXED_1V8)
375 dwcmshc_phy_1_8v_init(host);
376 else
377 dwcmshc_phy_3_3v_init(host);
378
379 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) {
380 emmc_ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL);
381 emmc_ctrl |= DWCMSHC_CARD_IS_EMMC;
382 sdhci_writew(host, emmc_ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL);
383 }
384
385 sdhci_writeb(host, FIELD_PREP(PHY_DLL_CNFG1_SLVDLY_MASK, PHY_DLL_CNFG1_SLVDLY) |
386 PHY_DLL_CNFG1_WAITCYCLE, PHY_DLL_CNFG1_R);
387}
388
554232e8
JZ
389static void dwcmshc_set_uhs_signaling(struct sdhci_host *host,
390 unsigned int timing)
391{
c6f361cb
YZ
392 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
393 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
394 u16 ctrl, ctrl_2;
554232e8
JZ
395
396 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
397 /* Select Bus Speed Mode for host */
398 ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
399 if ((timing == MMC_TIMING_MMC_HS200) ||
400 (timing == MMC_TIMING_UHS_SDR104))
401 ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
402 else if (timing == MMC_TIMING_UHS_SDR12)
403 ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
404 else if ((timing == MMC_TIMING_UHS_SDR25) ||
405 (timing == MMC_TIMING_MMC_HS))
406 ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
407 else if (timing == MMC_TIMING_UHS_SDR50)
408 ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
409 else if ((timing == MMC_TIMING_UHS_DDR50) ||
410 (timing == MMC_TIMING_MMC_DDR52))
411 ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
c6f361cb
YZ
412 else if (timing == MMC_TIMING_MMC_HS400) {
413 /* set CARD_IS_EMMC bit to enable Data Strobe for HS400 */
414 ctrl = sdhci_readw(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL);
415 ctrl |= DWCMSHC_CARD_IS_EMMC;
416 sdhci_writew(host, ctrl, priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL);
417
554232e8 418 ctrl_2 |= DWCMSHC_CTRL_HS400;
c6f361cb
YZ
419 }
420
43658a54
DF
421 if (priv->flags & FLAG_IO_FIXED_1V8)
422 ctrl_2 |= SDHCI_CTRL_VDD_180;
554232e8
JZ
423 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
424}
425
43658a54
DF
426static void th1520_set_uhs_signaling(struct sdhci_host *host,
427 unsigned int timing)
428{
429 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
430 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
431
432 dwcmshc_set_uhs_signaling(host, timing);
433 if (timing == MMC_TIMING_MMC_HS400)
434 priv->delay_line = PHY_SDCLKDL_DC_HS400;
435 else
436 sdhci_writeb(host, 0, PHY_DLLDL_CNFG_R);
437 th1520_sdhci_set_phy(host);
438}
439
08f3dff7
SL
440static void dwcmshc_hs400_enhanced_strobe(struct mmc_host *mmc,
441 struct mmc_ios *ios)
442{
443 u32 vendor;
444 struct sdhci_host *host = mmc_priv(mmc);
445 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
446 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
447 int reg = priv->vendor_specific_area1 + DWCMSHC_EMMC_CONTROL;
448
449 vendor = sdhci_readl(host, reg);
450 if (ios->enhanced_strobe)
451 vendor |= DWCMSHC_ENHANCED_STROBE;
452 else
453 vendor &= ~DWCMSHC_ENHANCED_STROBE;
454
455 sdhci_writel(host, vendor, reg);
456}
457
458static void dwcmshc_rk3568_set_clock(struct sdhci_host *host, unsigned int clock)
459{
460 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
461 struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
86e1a8e1 462 struct rk35xx_priv *priv = dwc_priv->priv;
08f3dff7
SL
463 u8 txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT;
464 u32 extra, reg;
465 int err;
466
467 host->mmc->actual_clock = 0;
468
c6f361cb
YZ
469 if (clock == 0) {
470 /* Disable interface clock at initial state. */
471 sdhci_set_clock(host, clock);
08f3dff7 472 return;
c6f361cb 473 }
08f3dff7
SL
474
475 /* Rockchip platform only support 375KHz for identify mode */
476 if (clock <= 400000)
477 clock = 375000;
478
479 err = clk_set_rate(pltfm_host->clk, clock);
480 if (err)
481 dev_err(mmc_dev(host->mmc), "fail to set clock %d", clock);
482
483 sdhci_set_clock(host, clock);
484
485 /* Disable cmd conflict check */
486 reg = dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3;
487 extra = sdhci_readl(host, reg);
488 extra &= ~BIT(0);
489 sdhci_writel(host, extra, reg);
490
c6f361cb 491 if (clock <= 52000000) {
b75a52b0
SL
492 /*
493 * Disable DLL and reset both of sample and drive clock.
494 * The bypass bit and start bit need to be set if DLL is not locked.
495 */
496 sdhci_writel(host, DWCMSHC_EMMC_DLL_BYPASS | DWCMSHC_EMMC_DLL_START, DWCMSHC_EMMC_DLL_CTRL);
497 sdhci_writel(host, DLL_RXCLK_ORI_GATE, DWCMSHC_EMMC_DLL_RXCLK);
c6f361cb
YZ
498 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
499 sdhci_writel(host, 0, DECMSHC_EMMC_DLL_CMDOUT);
500 /*
501 * Before switching to hs400es mode, the driver will enable
502 * enhanced strobe first. PHY needs to configure the parameters
503 * of enhanced strobe first.
504 */
505 extra = DWCMSHC_EMMC_DLL_DLYENA |
506 DLL_STRBIN_DELAY_NUM_SEL |
507 DLL_STRBIN_DELAY_NUM_DEFAULT << DLL_STRBIN_DELAY_NUM_OFFSET;
508 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
08f3dff7
SL
509 return;
510 }
511
512 /* Reset DLL */
513 sdhci_writel(host, BIT(1), DWCMSHC_EMMC_DLL_CTRL);
514 udelay(1);
515 sdhci_writel(host, 0x0, DWCMSHC_EMMC_DLL_CTRL);
516
c6f361cb
YZ
517 /*
518 * We shouldn't set DLL_RXCLK_NO_INVERTER for identify mode but
519 * we must set it in higher speed mode.
520 */
521 extra = DWCMSHC_EMMC_DLL_DLYENA;
522 if (priv->devtype == DWCMSHC_RK3568)
523 extra |= DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL;
524 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_RXCLK);
525
08f3dff7
SL
526 /* Init DLL settings */
527 extra = 0x5 << DWCMSHC_EMMC_DLL_START_POINT |
528 0x2 << DWCMSHC_EMMC_DLL_INC |
529 DWCMSHC_EMMC_DLL_START;
530 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CTRL);
531 err = readl_poll_timeout(host->ioaddr + DWCMSHC_EMMC_DLL_STATUS0,
532 extra, DLL_LOCK_WO_TMOUT(extra), 1,
533 500 * USEC_PER_MSEC);
534 if (err) {
535 dev_err(mmc_dev(host->mmc), "DLL lock timeout!\n");
536 return;
537 }
538
539 extra = 0x1 << 16 | /* tune clock stop en */
b75a52b0 540 0x3 << 17 | /* pre-change delay */
08f3dff7
SL
541 0x3 << 19; /* post-change delay */
542 sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
543
544 if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
545 host->mmc->ios.timing == MMC_TIMING_MMC_HS400)
546 txclk_tapnum = priv->txclk_tapnum;
547
c6f361cb
YZ
548 if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
549 txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES;
550
551 extra = DLL_CMDOUT_SRC_CLK_NEG |
552 DLL_CMDOUT_EN_SRC_CLK_NEG |
553 DWCMSHC_EMMC_DLL_DLYENA |
554 DLL_CMDOUT_TAPNUM_90_DEGREES |
555 DLL_CMDOUT_TAPNUM_FROM_SW;
556 sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT);
557 }
558
08f3dff7
SL
559 extra = DWCMSHC_EMMC_DLL_DLYENA |
560 DLL_TXCLK_TAPNUM_FROM_SW |
c6f361cb 561 DLL_RXCLK_NO_INVERTER << DWCMSHC_EMMC_DLL_RXCLK_SRCSEL |
08f3dff7
SL
562 txclk_tapnum;
563 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK);
564
565 extra = DWCMSHC_EMMC_DLL_DLYENA |
566 DLL_STRBIN_TAPNUM_DEFAULT |
567 DLL_STRBIN_TAPNUM_FROM_SW;
568 sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN);
569}
570
70f83220
YZ
571static void rk35xx_sdhci_reset(struct sdhci_host *host, u8 mask)
572{
573 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
574 struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host);
575 struct rk35xx_priv *priv = dwc_priv->priv;
576
577 if (mask & SDHCI_RESET_ALL && priv->reset) {
578 reset_control_assert(priv->reset);
579 udelay(1);
580 reset_control_deassert(priv->reset);
581 }
582
583 sdhci_reset(host, mask);
584}
585
43658a54
DF
586static int th1520_execute_tuning(struct sdhci_host *host, u32 opcode)
587{
588 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
589 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
590 u32 val = 0;
591
592 if (host->flags & SDHCI_HS400_TUNING)
593 return 0;
594
595 sdhci_writeb(host, FIELD_PREP(PHY_ATDL_CNFG_INPSEL_MASK, PHY_ATDL_CNFG_INPSEL),
596 PHY_ATDL_CNFG_R);
597 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
598
599 /*
600 * configure tuning settings:
601 * - center phase select code driven in block gap interval
602 * - disable reporting of framing errors
603 * - disable software managed tuning
604 * - disable user selection of sampling window edges,
605 * instead tuning calculated edges are used
606 */
607 val &= ~(AT_CTRL_CI_SEL | AT_CTRL_RPT_TUNE_ERR | AT_CTRL_SW_TUNE_EN |
608 FIELD_PREP(AT_CTRL_WIN_EDGE_SEL_MASK, AT_CTRL_WIN_EDGE_SEL));
609
610 /*
611 * configure tuning settings:
612 * - enable auto-tuning
613 * - enable sampling window threshold
614 * - stop clocks during phase code change
615 * - set max latency in cycles between tx and rx clocks
616 * - set max latency in cycles to switch output phase
617 * - set max sampling window threshold value
618 */
619 val |= AT_CTRL_AT_EN | AT_CTRL_SWIN_TH_EN | AT_CTRL_TUNE_CLK_STOP_EN;
620 val |= FIELD_PREP(AT_CTRL_PRE_CHANGE_DLY_MASK, AT_CTRL_PRE_CHANGE_DLY);
621 val |= FIELD_PREP(AT_CTRL_POST_CHANGE_DLY_MASK, AT_CTRL_POST_CHANGE_DLY);
622 val |= FIELD_PREP(AT_CTRL_SWIN_TH_VAL_MASK, AT_CTRL_SWIN_TH_VAL);
623
624 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
625 val = sdhci_readl(host, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
626
627 /* perform tuning */
628 sdhci_start_tuning(host);
ace323f8 629 host->tuning_loop_count = 128;
43658a54
DF
630 host->tuning_err = __sdhci_execute_tuning(host, opcode);
631 if (host->tuning_err) {
632 /* disable auto-tuning upon tuning error */
633 val &= ~AT_CTRL_AT_EN;
634 sdhci_writel(host, val, priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL);
635 dev_err(mmc_dev(host->mmc), "tuning failed: %d\n", host->tuning_err);
636 return -EIO;
637 }
638 sdhci_end_tuning(host);
639
640 return 0;
641}
642
643static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask)
644{
645 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
646 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
647 u16 ctrl_2;
648
649 sdhci_reset(host, mask);
650
651 if (priv->flags & FLAG_IO_FIXED_1V8) {
652 ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
653 if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) {
654 ctrl_2 |= SDHCI_CTRL_VDD_180;
655 sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
656 }
657 }
658}
659
017199c2
JZ
660static void cv18xx_sdhci_reset(struct sdhci_host *host, u8 mask)
661{
662 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
663 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
664 u32 val, emmc_caps = MMC_CAP2_NO_SD | MMC_CAP2_NO_SDIO;
665
666 sdhci_reset(host, mask);
667
668 if ((host->mmc->caps2 & emmc_caps) == emmc_caps) {
669 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL);
670 val |= CV18XX_EMMC_FUNC_EN;
671 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL);
672 }
673
674 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL);
675 val |= CV18XX_LATANCY_1T;
676 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_MSHC_CTRL);
677
678 val = sdhci_readl(host, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG);
679 val |= CV18XX_PHY_TX_BPS;
680 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_CONFIG);
681
682 val = (FIELD_PREP(CV18XX_PHY_TX_DLY_MSK, 0) |
683 FIELD_PREP(CV18XX_PHY_TX_SRC_MSK, CV18XX_PHY_TX_SRC_INVERT_CLK_TX) |
684 FIELD_PREP(CV18XX_PHY_RX_DLY_MSK, 0) |
685 FIELD_PREP(CV18XX_PHY_RX_SRC_MSK, CV18XX_PHY_RX_SRC_INVERT_RX_CLK));
686 sdhci_writel(host, val, priv->vendor_specific_area1 + CV18XX_SDHCI_PHY_TX_RX_DLY);
687}
688
e438cf49
JZ
689static const struct sdhci_ops sdhci_dwcmshc_ops = {
690 .set_clock = sdhci_set_clock,
691 .set_bus_width = sdhci_set_bus_width,
554232e8 692 .set_uhs_signaling = dwcmshc_set_uhs_signaling,
eb81ed51 693 .get_max_clock = dwcmshc_get_max_clock,
e438cf49 694 .reset = sdhci_reset,
b85c997d 695 .adma_write_desc = dwcmshc_adma_write_desc,
e438cf49
JZ
696};
697
86e1a8e1 698static const struct sdhci_ops sdhci_dwcmshc_rk35xx_ops = {
08f3dff7
SL
699 .set_clock = dwcmshc_rk3568_set_clock,
700 .set_bus_width = sdhci_set_bus_width,
701 .set_uhs_signaling = dwcmshc_set_uhs_signaling,
49502408 702 .get_max_clock = rk35xx_get_max_clock,
70f83220 703 .reset = rk35xx_sdhci_reset,
08f3dff7
SL
704 .adma_write_desc = dwcmshc_adma_write_desc,
705};
706
43658a54
DF
707static const struct sdhci_ops sdhci_dwcmshc_th1520_ops = {
708 .set_clock = sdhci_set_clock,
709 .set_bus_width = sdhci_set_bus_width,
710 .set_uhs_signaling = th1520_set_uhs_signaling,
711 .get_max_clock = dwcmshc_get_max_clock,
712 .reset = th1520_sdhci_reset,
713 .adma_write_desc = dwcmshc_adma_write_desc,
714 .voltage_switch = dwcmshc_phy_1_8v_init,
715 .platform_execute_tuning = &th1520_execute_tuning,
716};
717
017199c2
JZ
718static const struct sdhci_ops sdhci_dwcmshc_cv18xx_ops = {
719 .set_clock = sdhci_set_clock,
720 .set_bus_width = sdhci_set_bus_width,
721 .set_uhs_signaling = dwcmshc_set_uhs_signaling,
722 .get_max_clock = dwcmshc_get_max_clock,
723 .reset = cv18xx_sdhci_reset,
724 .adma_write_desc = dwcmshc_adma_write_desc,
725};
726
e438cf49
JZ
727static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = {
728 .ops = &sdhci_dwcmshc_ops,
729 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
5f7dfda4 730 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
e438cf49
JZ
731};
732
a0753ef6
LS
733#ifdef CONFIG_ACPI
734static const struct sdhci_pltfm_data sdhci_dwcmshc_bf3_pdata = {
735 .ops = &sdhci_dwcmshc_ops,
736 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
737 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
738 SDHCI_QUIRK2_ACMD23_BROKEN,
739};
740#endif
741
86e1a8e1
SR
742static const struct sdhci_pltfm_data sdhci_dwcmshc_rk35xx_pdata = {
743 .ops = &sdhci_dwcmshc_rk35xx_ops,
08f3dff7
SL
744 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
745 SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
746 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
747 SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN,
748};
749
43658a54
DF
750static const struct sdhci_pltfm_data sdhci_dwcmshc_th1520_pdata = {
751 .ops = &sdhci_dwcmshc_th1520_ops,
752 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
753 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
754};
755
017199c2
JZ
756static const struct sdhci_pltfm_data sdhci_dwcmshc_cv18xx_pdata = {
757 .ops = &sdhci_dwcmshc_cv18xx_ops,
758 .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
759 .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
760};
761
86e1a8e1 762static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv)
08f3dff7
SL
763{
764 int err;
86e1a8e1 765 struct rk35xx_priv *priv = dwc_priv->priv;
08f3dff7 766
70f83220
YZ
767 priv->reset = devm_reset_control_array_get_optional_exclusive(mmc_dev(host->mmc));
768 if (IS_ERR(priv->reset)) {
769 err = PTR_ERR(priv->reset);
770 dev_err(mmc_dev(host->mmc), "failed to get reset control %d\n", err);
771 return err;
772 }
773
08f3dff7
SL
774 priv->rockchip_clks[0].id = "axi";
775 priv->rockchip_clks[1].id = "block";
776 priv->rockchip_clks[2].id = "timer";
86e1a8e1 777 err = devm_clk_bulk_get_optional(mmc_dev(host->mmc), RK35xx_MAX_CLKS,
08f3dff7
SL
778 priv->rockchip_clks);
779 if (err) {
780 dev_err(mmc_dev(host->mmc), "failed to get clocks %d\n", err);
781 return err;
782 }
783
86e1a8e1 784 err = clk_bulk_prepare_enable(RK35xx_MAX_CLKS, priv->rockchip_clks);
08f3dff7
SL
785 if (err) {
786 dev_err(mmc_dev(host->mmc), "failed to enable clocks %d\n", err);
787 return err;
788 }
789
790 if (of_property_read_u8(mmc_dev(host->mmc)->of_node, "rockchip,txclk-tapnum",
791 &priv->txclk_tapnum))
792 priv->txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT;
793
794 /* Disable cmd conflict check */
795 sdhci_writel(host, 0x0, dwc_priv->vendor_specific_area1 + DWCMSHC_HOST_CTRL3);
796 /* Reset previous settings */
797 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_TXCLK);
798 sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_STRBIN);
799
800 return 0;
801}
802
c6f361cb
YZ
803static void dwcmshc_rk35xx_postinit(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv)
804{
805 /*
806 * Don't support highspeed bus mode with low clk speed as we
807 * cannot use DLL for this condition.
808 */
809 if (host->mmc->f_max <= 52000000) {
810 dev_info(mmc_dev(host->mmc), "Disabling HS200/HS400, frequency too low (%d)\n",
811 host->mmc->f_max);
812 host->mmc->caps2 &= ~(MMC_CAP2_HS200 | MMC_CAP2_HS400);
813 host->mmc->caps &= ~(MMC_CAP_3_3V_DDR | MMC_CAP_1_8V_DDR);
814 }
815}
816
08f3dff7 817static const struct of_device_id sdhci_dwcmshc_dt_ids[] = {
c6f361cb
YZ
818 {
819 .compatible = "rockchip,rk3588-dwcmshc",
820 .data = &sdhci_dwcmshc_rk35xx_pdata,
821 },
08f3dff7
SL
822 {
823 .compatible = "rockchip,rk3568-dwcmshc",
86e1a8e1 824 .data = &sdhci_dwcmshc_rk35xx_pdata,
08f3dff7
SL
825 },
826 {
827 .compatible = "snps,dwcmshc-sdhci",
828 .data = &sdhci_dwcmshc_pdata,
829 },
017199c2
JZ
830 {
831 .compatible = "sophgo,cv1800b-dwcmshc",
832 .data = &sdhci_dwcmshc_cv18xx_pdata,
833 },
834 {
835 .compatible = "sophgo,sg2002-dwcmshc",
836 .data = &sdhci_dwcmshc_cv18xx_pdata,
837 },
43658a54
DF
838 {
839 .compatible = "thead,th1520-dwcmshc",
840 .data = &sdhci_dwcmshc_th1520_pdata,
841 },
08f3dff7
SL
842 {},
843};
844MODULE_DEVICE_TABLE(of, sdhci_dwcmshc_dt_ids);
845
eb81ed51
LS
846#ifdef CONFIG_ACPI
847static const struct acpi_device_id sdhci_dwcmshc_acpi_ids[] = {
a0753ef6
LS
848 {
849 .id = "MLNXBF30",
850 .driver_data = (kernel_ulong_t)&sdhci_dwcmshc_bf3_pdata,
851 },
eb81ed51
LS
852 {}
853};
cfd4ea48 854MODULE_DEVICE_TABLE(acpi, sdhci_dwcmshc_acpi_ids);
eb81ed51
LS
855#endif
856
e438cf49
JZ
857static int dwcmshc_probe(struct platform_device *pdev)
858{
eb81ed51 859 struct device *dev = &pdev->dev;
e438cf49
JZ
860 struct sdhci_pltfm_host *pltfm_host;
861 struct sdhci_host *host;
862 struct dwcmshc_priv *priv;
86e1a8e1 863 struct rk35xx_priv *rk_priv = NULL;
08f3dff7 864 const struct sdhci_pltfm_data *pltfm_data;
e438cf49 865 int err;
b85c997d 866 u32 extra;
e438cf49 867
a0753ef6 868 pltfm_data = device_get_match_data(&pdev->dev);
08f3dff7
SL
869 if (!pltfm_data) {
870 dev_err(&pdev->dev, "Error: No device match data found\n");
871 return -ENODEV;
872 }
873
874 host = sdhci_pltfm_init(pdev, pltfm_data,
e438cf49
JZ
875 sizeof(struct dwcmshc_priv));
876 if (IS_ERR(host))
877 return PTR_ERR(host);
878
b85c997d
JZ
879 /*
880 * extra adma table cnt for cross 128M boundary handling.
881 */
eb81ed51 882 extra = DIV_ROUND_UP_ULL(dma_get_required_mask(dev), SZ_128M);
b85c997d
JZ
883 if (extra > SDHCI_MAX_SEGS)
884 extra = SDHCI_MAX_SEGS;
885 host->adma_table_cnt += extra;
886
e438cf49
JZ
887 pltfm_host = sdhci_priv(host);
888 priv = sdhci_pltfm_priv(pltfm_host);
889
eb81ed51
LS
890 if (dev->of_node) {
891 pltfm_host->clk = devm_clk_get(dev, "core");
892 if (IS_ERR(pltfm_host->clk)) {
893 err = PTR_ERR(pltfm_host->clk);
894 dev_err(dev, "failed to get core clk: %d\n", err);
895 goto free_pltfm;
896 }
897 err = clk_prepare_enable(pltfm_host->clk);
898 if (err)
899 goto free_pltfm;
e438cf49 900
eb81ed51
LS
901 priv->bus_clk = devm_clk_get(dev, "bus");
902 if (!IS_ERR(priv->bus_clk))
903 clk_prepare_enable(priv->bus_clk);
904 }
e438cf49
JZ
905
906 err = mmc_of_parse(host->mmc);
907 if (err)
908 goto err_clk;
909
910 sdhci_get_of_property(pdev);
911
08f3dff7
SL
912 priv->vendor_specific_area1 =
913 sdhci_readl(host, DWCMSHC_P_VENDOR_AREA1) & DWCMSHC_AREA1_MASK;
914
ca1219c0 915 host->mmc_host_ops.request = dwcmshc_request;
08f3dff7
SL
916 host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe;
917
86e1a8e1
SR
918 if (pltfm_data == &sdhci_dwcmshc_rk35xx_pdata) {
919 rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL);
34884c4f
WY
920 if (!rk_priv) {
921 err = -ENOMEM;
08f3dff7 922 goto err_clk;
34884c4f 923 }
08f3dff7 924
c6f361cb
YZ
925 if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc"))
926 rk_priv->devtype = DWCMSHC_RK3588;
927 else
928 rk_priv->devtype = DWCMSHC_RK3568;
929
08f3dff7
SL
930 priv->priv = rk_priv;
931
86e1a8e1 932 err = dwcmshc_rk35xx_init(host, priv);
08f3dff7
SL
933 if (err)
934 goto err_clk;
935 }
ca1219c0 936
43658a54
DF
937 if (pltfm_data == &sdhci_dwcmshc_th1520_pdata) {
938 priv->delay_line = PHY_SDCLKDL_DC_DEFAULT;
939
e18a3866
NC
940 if (device_property_read_bool(dev, "mmc-ddr-1_8v") ||
941 device_property_read_bool(dev, "mmc-hs200-1_8v") ||
942 device_property_read_bool(dev, "mmc-hs400-1_8v"))
43658a54
DF
943 priv->flags |= FLAG_IO_FIXED_1V8;
944 else
945 priv->flags &= ~FLAG_IO_FIXED_1V8;
946
947 /*
948 * start_signal_voltage_switch() will try 3.3V first
949 * then 1.8V. Use SDHCI_SIGNALING_180 rather than
950 * SDHCI_SIGNALING_330 to avoid setting voltage to 3.3V
951 * in sdhci_start_signal_voltage_switch().
952 */
953 if (priv->flags & FLAG_IO_FIXED_1V8) {
954 host->flags &= ~SDHCI_SIGNALING_330;
955 host->flags |= SDHCI_SIGNALING_180;
956 }
957
958 sdhci_enable_v4_mode(host);
959 }
960
95921151
LS
961#ifdef CONFIG_ACPI
962 if (pltfm_data == &sdhci_dwcmshc_bf3_pdata)
963 sdhci_enable_v4_mode(host);
964#endif
965
57ac3084
JZ
966 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
967
48fe8fad
LS
968 pm_runtime_get_noresume(dev);
969 pm_runtime_set_active(dev);
970 pm_runtime_enable(dev);
971
c6f361cb 972 err = sdhci_setup_host(host);
e438cf49 973 if (err)
48fe8fad 974 goto err_rpm;
e438cf49 975
c6f361cb
YZ
976 if (rk_priv)
977 dwcmshc_rk35xx_postinit(host, priv);
978
979 err = __sdhci_add_host(host);
980 if (err)
981 goto err_setup_host;
982
48fe8fad
LS
983 pm_runtime_put(dev);
984
e438cf49
JZ
985 return 0;
986
c6f361cb
YZ
987err_setup_host:
988 sdhci_cleanup_host(host);
48fe8fad
LS
989err_rpm:
990 pm_runtime_disable(dev);
991 pm_runtime_put_noidle(dev);
e438cf49
JZ
992err_clk:
993 clk_disable_unprepare(pltfm_host->clk);
994 clk_disable_unprepare(priv->bus_clk);
08f3dff7 995 if (rk_priv)
86e1a8e1 996 clk_bulk_disable_unprepare(RK35xx_MAX_CLKS,
08f3dff7 997 rk_priv->rockchip_clks);
e438cf49
JZ
998free_pltfm:
999 sdhci_pltfm_free(pdev);
1000 return err;
1001}
1002
03749309
LS
1003static void dwcmshc_disable_card_clk(struct sdhci_host *host)
1004{
1005 u16 ctrl;
1006
1007 ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1008 if (ctrl & SDHCI_CLOCK_CARD_EN) {
1009 ctrl &= ~SDHCI_CLOCK_CARD_EN;
1010 sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
1011 }
1012}
1013
5905a1f1 1014static void dwcmshc_remove(struct platform_device *pdev)
e438cf49
JZ
1015{
1016 struct sdhci_host *host = platform_get_drvdata(pdev);
1017 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1018 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
86e1a8e1 1019 struct rk35xx_priv *rk_priv = priv->priv;
e438cf49 1020
03749309
LS
1021 pm_runtime_get_sync(&pdev->dev);
1022 pm_runtime_disable(&pdev->dev);
1023 pm_runtime_put_noidle(&pdev->dev);
1024
e438cf49
JZ
1025 sdhci_remove_host(host, 0);
1026
03749309
LS
1027 dwcmshc_disable_card_clk(host);
1028
e438cf49
JZ
1029 clk_disable_unprepare(pltfm_host->clk);
1030 clk_disable_unprepare(priv->bus_clk);
08f3dff7 1031 if (rk_priv)
86e1a8e1 1032 clk_bulk_disable_unprepare(RK35xx_MAX_CLKS,
08f3dff7 1033 rk_priv->rockchip_clks);
e438cf49 1034 sdhci_pltfm_free(pdev);
e438cf49
JZ
1035}
1036
bccce2ec
JZ
1037#ifdef CONFIG_PM_SLEEP
1038static int dwcmshc_suspend(struct device *dev)
1039{
1040 struct sdhci_host *host = dev_get_drvdata(dev);
1041 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1042 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
86e1a8e1 1043 struct rk35xx_priv *rk_priv = priv->priv;
bccce2ec
JZ
1044 int ret;
1045
48fe8fad
LS
1046 pm_runtime_resume(dev);
1047
bccce2ec
JZ
1048 ret = sdhci_suspend_host(host);
1049 if (ret)
1050 return ret;
1051
1052 clk_disable_unprepare(pltfm_host->clk);
1053 if (!IS_ERR(priv->bus_clk))
1054 clk_disable_unprepare(priv->bus_clk);
1055
08f3dff7 1056 if (rk_priv)
86e1a8e1 1057 clk_bulk_disable_unprepare(RK35xx_MAX_CLKS,
08f3dff7
SL
1058 rk_priv->rockchip_clks);
1059
bccce2ec
JZ
1060 return ret;
1061}
1062
1063static int dwcmshc_resume(struct device *dev)
1064{
1065 struct sdhci_host *host = dev_get_drvdata(dev);
1066 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1067 struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
86e1a8e1 1068 struct rk35xx_priv *rk_priv = priv->priv;
bccce2ec
JZ
1069 int ret;
1070
1071 ret = clk_prepare_enable(pltfm_host->clk);
1072 if (ret)
1073 return ret;
1074
1075 if (!IS_ERR(priv->bus_clk)) {
1076 ret = clk_prepare_enable(priv->bus_clk);
1077 if (ret)
a11937b3 1078 goto disable_clk;
bccce2ec
JZ
1079 }
1080
08f3dff7 1081 if (rk_priv) {
86e1a8e1 1082 ret = clk_bulk_prepare_enable(RK35xx_MAX_CLKS,
08f3dff7
SL
1083 rk_priv->rockchip_clks);
1084 if (ret)
a11937b3 1085 goto disable_bus_clk;
08f3dff7
SL
1086 }
1087
a11937b3
LS
1088 ret = sdhci_resume_host(host);
1089 if (ret)
1090 goto disable_rockchip_clks;
1091
1092 return 0;
1093
1094disable_rockchip_clks:
1095 if (rk_priv)
1096 clk_bulk_disable_unprepare(RK35xx_MAX_CLKS,
1097 rk_priv->rockchip_clks);
1098disable_bus_clk:
1099 if (!IS_ERR(priv->bus_clk))
1100 clk_disable_unprepare(priv->bus_clk);
1101disable_clk:
1102 clk_disable_unprepare(pltfm_host->clk);
1103 return ret;
bccce2ec
JZ
1104}
1105#endif
1106
48fe8fad
LS
1107#ifdef CONFIG_PM
1108
1109static void dwcmshc_enable_card_clk(struct sdhci_host *host)
1110{
1111 u16 ctrl;
1112
1113 ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
1114 if ((ctrl & SDHCI_CLOCK_INT_EN) && !(ctrl & SDHCI_CLOCK_CARD_EN)) {
1115 ctrl |= SDHCI_CLOCK_CARD_EN;
1116 sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
1117 }
1118}
1119
48fe8fad
LS
1120static int dwcmshc_runtime_suspend(struct device *dev)
1121{
1122 struct sdhci_host *host = dev_get_drvdata(dev);
1123
1124 dwcmshc_disable_card_clk(host);
1125
1126 return 0;
1127}
1128
1129static int dwcmshc_runtime_resume(struct device *dev)
1130{
1131 struct sdhci_host *host = dev_get_drvdata(dev);
1132
1133 dwcmshc_enable_card_clk(host);
1134
1135 return 0;
1136}
1137
1138#endif
1139
1140static const struct dev_pm_ops dwcmshc_pmops = {
1141 SET_SYSTEM_SLEEP_PM_OPS(dwcmshc_suspend, dwcmshc_resume)
1142 SET_RUNTIME_PM_OPS(dwcmshc_runtime_suspend,
1143 dwcmshc_runtime_resume, NULL)
1144};
bccce2ec 1145
e438cf49
JZ
1146static struct platform_driver sdhci_dwcmshc_driver = {
1147 .driver = {
1148 .name = "sdhci-dwcmshc",
a1a48919 1149 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
e438cf49 1150 .of_match_table = sdhci_dwcmshc_dt_ids,
eb81ed51 1151 .acpi_match_table = ACPI_PTR(sdhci_dwcmshc_acpi_ids),
bccce2ec 1152 .pm = &dwcmshc_pmops,
e438cf49
JZ
1153 },
1154 .probe = dwcmshc_probe,
5905a1f1 1155 .remove_new = dwcmshc_remove,
e438cf49
JZ
1156};
1157module_platform_driver(sdhci_dwcmshc_driver);
1158
1159MODULE_DESCRIPTION("SDHCI platform driver for Synopsys DWC MSHC");
1160MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
1161MODULE_LICENSE("GPL v2");