xref: /aosp_15_r20/external/coreboot/src/commonlib/storage/sdhci_display.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Secure Digital (SD) Host Controller interface specific code
4  */
5 
6 #include <commonlib/sd_mmc_ctrlr.h>
7 #include <commonlib/sdhci.h>
8 #include <commonlib/storage.h>
9 #include "sdhci.h"
10 #include "sd_mmc.h"
11 #include "storage.h"
12 
sdhci_display_bus_width(struct sdhci_ctrlr * sdhci_ctrlr)13 static void sdhci_display_bus_width(struct sdhci_ctrlr *sdhci_ctrlr)
14 {
15 	if (CONFIG(SDHC_DEBUG)) {
16 		int bits;
17 		uint8_t host_ctrl;
18 		uint16_t host2;
19 		const char *rate;
20 		uint16_t timing;
21 
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;
26 		bits = 1;
27 		if (host_ctrl & SDHCI_CTRL_8BITBUS)
28 			bits = 8;
29 		else if (host_ctrl & SDHCI_CTRL_4BITBUS)
30 			bits = 4;
31 		rate = "SDR";
32 		if ((timing == SDHCI_CTRL_UHS_DDR50)
33 			|| (timing == SDHCI_CTRL_HS400))
34 			rate = "DDR";
35 		sdhc_debug("SDHCI bus width: %d bit%s %s\n", bits,
36 			(bits != 1) ? "s" : "", rate);
37 	}
38 }
39 
sdhci_display_clock(struct sdhci_ctrlr * sdhci_ctrlr)40 static void sdhci_display_clock(struct sdhci_ctrlr *sdhci_ctrlr)
41 {
42 	if (CONFIG(SDHC_DEBUG)) {
43 		uint16_t clk_ctrl;
44 		uint32_t clock;
45 		uint32_t divisor;
46 
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)
52 				& SDHCI_DIV_MASK;
53 			divisor |= ((clk_ctrl >> SDHCI_DIVIDER_SHIFT)
54 				<< SDHCI_DIV_MASK_LEN) & SDHCI_DIV_HI_MASK;
55 			divisor <<= 1;
56 			clock = sdhci_ctrlr->sd_mmc_ctrlr.clock_base;
57 			if (divisor)
58 				clock /= divisor;
59 			sdhc_debug("%d.%03d MHz\n", clock / 1000000,
60 				(clock / 1000) % 1000);
61 		} else
62 			sdhc_debug("Off\n");
63 	}
64 }
65 
sdhci_display_voltage(struct sdhci_ctrlr * sdhci_ctrlr)66 static void sdhci_display_voltage(struct sdhci_ctrlr *sdhci_ctrlr)
67 {
68 	if (CONFIG(SDHC_DEBUG)) {
69 		u8 pwr_ctrl;
70 		const char *voltage;
71 		const char *voltage_table[8] = {
72 			"Unknown",	/* 0 */
73 			"Unknown",	/* 1 */
74 			"Unknown",	/* 2 */
75 			"Unknown",	/* 3 */
76 			"Unknown",	/* 4 */
77 			"1.8",		/* 5 */
78 			"3.0",		/* 6 */
79 			"3.3",		/* 7 */
80 		};
81 
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)
85 				>> 1];
86 			sdhc_debug("SDHCI voltage: %s Volts\n", voltage);
87 		} else
88 			sdhc_debug("SDHCI voltage: Off\n");
89 	}
90 }
91 
sdhci_display_setup(struct sdhci_ctrlr * sdhci_ctrlr)92 void sdhci_display_setup(struct sdhci_ctrlr *sdhci_ctrlr)
93 {
94 	/* Display the controller setup */
95 	sdhci_display_voltage(sdhci_ctrlr);
96 	sdhci_display_clock(sdhci_ctrlr);
97 	sdhci_display_bus_width(sdhci_ctrlr);
98 }
99