1 /*
2 * Sunxi SD/MMC host driver
3 *
4 * Copyright (C) 2015 AllWinnertech Ltd.
5 * Author: lixiang <lixiang@allwinnertech>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17
18 #ifdef CONFIG_ARCH_SUN50IW1P1
19
20 #include <linux/clk.h>
21 #include <sunxi-clk.h>
22
23 #include <linux/gpio.h>
24 #include <linux/platform_device.h>
25 #include <linux/spinlock.h>
26 #include <linux/scatterlist.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/slab.h>
29 #include <linux/reset.h>
30
31 #include <linux/of_address.h>
32 #include <linux/of_gpio.h>
33 #include <linux/of_platform.h>
34
35 #include <linux/mmc/host.h>
36 #include <linux/mmc/sd.h>
37 #include <linux/mmc/sdio.h>
38 #include <linux/mmc/mmc.h>
39 #include <linux/mmc/core.h>
40 #include <linux/mmc/card.h>
41 #include <linux/mmc/slot-gpio.h>
42
43 #include "sunxi-mmc.h"
44 #include "sunxi-mmc-sun50iw1p1-2.h"
45
46 /*reg*/
47 /*SMHC eMMC4.5 DDR Start Bit Detection Control Register */
48 /*SMHC CRC Status Detect Control Register */
49 /*SMHC Card Threshold Control Register */
50 /*SMHC Drive Delay Control Register */
51 /*SMHC Sample Delay Control Register */
52 /*SMHC Data Strobe Delay Control Register */
53 #define SDXC_REG_EDSD (0x010C)
54 #define SDXC_REG_CSDC (0x0054)
55 #define SDXC_REG_THLD (0x0100)
56 #define SDXC_REG_DRV_DL (0x0140)
57 #define SDXC_REG_SAMP_DL (0x0144)
58 #define SDXC_REG_DS_DL (0x0148)
59
60 /*bit*/
61 #define SDXC_HS400_MD_EN (1U<<31)
62 #define SDXC_CARD_WR_THLD_ENB (1U<<2)
63 #define SDXC_CARD_RD_THLD_ENB (1U)
64
65 #define SDXC_DAT_DRV_PH_SEL (1U<<17)
66 #define SDXC_CMD_DRV_PH_SEL (1U<<16)
67 #define SDXC_SAMP_DL_SW_EN (1u<<7)
68 #define SDXC_DS_DL_SW_EN (1u<<7)
69
70 /*mask*/
71 #define SDXC_CRC_DET_PARA_MASK (0xf)
72 #define SDXC_CARD_RD_THLD_MASK (0x0FFF0000)
73 #define SDXC_TX_TL_MASK (0xff)
74 #define SDXC_RX_TL_MASK (0x00FF0000)
75
76 #define SDXC_SAMP_DL_SW_MASK (0x0000003F)
77 #define SDXC_DS_DL_SW_MASK (0x0000003F)
78
79 /*value*/
80 #define SDXC_CRC_DET_PARA_HS400 (6)
81 #define SDXC_CRC_DET_PARA_OTHER (3)
82 #define SDXC_FIFO_DETH (1024>>2)
83
84 /*size*/
85 #define SDXC_CARD_RD_THLD_SIZE (0x00000FFF)
86
87 /*shit*/
88 #define SDXC_CARD_RD_THLD_SIZE_SHIFT (16)
89
90 struct sunxi_mmc_spec_regs {
91 u32 drv_dl; /*REG_DRV_DL */
92 u32 samp_dl; /*REG_SAMP_DL */
93 u32 ds_dl; /*REG_DS_DL */
94 /*u32 sd_ntsr;//REG_SD_NTSR */
95 u32 edsd; /*REG_EDSD */
96 u32 csdc; /*REG_CSDC */
97 };
98
99 static struct sunxi_mmc_spec_regs bak_spec_regs;
100
101 enum sunxi_mmc_speed_mode {
102 SM0_DS26_SDR12 = 0,
103 SM1_HSSDR52_SDR25,
104 SM2_HSDDR52_DDR50,
105 SM3_HS200_SDR104,
106 SM4_HS400,
107 SM_NUM,
108 };
109
110 struct sunxi_mmc_clk_dly {
111 enum sunxi_mmc_speed_mode spm;
112 char *mod_str;
113 char *raw_tm_sm_str[2];
114 u32 raw_tm_sm[2];
115 u32 raw_tm_sm_def[2];
116 };
117
118 static struct sunxi_mmc_clk_dly mmc_clk_dly[SM_NUM] = {
119 [SM0_DS26_SDR12] = {
120 .spm = SM0_DS26_SDR12,
121 .mod_str = "DS26_SDR12",
122 .raw_tm_sm_str[0] = "sdc_tm4_sm0_freq0",
123 .raw_tm_sm_str[1] = "sdc_tm4_sm0_freq1",
124 .raw_tm_sm[0] = 0,
125 .raw_tm_sm[1] = 0,
126 .raw_tm_sm_def[0] = 0,
127 .raw_tm_sm_def[1] = 0,
128 },
129 [SM1_HSSDR52_SDR25] = {
130 .spm = SM1_HSSDR52_SDR25,
131 .mod_str = "HSSDR52_SDR25",
132 .raw_tm_sm_str[0] = "sdc_tm4_sm1_freq0",
133 .raw_tm_sm_str[1] = "sdc_tm4_sm1_freq1",
134 .raw_tm_sm[0] = 0,
135 .raw_tm_sm[1] = 0,
136 .raw_tm_sm_def[0] = 0,
137 .raw_tm_sm_def[1] = 0,
138 },
139 [SM2_HSDDR52_DDR50] = {
140 .spm = SM2_HSDDR52_DDR50,
141 .mod_str = "HSDDR52_DDR50",
142 .raw_tm_sm_str[0] = "sdc_tm4_sm2_freq0",
143 .raw_tm_sm_str[1] = "sdc_tm4_sm2_freq1",
144 .raw_tm_sm[0] = 0,
145 .raw_tm_sm[1] = 0,
146 .raw_tm_sm_def[0] = 0,
147 .raw_tm_sm_def[1] = 0,
148 },
149 [SM3_HS200_SDR104] = {
150 .spm = SM3_HS200_SDR104,
151 .mod_str = "HS200_SDR104",
152 .raw_tm_sm_str[0] = "sdc_tm4_sm3_freq0",
153 .raw_tm_sm_str[1] = "sdc_tm4_sm3_freq1",
154 .raw_tm_sm[0] = 0,
155 .raw_tm_sm[1] = 0,
156 .raw_tm_sm_def[0] = 0,
157 .raw_tm_sm_def[1] = 0x00000405,
158 },
159 [SM4_HS400] = {
160 .spm = SM4_HS400,
161 .mod_str = "HS400",
162 .raw_tm_sm_str[0] = "sdc_tm4_sm4_freq0",
163 .raw_tm_sm_str[1] = "sdc_tm4_sm4_freq1",
164 .raw_tm_sm[0] = 0,
165 .raw_tm_sm[1] = 0x00000608,
166 .raw_tm_sm_def[0] = 0,
167 .raw_tm_sm_def[1] = 0x00000408,
168 },
169 };
170
sunxi_mmc_set_clk_dly(struct sunxi_mmc_host * host,int clk,int bus_width,int timing)171 static void sunxi_mmc_set_clk_dly(struct sunxi_mmc_host *host, int clk,
172 int bus_width, int timing)
173 {
174 struct mmc_host *mmc = host->mmc;
175 enum sunxi_mmc_speed_mode speed_mod = SM0_DS26_SDR12;
176 char *raw_sm_str = NULL;
177 char *m_str = NULL;
178 struct device_node *np = NULL;
179 u32 *raw_sm = 0;
180 u32 *raw_sm_def = 0;
181 u32 rval = 0;
182 int frq_index = 0;
183 u32 cmd_drv_ph = 1;
184 u32 dat_drv_ph = 0;
185 u32 sam_dly = 0;
186 u32 ds_dly = 0;
187
188 if (!mmc->parent || !mmc->parent->of_node) {
189 SM_ERR(mmc_dev(host->mmc),
190 "no dts to parse clk dly,use default\n");
191 return;
192 }
193
194 np = mmc->parent->of_node;
195
196 switch (timing) {
197 case MMC_TIMING_LEGACY:
198 case MMC_TIMING_UHS_SDR12:
199 speed_mod = SM0_DS26_SDR12;
200 break;
201 case MMC_TIMING_MMC_HS:
202 case MMC_TIMING_SD_HS:
203 case MMC_TIMING_UHS_SDR25:
204 speed_mod = SM1_HSSDR52_SDR25;
205 break;
206 case MMC_TIMING_UHS_DDR50:
207 case MMC_TIMING_MMC_DDR52:
208 speed_mod = SM2_HSDDR52_DDR50;
209 dat_drv_ph = 1;
210 break;
211 case MMC_TIMING_UHS_SDR50:
212 case MMC_TIMING_UHS_SDR104:
213 case MMC_TIMING_MMC_HS200:
214 speed_mod = SM3_HS200_SDR104;
215 break;
216 case MMC_TIMING_MMC_HS400:
217 speed_mod = SM4_HS400;
218 break;
219 default:
220 SM_ERR(mmc_dev(mmc), "Wrong timing input\n");
221 return;
222 }
223
224 if (clk <= 400 * 1000) {
225 frq_index = 0;
226 } else if (clk <= 25 * 1000 * 1000) {
227 frq_index = 1;
228 } else if (clk <= 50 * 1000 * 1000) {
229 frq_index = 2;
230 } else if (clk <= 100 * 1000 * 1000) {
231 frq_index = 3;
232 } else if (clk <= 150 * 1000 * 1000) {
233 frq_index = 4;
234 } else if (clk <= 200 * 1000 * 1000) {
235 frq_index = 5;
236 } else if (clk <= 250 * 1000 * 1000) {
237 frq_index = 6;
238 } else if (clk <= 300 * 1000 * 1000) {
239 frq_index = 7;
240 } else {
241 SM_ERR(mmc_dev(mmc), "clk is over 300mhz\n");
242 return;
243 }
244
245 if (frq_index / 4 > 2) {
246 SM_ERR(mmc_dev(host->mmc), "err frq_index\n");
247 return;
248 }
249 SM_DBG(mmc_dev(host->mmc), "freq %d frq index %d,frq/4 %x\n", clk,
250 frq_index, frq_index / 4);
251 raw_sm_str = mmc_clk_dly[speed_mod].raw_tm_sm_str[frq_index / 4];
252 raw_sm = &mmc_clk_dly[speed_mod].raw_tm_sm[frq_index / 4];
253 raw_sm_def = &mmc_clk_dly[speed_mod].raw_tm_sm_def[frq_index / 4];
254 m_str = mmc_clk_dly[speed_mod].mod_str;
255
256 rval = of_property_read_u32(np, raw_sm_str, raw_sm);
257 if (rval) {
258 SM_INFO(mmc_dev(host->mmc), "failded to get %s used default\n",
259 m_str);
260 } else {
261 u32 sm_shift = (frq_index % 4) * 8;
262
263 rval = ((*raw_sm) >> sm_shift) & 0xff;
264 if (rval != 0xff) {
265 if (timing == MMC_TIMING_MMC_HS400) {
266 u32 raw_sm_hs200 = 0;
267
268 ds_dly = rval;
269 raw_sm_hs200 =
270 mmc_clk_dly[SM3_HS200_SDR104].
271 raw_tm_sm[frq_index / 4];
272 sam_dly = ((raw_sm_hs200) >> sm_shift) & 0xff;
273 } else {
274 sam_dly = rval;
275 }
276 SM_DBG(mmc_dev(host->mmc),
277 "Get speed mode %s clk dly %s ok\n", m_str,
278 raw_sm_str);
279 } else {
280 u32 sm_shift = (frq_index % 4) * 8;
281
282 SM_DBG(mmc_dev(host->mmc), "%s use default value\n",
283 m_str);
284 rval = ((*raw_sm_def) >> sm_shift) & 0xff;
285 if (timing == MMC_TIMING_MMC_HS400) {
286 u32 raw_sm_hs200 = 0;
287
288 ds_dly = rval;
289 raw_sm_hs200 =
290 mmc_clk_dly[SM3_HS200_SDR104].
291 raw_tm_sm_def[frq_index / 4];
292 sam_dly = ((raw_sm_hs200) >> sm_shift) & 0xff;
293 } else {
294 sam_dly = rval;
295 }
296 }
297
298 }
299
300 SM_DBG(mmc_dev(host->mmc), "Try set %s clk dly ok\n", m_str);
301 SM_DBG(mmc_dev(host->mmc), "cmd_drv_ph %d\n", cmd_drv_ph);
302 SM_DBG(mmc_dev(host->mmc), "dat_drv_ph %d\n", dat_drv_ph);
303 SM_DBG(mmc_dev(host->mmc), "sam_dly %d\n", sam_dly);
304 SM_DBG(mmc_dev(host->mmc), "ds_dly %d\n", ds_dly);
305
306 rval = mmc_readl(host, REG_DRV_DL);
307 if (cmd_drv_ph)
308 rval |= SDXC_CMD_DRV_PH_SEL; /*180 phase */
309 else
310 rval &= ~SDXC_CMD_DRV_PH_SEL; /*90 phase */
311
312
313 if (dat_drv_ph)
314 rval |= SDXC_DAT_DRV_PH_SEL; /*180 phase */
315 else
316 rval &= ~SDXC_DAT_DRV_PH_SEL; /*90 phase */
317
318 sunxi_r_op(host, mmc_writel(host, REG_DRV_DL, rval));
319
320 rval = mmc_readl(host, REG_SAMP_DL);
321 rval &= ~SDXC_SAMP_DL_SW_MASK;
322 rval |= sam_dly & SDXC_SAMP_DL_SW_MASK;
323 rval |= SDXC_SAMP_DL_SW_EN;
324 mmc_writel(host, REG_SAMP_DL, rval);
325
326 rval = mmc_readl(host, REG_DS_DL);
327 rval &= ~SDXC_DS_DL_SW_MASK;
328 rval |= ds_dly & SDXC_DS_DL_SW_MASK;
329 rval |= SDXC_DS_DL_SW_EN;
330 mmc_writel(host, REG_DS_DL, rval);
331
332 SM_DBG(mmc_dev(host->mmc), " REG_DRV_DL %08x\n",
333 mmc_readl(host, REG_DRV_DL));
334 SM_DBG(mmc_dev(host->mmc), " REG_SAMP_DL %08x\n",
335 mmc_readl(host, REG_SAMP_DL));
336 SM_DBG(mmc_dev(host->mmc), " REG_DS_DL %08x\n",
337 mmc_readl(host, REG_DS_DL));
338
339 }
340
sunxi_mmc_dump_dly2(struct sunxi_mmc_host * host)341 void sunxi_mmc_dump_dly2(struct sunxi_mmc_host *host)
342 {
343 int i = 0;
344
345 for (i = 0; i < SM_NUM; i++) {
346 pr_info("mod_str %s\n", mmc_clk_dly[i].mod_str);
347 pr_info("raw_tm_sm_str %s\n", mmc_clk_dly[i].raw_tm_sm_str[0]);
348 pr_info("raw_tm_sm_str %s\n", mmc_clk_dly[i].raw_tm_sm_str[1]);
349 pr_info("raw_tm_sm0 %x\n", mmc_clk_dly[i].raw_tm_sm[0]);
350 pr_info("raw_tm_sm1 %x\n", mmc_clk_dly[i].raw_tm_sm[1]);
351 pr_info("********************\n");
352 }
353 }
354
__sunxi_mmc_do_oclk_onoff(struct sunxi_mmc_host * host,u32 oclk_en,u32 pwr_save,u32 ignore_dat0)355 static int __sunxi_mmc_do_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en,
356 u32 pwr_save, u32 ignore_dat0)
357 {
358 unsigned long expire = jiffies + msecs_to_jiffies(250);
359 u32 rval;
360
361 rval = mmc_readl(host, REG_CLKCR);
362 rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON | SDXC_MASK_DATA0);
363
364 if (oclk_en)
365 rval |= SDXC_CARD_CLOCK_ON;
366 if (pwr_save)
367 rval |= SDXC_LOW_POWER_ON;
368 if (ignore_dat0)
369 rval |= SDXC_MASK_DATA0;
370
371 mmc_writel(host, REG_CLKCR, rval);
372
373 SM_DBG(mmc_dev(host->mmc), "%s REG_CLKCR:%x\n", __func__,
374 mmc_readl(host, REG_CLKCR));
375
376 rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER;
377 mmc_writel(host, REG_CMDR, rval);
378
379 do {
380 rval = mmc_readl(host, REG_CMDR);
381 } while (time_before(jiffies, expire) && (rval & SDXC_START));
382
383 /* clear irq status bits set by the command */
384 /*? */
385 mmc_writel(host, REG_RINTR,
386 mmc_readl(host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT);
387
388 if (rval & SDXC_START) {
389 SM_ERR(mmc_dev(host->mmc), "fatal err update clk timeout\n");
390 return -EIO;
391 }
392
393 /*only use mask data0 when update clk,clear it when not update clk */
394 if (ignore_dat0)
395 mmc_writel(host, REG_CLKCR,
396 mmc_readl(host, REG_CLKCR) & ~SDXC_MASK_DATA0);
397
398 return 0;
399 }
400
sunxi_mmc_oclk_onoff(struct sunxi_mmc_host * host,u32 oclk_en)401 static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
402 {
403 struct device_node *np = NULL;
404 struct mmc_host *mmc = host->mmc;
405 int pwr_save = 0;
406 int len = 0;
407
408 if (!mmc->parent || !mmc->parent->of_node) {
409 SM_ERR(mmc_dev(host->mmc),
410 "no dts to parse power save mode\n");
411 return -EIO;
412 }
413
414 np = mmc->parent->of_node;
415 if (of_find_property(np, "sunxi-power-save-mode", &len))
416 pwr_save = 1;
417 return __sunxi_mmc_do_oclk_onoff(host, oclk_en, pwr_save, 1);
418 }
419
sunxi_mmc_oclk_onoff_sdmmc2(struct sunxi_mmc_host * host,u32 oclk_en)420 int sunxi_mmc_oclk_onoff_sdmmc2(struct sunxi_mmc_host *host, u32 oclk_en)
421 {
422 return sunxi_mmc_oclk_onoff(host, oclk_en);
423 }
424
sunxi_mmc_clk_set_rate_for_sdmmc2(struct sunxi_mmc_host * host,struct mmc_ios * ios)425 int sunxi_mmc_clk_set_rate_for_sdmmc2(struct sunxi_mmc_host *host,
426 struct mmc_ios *ios)
427 {
428 u32 mod_clk = 0;
429 u32 src_clk = 0;
430 u32 rval = 0;
431 s32 err = 0;
432 u32 rate = 0;
433 char *sclk_name = NULL;
434 struct clk *mclk = host->clk_mmc;
435 struct clk *sclk = NULL;
436 struct device *dev = mmc_dev(host->mmc);
437 int div = 0;
438
439 if (ios->clock == 0) {
440 __sunxi_mmc_do_oclk_onoff(host, 0, 0, 1);
441 return 0;
442 }
443
444 if ((ios->bus_width == MMC_BUS_WIDTH_8)
445 && (ios->timing == MMC_TIMING_MMC_DDR52)
446 ) {
447 mod_clk = ios->clock << 2;
448 div = 1;
449 } else {
450 mod_clk = ios->clock << 1;
451 div = 0;
452 }
453
454 if (ios->clock <= 400000) {
455 sclk = clk_get(dev, "osc24m");
456 sclk_name = "osc24m";
457 } else {
458 sclk = clk_get(dev, "pll_periph");
459 sclk_name = "pll_periph";
460 }
461 if (IS_ERR(sclk)) {
462 SM_ERR(mmc_dev(host->mmc), "Error to get source clock %s\n",
463 sclk_name);
464 return -1;
465 }
466
467 sunxi_mmc_oclk_onoff(host, 0);
468
469 err = clk_set_parent(mclk, sclk);
470 if (err) {
471 SM_ERR(mmc_dev(host->mmc), "set parent failed\n");
472 clk_put(sclk);
473 return -1;
474 }
475
476 rate = clk_round_rate(mclk, mod_clk);
477
478 SM_DBG(mmc_dev(host->mmc), "get round rate %d\n", rate);
479
480 clk_disable_unprepare(host->clk_mmc);
481
482 err = clk_set_rate(mclk, rate);
483 if (err) {
484 SM_ERR(mmc_dev(host->mmc), "set mclk rate error, rate %dHz\n",
485 rate);
486 clk_put(sclk);
487 return -1;
488 }
489
490 rval = clk_prepare_enable(host->clk_mmc);
491 if (rval) {
492 SM_ERR(mmc_dev(host->mmc), "Enable mmc clk err %d\n", rval);
493 return -1;
494 }
495
496 src_clk = clk_get_rate(sclk);
497 clk_put(sclk);
498
499 SM_DBG(mmc_dev(host->mmc), "set round clock %d, soure clk is %d\n",
500 rate, src_clk);
501
502 #ifdef MMC_FPGA
503 if ((ios->bus_width == MMC_BUS_WIDTH_8)
504 && (ios->timing == MMC_TIMING_MMC_DDR52)
505 ) {
506 /* clear internal divider */
507 rval = mmc_readl(host, REG_CLKCR);
508 rval &= ~0xff;
509 rval |= 1;
510 } else {
511 /* support internal divide clock under fpga environment */
512 rval = mmc_readl(host, REG_CLKCR);
513 rval &= ~0xff;
514 rval |= 24000000 / mod_clk / 2; /* =24M/400K/2=0x1E*/
515 }
516 mmc_writel(host, REG_CLKCR, rval);
517 SM_INFO(mmc_dev(host->mmc), "--FPGA REG_CLKCR: 0x%08x\n",
518 mmc_readl(host, REG_CLKCR));
519 #else
520 /* clear internal divider */
521 rval = mmc_readl(host, REG_CLKCR);
522 rval &= ~0xff;
523 rval |= div;
524 mmc_writel(host, REG_CLKCR, rval);
525 #endif
526
527 if ((ios->bus_width == MMC_BUS_WIDTH_8)
528 && (ios->timing == MMC_TIMING_MMC_HS400)
529 ) {
530 rval = mmc_readl(host, REG_EDSD);
531 rval |= SDXC_HS400_MD_EN;
532 mmc_writel(host, REG_EDSD, rval);
533 rval = mmc_readl(host, REG_CSDC);
534 rval &= ~SDXC_CRC_DET_PARA_MASK;
535 rval |= SDXC_CRC_DET_PARA_HS400;
536 mmc_writel(host, REG_CSDC, rval);
537 } else {
538 rval = mmc_readl(host, REG_EDSD);
539 rval &= ~SDXC_HS400_MD_EN;
540 mmc_writel(host, REG_EDSD, rval);
541 rval = mmc_readl(host, REG_CSDC);
542 rval &= ~SDXC_CRC_DET_PARA_MASK;
543 rval |= SDXC_CRC_DET_PARA_OTHER;
544 mmc_writel(host, REG_CSDC, rval);
545 }
546 SM_DBG(mmc_dev(host->mmc), "SDXC_REG_EDSD: 0x%08x\n",
547 mmc_readl(host, REG_EDSD));
548 SM_DBG(mmc_dev(host->mmc), "SDXC_REG_CSDC: 0x%08x\n",
549 mmc_readl(host, REG_CSDC));
550
551 if ((ios->bus_width == MMC_BUS_WIDTH_8)
552 && (ios->timing == MMC_TIMING_MMC_DDR52)
553 ) {
554 ios->clock = rate >> 2;
555 } else {
556 ios->clock = rate >> 1;
557 }
558
559 sunxi_mmc_set_clk_dly(host, ios->clock, ios->bus_width, ios->timing);
560
561 return sunxi_mmc_oclk_onoff(host, 1);
562 }
563
sunxi_mmc_thld_ctl_for_sdmmc2(struct sunxi_mmc_host * host,struct mmc_ios * ios,struct mmc_data * data)564 void sunxi_mmc_thld_ctl_for_sdmmc2(struct sunxi_mmc_host *host,
565 struct mmc_ios *ios, struct mmc_data *data)
566 {
567 u32 bsz = data->blksz;
568 /*unit:byte */
569 u32 tdtl = (host->dma_tl & SDXC_TX_TL_MASK) << 2;
570 /*unit:byte */
571 u32 rdtl = ((host->dma_tl & SDXC_RX_TL_MASK) >> 16) << 2;
572 u32 rval = 0;
573
574 if ((data->flags & MMC_DATA_WRITE)
575 && (bsz <= SDXC_CARD_RD_THLD_SIZE)
576 && (bsz <= tdtl)) {
577 rval = mmc_readl(host, REG_THLD);
578 rval &= ~SDXC_CARD_RD_THLD_MASK;
579 rval |= data->blksz << SDXC_CARD_RD_THLD_SIZE_SHIFT;
580 rval |= SDXC_CARD_WR_THLD_ENB;
581 mmc_writel(host, REG_THLD, rval);
582 } else {
583 rval = mmc_readl(host, REG_THLD);
584 rval &= ~SDXC_CARD_WR_THLD_ENB;
585 mmc_writel(host, REG_THLD, rval);
586 }
587
588 if ((data->flags & MMC_DATA_READ)
589 && (bsz <= SDXC_CARD_RD_THLD_SIZE)
590 /*((SDXC_FIFO_DETH<<2)-bsz) >= (rdtl) */
591 && ((SDXC_FIFO_DETH << 2) >= (rdtl + bsz))
592 && ((ios->timing == MMC_TIMING_MMC_HS200)
593 || (ios->timing == MMC_TIMING_MMC_HS400))) {
594 rval = mmc_readl(host, REG_THLD);
595 rval &= ~SDXC_CARD_RD_THLD_MASK;
596 rval |= data->blksz << SDXC_CARD_RD_THLD_SIZE_SHIFT;
597 rval |= SDXC_CARD_RD_THLD_ENB;
598 mmc_writel(host, REG_THLD, rval);
599 } else {
600 rval = mmc_readl(host, REG_THLD);
601 rval &= ~SDXC_CARD_RD_THLD_ENB;
602 mmc_writel(host, REG_THLD, rval);
603 }
604
605 SM_DBG(mmc_dev(host->mmc), "--SDXC_REG_THLD: 0x%08x\n",
606 mmc_readl(host, REG_THLD));
607
608 }
609
sunxi_mmc_save_spec_reg2(struct sunxi_mmc_host * host)610 void sunxi_mmc_save_spec_reg2(struct sunxi_mmc_host *host)
611 {
612 bak_spec_regs.drv_dl = mmc_readl(host, REG_DRV_DL);
613 bak_spec_regs.samp_dl = mmc_readl(host, REG_SAMP_DL);
614 bak_spec_regs.ds_dl = mmc_readl(host, REG_DS_DL);
615 /*bak_spec_regs.sd_ntsr = mmc_readl(host,REG_SD_NTSR);*/
616 bak_spec_regs.edsd = mmc_readl(host, REG_EDSD);
617 bak_spec_regs.csdc = mmc_readl(host, REG_CSDC);
618 }
619
sunxi_mmc_restore_spec_reg2(struct sunxi_mmc_host * host)620 void sunxi_mmc_restore_spec_reg2(struct sunxi_mmc_host *host)
621 {
622 sunxi_r_op(host, mmc_writel(host, REG_DRV_DL, bak_spec_regs.drv_dl));
623 mmc_writel(host, REG_SAMP_DL, bak_spec_regs.samp_dl);
624 mmc_writel(host, REG_DS_DL, bak_spec_regs.ds_dl);
625 /*mmc_writel(host,REG_SD_NTSR,bak_spec_regs.sd_ntsr);*/
626 mmc_writel(host, REG_EDSD, bak_spec_regs.edsd);
627 mmc_writel(host, REG_CSDC, bak_spec_regs.csdc);
628 }
629 #endif
630