Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. |
| 5 | * Copyright (C) 2015 Intel Corporation |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; version 2 of the License. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 15 | */ |
| 16 | |
| 17 | #include <types.h> |
| 18 | #include <string.h> |
| 19 | #include <console/console.h> |
| 20 | #include <bootstate.h> |
| 21 | #include <cbmem.h> |
Patrick Rudolph | 45022ae | 2018-10-01 19:17:11 +0200 | [diff] [blame] | 22 | #include <cf9_reset.h> |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 23 | #include <device/device.h> |
| 24 | #include <southbridge/intel/fsp_rangeley/pci_devs.h> |
| 25 | #include <drivers/intel/fsp1_0/fsp_util.h> |
| 26 | #include <fspvpd.h> |
| 27 | #include <fspbootmode.h> |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 28 | #include "../chip.h" |
| 29 | |
| 30 | #ifdef __PRE_RAM__ |
| 31 | #include <southbridge/intel/fsp_rangeley/romstage.h> |
| 32 | #endif |
| 33 | |
| 34 | #ifdef __PRE_RAM__ |
| 35 | |
| 36 | /* Copy the default UPD region and settings to a buffer for modification */ |
| 37 | static void GetUpdDefaultFromFsp |
| 38 | (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData) |
| 39 | { |
| 40 | VPD_DATA_REGION *VpdDataRgnPtr; |
| 41 | UPD_DATA_REGION *UpdDataRgnPtr; |
| 42 | VpdDataRgnPtr = (VPD_DATA_REGION *)(UINT32)(FspInfo->CfgRegionOffset |
| 43 | + FspInfo->ImageBase); |
| 44 | UpdDataRgnPtr = (UPD_DATA_REGION *)(UINT32) |
| 45 | (VpdDataRgnPtr->PcdUpdRegionOffset + FspInfo->ImageBase); |
Elyes HAOUAS | fd051dc | 2018-07-08 12:39:34 +0200 | [diff] [blame] | 46 | memcpy((void *)UpdData, (void *)UpdDataRgnPtr, sizeof(UPD_DATA_REGION)); |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 47 | } |
| 48 | |
| 49 | typedef struct northbridge_intel_fsp_rangeley_config config_t; |
| 50 | |
| 51 | /** |
| 52 | * Update the UPD data based on values from devicetree.cb |
| 53 | * |
| 54 | * @param UpdData Pointer to the UPD Data structure |
| 55 | */ |
| 56 | static void ConfigureDefaultUpdData(UPD_DATA_REGION *UpdData) |
| 57 | { |
Aaron Durbin | e4d7abc | 2017-04-16 22:05:36 -0500 | [diff] [blame] | 58 | DEVTREE_CONST struct device *dev; |
| 59 | DEVTREE_CONST config_t *config; |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 60 | printk(BIOS_DEBUG, "Configure Default UPD Data\n"); |
| 61 | |
Kyösti Mälkki | e737755 | 2018-06-21 16:20:55 +0300 | [diff] [blame] | 62 | dev = pcidev_path_on_root(SOC_DEV_FUNC); |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 63 | config = dev->chip_info; |
| 64 | |
| 65 | /* Set SPD addresses */ |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 66 | if (config->SpdBaseAddress_0_0) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 67 | UpdData->PcdSpdBaseAddress_0_0 = config->SpdBaseAddress_0_0; |
| 68 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 69 | if (config->SpdBaseAddress_0_1) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 70 | UpdData->PcdSpdBaseAddress_0_1 = config->SpdBaseAddress_0_1; |
| 71 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 72 | if (config->SpdBaseAddress_1_0) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 73 | UpdData->PcdSpdBaseAddress_1_0 = config->SpdBaseAddress_1_0; |
| 74 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 75 | if (config->SpdBaseAddress_1_1) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 76 | UpdData->PcdSpdBaseAddress_1_1 = config->SpdBaseAddress_1_1; |
| 77 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 78 | if (config->EccSupport) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 79 | UpdData->PcdEccSupport = config->EccSupport; |
| 80 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 81 | if (config->PrintDebugMessages) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 82 | UpdData->PcdPrintDebugMessages = config->PrintDebugMessages; |
| 83 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 84 | if (config->Bifurcation) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 85 | UpdData->PcdBifurcation = config->Bifurcation; |
| 86 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 87 | if (config->MemoryDown) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 88 | UpdData->PcdMemoryDown = config->MemoryDown; |
| 89 | } |
| 90 | |
| 91 | UpdData->PcdMrcInitTsegSize = CONFIG_SMM_TSEG_SIZE >> 20; |
| 92 | |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 93 | if (config->MrcRmtCpgcExpLoopCntValue) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 94 | UpdData->PcdMrcRmtCpgcExpLoopCntValue = |
| 95 | config->MrcRmtCpgcExpLoopCntValue; |
| 96 | } |
Elyes HAOUAS | 12df950 | 2016-08-23 21:29:48 +0200 | [diff] [blame] | 97 | if (config->MrcRmtCpgcNumBursts) { |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 98 | UpdData->PcdMrcRmtCpgcNumBursts = config->MrcRmtCpgcNumBursts; |
| 99 | } |
| 100 | #if IS_ENABLED(CONFIG_ENABLE_FSP_FAST_BOOT) |
| 101 | UpdData->PcdFastboot = UPD_ENABLE; |
| 102 | #endif |
| 103 | /* |
| 104 | * Loop through all the SOC devices in the devicetree |
| 105 | * enabling and disabling them as requested. |
| 106 | */ |
| 107 | for (; dev; dev = dev->sibling) { |
| 108 | |
| 109 | if (dev->path.type != DEVICE_PATH_PCI) |
| 110 | continue; |
| 111 | |
| 112 | switch (dev->path.pci.devfn) { |
| 113 | case GBE1_DEV_FUNC: |
| 114 | case GBE2_DEV_FUNC: |
| 115 | case GBE3_DEV_FUNC: |
| 116 | case GBE4_DEV_FUNC: |
| 117 | UpdData->PcdEnableLan |= dev->enabled; |
| 118 | printk(BIOS_DEBUG, "PcdEnableLan %d\n", |
| 119 | UpdData->PcdEnableLan); |
| 120 | break; |
| 121 | case SATA2_DEV_FUNC: |
| 122 | UpdData->PcdEnableSata2 = dev->enabled; |
| 123 | printk(BIOS_DEBUG, "PcdEnableSata2 %d\n", |
| 124 | UpdData->PcdEnableSata2); |
| 125 | break; |
| 126 | case SATA3_DEV_FUNC: |
| 127 | UpdData->PcdEnableSata3 = dev->enabled; |
| 128 | printk(BIOS_DEBUG, "PcdEnableSata3 %d\n", |
| 129 | UpdData->PcdEnableSata3); |
| 130 | break; |
| 131 | case IQAT_DEV_FUNC: |
| 132 | UpdData->PcdEnableIQAT |= dev->enabled; |
| 133 | printk(BIOS_DEBUG, "PcdEnableIQAT %d\n", |
| 134 | UpdData->PcdEnableIQAT); |
| 135 | break; |
| 136 | case USB2_DEV_FUNC: |
| 137 | UpdData->PcdEnableUsb20 = dev->enabled; |
| 138 | printk(BIOS_DEBUG, "PcdEnableUsb20 %d\n", |
| 139 | UpdData->PcdEnableUsb20); |
| 140 | break; |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | /* Set PCIe de-emphasis */ |
| 145 | UPD_DEFAULT_CHECK(PcdPcieRootPort1DeEmphasis); |
| 146 | UPD_DEFAULT_CHECK(PcdPcieRootPort2DeEmphasis); |
| 147 | UPD_DEFAULT_CHECK(PcdPcieRootPort3DeEmphasis); |
| 148 | UPD_DEFAULT_CHECK(PcdPcieRootPort4DeEmphasis); |
| 149 | } |
| 150 | |
| 151 | /* Set up the Rangeley specific structures for the call into the FSP */ |
| 152 | void chipset_fsp_early_init(FSP_INIT_PARAMS *pFspInitParams, |
| 153 | FSP_INFO_HEADER *fsp_ptr) |
| 154 | { |
| 155 | FSP_INIT_RT_BUFFER *pFspRtBuffer = pFspInitParams->RtBufferPtr; |
| 156 | |
| 157 | /* Initialize the UPD Data */ |
| 158 | GetUpdDefaultFromFsp (fsp_ptr, pFspRtBuffer->Common.UpdDataRgnPtr); |
| 159 | ConfigureDefaultUpdData(pFspRtBuffer->Common.UpdDataRgnPtr); |
| 160 | pFspInitParams->NvsBufferPtr = NULL; |
| 161 | pFspRtBuffer->Common.BootMode = BOOT_WITH_FULL_CONFIGURATION; |
| 162 | |
| 163 | /* Find the fastboot cache that was saved in the ROM */ |
| 164 | pFspInitParams->NvsBufferPtr = find_and_set_fastboot_cache(); |
| 165 | |
| 166 | return; |
| 167 | } |
| 168 | |
| 169 | /* The FSP returns here after the fsp_early_init call */ |
| 170 | void ChipsetFspReturnPoint(EFI_STATUS Status, |
| 171 | VOID *HobListPtr) |
| 172 | { |
Elyes HAOUAS | d4fea5c | 2016-09-17 20:48:29 +0200 | [diff] [blame] | 173 | *(void **)CBMEM_FSP_HOB_PTR = HobListPtr; |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 174 | |
| 175 | if (Status == 0xFFFFFFFF) { |
Patrick Rudolph | 45022ae | 2018-10-01 19:17:11 +0200 | [diff] [blame] | 176 | system_reset(); |
Martin Roth | 5856240 | 2015-10-11 10:36:26 +0200 | [diff] [blame] | 177 | } |
| 178 | romstage_main_continue(Status, HobListPtr); |
| 179 | } |
| 180 | |
| 181 | #endif /* __PRE_RAM__ */ |