xref: /aosp_15_r20/external/coreboot/src/soc/qualcomm/common/storage/sdhci_msm.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <commonlib/sd_mmc_ctrlr.h>
5 #include <commonlib/sdhci.h>
6 #include <commonlib/storage/sdhci.h>
7 #include <delay.h>
8 #include <soc/sdhci_msm.h>
9 
10 /*
11  * msm specific SDHC initialization.  This is ported from depthcharge's
12  * sdhci_msm_init().
13  */
sdhci_msm_init(struct sdhci_ctrlr * host)14 static int sdhci_msm_init(struct sdhci_ctrlr *host)
15 {
16 	uint32_t vendor_caps = 0;
17 
18 	printk(BIOS_INFO, "Initializing SDHCI MSM host controller!\n");
19 
20 	/* Read host controller capabilities */
21 	vendor_caps = sdhci_readl(host, SDHCI_CAPABILITIES);
22 
23 	/*
24 	 * Explicitly enable the capabilities which are not advertised
25 	 * by default
26 	 */
27 	vendor_caps |= SDHCI_CAN_VDD_180 | SDHCI_CAN_DO_8BIT;
28 
29 	/*
30 	 * Update internal capabilities register so that these updated values
31 	 * will get reflected in SDHCI_CAPABILITEIS register.
32 	 */
33 	sdhci_writel(host, vendor_caps, SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0);
34 
35 	/*
36 	 * Reset the vendor spec register to power on reset state.
37 	 * This is to ensure that this register is set to right value
38 	 * incase if this register get updated by bootrom when using SDHCI boot.
39 	 */
40 	sdhci_writel(host, VENDOR_SPEC_FUN3_POR_VAL,
41 		     SDCC_HC_VENDOR_SPECIFIC_FUNC3);
42 
43 	/*
44 	 * Set SD power off, otherwise reset will result in pwr irq.
45 	 * And without setting bus off status, reset would fail.
46 	 */
47 	sdhci_writeb(host, 0x0, SDHCI_POWER_CONTROL);
48 	udelay(10);
49 
50 	return 0;
51 }
52 
53 
54 /*
55  * This function is a wrapper around new_mem_sdhci_controller().  It initializes
56  * the pre_init callback function to sdhci_msm_init(), which takes care of any
57  * msm initialization before the actual sdhci initialization is executed.
58  */
new_sdhci_msm_host(void * ioaddr)59 struct sd_mmc_ctrlr *new_sdhci_msm_host(void *ioaddr)
60 {
61 	struct sd_mmc_ctrlr *host;
62 
63 	host = new_mem_sdhci_controller(ioaddr, sdhci_msm_init);
64 	if (host == NULL)
65 		printk(BIOS_ERR, "Error initializing SDHCI MSM host controller!\n");
66 
67 	return host;
68 }
69