1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Description: SDHCI controller platform adaptation.
18 */
19
20 #define SDIO_DRV_DLL_SRST_REQ (0x1 << 29)
21 #define SDIO_CLK_EN (0x1 << 28)
22 #define SDIO_SRST_REQ (0x1 << 27)
23 #define SDIO_CLK_SEL (0x7 << 24)
24 #define SDIO_CLK_SEL_400K (0x1 << 24)
25
26 #define REG_EMMC_DRV_DLL_STATUS (CRG_REG_BASE + 0x210)
27 #define REG_SDIO0_DRV_DLL_STATUS REG_EMMC_DRV_DLL_STATUS
28 #define REG_SDIO1_DRV_DLL_STATUS (CRG_REG_BASE + 0x228)
29 #define SDIO_DRV_DLL_LOCK BIT(15)
30 #define SDIO_DRV_DLL_READY BIT(14)
31
32 #define REG_EMMC_SAMPL_DLL_STATUS (CRG_REG_BASE + 0x208)
33 #define REG_SDIO0_SAMPL_DLL_STATUS REG_EMMC_SAMPL_DLL_STATUS
34 #define REG_SDIO1_SAMPL_DLL_STATUS (CRG_REG_BASE + 0x224)
35 #define SDIO_SAMPL_DLL_SLAVE_READY BIT(0)
36
37 #define REG_EMMC_SAMPL_DLL_CTRL (CRG_REG_BASE + 0x1f4)
38 #define REG_SDIO0_SAMPL_DLL_CTRL REG_EMMC_SAMPL_DLL_CTRL
39 #define REG_SDIO1_SAMPL_DLL_CTRL (CRG_REG_BASE + 0x22c)
40 #define SDIO_SAMPL_DLL_SLAVE_EN BIT(16)
41
42 #define REG_EMMC_SAMPLB_DLL_CTRL (CRG_REG_BASE + 0x1f8)
43 #define REG_SDIO0_SAMPLB_DLL_CTRL REG_EMMC_SAMPLB_DLL_CTRL
44 #define REG_SDIO1_SAMPLB_DLL_CTRL (CRG_REG_BASE + 0x21c)
45 #define SDIO_SAMPLB_DLL_CLK_MASK (0x1f << 0)
46 #define sdio_samplb_sel(phase) ((phase) << 0)
47
48 #define REG_EMMC_DRV_DLL_CTRL (CRG_REG_BASE + 0x1fc)
49 #define REG_SDIO0_DRV_DLL_CTRL REG_EMMC_DRV_DLL_CTRL
50 #define REG_SDIO1_DRV_DLL_CTRL (CRG_REG_BASE + 0x220)
51 #define SDIO_DRV_PHASE_SEL_MASK (0x1f << 24)
52 #define sdio_drv_sel(phase) ((phase) << 24)
53
54 #define REG_EMMC_DS_DLL_CTRL (CRG_REG_BASE + 0x200)
55 #define EMMC_DS_DLL_MODE_SSEL BIT(13)
56 #define EMMC_DS_DLL_SSEL_MASK 0x7f
57
58 #define REG_EMMC_DS180_DLL_CTRL (CRG_REG_BASE + 0x204)
59 #define EMMC_DS180_DLL_BYPASS BIT(15)
60 #define REG_EMMC_DS180_DLL_STATUS (CRG_REG_BASE + 0x218)
61 #define EMMC_DS180_DLL_READY BIT(0)
62
63 #define IO_CFG_SR BIT(10)
64 #define IO_CFG_PULL_DOWN BIT(9)
65 #define IO_CFG_PULL_UP BIT(8)
66 #define IO_CFG_DRV_STR_MASK (0xf << 4)
67 #define io_cfg_drv_str_sel(str) ((str) << 4)
68
69 #define REG_IO_CFG_BASE 0x100C0000
70 /* EMMC_IOCFG */
71 #define IO_CFG_EMMC_DATA_LINE_COUNT 4
72 #define REG_CTRL_EMMC_CLK 0x0014
73 #define REG_CTRL_EMMC_CMD 0x0018
74 #define REG_CTRL_EMMC_DATA0 0x001c
75 #define REG_CTRL_EMMC_DATA1 0x0028
76 #define REG_CTRL_EMMC_DATA2 0x0024
77 #define REG_CTRL_EMMC_DATA3 0x0020
78 #define REG_CTRL_EMMC_DS 0x0058
79 #define REG_CTRL_EMMC_RST 0x005c
80 static unsigned int io_emmc_data_reg[IO_CFG_EMMC_DATA_LINE_COUNT] = {
81 REG_CTRL_EMMC_DATA0, REG_CTRL_EMMC_DATA1,
82 REG_CTRL_EMMC_DATA2, REG_CTRL_EMMC_DATA3
83 };
84
85 #define IO_CFG_SDIO0_DATA_LINE_COUNT 4
86 #define REG_CTRL_SDIO0_CLK 0x0040
87 #define REG_CTRL_SDIO0_CMD 0x0044
88 #define REG_CTRL_SDIO0_DATA0 0x0048
89 #define REG_CTRL_SDIO0_DATA1 0x004C
90 #define REG_CTRL_SDIO0_DATA2 0x0050
91 #define REG_CTRL_SDIO0_DATA3 0x0054
92 static unsigned int io_sdio0_data_reg[IO_CFG_SDIO0_DATA_LINE_COUNT] = {
93 REG_CTRL_SDIO0_DATA0, REG_CTRL_SDIO0_DATA1,
94 REG_CTRL_SDIO0_DATA2, REG_CTRL_SDIO0_DATA3
95 };
96
97 #define CLK_100K 100000
98 #define CLK_400K 400000
99 #define CLK_25M 25000000
100 #define CLK_50M 50000000
101 #define CLK_90M 90000000
102 #define CLK_112M 112000000
103 #define CLK_150M 150000000
104 #define CLK_198M 198000000
105
hisi_dll_reset_assert(struct sdhci_host * host)106 static void hisi_dll_reset_assert(struct sdhci_host *host)
107 {
108 uintptr_t crg_addr;
109 unsigned int reg;
110
111 crg_addr = REG_EMMC_CRG;
112 reg = readl(crg_addr);
113 reg |= SDIO_DRV_DLL_SRST_REQ;
114 writel(reg, crg_addr);
115 }
116
hisi_dll_reset_deassert(struct sdhci_host * host)117 static void hisi_dll_reset_deassert(struct sdhci_host *host)
118 {
119 uintptr_t crg_addr;
120 unsigned int reg;
121
122 crg_addr = REG_EMMC_CRG;
123 reg = readl(crg_addr);
124 reg &= ~SDIO_DRV_DLL_SRST_REQ;
125 writel(reg, crg_addr);
126 }
127
hisi_set_crg(struct sdhci_host * host,unsigned int clk)128 static void hisi_set_crg(struct sdhci_host *host, unsigned int clk)
129 {
130 uintptr_t crg_addr;
131 unsigned int sel, reg;
132 unsigned int clk_mux[] = {
133 CLK_100K, CLK_400K, CLK_25M, CLK_50M,
134 CLK_90M, CLK_112M, CLK_150M, CLK_198M
135 };
136
137 crg_addr = REG_EMMC_CRG;
138 reg = readl(crg_addr);
139 reg &= ~MMC_CLK_SEL_MASK;
140
141 if (clk <= MIN_FREQ) {
142 sel = 1;
143 } else {
144 for (sel = 0x6; sel > 0; sel--) {
145 if (clk >= clk_mux[sel])
146 break;
147 }
148 }
149
150 reg |= mmc_clk_sel(sel);
151 writel(reg, crg_addr);
152 }
153
hisi_wait_ds180_dll_ready(void)154 static void hisi_wait_ds180_dll_ready(void)
155 {
156 unsigned int reg;
157 unsigned int timeout = 20;
158
159 do {
160 reg = readl(REG_EMMC_DS180_DLL_STATUS);
161 if (reg & EMMC_DS180_DLL_READY)
162 return;
163
164 udelay(1000); /* delay 1000us */
165 timeout--;
166 } while (timeout > 0);
167
168 printf("DS180 DLL master not ready.\n");
169 }
170
hisi_mmc_priv_init(struct sdhci_host * host)171 static void hisi_mmc_priv_init(struct sdhci_host *host)
172 {
173 unsigned short ctrl;
174 unsigned int reg;
175
176 ctrl = sdhci_readw(host, SDHCI_MSHC_CTRL);
177 ctrl &= ~SDHCI_CMD_CONFLIT_CHECK;
178 sdhci_writew(host, ctrl, SDHCI_MSHC_CTRL);
179
180 reg = sdhci_readl(host, SDHCI_AXI_MBIIU_CTRL);
181 reg |= SDHCI_GM_WR_OSRC_LMT | SDHCI_GM_RD_OSRC_LMT;
182 reg &= ~SDHCI_UNDEFL_INCR_EN;
183 sdhci_writel(host, reg, SDHCI_AXI_MBIIU_CTRL);
184
185 reg = sdhci_readl(host, SDHCI_MULTI_CYCLE);
186 reg &= ~SDHCI_CMD_DLY_EN;
187 reg |= SDHCI_EDGE_DETECT_EN | SDHCI_DATA_DLY_EN;
188 sdhci_writel(host, reg, SDHCI_MULTI_CYCLE);
189 }
190
hisi_set_drv_str(unsigned int offset,unsigned int pull_up,unsigned int pull_down,unsigned int sr,unsigned int drv_str)191 static void hisi_set_drv_str(unsigned int offset, unsigned int pull_up,
192 unsigned int pull_down, unsigned int sr,
193 unsigned int drv_str)
194 {
195 unsigned int reg;
196 const uintptr_t crg_addr = REG_IO_CFG_BASE + offset;
197
198 reg = readl(crg_addr);
199 reg &= ~(IO_CFG_PULL_UP | IO_CFG_PULL_DOWN |
200 IO_CFG_DRV_STR_MASK | IO_CFG_SR);
201 reg |= (pull_up ? IO_CFG_PULL_UP : 0);
202 reg |= (pull_down ? IO_CFG_PULL_DOWN : 0);
203 reg |= (sr ? IO_CFG_SR : 0);
204 reg |= io_cfg_drv_str_sel(drv_str);
205 writel(reg, crg_addr);
206 }
207
sd_hardware_init(void)208 static int sd_hardware_init(void)
209 {
210 unsigned int reg;
211
212 /* clk enable */
213 reg = readl(REG_EMMC_CRG);
214 reg |= SDIO_CLK_EN;
215 writel(reg, REG_EMMC_CRG);
216
217 /* reset assert */
218 reg = readl(REG_EMMC_CRG);
219 reg |= SDIO_SRST_REQ | SDIO_DRV_DLL_SRST_REQ;
220 writel(reg, REG_EMMC_CRG);
221 udelay(25); /* delay 25us */
222
223 /* reset deassert */
224 reg &= ~SDIO_SRST_REQ;
225 writel(reg, REG_EMMC_CRG);
226 udelay(1); /* delay 1us */
227
228 udelay(5000); /* delay 5000us */
229
230 return 0;
231 }
232
emmc_hardware_init(void)233 static int emmc_hardware_init(void)
234 {
235 unsigned int reg;
236
237 /* eMMC clk enable */
238 reg = readl(REG_EMMC_CRG);
239 reg |= SDIO_CLK_EN;
240 writel(reg, REG_EMMC_CRG);
241
242 /* eMMC reset assert */
243 reg = readl(REG_EMMC_CRG);
244 reg |= SDIO_SRST_REQ | SDIO_DRV_DLL_SRST_REQ;
245 writel(reg, REG_EMMC_CRG);
246 udelay(25); /* delay 25us */
247
248 /* select 400K clk */
249 reg = readl(REG_EMMC_CRG);
250 reg &= ~SDIO_CLK_SEL;
251 reg |= SDIO_CLK_SEL_400K;
252 writel(reg, REG_EMMC_CRG);
253 udelay(25); /* delay 25us */
254
255 /* eMMC reset deassert */
256 reg = readl(REG_EMMC_CRG);
257 reg &= ~SDIO_SRST_REQ;
258 writel(reg, REG_EMMC_CRG);
259 udelay(1); /* delay 1us */
260
261 return 0;
262 }
263
hisi_emmc_set_ioconfig(struct sdhci_host * host)264 static void hisi_emmc_set_ioconfig(struct sdhci_host *host)
265 {
266 int i;
267
268 switch (host->mmc->selected_mode) {
269 case MMC_HS_400:
270 case MMC_HS_400_ES:
271 hisi_set_drv_str(REG_CTRL_EMMC_CLK, 0, 1, 0, 0x3); /* set drv level 3 */
272 hisi_set_drv_str(REG_CTRL_EMMC_CMD, 1, 0, 0, 0x4); /* set drv level 4 */
273 for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++)
274 hisi_set_drv_str(io_emmc_data_reg[i], 1, 0, 0, 0x4); /* set drv level 4 */
275
276 hisi_set_drv_str(REG_CTRL_EMMC_DS, 0, 1, 1, 0x3); /* set drv level 3 */
277 hisi_set_drv_str(REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */
278 break;
279 case MMC_HS_200:
280 hisi_set_drv_str(REG_CTRL_EMMC_CLK, 0, 1, 0, 0x2); /* set drv level 2 */
281 hisi_set_drv_str(REG_CTRL_EMMC_CMD, 1, 0, 1, 0x4); /* set drv level 4 */
282 for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++)
283 hisi_set_drv_str(io_emmc_data_reg[i], 1, 0, 1, 0x4); /* set drv level 4 */
284
285 hisi_set_drv_str(REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */
286 break;
287 case MMC_HS:
288 case MMC_HS_52:
289 hisi_set_drv_str(REG_CTRL_EMMC_CLK, 0, 1, 1, 0x4); /* set drv level 4 */
290 hisi_set_drv_str(REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */
291 for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++)
292 hisi_set_drv_str(io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */
293
294 hisi_set_drv_str(REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */
295 break;
296 case MMC_LEGACY:
297 default:
298 hisi_set_drv_str(REG_CTRL_EMMC_CLK, 0, 1, 1, 0x5); /* set drv level 5 */
299 hisi_set_drv_str(REG_CTRL_EMMC_CMD, 1, 0, 1, 0x6); /* set drv level 6 */
300 for (i = 0; i < IO_CFG_EMMC_DATA_LINE_COUNT; i++)
301 hisi_set_drv_str(io_emmc_data_reg[i], 1, 0, 1, 0x6); /* set drv level 6 */
302
303 hisi_set_drv_str(REG_CTRL_EMMC_RST, 1, 0, 1, 0x3); /* set drv level 3 */
304 break;
305 }
306 }
307
hisi_sd_set_ioconfig(struct sdhci_host * host)308 static void hisi_sd_set_ioconfig(struct sdhci_host *host)
309 {
310 int i;
311
312 switch (host->mmc->selected_mode) {
313 case SD_HS:
314 hisi_set_drv_str(REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x5); /* set drv level 5 */
315 hisi_set_drv_str(REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */
316 for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++)
317 hisi_set_drv_str(io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */
318 break;
319 case SD_LEGACY:
320 default:
321 hisi_set_drv_str(REG_CTRL_SDIO0_CLK, 0, 1, 1, 0x7); /* set drv level 7 */
322 hisi_set_drv_str(REG_CTRL_SDIO0_CMD, 1, 0, 1, 0x7); /* set drv level 7 */
323 for (i = 0; i < IO_CFG_SDIO0_DATA_LINE_COUNT; i++)
324 hisi_set_drv_str(io_sdio0_data_reg[i], 1, 0, 1, 0x7); /* set drv level 7 */
325 break;
326 }
327 }
328
hisi_mmc_set_ioconfig(struct sdhci_host * host)329 static void hisi_mmc_set_ioconfig(struct sdhci_host *host)
330 {
331 unsigned int reg;
332
333 if (host->type == MMC_TYPE_MMC) {
334 reg = sdhci_readw(host, SDHCI_EMMC_CTRL);
335 reg |= SDHCI_CARD_IS_EMMC;
336 sdhci_writew(host, reg, SDHCI_EMMC_CTRL);
337
338 hisi_emmc_set_ioconfig(host);
339 } else {
340 hisi_sd_set_ioconfig(host);
341 }
342 sdhci_set_uhs_timing(host);
343 }
344
hisi_set_phase(struct sdhci_host * host)345 static void hisi_set_phase(struct sdhci_host *host)
346 {
347 unsigned int drv_phase, sample_phase;
348
349 if (host->mmc->selected_mode == MMC_HS_400_ES ||
350 host->mmc->selected_mode == MMC_HS_400) {
351 drv_phase = 10; /* 10 for 112.5 degree */
352 sample_phase = host->tuning_phase;
353 } else if (host->mmc->selected_mode == MMC_HS_200) {
354 drv_phase = 23; /* 23 for 258.75 degree */
355 sample_phase = host->tuning_phase;
356 } else if (host->mmc->selected_mode == MMC_HS ||
357 host->mmc->selected_mode == MMC_HS_52) {
358 drv_phase = 16; /* 16 for 180 degree */
359 sample_phase = 4; /* 4 for 45 degree */
360 } else if (host->mmc->selected_mode == SD_HS) {
361 drv_phase = 20; /* 20 for 225 degree */
362 sample_phase = 4; /* 4 for 45 degree */
363 } else if (host->mmc->selected_mode == MMC_LEGACY ||
364 host->mmc->selected_mode == SD_LEGACY) {
365 drv_phase = 16; /* 16 for 180 degree */
366 sample_phase = 0; /* 0 for degree */
367 } else {
368 drv_phase = 16; /* 16 for 180 degree */
369 sample_phase = 4; /* 4 for 45 degree */
370 }
371
372 hisi_set_drv_phase(host, drv_phase);
373 hisi_enable_sample(host);
374 hisi_set_sampl_phase(host, sample_phase);
375
376 udelay(25); /* delay 25us */
377 }
378
hisi_wait_drv_dll_lock(struct sdhci_host * host)379 static void hisi_wait_drv_dll_lock(struct sdhci_host *host)
380 {
381 unsigned int timeout = 20;
382 unsigned int reg;
383 uintptr_t reg_addr;
384
385 reg_addr = host->type == MMC_TYPE_MMC ?
386 REG_EMMC_DRV_DLL_STATUS : REG_SDIO0_DRV_DLL_STATUS;
387 do {
388 reg = readl(reg_addr);
389 if (reg & SDIO_DRV_DLL_LOCK)
390 return;
391
392 udelay(1000); /* delay 1000us */
393 timeout--;
394 } while (timeout > 0);
395
396 printf("sdhci-hisi: DRV DLL master not locked.\n");
397 }
398
hisi_enable_sampl_dll_slave(struct sdhci_host * host)399 static void hisi_enable_sampl_dll_slave(struct sdhci_host *host)
400 {
401 unsigned int reg;
402 uintptr_t reg_addr;
403
404 reg_addr = host->type == MMC_TYPE_MMC ?
405 REG_EMMC_SAMPL_DLL_CTRL : REG_SDIO0_SAMPL_DLL_CTRL;
406 reg = readl(reg_addr);
407 reg |= SDIO_SAMPL_DLL_SLAVE_EN;
408 writel(reg, reg_addr);
409 }
410
hisi_mmc_set_clk(struct sdhci_host * host,unsigned int clk)411 static int hisi_mmc_set_clk(struct sdhci_host *host, unsigned int clk)
412 {
413 hisi_dll_reset_assert(host);
414 udelay(25); /* delay 25us */
415 hisi_set_crg(host, clk);
416 hisi_set_phase(host);
417 udelay(25); /* delay 25us */
418
419 if (clk > MMC_HIGH_52_MAX_DTR) {
420 hisi_enable_sampl_dll_slave(host);
421 hisi_dll_reset_deassert(host);
422 }
423
424 hisi_enable_internal_clk(host);
425
426 if (clk > MMC_HIGH_52_MAX_DTR) {
427 hisi_wait_drv_dll_lock(host);
428 hisi_wait_sampl_dll_slave_ready(host);
429 hisi_wait_ds180_dll_ready();
430 }
431
432 hisi_enable_card_clk(host);
433 udelay(100); /* delay 100us */
434
435 return 0;
436 }