common/block/cse: Add Kconfig to support ME specification version 21
[coreboot.git] / src / soc / intel / common / block / scs / early_mmc.c
blobc0ca1374c3da4cbad3f5193f0a405c61f2e70ff5
1 /* SPDX-License-Identifier: GPL-2.0-only */
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>
14 void soc_sd_mmc_controller_quirks(struct sd_mmc_ctrlr *ctrlr)
16 uint32_t f_min, f_max;
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;
24 ctrlr->f_min = f_min;
25 ctrlr->f_max = f_max;
28 static void enable_mmc_controller_bar(void)
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);
36 static void disable_mmc_controller_bar(void)
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));
43 int early_mmc_wake_hw(void)
45 struct storage_media media;
46 struct sd_mmc_ctrlr *mmc_ctrlr;
47 struct sdhci_ctrlr *sdhci_ctrlr;
48 int err;
50 if (acpi_is_wakeup_s3())
51 return -1;
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;
60 /* Setup pci bar */
61 enable_mmc_controller_bar();
63 /* Initialize sdhci */
64 mmc_ctrlr = new_pci_sdhci_controller(PCH_DEV_EMMC);
65 if (mmc_ctrlr == NULL)
66 goto out_err;
68 sdhci_ctrlr = container_of(mmc_ctrlr, struct sdhci_ctrlr, sd_mmc_ctrlr);
70 /* set emmc DLL tuning parameters */
71 if (set_mmc_dll(sdhci_ctrlr->ioaddr) < 0)
72 goto out_err;
74 memset(&media, 0, sizeof(media));
75 media.ctrlr = mmc_ctrlr;
76 SET_BUS_WIDTH(mmc_ctrlr, 1);
78 * Set clock to 1 so that the driver can choose minimum frequency
79 * possible
81 SET_CLOCK(mmc_ctrlr, 1);
83 /* Reset emmc, send CMD0 */
84 if (sd_mmc_go_idle(&media))
85 goto out_err;
87 /* Send CMD1 */
88 err = mmc_send_op_cond(&media);
89 if (err != 0 && err != CARD_IN_PROGRESS)
90 goto out_err;
92 disable_mmc_controller_bar();
94 mmc_set_early_wake_status(1);
95 return 0;
97 out_err:
99 disable_mmc_controller_bar();
100 return -1;