xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/scs/early_mmc.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <commonlib/storage/sd_mmc.h>
5 #include <commonlib/sd_mmc_ctrlr.h>
6 #include <commonlib/sdhci.h>
7 #include <console/console.h>
8 #include <device/pci.h>
9 #include <intelblocks/mmc.h>
10 #include <soc/iomap.h>
11 #include <soc/pci_devs.h>
12 #include <string.h>
13 
soc_sd_mmc_controller_quirks(struct sd_mmc_ctrlr * ctrlr)14 void soc_sd_mmc_controller_quirks(struct sd_mmc_ctrlr *ctrlr)
15 {
16 	uint32_t f_min, f_max;
17 
18 	if (soc_get_mmc_frequencies(&f_min, &f_max) < 0) {
19 		printk(BIOS_ERR,
20 			"MMC early init: failed to get mmc frequencies\n");
21 		return;
22 	}
23 
24 	ctrlr->f_min = f_min;
25 	ctrlr->f_max = f_max;
26 }
27 
enable_mmc_controller_bar(void)28 static void enable_mmc_controller_bar(void)
29 {
30 	pci_write_config32(PCH_DEV_EMMC, PCI_BASE_ADDRESS_0,
31 				PRERAM_MMC_BASE_ADDRESS);
32 	pci_write_config16(PCH_DEV_EMMC, PCI_COMMAND,
33 				PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
34 }
35 
disable_mmc_controller_bar(void)36 static void disable_mmc_controller_bar(void)
37 {
38 	pci_write_config32(PCH_DEV_EMMC, PCI_BASE_ADDRESS_0, 0);
39 	pci_write_config16(PCH_DEV_EMMC, PCI_COMMAND,
40 				~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY));
41 }
42 
early_mmc_wake_hw(void)43 int early_mmc_wake_hw(void)
44 {
45 	struct storage_media media;
46 	struct sd_mmc_ctrlr *mmc_ctrlr;
47 	struct sdhci_ctrlr *sdhci_ctrlr;
48 	int err;
49 
50 	if (acpi_is_wakeup_s3())
51 		return -1;
52 
53 	/* Configure mmc gpios */
54 	if (soc_configure_mmc_gpios() < 0) {
55 		printk(BIOS_ERR,
56 			"%s: MMC early init: failed to configure mmc gpios\n",
57 			__func__);
58 		return -1;
59 	}
60 	/* Setup pci bar */
61 	enable_mmc_controller_bar();
62 
63 	/* Initialize sdhci */
64 	mmc_ctrlr = new_pci_sdhci_controller(PCH_DEV_EMMC);
65 	if (mmc_ctrlr == NULL)
66 		goto out_err;
67 
68 	sdhci_ctrlr = container_of(mmc_ctrlr, struct sdhci_ctrlr, sd_mmc_ctrlr);
69 
70 	/* set emmc DLL tuning parameters */
71 	if (set_mmc_dll(sdhci_ctrlr->ioaddr) < 0)
72 		goto out_err;
73 
74 	memset(&media, 0, sizeof(media));
75 	media.ctrlr = mmc_ctrlr;
76 	SET_BUS_WIDTH(mmc_ctrlr, 1);
77 	/*
78 	 * Set clock to 1 so that the driver can choose minimum frequency
79 	 * possible
80 	 */
81 	SET_CLOCK(mmc_ctrlr, 1);
82 
83 	/* Reset emmc, send CMD0 */
84 	if (sd_mmc_go_idle(&media))
85 		goto out_err;
86 
87 	/* Send CMD1 */
88 	err = mmc_send_op_cond(&media);
89 	if (err != 0 && err != CARD_IN_PROGRESS)
90 		goto out_err;
91 
92 	disable_mmc_controller_bar();
93 
94 	mmc_set_early_wake_status(1);
95 	return 0;
96 
97 out_err:
98 
99 	disable_mmc_controller_bar();
100 	return -1;
101 }
102