1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Secure Digital (SD) Host Controller interface specific code
6 #include <commonlib/sd_mmc_ctrlr.h>
7 #include <commonlib/sdhci.h>
8 #include <commonlib/storage.h>
13 static void sdhci_display_bus_width(struct sdhci_ctrlr
*sdhci_ctrlr
)
15 if (CONFIG(SDHC_DEBUG
)) {
22 /* Display the bus width */
23 host_ctrl
= sdhci_readb(sdhci_ctrlr
, SDHCI_HOST_CONTROL
);
24 host2
= sdhci_readw(sdhci_ctrlr
, SDHCI_HOST_CONTROL2
);
25 timing
= host2
& SDHCI_CTRL_UHS_MASK
;
27 if (host_ctrl
& SDHCI_CTRL_8BITBUS
)
29 else if (host_ctrl
& SDHCI_CTRL_4BITBUS
)
32 if ((timing
== SDHCI_CTRL_UHS_DDR50
)
33 || (timing
== SDHCI_CTRL_HS400
))
35 sdhc_debug("SDHCI bus width: %d bit%s %s\n", bits
,
36 (bits
!= 1) ? "s" : "", rate
);
40 static void sdhci_display_clock(struct sdhci_ctrlr
*sdhci_ctrlr
)
42 if (CONFIG(SDHC_DEBUG
)) {
47 /* Display the clock */
48 clk_ctrl
= sdhci_readw(sdhci_ctrlr
, SDHCI_CLOCK_CONTROL
);
49 sdhc_debug("SDHCI bus clock: ");
50 if (clk_ctrl
& SDHCI_CLOCK_CARD_EN
) {
51 divisor
= (clk_ctrl
>> SDHCI_DIVIDER_SHIFT
)
53 divisor
|= ((clk_ctrl
>> SDHCI_DIVIDER_SHIFT
)
54 << SDHCI_DIV_MASK_LEN
) & SDHCI_DIV_HI_MASK
;
56 clock
= sdhci_ctrlr
->sd_mmc_ctrlr
.clock_base
;
59 sdhc_debug("%d.%03d MHz\n", clock
/ 1000000,
60 (clock
/ 1000) % 1000);
66 static void sdhci_display_voltage(struct sdhci_ctrlr
*sdhci_ctrlr
)
68 if (CONFIG(SDHC_DEBUG
)) {
71 const char *voltage_table
[8] = {
82 pwr_ctrl
= sdhci_readb(sdhci_ctrlr
, SDHCI_POWER_CONTROL
);
83 if (pwr_ctrl
& SDHCI_POWER_ON
) {
84 voltage
= voltage_table
[(pwr_ctrl
& SDHCI_POWER_330
)
86 sdhc_debug("SDHCI voltage: %s Volts\n", voltage
);
88 sdhc_debug("SDHCI voltage: Off\n");
92 void sdhci_display_setup(struct sdhci_ctrlr
*sdhci_ctrlr
)
94 /* Display the controller setup */
95 sdhci_display_voltage(sdhci_ctrlr
);
96 sdhci_display_clock(sdhci_ctrlr
);
97 sdhci_display_bus_width(sdhci_ctrlr
);