Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bdk/storage/sdmmc_driver.c
3694 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018-2025 CTCaer
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms and conditions of the GNU General Public License,
7
* version 2, as published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* 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
18
#include <string.h>
19
20
#include <storage/mmc_def.h>
21
#include <storage/sdmmc.h>
22
#include <gfx_utils.h>
23
#include <power/max7762x.h>
24
#include <soc/bpmp.h>
25
#include <soc/clock.h>
26
#include <soc/gpio.h>
27
#include <soc/hw_init.h>
28
#include <soc/pinmux.h>
29
#include <soc/pmc.h>
30
#include <soc/timer.h>
31
#include <soc/t210.h>
32
33
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
34
//#define ERROR_EXTRA_PRINTING
35
#define DPRINTF(...)
36
37
#ifdef BDK_SDMMC_EXTRA_PRINT
38
#define ERROR_EXTRA_PRINTING
39
#endif
40
41
/*! SCMMC controller base addresses. */
42
static const u16 _sdmmc_base_offsets[4] = { 0x0, 0x200, 0x400, 0x600 };
43
44
int sdmmc_get_io_power(sdmmc_t *sdmmc)
45
{
46
u32 p = sdmmc->regs->pwrcon;
47
if (!(p & SDHCI_POWER_ON))
48
return SDMMC_POWER_OFF;
49
if (p & SDHCI_POWER_180)
50
return SDMMC_POWER_1_8;
51
if (p & SDHCI_POWER_330)
52
return SDMMC_POWER_3_3;
53
return -1;
54
}
55
56
static int _sdmmc_set_io_power(sdmmc_t *sdmmc, u32 power)
57
{
58
switch (power)
59
{
60
case SDMMC_POWER_OFF:
61
sdmmc->regs->pwrcon &= ~SDHCI_POWER_ON;
62
break;
63
64
case SDMMC_POWER_1_8:
65
sdmmc->regs->pwrcon = SDHCI_POWER_180;
66
break;
67
68
case SDMMC_POWER_3_3:
69
sdmmc->regs->pwrcon = SDHCI_POWER_330;
70
break;
71
72
default:
73
return 1;
74
}
75
76
if (power != SDMMC_POWER_OFF)
77
sdmmc->regs->pwrcon |= SDHCI_POWER_ON;
78
79
return 0;
80
}
81
82
u32 sdmmc_get_bus_width(sdmmc_t *sdmmc)
83
{
84
u32 h = sdmmc->regs->hostctl;
85
if (h & SDHCI_CTRL_8BITBUS) // eMMC only (or UHS-II).
86
return SDMMC_BUS_WIDTH_8;
87
if (h & SDHCI_CTRL_4BITBUS) // SD only.
88
return SDMMC_BUS_WIDTH_4;
89
return SDMMC_BUS_WIDTH_1;
90
}
91
92
void sdmmc_set_bus_width(sdmmc_t *sdmmc, u32 bus_width)
93
{
94
u32 host_control = sdmmc->regs->hostctl & ~(SDHCI_CTRL_4BITBUS | SDHCI_CTRL_8BITBUS);
95
96
if (bus_width == SDMMC_BUS_WIDTH_1)
97
sdmmc->regs->hostctl = host_control;
98
else if (bus_width == SDMMC_BUS_WIDTH_4)
99
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_4BITBUS; // SD only.
100
else if (bus_width == SDMMC_BUS_WIDTH_8)
101
sdmmc->regs->hostctl = host_control | SDHCI_CTRL_8BITBUS; // eMMC only (or UHS-II).
102
}
103
104
void sdmmc_save_tap_value(sdmmc_t *sdmmc)
105
{
106
sdmmc->venclkctl_tap = (sdmmc->regs->venclkctl & 0xFF0000) >> 16;
107
sdmmc->venclkctl_set = 1;
108
}
109
110
static int _sdmmc_config_tap_val(sdmmc_t *sdmmc, u32 type)
111
{
112
static const u32 dqs_trim_val = 40; // 24 if HS533/HS667.
113
static const u8 tap_values_t210[4] = { 4, 0, 3, 0 };
114
115
u32 tap_val = 0;
116
117
if (type == SDHCI_TIMING_MMC_HS400)
118
sdmmc->regs->vencapover = (sdmmc->regs->vencapover & ~0x3F00) | (dqs_trim_val << 8);
119
120
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
121
122
if (type == SDHCI_TIMING_MMC_HS400)
123
{
124
// Tap is saved during HS200 switch.
125
if (!sdmmc->venclkctl_set)
126
return 1;
127
128
tap_val = sdmmc->venclkctl_tap;
129
}
130
else
131
tap_val = sdmmc->t210b01 ? 11 : tap_values_t210[sdmmc->id];
132
133
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & ~0xFF0000) | (tap_val << 16);
134
135
return 0;
136
}
137
138
static void _sdmmc_commit_changes(sdmmc_t *sdmmc)
139
{
140
(void)sdmmc->regs->clkcon;
141
}
142
143
static void _sdmmc_pad_config_fallback(sdmmc_t *sdmmc, u32 power)
144
{
145
_sdmmc_commit_changes(sdmmc);
146
switch (sdmmc->id)
147
{
148
case SDMMC_1: // 50 Ohm 2X Driver.
149
if (power == SDMMC_POWER_OFF)
150
break;
151
u32 sdmmc1_pad_cfg = APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xF8080FFF;
152
if (sdmmc->t210b01)
153
sdmmc1_pad_cfg |= (0x808 << 12); // Up: 8, Dn: 8. For 50 ohm.
154
else if (power == SDMMC_POWER_1_8)
155
sdmmc1_pad_cfg |= (0xB0F << 12); // Up: 11, Dn: 15. For 50 ohm.
156
else if (power == SDMMC_POWER_3_3)
157
sdmmc1_pad_cfg |= (0xC0C << 12); // Up: 12, Dn: 12. For 50 ohm.
158
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = sdmmc1_pad_cfg;
159
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
160
break;
161
162
case SDMMC_2:
163
if (sdmmc->t210b01)
164
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) & 0xF8080FFF) | 0xA0A000;
165
else
166
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) & 0xFFFFC003) | 0x1040; // PU:16, PD:16.
167
(void)APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL);
168
break;
169
170
case SDMMC_4: // 50 Ohm 2X Driver. PU:16, PD:16, B01: PU:10, PD:10.
171
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) & 0xFFFFC003) |
172
(sdmmc->t210b01 ? 0xA28 : 0x1040);
173
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
174
break;
175
}
176
}
177
178
static void _sdmmc_autocal_execute(sdmmc_t *sdmmc, u32 power)
179
{
180
bool should_enable_sd_clock = false;
181
if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
182
{
183
should_enable_sd_clock = true;
184
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
185
}
186
187
// Enable E_INPUT (SD) or Disable E_PWRD (eMMC) power.
188
if (!(sdmmc->regs->sdmemcmppadctl & SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD))
189
{
190
sdmmc->regs->sdmemcmppadctl |= SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD;
191
_sdmmc_commit_changes(sdmmc);
192
usleep(1);
193
}
194
195
// Enable auto calibration and start auto configuration.
196
sdmmc->regs->autocalcfg |= SDHCI_TEGRA_AUTOCAL_ENABLE | SDHCI_TEGRA_AUTOCAL_START;
197
_sdmmc_commit_changes(sdmmc);
198
usleep(2);
199
200
u32 timeout = get_tmr_ms() + 10;
201
while (sdmmc->regs->autocalsts & SDHCI_TEGRA_AUTOCAL_ACTIVE)
202
{
203
if (get_tmr_ms() > timeout)
204
{
205
timeout = 0; // Set timeout to 0 if we timed out.
206
break;
207
}
208
}
209
210
#ifdef ERROR_EXTRA_PRINTING
211
// Check if Comp pad is open or short to ground.
212
// SDMMC1: CZ pads - T210/T210B01: 7-bit/5-bit. SDMMC2/4: LV_CZ pads - 5-bit.
213
// Use 0x1F mask for all.
214
u8 autocal_pu_status = sdmmc->regs->autocalsts & 0x1F;
215
if (!autocal_pu_status)
216
EPRINTFARGS("SDMMC%d: Comp Pad open!", sdmmc->id + 1); // Or resistance is extreme.
217
else if (autocal_pu_status == 0x1F)
218
EPRINTFARGS("SDMMC%d: Comp Pad short to gnd!", sdmmc->id + 1);
219
#endif
220
221
// In case auto calibration fails, we load suggested standard values.
222
if (!timeout)
223
{
224
sdmmc->regs->autocalcfg &= ~SDHCI_TEGRA_AUTOCAL_ENABLE;
225
_sdmmc_pad_config_fallback(sdmmc, power);
226
#ifdef ERROR_EXTRA_PRINTING
227
EPRINTFARGS("SDMMC%d: Comp Pad cal timeout!", sdmmc->id + 1);
228
#endif
229
}
230
231
// Disable E_INPUT (SD) or enable E_PWRD (eMMC) to conserve power.
232
sdmmc->regs->sdmemcmppadctl &= ~SDHCI_TEGRA_PADCTRL_E_INPUT_PWRD;
233
234
if (should_enable_sd_clock)
235
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
236
}
237
238
static int _sdmmc_dll_cal_execute(sdmmc_t *sdmmc)
239
{
240
int res = 0, should_disable_sd_clock = 0;
241
242
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
243
{
244
should_disable_sd_clock = 1;
245
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
246
}
247
248
// Add -4 TX_DLY_CODE_OFFSET if HS533/HS667.
249
// if (sdmmc->id == SDMMC_4 && sdmmc->card_clock > 208000)
250
// sdmmc->regs->vendllctl0 = sdmmc->regs->vendllctl0 &= 0xFFFFC07F | (0x7C << 7);
251
252
sdmmc->regs->vendllcalcfg |= SDHCI_TEGRA_DLLCAL_CALIBRATE;
253
_sdmmc_commit_changes(sdmmc);
254
255
u32 timeout = get_tmr_ms() + 5;
256
while (sdmmc->regs->vendllcalcfg & SDHCI_TEGRA_DLLCAL_CALIBRATE)
257
{
258
if (get_tmr_ms() > timeout)
259
{
260
res = 1;
261
goto out;
262
}
263
}
264
265
timeout = get_tmr_ms() + 10;
266
while (sdmmc->regs->vendllcalcfgsts & SDHCI_TEGRA_DLLCAL_ACTIVE)
267
{
268
if (get_tmr_ms() > timeout)
269
{
270
res = 1;
271
goto out;
272
}
273
}
274
275
out:
276
if (should_disable_sd_clock)
277
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
278
279
return res;
280
}
281
282
static void _sdmmc_reset_cmd_data(sdmmc_t *sdmmc)
283
{
284
sdmmc->regs->swrst |= SDHCI_RESET_CMD | SDHCI_RESET_DATA;
285
_sdmmc_commit_changes(sdmmc);
286
u32 timeout = get_tmr_ms() + 2000;
287
while ((sdmmc->regs->swrst & (SDHCI_RESET_CMD | SDHCI_RESET_DATA)) && get_tmr_ms() < timeout)
288
;
289
}
290
291
static void _sdmmc_reset_all(sdmmc_t *sdmmc)
292
{
293
sdmmc->regs->swrst |= SDHCI_RESET_ALL;
294
_sdmmc_commit_changes(sdmmc);
295
u32 timeout = get_tmr_ms() + 2000;//100ms
296
while ((sdmmc->regs->swrst & SDHCI_RESET_ALL) && get_tmr_ms() < timeout)
297
;
298
}
299
300
void sdmmc_setup_drv_type(sdmmc_t *sdmmc, u32 type)
301
{
302
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_DRV_TYPE_MASK)) | SDHCI_CTRL_DRV_TYPE(type);
303
304
_sdmmc_commit_changes(sdmmc);
305
}
306
307
int sdmmc_setup_clock(sdmmc_t *sdmmc, u32 type)
308
{
309
// Disable the SD clock if it was enabled, and reenable it later.
310
bool should_enable_sd_clock = false;
311
if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
312
{
313
should_enable_sd_clock = true;
314
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
315
}
316
317
_sdmmc_config_tap_val(sdmmc, type);
318
319
_sdmmc_reset_cmd_data(sdmmc);
320
321
switch (type)
322
{
323
case SDHCI_TIMING_MMC_ID:
324
case SDHCI_TIMING_MMC_LS26:
325
case SDHCI_TIMING_SD_ID:
326
case SDHCI_TIMING_SD_DS12:
327
sdmmc->regs->hostctl &= ~SDHCI_CTRL_HISPD;
328
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180;
329
break;
330
331
case SDHCI_TIMING_MMC_HS52:
332
case SDHCI_TIMING_SD_HS25:
333
sdmmc->regs->hostctl |= SDHCI_CTRL_HISPD;
334
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_VDD_180;
335
break;
336
337
case SDHCI_TIMING_MMC_HS200:
338
case SDHCI_TIMING_UHS_SDR50: // T210 Errata: the host must be set to SDR104 to WAR a CRC issue.
339
case SDHCI_TIMING_UHS_SDR104:
340
case SDHCI_TIMING_UHS_SDR82:
341
case SDHCI_TIMING_MMC_HS100:
342
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR104_BUS_SPEED;
343
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
344
break;
345
346
case SDHCI_TIMING_MMC_HS400:
347
// Non standard.
348
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | HS400_BUS_SPEED;
349
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
350
break;
351
352
case SDHCI_TIMING_UHS_SDR25:
353
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR25_BUS_SPEED;
354
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
355
break;
356
357
case SDHCI_TIMING_UHS_SDR12:
358
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_SDR12_BUS_SPEED;
359
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
360
break;
361
362
case SDHCI_TIMING_UHS_DDR50:
363
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
364
case SDHCI_TIMING_UHS_DDR200:
365
#endif
366
sdmmc->regs->hostctl2 = (sdmmc->regs->hostctl2 & (~SDHCI_CTRL_UHS_MASK)) | UHS_DDR50_BUS_SPEED;
367
sdmmc->regs->hostctl2 |= SDHCI_CTRL_VDD_180;
368
break;
369
}
370
371
_sdmmc_commit_changes(sdmmc);
372
373
u32 clock;
374
u16 divisor;
375
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
376
clock_sdmmc_config_clock_source(&clock, sdmmc->id, clock);
377
sdmmc->card_clock = (clock + divisor - 1) / divisor;
378
379
// (divisor != 1) && (divisor & 1) -> error
380
381
u16 div_lo = divisor >> 1;
382
u16 div_hi = div_lo >> 8;
383
384
sdmmc->regs->clkcon = (sdmmc->regs->clkcon & ~(SDHCI_DIV_MASK | SDHCI_DIV_HI_MASK)) |
385
(div_lo << SDHCI_DIV_LO_SHIFT) | (div_hi << SDHCI_DIV_HI_SHIFT);
386
387
// Enable the SD clock again.
388
if (should_enable_sd_clock)
389
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
390
391
if (type == SDHCI_TIMING_MMC_HS400)
392
return _sdmmc_dll_cal_execute(sdmmc);
393
394
return 0;
395
}
396
397
static void _sdmmc_card_clock_enable(sdmmc_t *sdmmc)
398
{
399
// Recalibrate periodically if needed.
400
if (sdmmc->periodic_calibration && !sdmmc->powersave_enabled)
401
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
402
403
if (!sdmmc->powersave_enabled)
404
{
405
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
406
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
407
}
408
sdmmc->card_clock_enabled = 1;
409
}
410
411
static void _sdmmc_card_clock_disable(sdmmc_t *sdmmc)
412
{
413
sdmmc->card_clock_enabled = 0;
414
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
415
}
416
417
void sdmmc_card_clock_powersave(sdmmc_t *sdmmc, int powersave_enable)
418
{
419
// Recalibrate periodically if needed.
420
if (sdmmc->periodic_calibration && !powersave_enable && sdmmc->card_clock_enabled)
421
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
422
423
sdmmc->powersave_enabled = powersave_enable;
424
if (powersave_enable)
425
{
426
if (sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN)
427
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
428
return;
429
}
430
431
if (sdmmc->card_clock_enabled)
432
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
433
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
434
}
435
436
static int _sdmmc_cache_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
437
{
438
switch (type)
439
{
440
case SDMMC_RSP_TYPE_1:
441
case SDMMC_RSP_TYPE_3:
442
case SDMMC_RSP_TYPE_6:
443
case SDMMC_RSP_TYPE_7:
444
rsp[0] = sdmmc->regs->rspreg[0];
445
break;
446
447
case SDMMC_RSP_TYPE_2:
448
// CRC is stripped, so shifting is needed.
449
for (u32 i = 0; i < 4; i++)
450
{
451
u32 tempreg = sdmmc->regs->rspreg[3 - i];
452
rsp[i] = tempreg << 8;
453
454
if (i != 0)
455
rsp[i - 1] |= (tempreg >> 24) & 0xFF;
456
}
457
break;
458
459
default:
460
return 1;
461
}
462
463
return 0;
464
}
465
466
int sdmmc_get_cached_rsp(sdmmc_t *sdmmc, u32 *rsp, u32 type)
467
{
468
if (sdmmc->expected_rsp_type != type)
469
return 1;
470
471
switch (type)
472
{
473
case SDMMC_RSP_TYPE_1:
474
case SDMMC_RSP_TYPE_3:
475
case SDMMC_RSP_TYPE_6:
476
case SDMMC_RSP_TYPE_7:
477
rsp[0] = sdmmc->rsp[0];
478
break;
479
480
case SDMMC_RSP_TYPE_2:
481
for (u32 i = 0; i < 4; i++)
482
rsp[i] = sdmmc->rsp[i];
483
break;
484
485
default:
486
return 1;
487
}
488
489
return 0;
490
}
491
492
static int _sdmmc_wait_cmd_data_inhibit(sdmmc_t *sdmmc, bool wait_dat)
493
{
494
_sdmmc_commit_changes(sdmmc);
495
496
u32 timeout = get_tmr_ms() + 2000;
497
while (sdmmc->regs->prnsts & SDHCI_CMD_INHIBIT)
498
if (get_tmr_ms() > timeout)
499
{
500
_sdmmc_reset_cmd_data(sdmmc);
501
return 1;
502
}
503
504
if (wait_dat)
505
{
506
timeout = get_tmr_ms() + 2000;
507
while (sdmmc->regs->prnsts & SDHCI_DATA_INHIBIT)
508
if (get_tmr_ms() > timeout)
509
{
510
_sdmmc_reset_cmd_data(sdmmc);
511
return 1;
512
}
513
}
514
515
return 0;
516
}
517
518
static int _sdmmc_wait_card_busy(sdmmc_t *sdmmc)
519
{
520
_sdmmc_commit_changes(sdmmc);
521
522
u32 timeout = get_tmr_ms() + 2000;
523
while (!(sdmmc->regs->prnsts & SDHCI_DATA_0_LVL))
524
if (get_tmr_ms() > timeout)
525
{
526
_sdmmc_reset_cmd_data(sdmmc);
527
return 1;
528
}
529
530
return 0;
531
}
532
533
static int _sdmmc_setup_read_small_block(sdmmc_t *sdmmc)
534
{
535
switch (sdmmc_get_bus_width(sdmmc))
536
{
537
case SDMMC_BUS_WIDTH_1:
538
return 1;
539
540
case SDMMC_BUS_WIDTH_4:
541
sdmmc->regs->blksize = 64;
542
break;
543
544
case SDMMC_BUS_WIDTH_8:
545
sdmmc->regs->blksize = 128;
546
break;
547
}
548
549
sdmmc->regs->blkcnt = 1;
550
sdmmc->regs->trnmod = SDHCI_TRNS_READ;
551
552
return 0;
553
}
554
555
static int _sdmmc_send_cmd(sdmmc_t *sdmmc, const sdmmc_cmd_t *cmd, bool is_data_present)
556
{
557
u16 cmdflags = 0;
558
559
switch (cmd->rsp_type)
560
{
561
case SDMMC_RSP_TYPE_0:
562
break;
563
564
case SDMMC_RSP_TYPE_1:
565
case SDMMC_RSP_TYPE_6:
566
case SDMMC_RSP_TYPE_7:
567
if (cmd->check_busy)
568
cmdflags = SDHCI_CMD_RESP_LEN48_BUSY | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
569
else
570
cmdflags = SDHCI_CMD_RESP_LEN48 | SDHCI_CMD_INDEX | SDHCI_CMD_CRC;
571
break;
572
573
case SDMMC_RSP_TYPE_2:
574
cmdflags = SDHCI_CMD_RESP_LEN136 | SDHCI_CMD_CRC;
575
break;
576
577
case SDMMC_RSP_TYPE_3:
578
cmdflags = SDHCI_CMD_RESP_LEN48;
579
break;
580
581
default:
582
return 1;
583
}
584
585
if (is_data_present)
586
cmdflags |= SDHCI_CMD_DATA;
587
588
sdmmc->regs->argument = cmd->arg;
589
sdmmc->regs->cmdreg = SDHCI_CMD_IDX(cmd->cmd) | cmdflags;
590
591
return 0;
592
}
593
594
static void _sdmmc_send_tuning_cmd(sdmmc_t *sdmmc, u32 cmd)
595
{
596
sdmmc_cmd_t cmdbuf;
597
cmdbuf.cmd = cmd;
598
cmdbuf.arg = 0;
599
cmdbuf.rsp_type = SDMMC_RSP_TYPE_1;
600
cmdbuf.check_busy = 0;
601
_sdmmc_send_cmd(sdmmc, &cmdbuf, true);
602
}
603
604
static int _sdmmc_tuning_execute_once(sdmmc_t *sdmmc, u32 cmd, u32 tap)
605
{
606
if (_sdmmc_wait_cmd_data_inhibit(sdmmc, true))
607
return 1;
608
609
_sdmmc_setup_read_small_block(sdmmc);
610
611
sdmmc->regs->norintstsen |= SDHCI_INT_DATA_AVAIL;
612
sdmmc->regs->norintsts = sdmmc->regs->norintsts;
613
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
614
615
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
616
// Set tap if manual tuning.
617
if (tap != SDMMC_HW_TAP_TUNING)
618
{
619
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
620
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (tap << 16);
621
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
622
}
623
#endif
624
625
_sdmmc_send_tuning_cmd(sdmmc, cmd);
626
_sdmmc_commit_changes(sdmmc);
627
usleep(1);
628
629
_sdmmc_reset_cmd_data(sdmmc);
630
631
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
632
_sdmmc_commit_changes(sdmmc);
633
634
u32 timeout = get_tmr_us() + 5000;
635
while (get_tmr_us() < timeout)
636
{
637
// Check if we got valid data.
638
if (sdmmc->regs->norintsts & SDHCI_INT_DATA_AVAIL)
639
{
640
sdmmc->regs->norintsts = SDHCI_INT_DATA_AVAIL;
641
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
642
_sdmmc_commit_changes(sdmmc);
643
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
644
645
return 0;
646
}
647
}
648
649
_sdmmc_reset_cmd_data(sdmmc);
650
651
sdmmc->regs->norintstsen &= ~SDHCI_INT_DATA_AVAIL;
652
_sdmmc_commit_changes(sdmmc);
653
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
654
655
return 1;
656
}
657
658
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
659
typedef struct _sdmmc_manual_tuning_t
660
{
661
u32 result[8];
662
u32 num_iter;
663
u32 tap_start;
664
u32 tap_end;
665
} sdmmc_manual_tuning_t;
666
667
static int _sdmmc_manual_tuning_set_tap(sdmmc_t *sdmmc, sdmmc_manual_tuning_t *tuning)
668
{
669
u32 tap_start = SDMMC_INVALID_TAP;
670
u32 win_size = 0;
671
u32 best_tap = 0;
672
u32 best_size = 0;
673
674
for (u32 i = 0; i < tuning->num_iter; i++)
675
{
676
u32 iter_end = i == (tuning->num_iter - 1) ? 1 : 0;
677
u32 stable = tuning->result[i / 32] & BIT(i % 32);
678
if (stable && !iter_end)
679
{
680
if (tap_start == SDMMC_INVALID_TAP)
681
tap_start = i;
682
683
win_size++;
684
}
685
else
686
{
687
if (tap_start != SDMMC_INVALID_TAP)
688
{
689
u32 tap_end = !iter_end ? (i - 1) : i;
690
691
// Check if window is wider.
692
if (win_size > best_size)
693
{
694
best_tap = (tap_start + tap_end) / 2;
695
best_size = win_size + iter_end;
696
}
697
698
tap_start = SDMMC_INVALID_TAP;
699
win_size = 0;
700
}
701
}
702
}
703
704
705
// Check if failed or window too small.
706
if (!best_tap || best_size < SDMMC_SAMPLE_WIN_SIZE_MIN)
707
return 1;
708
709
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
710
sdmmc->regs->ventunctl0 &= ~SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
711
712
// Set tap.
713
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xFF00FFFF) | (best_tap << 16);
714
715
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
716
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
717
718
return 0;
719
}
720
721
/*
722
* SD Card DDR200 (DDR208) support
723
*
724
* On Tegra X1, that can be done with DDR50 host mode.
725
* That's because HS400 4-bit or HS400 generally, is not supported on SDMMC1/3.
726
* And also, tuning can't be done automatically on any DDR mode.
727
* So it needs to be done manually and selected tap will be applied from the biggest
728
* sampling window.
729
* That allows DDR200 support on every DDR200 sd card, other than the original maker
730
* of DDR200, Sandisk. Since Sandisk cards mandate DLL syncing.
731
*/
732
static int sdmmc_tuning_execute_ddr200(sdmmc_t *sdmmc)
733
{
734
sdmmc_manual_tuning_t manual_tuning = { 0 };
735
manual_tuning.num_iter = 128;
736
737
sdmmc->regs->ventunctl1 = 0; // step_size 1.
738
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | (2 << 13); // 128 Tries.
739
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
740
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
741
742
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
743
744
for (u32 i = 0; i < manual_tuning.num_iter; i++)
745
{
746
_sdmmc_tuning_execute_once(sdmmc, MMC_SEND_TUNING_BLOCK, i);
747
748
// Save result for manual tuning.
749
int sampled = (sdmmc->regs->hostctl2 >> SDHCI_CTRL_TUNED_CLK_SHIFT) & 1;
750
manual_tuning.result[i / 32] |= sampled << (i % 32);
751
752
if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))
753
break;
754
}
755
756
return _sdmmc_manual_tuning_set_tap(sdmmc, &manual_tuning);
757
}
758
#endif
759
760
int sdmmc_tuning_execute(sdmmc_t *sdmmc, u32 type, u32 cmd)
761
{
762
u32 num_iter, flag;
763
764
if (sdmmc->powersave_enabled)
765
return 1;
766
767
switch (type)
768
{
769
case SDHCI_TIMING_MMC_HS200:
770
case SDHCI_TIMING_UHS_SDR104:
771
case SDHCI_TIMING_UHS_SDR82:
772
num_iter = 128;
773
flag = (2 << 13); // 128 iterations.
774
break;
775
776
case SDHCI_TIMING_UHS_SDR50:
777
case SDHCI_TIMING_UHS_DDR50: // HW tuning is not supported on DDR modes. But it sets tap to 0 which is proper.
778
case SDHCI_TIMING_MMC_HS100:
779
num_iter = 256;
780
flag = (4 << 13); // 256 iterations.
781
break;
782
783
case SDHCI_TIMING_MMC_HS400:
784
case SDHCI_TIMING_UHS_SDR12:
785
case SDHCI_TIMING_UHS_SDR25:
786
return 0;
787
788
#ifdef BDK_SDMMC_UHS_DDR200_SUPPORT
789
case SDHCI_TIMING_UHS_DDR200:
790
return sdmmc_tuning_execute_ddr200(sdmmc);
791
#endif
792
793
default:
794
return 1;
795
}
796
797
sdmmc->regs->ventunctl1 = 0; // step_size 1.
798
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFF1FFF) | flag; // Tries.
799
sdmmc->regs->ventunctl0 = (sdmmc->regs->ventunctl0 & 0xFFFFE03F) | (1 << 6); // 1x Multiplier.
800
sdmmc->regs->ventunctl0 |= SDHCI_TEGRA_TUNING_TAP_HW_UPDATED;
801
802
sdmmc->regs->hostctl2 |= SDHCI_CTRL_EXEC_TUNING;
803
804
for (u32 i = 0; i < num_iter; i++)
805
{
806
_sdmmc_tuning_execute_once(sdmmc, cmd, SDMMC_HW_TAP_TUNING);
807
808
if (!(sdmmc->regs->hostctl2 & SDHCI_CTRL_EXEC_TUNING))
809
break;
810
}
811
812
if (sdmmc->regs->hostctl2 & SDHCI_CTRL_TUNED_CLK)
813
return 0;
814
815
return 1;
816
}
817
818
static int _sdmmc_enable_internal_clock(sdmmc_t *sdmmc)
819
{
820
//Enable internal clock and wait till it is stable.
821
sdmmc->regs->clkcon |= SDHCI_CLOCK_INT_EN;
822
_sdmmc_commit_changes(sdmmc);
823
u32 timeout = get_tmr_ms() + 2000;
824
while (!(sdmmc->regs->clkcon & SDHCI_CLOCK_INT_STABLE))
825
{
826
if (get_tmr_ms() > timeout)
827
return 1;
828
}
829
830
sdmmc->regs->hostctl2 &= ~SDHCI_CTRL_PRESET_VAL_EN;
831
sdmmc->regs->clkcon &= ~SDHCI_PROG_CLOCK_MODE;
832
// Enable 32/64bit addressing if used (sysad. if blkcnt it fallbacks to 16bit).
833
sdmmc->regs->hostctl2 |= SDHCI_HOST_VERSION_4_EN;
834
835
if (!(sdmmc->regs->capareg & SDHCI_CAP_64BIT))
836
return 1;
837
838
sdmmc->regs->hostctl2 |= SDHCI_ADDRESSING_64BIT_EN;
839
sdmmc->regs->hostctl &= ~SDHCI_CTRL_DMA_MASK; // Use SDMA. Host V4 enabled so adma address regs in use.
840
sdmmc->regs->timeoutcon = (sdmmc->regs->timeoutcon & 0xF0) | 14; // TMCLK * 2^27.
841
842
return 0;
843
}
844
845
static int _sdmmc_autocal_config_offset(sdmmc_t *sdmmc, u32 power)
846
{
847
u32 off_pd = 0;
848
u32 off_pu = 0;
849
850
switch (sdmmc->id)
851
{
852
case SDMMC_2:
853
case SDMMC_4:
854
if (power != SDMMC_POWER_1_8)
855
return 1;
856
off_pd = 5;
857
off_pu = 5;
858
break;
859
860
case SDMMC_1:
861
if (power == SDMMC_POWER_1_8)
862
{
863
if (!sdmmc->t210b01)
864
{
865
off_pd = 0x7B; // -5.
866
off_pu = 0x7B; // -5.
867
}
868
else
869
{
870
off_pd = 6;
871
off_pu = 6;
872
}
873
}
874
else if (power == SDMMC_POWER_3_3)
875
{
876
if (!sdmmc->t210b01)
877
{
878
off_pd = 0x7D; // -3.
879
off_pu = 0;
880
}
881
}
882
else
883
return 1;
884
break;
885
}
886
887
sdmmc->regs->autocalcfg = (sdmmc->regs->autocalcfg & 0xFFFF8080) | (off_pd << 8) | off_pu;
888
return 0;
889
}
890
891
static void _sdmmc_enable_interrupts(sdmmc_t *sdmmc)
892
{
893
sdmmc->regs->norintstsen |= SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE;
894
sdmmc->regs->errintstsen |= SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR;
895
sdmmc->regs->norintsts = sdmmc->regs->norintsts;
896
sdmmc->regs->errintsts = sdmmc->regs->errintsts;
897
sdmmc->error_sts = 0;
898
}
899
900
static void _sdmmc_mask_interrupts(sdmmc_t *sdmmc)
901
{
902
sdmmc->regs->errintstsen &= ~SDHCI_ERR_INT_ALL_EXCEPT_ADMA_BUSPWR;
903
sdmmc->regs->norintstsen &= ~(SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
904
}
905
906
static u32 _sdmmc_check_mask_interrupt(sdmmc_t *sdmmc, u16 *pout, u16 mask)
907
{
908
u16 norintsts = sdmmc->regs->norintsts;
909
u16 errintsts = sdmmc->regs->errintsts;
910
911
DPRINTF("norintsts %08X, errintsts %08X\n", norintsts, errintsts);
912
913
if (pout)
914
*pout = norintsts;
915
916
// Check for error interrupt.
917
if (norintsts & SDHCI_INT_ERROR)
918
{
919
#ifdef ERROR_EXTRA_PRINTING
920
EPRINTFARGS("SDMMC%d: intsts %08X, errintsts %08X", sdmmc->id + 1, norintsts, errintsts);
921
#endif
922
sdmmc->error_sts = errintsts;
923
sdmmc->regs->errintsts = errintsts;
924
return SDMMC_MASKINT_ERROR;
925
}
926
else if (norintsts & mask)
927
{
928
sdmmc->regs->norintsts = norintsts & mask;
929
return SDMMC_MASKINT_MASKED;
930
}
931
932
return SDMMC_MASKINT_NOERROR;
933
}
934
935
static int _sdmmc_wait_response(sdmmc_t *sdmmc)
936
{
937
_sdmmc_commit_changes(sdmmc);
938
939
u32 timeout = get_tmr_ms() + 2000;
940
while (true)
941
{
942
u32 res = _sdmmc_check_mask_interrupt(sdmmc, NULL, SDHCI_INT_RESPONSE);
943
if (res == SDMMC_MASKINT_MASKED)
944
break;
945
if (res != SDMMC_MASKINT_NOERROR || get_tmr_ms() > timeout)
946
{
947
_sdmmc_reset_cmd_data(sdmmc);
948
return 1;
949
}
950
}
951
952
return 0;
953
}
954
955
static int _sdmmc_stop_transmission_inner(sdmmc_t *sdmmc, u32 *rsp)
956
{
957
sdmmc_cmd_t cmd;
958
959
if (_sdmmc_wait_cmd_data_inhibit(sdmmc, false))
960
return 1;
961
962
_sdmmc_enable_interrupts(sdmmc);
963
964
cmd.cmd = MMC_STOP_TRANSMISSION;
965
cmd.arg = 0;
966
cmd.rsp_type = SDMMC_RSP_TYPE_1;
967
cmd.check_busy = 1;
968
969
_sdmmc_send_cmd(sdmmc, &cmd, false);
970
971
int res = _sdmmc_wait_response(sdmmc);
972
_sdmmc_mask_interrupts(sdmmc);
973
974
if (res)
975
return 1;
976
977
_sdmmc_cache_rsp(sdmmc, rsp, SDMMC_RSP_TYPE_1);
978
979
return _sdmmc_wait_card_busy(sdmmc);
980
}
981
982
int sdmmc_stop_transmission(sdmmc_t *sdmmc, u32 *rsp)
983
{
984
if (!sdmmc->card_clock_enabled)
985
return 1;
986
987
// Recalibrate periodically if needed.
988
if (sdmmc->periodic_calibration && sdmmc->powersave_enabled)
989
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
990
991
bool should_disable_sd_clock = false;
992
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
993
{
994
should_disable_sd_clock = true;
995
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
996
_sdmmc_commit_changes(sdmmc);
997
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
998
}
999
1000
int res = _sdmmc_stop_transmission_inner(sdmmc, rsp);
1001
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
1002
1003
if (should_disable_sd_clock)
1004
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
1005
1006
return res;
1007
}
1008
1009
static int _sdmmc_config_sdma(sdmmc_t *sdmmc, u32 *blkcnt_out, const sdmmc_req_t *request)
1010
{
1011
if (!request->blksize || !request->num_sectors)
1012
return 1;
1013
1014
u32 blkcnt = request->num_sectors;
1015
if (blkcnt >= SDMMC_HMAX_BLOCKNUM)
1016
blkcnt = SDMMC_HMAX_BLOCKNUM;
1017
u32 admaaddr = (u32)request->buf;
1018
1019
// Check alignment.
1020
if (admaaddr & 7)
1021
return 1;
1022
1023
sdmmc->regs->admaaddr = admaaddr;
1024
sdmmc->regs->admaaddr_hi = 0;
1025
1026
sdmmc->dma_addr_next = ALIGN_DOWN((admaaddr + SZ_512K), SZ_512K);
1027
1028
sdmmc->regs->blksize = request->blksize | (7u << 12); // SDMA DMA 512KB Boundary (Detects A18 carry out).
1029
sdmmc->regs->blkcnt = blkcnt;
1030
1031
if (blkcnt_out)
1032
*blkcnt_out = blkcnt;
1033
1034
u32 trnmode = SDHCI_TRNS_DMA | SDHCI_TRNS_RTYPE_R1;
1035
1036
// Set multiblock request.
1037
if (request->is_multi_block)
1038
trnmode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_BLK_CNT_EN;
1039
1040
// Set request direction.
1041
if (!request->is_write)
1042
trnmode |= SDHCI_TRNS_READ;
1043
1044
// Automatic send of stop transmission or set block count cmd.
1045
if (request->is_auto_stop_trn)
1046
trnmode |= SDHCI_TRNS_AUTO_CMD12;
1047
//else if (request->is_auto_set_blkcnt)
1048
// trnmode |= SDHCI_TRNS_AUTO_CMD23;
1049
1050
sdmmc->regs->trnmod = trnmode;
1051
1052
return 0;
1053
}
1054
1055
static int _sdmmc_update_sdma(sdmmc_t *sdmmc)
1056
{
1057
u16 blkcnt = 0;
1058
do
1059
{
1060
blkcnt = sdmmc->regs->blkcnt;
1061
u32 timeout = get_tmr_ms() + 1500;
1062
do
1063
{
1064
u32 res = SDMMC_MASKINT_MASKED;
1065
while (true)
1066
{
1067
u16 intr = 0;
1068
res = _sdmmc_check_mask_interrupt(sdmmc, &intr,
1069
SDHCI_INT_DATA_END | SDHCI_INT_DMA_END);
1070
if (res != SDMMC_MASKINT_MASKED)
1071
break;
1072
1073
if (intr & SDHCI_INT_DATA_END)
1074
return 0; // Transfer complete.
1075
1076
if (intr & SDHCI_INT_DMA_END)
1077
{
1078
// Update DMA.
1079
sdmmc->regs->admaaddr = sdmmc->dma_addr_next;
1080
sdmmc->regs->admaaddr_hi = 0;
1081
sdmmc->dma_addr_next += SZ_512K;
1082
}
1083
}
1084
1085
if (res != SDMMC_MASKINT_NOERROR)
1086
{
1087
#ifdef ERROR_EXTRA_PRINTING
1088
EPRINTFARGS("SDMMC%d: int error!", sdmmc->id + 1);
1089
#endif
1090
_sdmmc_reset_cmd_data(sdmmc);
1091
1092
return 1;
1093
}
1094
} while (get_tmr_ms() < timeout);
1095
} while (sdmmc->regs->blkcnt != blkcnt);
1096
1097
_sdmmc_reset_cmd_data(sdmmc);
1098
1099
return 1;
1100
}
1101
1102
static int _sdmmc_execute_cmd_inner(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *request, u32 *blkcnt_out)
1103
{
1104
bool has_req_or_check_busy = request || cmd->check_busy;
1105
if (_sdmmc_wait_cmd_data_inhibit(sdmmc, has_req_or_check_busy))
1106
return 1;
1107
1108
u32 blkcnt = 0;
1109
bool is_data_present = false;
1110
if (request)
1111
{
1112
if (_sdmmc_config_sdma(sdmmc, &blkcnt, request))
1113
{
1114
#ifdef ERROR_EXTRA_PRINTING
1115
EPRINTFARGS("SDMMC%d: DMA Wrong cfg!", sdmmc->id + 1);
1116
#endif
1117
return 1;
1118
}
1119
1120
// Flush cache before starting the transfer.
1121
bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLEAN_WAY, false);
1122
1123
is_data_present = true;
1124
}
1125
1126
_sdmmc_enable_interrupts(sdmmc);
1127
1128
if (_sdmmc_send_cmd(sdmmc, cmd, is_data_present))
1129
{
1130
#ifdef ERROR_EXTRA_PRINTING
1131
EPRINTFARGS("SDMMC%d: Wrong Response type %08X!", sdmmc->id + 1, cmd->rsp_type);
1132
#endif
1133
return 1;
1134
}
1135
1136
int res = _sdmmc_wait_response(sdmmc);
1137
#ifdef ERROR_EXTRA_PRINTING
1138
if (res)
1139
EPRINTFARGS("SDMMC%d: Transfer error!", sdmmc->id + 1);
1140
#endif
1141
DPRINTF("rsp(%d): %08X, %08X, %08X, %08X\n", res,
1142
sdmmc->regs->rspreg[0], sdmmc->regs->rspreg[1], sdmmc->regs->rspreg[2], sdmmc->regs->rspreg[3]);
1143
1144
if (!res)
1145
{
1146
if (cmd->rsp_type)
1147
{
1148
sdmmc->expected_rsp_type = cmd->rsp_type;
1149
res = _sdmmc_cache_rsp(sdmmc, sdmmc->rsp, cmd->rsp_type);
1150
}
1151
if (request && !res)
1152
{
1153
res = _sdmmc_update_sdma(sdmmc);
1154
#ifdef ERROR_EXTRA_PRINTING
1155
if (res)
1156
EPRINTFARGS("SDMMC%d: DMA Update failed!", sdmmc->id + 1);
1157
#endif
1158
}
1159
}
1160
1161
_sdmmc_mask_interrupts(sdmmc);
1162
1163
if (!res)
1164
{
1165
if (request)
1166
{
1167
// Invalidate cache after transfer.
1168
bpmp_mmu_maintenance(BPMP_MMU_MAINT_INVALID_WAY, false);
1169
1170
if (blkcnt_out)
1171
*blkcnt_out = blkcnt;
1172
1173
if (request->is_auto_stop_trn)
1174
sdmmc->stop_trn_rsp = sdmmc->regs->rspreg[3];
1175
}
1176
1177
if (has_req_or_check_busy)
1178
{
1179
res = _sdmmc_wait_card_busy(sdmmc);
1180
#ifdef ERROR_EXTRA_PRINTING
1181
if (res)
1182
EPRINTFARGS("SDMMC%d: Busy timeout!", sdmmc->id + 1);
1183
#endif
1184
}
1185
}
1186
1187
return res;
1188
}
1189
1190
bool sdmmc_get_sd_inserted()
1191
{
1192
return (!gpio_read(GPIO_PORT_Z, GPIO_PIN_1));
1193
}
1194
1195
static void _sdmmc_config_sdmmc1_schmitt()
1196
{
1197
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_SCHMT;
1198
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) |= PINMUX_SCHMT;
1199
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) |= PINMUX_SCHMT;
1200
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) |= PINMUX_SCHMT;
1201
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) |= PINMUX_SCHMT;
1202
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) |= PINMUX_SCHMT;
1203
}
1204
1205
static void _sdmmc_config_sdmmc2_schmitt()
1206
{
1207
PINMUX_AUX(PINMUX_AUX_SDMMC2_CLK) |= PINMUX_SCHMT;
1208
PINMUX_AUX(PINMUX_AUX_SDMMC2_CMD) |= PINMUX_SCHMT;
1209
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT7) |= PINMUX_SCHMT;
1210
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT6) |= PINMUX_SCHMT;
1211
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT5) |= PINMUX_SCHMT;
1212
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT4) |= PINMUX_SCHMT;
1213
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT3) |= PINMUX_SCHMT;
1214
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT2) |= PINMUX_SCHMT;
1215
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT1) |= PINMUX_SCHMT;
1216
PINMUX_AUX(PINMUX_AUX_SDMMC2_DAT0) |= PINMUX_SCHMT;
1217
}
1218
1219
static void _sdmmc_config_sdmmc1_pads(bool discharge)
1220
{
1221
u32 sdmmc1_pin_mask = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
1222
1223
// Set values for Reset state.
1224
u32 function = GPIO_MODE_SPIO;
1225
u32 level = GPIO_LOW;
1226
u32 output = GPIO_OUTPUT_DISABLE;
1227
1228
// Set values for discharging.
1229
if (discharge)
1230
{
1231
function = GPIO_MODE_GPIO;
1232
level = GPIO_HIGH;
1233
output = GPIO_OUTPUT_ENABLE;
1234
}
1235
1236
// Set all pads function.
1237
gpio_config(GPIO_PORT_M, sdmmc1_pin_mask, function);
1238
// Set all pads output level.
1239
gpio_write(GPIO_PORT_M, sdmmc1_pin_mask, level);
1240
// Set all pads output.
1241
gpio_output_enable(GPIO_PORT_M, sdmmc1_pin_mask, output);
1242
}
1243
1244
static int _sdmmc_config_sdmmc1(bool t210b01)
1245
{
1246
// Configure SD card detect.
1247
PINMUX_AUX(PINMUX_AUX_GPIO_PZ1) = PINMUX_INPUT_ENABLE | PINMUX_PULL_UP | 2; // GPIO control, pull up.
1248
APB_MISC(APB_MISC_GP_VGPIO_GPIO_MUX_SEL) = 0;
1249
gpio_direction_input(GPIO_PORT_Z, GPIO_PIN_1);
1250
usleep(100);
1251
1252
// Check if SD card is inserted.
1253
if (!sdmmc_get_sd_inserted())
1254
return 1;
1255
1256
// Enable deep loopback for SDMMC1 CLK pad so reads work.
1257
APB_MISC(APB_MISC_GP_SDMMC1_CLK_LPBK_CONTROL) = 1;
1258
1259
// Configure SDMMC1 CLK pinmux, based on state and SoC type.
1260
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) &= ~PINMUX_SCHMT;
1261
if (PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) != (PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_DOWN)) // Check if CLK pad is already configured.
1262
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | (t210b01 ? PINMUX_PULL_NONE : PINMUX_PULL_DOWN);
1263
1264
// Configure reset state of SDMMC1 pins pinmux.
1265
PINMUX_AUX(PINMUX_AUX_SDMMC1_CMD) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
1266
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT3) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
1267
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT2) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
1268
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT1) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
1269
PINMUX_AUX(PINMUX_AUX_SDMMC1_DAT0) = PINMUX_DRIVE_2X | PINMUX_INPUT_ENABLE | PINMUX_PULL_UP;
1270
1271
// Force schmitt trigger for T210B01.
1272
if (t210b01)
1273
_sdmmc_config_sdmmc1_schmitt();
1274
1275
// Make sure the SDMMC1 controller is powered.
1276
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
1277
usleep(1000);
1278
PMC(APBDEV_PMC_NO_IOPOWER) &= ~PMC_NO_IOPOWER_SDMMC1;
1279
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
1280
1281
// Enable SD card power. Powers LDO2 also.
1282
PINMUX_AUX(PINMUX_AUX_DMIC3_CLK) = PINMUX_PULL_DOWN | 2;
1283
gpio_direction_output(GPIO_PORT_E, GPIO_PIN_4, GPIO_HIGH);
1284
usleep(10000); // Minimum 3 to 10 ms.
1285
1286
// Inform IO pads that voltage is gonna be 3.3V.
1287
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_33V_SDMMC1;
1288
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
1289
1290
// Enable SD card IO power.
1291
max7762x_regulator_set_voltage(REGULATOR_LDO2, 3300000);
1292
max7762x_regulator_enable(REGULATOR_LDO2, true);
1293
usleep(1000);
1294
1295
// Set pad slew codes to get good quality clock.
1296
if (!t210b01)
1297
{
1298
APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) = (APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL) & 0xFFFFFFF) | 0x50000000;
1299
(void)APB_MISC(APB_MISC_GP_SDMMC1_PAD_CFGPADCTRL); // Commit write.
1300
usleep(1000);
1301
}
1302
1303
return 0;
1304
}
1305
1306
static void _sdmmc_config_emmc(u32 id, bool t210b01)
1307
{
1308
switch (id)
1309
{
1310
case SDMMC_2:
1311
if (!t210b01)
1312
{
1313
// Unset park for pads.
1314
APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL) &= 0xF8003FFF;
1315
(void)APB_MISC(APB_MISC_GP_EMMC2_PAD_CFGPADCTRL); // Commit write.
1316
}
1317
else // Enable schmitt trigger for T210B01.
1318
_sdmmc_config_sdmmc2_schmitt();
1319
break;
1320
1321
case SDMMC_4:
1322
// Unset park for pads.
1323
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) &= 0xF8003FFF;
1324
// Set default pad cfg.
1325
if (t210b01)
1326
APB_MISC(APB_MISC_GP_EMMC4_PAD_PUPD_CFGPADCTRL) &= 0xFFBFFFF9; // Unset CMD/CLK/DQS weak pull up/down.
1327
// Enable schmitt trigger.
1328
APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL) |= 1;
1329
(void)APB_MISC(APB_MISC_GP_EMMC4_PAD_CFGPADCTRL); // Commit write.
1330
break;
1331
}
1332
}
1333
1334
int sdmmc_init(sdmmc_t *sdmmc, u32 id, u32 power, u32 bus_width, u32 type)
1335
{
1336
u32 clock;
1337
u16 divisor;
1338
u8 vref_sel = 7;
1339
1340
static const u8 trim_values_t210[4] = { 2, 8, 3, 8 };
1341
static const u8 trim_values_t210b01[4] = { 14, 13, 15, 13 };
1342
const u8 *trim_values;
1343
1344
if (id > SDMMC_4 || id == SDMMC_3)
1345
return 1;
1346
1347
memset(sdmmc, 0, sizeof(sdmmc_t));
1348
1349
sdmmc->regs = (t210_sdmmc_t *)(SDMMC_BASE + (u32)_sdmmc_base_offsets[id]);
1350
sdmmc->id = id;
1351
sdmmc->clock_stopped = 1;
1352
sdmmc->t210b01 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210B01;
1353
1354
trim_values = sdmmc->t210b01 ? trim_values_t210b01 : trim_values_t210;
1355
1356
// Do specific SDMMC HW configuration.
1357
switch (id)
1358
{
1359
case SDMMC_1:
1360
if (_sdmmc_config_sdmmc1(sdmmc->t210b01))
1361
return 1;
1362
if (sdmmc->t210b01)
1363
vref_sel = 0;
1364
else
1365
sdmmc->periodic_calibration = 1;
1366
break;
1367
1368
case SDMMC_2:
1369
case SDMMC_4:
1370
_sdmmc_config_emmc(id, sdmmc->t210b01);
1371
break;
1372
}
1373
1374
// Disable clock if enabled.
1375
if (clock_sdmmc_is_active(id))
1376
{
1377
_sdmmc_card_clock_disable(sdmmc);
1378
_sdmmc_commit_changes(sdmmc);
1379
}
1380
1381
// Configure and enable selected clock.
1382
clock_sdmmc_get_card_clock_div(&clock, &divisor, type);
1383
clock_sdmmc_enable(id, clock);
1384
sdmmc->clock_stopped = 0;
1385
1386
// Make sure all sdmmc registers are reset.
1387
_sdmmc_reset_all(sdmmc);
1388
1389
// Set default pad IO trimming configuration.
1390
sdmmc->regs->iospare |= BIT(19); // Enable 1 cycle delayed cmd_oen.
1391
sdmmc->regs->veniotrimctl &= ~BIT(2); // Set Band Gap VREG to supply DLL.
1392
sdmmc->regs->venclkctl = (sdmmc->regs->venclkctl & 0xE0FFFFFB) | ((u32)trim_values[sdmmc->id] << 24);
1393
sdmmc->regs->sdmemcmppadctl = (sdmmc->regs->sdmemcmppadctl & ~SDHCI_TEGRA_PADCTRL_VREF_SEL_MASK) | vref_sel;
1394
1395
// Configure auto calibration values.
1396
if (_sdmmc_autocal_config_offset(sdmmc, power))
1397
return 1;
1398
1399
_sdmmc_commit_changes(sdmmc);
1400
1401
// Calibrate pads.
1402
_sdmmc_autocal_execute(sdmmc, power);
1403
1404
// Enable internal clock and power.
1405
if (!_sdmmc_enable_internal_clock(sdmmc))
1406
{
1407
sdmmc_set_bus_width(sdmmc, bus_width);
1408
_sdmmc_set_io_power(sdmmc, power);
1409
1410
if (!sdmmc_setup_clock(sdmmc, type))
1411
{
1412
sdmmc_card_clock_powersave(sdmmc, SDMMC_POWER_SAVE_DISABLE);
1413
_sdmmc_card_clock_enable(sdmmc);
1414
_sdmmc_commit_changes(sdmmc);
1415
1416
return 0;
1417
}
1418
}
1419
1420
// Failed to enable clock.
1421
return 1;
1422
}
1423
1424
void sdmmc1_disable_power()
1425
{
1426
// T210B01 WAR: Clear pull down from CLK pad.
1427
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) &= ~PINMUX_PULL_MASK;
1428
1429
// T210B01 WAR: Set pads to discharge state.
1430
_sdmmc_config_sdmmc1_pads(true);
1431
1432
// Disable SD card IO power.
1433
max7762x_regulator_enable(REGULATOR_LDO2, false);
1434
usleep(4000);
1435
1436
// Disable SD card power.
1437
gpio_write(GPIO_PORT_E, GPIO_PIN_4, GPIO_LOW);
1438
1439
// T210/T210B01 WAR: Set start timer for IO and Controller power discharge.
1440
sd_power_cycle_time_start = get_tmr_ms();
1441
usleep(10000); // To power cycle, min 1ms without power is needed.
1442
1443
// Disable SDMMC1 controller power.
1444
PMC(APBDEV_PMC_NO_IOPOWER) |= PMC_NO_IOPOWER_SDMMC1;
1445
(void)PMC(APBDEV_PMC_NO_IOPOWER); // Commit write.
1446
1447
// Inform IO pads that next voltage might be 3.3V.
1448
PMC(APBDEV_PMC_PWR_DET_VAL) |= PMC_PWR_DET_33V_SDMMC1;
1449
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
1450
1451
// T210B01 WAR: Restore pads to reset state.
1452
_sdmmc_config_sdmmc1_pads(false);
1453
1454
// T210B01 WAR: Restore pull down to CLK pad.
1455
PINMUX_AUX(PINMUX_AUX_SDMMC1_CLK) |= PINMUX_PULL_DOWN;
1456
}
1457
1458
void sdmmc_end(sdmmc_t *sdmmc)
1459
{
1460
if (!sdmmc->clock_stopped)
1461
{
1462
_sdmmc_card_clock_disable(sdmmc);
1463
// Disable SDMMC power.
1464
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_OFF);
1465
_sdmmc_commit_changes(sdmmc);
1466
1467
// Disable SD card power.
1468
if (sdmmc->id == SDMMC_1)
1469
sdmmc1_disable_power();
1470
1471
clock_sdmmc_disable(sdmmc->id);
1472
sdmmc->clock_stopped = 1;
1473
}
1474
}
1475
1476
void sdmmc_init_cmd(sdmmc_cmd_t *cmdbuf, u16 cmd, u32 arg, u32 rsp_type, u32 check_busy)
1477
{
1478
cmdbuf->cmd = cmd;
1479
cmdbuf->arg = arg;
1480
cmdbuf->rsp_type = rsp_type;
1481
cmdbuf->check_busy = check_busy;
1482
}
1483
1484
int sdmmc_execute_cmd(sdmmc_t *sdmmc, sdmmc_cmd_t *cmd, sdmmc_req_t *request, u32 *blkcnt_out)
1485
{
1486
if (!sdmmc->card_clock_enabled)
1487
return 1;
1488
1489
// Recalibrate periodically if needed.
1490
if (sdmmc->periodic_calibration && sdmmc->powersave_enabled)
1491
_sdmmc_autocal_execute(sdmmc, sdmmc_get_io_power(sdmmc));
1492
1493
int should_disable_sd_clock = 0;
1494
if (!(sdmmc->regs->clkcon & SDHCI_CLOCK_CARD_EN))
1495
{
1496
should_disable_sd_clock = 1;
1497
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
1498
_sdmmc_commit_changes(sdmmc);
1499
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
1500
}
1501
1502
int res = _sdmmc_execute_cmd_inner(sdmmc, cmd, request, blkcnt_out);
1503
usleep((8 * 1000 + sdmmc->card_clock - 1) / sdmmc->card_clock); // Wait 8 cycles.
1504
1505
if (should_disable_sd_clock)
1506
sdmmc->regs->clkcon &= ~SDHCI_CLOCK_CARD_EN;
1507
1508
return res;
1509
}
1510
1511
int sdmmc_enable_low_voltage(sdmmc_t *sdmmc)
1512
{
1513
if (sdmmc->id != SDMMC_1)
1514
return 1;
1515
1516
_sdmmc_commit_changes(sdmmc);
1517
1518
// Switch to 1.8V and wait for regulator to stabilize. Assume max possible wait needed.
1519
max7762x_regulator_set_voltage(REGULATOR_LDO2, 1800000);
1520
usleep(150);
1521
1522
// Inform IO pads that we switched to 1.8V.
1523
PMC(APBDEV_PMC_PWR_DET_VAL) &= ~PMC_PWR_DET_33V_SDMMC1;
1524
(void)PMC(APBDEV_PMC_PWR_DET_VAL); // Commit write.
1525
1526
// Enable schmitt trigger for better duty cycle and low jitter clock.
1527
_sdmmc_config_sdmmc1_schmitt();
1528
1529
_sdmmc_autocal_config_offset(sdmmc, SDMMC_POWER_1_8);
1530
_sdmmc_autocal_execute(sdmmc, SDMMC_POWER_1_8);
1531
_sdmmc_set_io_power(sdmmc, SDMMC_POWER_1_8);
1532
_sdmmc_commit_changes(sdmmc);
1533
msleep(5); // Wait minimum 5ms before turning on the card clock.
1534
1535
// Turn on SDCLK.
1536
if (sdmmc->regs->hostctl2 & SDHCI_CTRL_VDD_180)
1537
{
1538
sdmmc->regs->clkcon |= SDHCI_CLOCK_CARD_EN;
1539
_sdmmc_commit_changes(sdmmc);
1540
usleep(1000);
1541
if ((sdmmc->regs->prnsts & SDHCI_DATA_LVL_MASK) == SDHCI_DATA_LVL_MASK)
1542
return 0;
1543
}
1544
1545
return 1;
1546
}
1547
1548