diff options
author | Kane Chen <kane.chen@intel.com> | 2019-08-23 12:03:05 +0800 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2019-08-28 09:22:34 +0000 |
commit | 01ebc74d5620f7cdbf3e51fae8e720e027d55f39 (patch) | |
tree | 7c4b3715f0e59b35da41563e739ea1811ecececc /src/soc/intel/common/block/scs/mmc.c | |
parent | fdd0e9b38f02f5903aee5adeff89c6d9a48c18d6 (diff) |
soc/intel/common/block: 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: set_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 overridden.
Change-Id: Ib3c72b9851f41585ec099d8ae83a721af87ed383
Signed-off-by: Kane Chen <kane.chen@intel.com>
Signed-off-by: Jamie Chen <jamie.chen@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/35040
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc/intel/common/block/scs/mmc.c')
-rw-r--r-- | src/soc/intel/common/block/scs/mmc.c | 95 |
1 files changed, 95 insertions, 0 deletions
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 0000000000..5b2e2c7d33 --- /dev/null +++ b/src/soc/intel/common/block/scs/mmc.c @@ -0,0 +1,95 @@ +/* + * 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/chip.h> +#include <intelblocks/mmc.h> + +static int mmc_write_dll_reg(void *bar, uint32_t reg, uint32_t val) +{ + int ret = 0; + if (val) { + write32(bar + reg, val); + ret = 1; + } + return ret; +} + +int set_mmc_dll(void *bar) +{ + const struct soc_intel_common_config *common_config; + const struct mmc_dll_params *dll_params; + int override = 0; + + common_config = chip_get_common_soc_structure(); + dll_params = &common_config->emmc_dll; + + override |= mmc_write_dll_reg(bar, EMMC_TX_CMD_CNTL_OFFSET, + dll_params->emmc_tx_cmd_cntl); + + override |= mmc_write_dll_reg(bar, EMMC_TX_DATA_CNTL1_OFFSET, + dll_params->emmc_tx_data_cntl1); + + override |= mmc_write_dll_reg(bar, EMMC_TX_DATA_CNTL2_OFFSET, + dll_params->emmc_tx_data_cntl2); + + override |= mmc_write_dll_reg(bar, EMMC_RX_CMD_DATA_CNTL1_OFFSET, + dll_params->emmc_rx_cmd_data_cntl1); + + override |= mmc_write_dll_reg(bar, EMMC_RX_STROBE_CNTL_OFFSET, + dll_params->emmc_rx_strobe_cntl); + + override |= mmc_write_dll_reg(bar, EMMC_RX_CMD_DATA_CNTL2_OFFSET, + dll_params->emmc_rx_cmd_data_cntl2); + + if (override == 0) { + printk(BIOS_INFO, "Skip Emmc dll value programming\n"); + return -1; + } + + return 0; +} + +static void mmc_soc_init(struct device *dev) +{ + const struct resource *res; + + if (!CONFIG(SOC_INTEL_COMMON_MMC_OVERRIDE)) + return; + + res = find_resource(dev, PCI_BASE_ADDRESS_0); + set_mmc_dll((void *)(uintptr_t)(res->base)); +} + +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_EMMC, + 0 +}; + +static const struct pci_driver pch_sd __pci_driver = { + .ops = &dev_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .devices = pci_device_ids, +}; |