Hello Kane Chen,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/35040
to review the following change.
Change subject: intel/common/mmc: Provide mmc.c for setting dll registers. ......................................................................
intel/common/mmc: Provide mmc.c for setting dll registers.
Currently, we don't have UPDs to set emmc settings per mainboard on CML.
This code change is to create mmc.c to provide interface to override dll settings per mainboard. Notice: mainboard_get_mmc_dll function will override the dll values in FSP.
BUG=b:131401116 BRANCH=none TEST=Boot to OS and confirm the dll values have been overrided.
Change-Id: Ib3c72b9851f41585ec099d8ae83a721af87ed383 Signed-off-by: Kane Chen kane.chen@intel.com Signed-off-by: Jamie Chen jamie.chen@intel.com --- M src/include/device/pci_ids.h M src/soc/intel/common/block/include/intelblocks/early_mmc.h M src/soc/intel/common/block/scs/Makefile.inc M src/soc/intel/common/block/scs/early_mmc.c A src/soc/intel/common/block/scs/mmc.c 5 files changed, 107 insertions(+), 33 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/40/35040/1
diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index 3ac6560..f7a4c95 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -3220,6 +3220,7 @@ #define PCI_DEVICE_ID_INTEL_CNP_H_SD 0xa375 #define PCI_DEVICE_ID_INTEL_ICL_SD 0x34f8 #define PCI_DEVICE_ID_INTEL_CMP_SD 0x02f5 +#define PCI_DEVICE_ID_INTEL_CMP_MMC 0x02c4
/* Intel EMMC device Ids */ #define PCI_DEVICE_ID_INTEL_SKL_EMMC 0x9d2b diff --git a/src/soc/intel/common/block/include/intelblocks/early_mmc.h b/src/soc/intel/common/block/include/intelblocks/early_mmc.h index 39aaf58..2ec22ec 100644 --- a/src/soc/intel/common/block/include/intelblocks/early_mmc.h +++ b/src/soc/intel/common/block/include/intelblocks/early_mmc.h @@ -60,6 +60,23 @@ * returns 0, if able to get register settings; otherwise returns -1 */ int soc_get_mmc_dll(struct mmc_dll_params *params); +/* + * SOC specific API to set mmc delay register settings. + * returns 0, if able to set register settings; otherwise returns -1 + */ +int set_mmc_dll(void *ioaddr); +/* + * mainboard specific API to get mmc delay register settings. + * returns 0, if able to get register settings; otherwise returns -1 + */ +int mainboard_get_mmc_dll(struct mmc_dll_params *params); + +#define EMMC_TX_CMD_CNTL_OFFSET 0x820 +#define EMMC_TX_DATA_CNTL1_OFFSET 0x824 +#define EMMC_TX_DATA_CNTL2_OFFSET 0x828 +#define EMMC_RX_CMD_DATA_CNTL1_OFFSET 0x82C +#define EMMC_RX_STROBE_CNTL_OFFSET 0x830 +#define EMMC_RX_CMD_DATA_CNTL2_OFFSET 0x834
#if CONFIG(SOC_INTEL_COMMON_EARLY_MMC_WAKE) /* diff --git a/src/soc/intel/common/block/scs/Makefile.inc b/src/soc/intel/common/block/scs/Makefile.inc index 1160802..707a334 100644 --- a/src/soc/intel/common/block/scs/Makefile.inc +++ b/src/soc/intel/common/block/scs/Makefile.inc @@ -1,2 +1,3 @@ ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SCS) += sd.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SCS) += mmc.c romstage-$(CONFIG_SOC_INTEL_COMMON_EARLY_MMC_WAKE) += early_mmc.c diff --git a/src/soc/intel/common/block/scs/early_mmc.c b/src/soc/intel/common/block/scs/early_mmc.c index 8f47ec7..297b9c4 100644 --- a/src/soc/intel/common/block/scs/early_mmc.c +++ b/src/soc/intel/common/block/scs/early_mmc.c @@ -26,13 +26,6 @@ #include <soc/pci_devs.h> #include <string.h>
-#define EMMC_TX_CMD_CNTL_OFFSET 0x820 -#define EMMC_TX_DATA_CNTL1_OFFSET 0x824 -#define EMMC_TX_DATA_CNTL2_OFFSET 0x828 -#define EMMC_RX_CMD_DATA_CNTL1_OFFSET 0x82C -#define EMMC_RX_STROBE_CNTL_OFFSET 0x830 -#define EMMC_RX_CMD_DATA_CNTL2_OFFSET 0x834 - void soc_sd_mmc_controller_quirks(struct sd_mmc_ctrlr *ctrlr) { uint32_t f_min, f_max; @@ -62,32 +55,6 @@ ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY)); }
-static int set_mmc_dll(void *ioaddr) -{ - struct mmc_dll_params dll_params; - - if (soc_get_mmc_dll(&dll_params) < 0) { - printk(BIOS_ERR, - "MMC early init: failed to get mmc DLL parameters\n"); - return -1; - } - - write32(ioaddr + EMMC_TX_DATA_CNTL1_OFFSET, - dll_params.emmc_tx_data_cntl1); - write32(ioaddr + EMMC_TX_DATA_CNTL2_OFFSET, - dll_params.emmc_tx_data_cntl2); - write32(ioaddr + EMMC_RX_CMD_DATA_CNTL1_OFFSET, - dll_params.emmc_rx_cmd_data_cntl1); - write32(ioaddr + EMMC_RX_CMD_DATA_CNTL2_OFFSET, - dll_params.emmc_rx_cmd_data_cntl2); - write32(ioaddr + EMMC_RX_STROBE_CNTL_OFFSET, - dll_params.emmc_rx_strobe_cntl); - write32(ioaddr + EMMC_TX_CMD_CNTL_OFFSET, - dll_params.emmc_tx_cmd_cntl); - - return 0; -} - static void set_early_mmc_wake_status(int32_t status) { int32_t *ms_cbmem; diff --git a/src/soc/intel/common/block/scs/mmc.c b/src/soc/intel/common/block/scs/mmc.c new file mode 100644 index 0000000..b55db4a --- /dev/null +++ b/src/soc/intel/common/block/scs/mmc.c @@ -0,0 +1,88 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <device/pci.h> +#include <device/pci_ids.h> +#include <console/console.h> +#include <intelblocks/early_mmc.h> + +/* Common weak definition, needs to be implemented in mainboard */ +int __weak mainboard_get_mmc_dll(struct mmc_dll_params *params) +{ + return -1; +} + +int set_mmc_dll(void *ioaddr) +{ + struct mmc_dll_params dll_params; + + if (mainboard_get_mmc_dll(&dll_params) < 0) { + printk(BIOS_INFO, "Skip Emmc dll value programming \n"); + return -1; + } + + printk(BIOS_INFO, "Override emmc dll value \n"); + + write32(ioaddr + EMMC_TX_DATA_CNTL1_OFFSET, + dll_params.emmc_tx_data_cntl1); + + write32(ioaddr + EMMC_TX_DATA_CNTL2_OFFSET, + dll_params.emmc_tx_data_cntl2); + + write32(ioaddr + EMMC_RX_CMD_DATA_CNTL1_OFFSET, + dll_params.emmc_rx_cmd_data_cntl1); + + write32(ioaddr + EMMC_RX_CMD_DATA_CNTL2_OFFSET, + dll_params.emmc_rx_cmd_data_cntl2); + + write32(ioaddr + EMMC_RX_STROBE_CNTL_OFFSET, + dll_params.emmc_rx_strobe_cntl); + + write32(ioaddr + EMMC_TX_CMD_CNTL_OFFSET, + dll_params.emmc_tx_cmd_cntl); + + return 0; +} + +static void mmc_soc_init(struct device *dev) +{ + uint32_t *cfg0; + const struct resource *res; + + res = find_resource(dev, PCI_BASE_ADDRESS_0); + cfg0 = (void *)(uintptr_t)(res->base); + + set_mmc_dll(cfg0); +} + + +static struct device_operations dev_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = mmc_soc_init, + .ops_pci = &pci_dev_ops_pci, +}; + +static const unsigned short pci_device_ids[] = { + PCI_DEVICE_ID_INTEL_CMP_MMC, + 0 +}; + +static const struct pci_driver pch_sd __pci_driver = { + .ops = &dev_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +};