blob: 018975f098ed68b34f83e482b5cb1adffae03909 [file] [log] [blame]
Martin Rothc450fbe2017-10-02 13:46:50 -06001/*
2 * This file is part of the coreboot project.
3 *
Marc Jonesa9f72772017-11-16 18:47:36 -07004 * Copyright (C) 2011, 2017 Advanced Micro Devices, Inc.
Martin Rothc450fbe2017-10-02 13:46:50 -06005 * Copyright (C) 2013 Sage Electronic Engineering, LLC
6 * Copyright (C) 2017 Google Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
Marc Jonesa9f72772017-11-16 18:47:36 -070018#include <device/device.h>
Martin Rothc450fbe2017-10-02 13:46:50 -060019#include <device/pci_def.h>
Richard Spiegel0ad74ac2017-12-08 16:53:29 -070020#include <amdblocks/BiosCallOuts.h>
Martin Rothc450fbe2017-10-02 13:46:50 -060021#include <soc/southbridge.h>
Marc Jonesa9f72772017-11-16 18:47:36 -070022#include <soc/pci_devs.h>
23#include <stdlib.h>
Martin Rothc450fbe2017-10-02 13:46:50 -060024
Richard Spiegel0ad74ac2017-12-08 16:53:29 -070025#include <amdblocks/agesawrapper.h>
Marc Jonesafd03d82017-11-16 10:01:08 -070026#include <amdblocks/dimm_spd.h>
Marc Jonesa9f72772017-11-16 18:47:36 -070027#include "chip.h"
Richard Spiegela9f49362018-03-05 08:11:50 -070028#include <amdblocks/car.h>
Martin Rothc450fbe2017-10-02 13:46:50 -060029
Richard Spiegel271b8a52018-11-06 16:32:28 -070030void __weak platform_FchParams_reset(FCH_RESET_DATA_BLOCK *FchParams_reset) {}
Richard Spiegeld1a44a12017-12-26 08:26:31 -070031
Richard Spiegel271b8a52018-11-06 16:32:28 -070032AGESA_STATUS agesa_fch_initreset(uint32_t Func, uintptr_t FchData,
33 void *ConfigPtr)
Martin Rothc450fbe2017-10-02 13:46:50 -060034{
35 AMD_CONFIG_PARAMS *StdHeader = ConfigPtr;
36
37 if (StdHeader->Func == AMD_INIT_RESET) {
38 FCH_RESET_DATA_BLOCK *FchParams_reset;
39 FchParams_reset = (FCH_RESET_DATA_BLOCK *)FchData;
40 printk(BIOS_DEBUG, "Fch OEM config in INIT RESET ");
Martin Rothc450fbe2017-10-02 13:46:50 -060041
42 /* Get platform specific configuration changes */
43 platform_FchParams_reset(FchParams_reset);
44
45 printk(BIOS_DEBUG, "Done\n");
46 }
47
48 return AGESA_SUCCESS;
49}
50
Richard Spiegel271b8a52018-11-06 16:32:28 -070051AGESA_STATUS agesa_fch_initenv(uint32_t Func, uintptr_t FchData,
52 void *ConfigPtr)
Martin Rothc450fbe2017-10-02 13:46:50 -060053{
54 AMD_CONFIG_PARAMS *StdHeader = ConfigPtr;
Kyösti Mälkkie7377552018-06-21 16:20:55 +030055 const struct device *dev = pcidev_path_on_root(SATA_DEVFN);
Martin Rothc450fbe2017-10-02 13:46:50 -060056
57 if (StdHeader->Func == AMD_INIT_ENV) {
58 FCH_DATA_BLOCK *FchParams_env = (FCH_DATA_BLOCK *)FchData;
59 printk(BIOS_DEBUG, "Fch OEM config in INIT ENV ");
60
Martin Rothc450fbe2017-10-02 13:46:50 -060061 /* XHCI configuration */
62 if (IS_ENABLED(CONFIG_STONEYRIDGE_XHCI_ENABLE))
63 FchParams_env->Usb.Xhci0Enable = TRUE;
64 else
65 FchParams_env->Usb.Xhci0Enable = FALSE;
66 FchParams_env->Usb.Xhci1Enable = FALSE;
67
Martin Rothc450fbe2017-10-02 13:46:50 -060068 /* SATA configuration */
69 FchParams_env->Sata.SataClass = CONFIG_STONEYRIDGE_SATA_MODE;
Richard Spiegelbb18b432018-08-03 10:37:28 -070070 if (dev && dev->enabled) {
71 switch ((SATA_CLASS)CONFIG_STONEYRIDGE_SATA_MODE) {
72 case SataRaid:
73 case SataAhci:
74 case SataAhci7804:
75 case SataLegacyIde:
76 FchParams_env->Sata.SataIdeMode = FALSE;
77 break;
78 case SataIde2Ahci:
79 case SataIde2Ahci7804:
80 default: /* SataNativeIde */
81 FchParams_env->Sata.SataIdeMode = TRUE;
82 break;
83 }
84 } else
Martin Rothc450fbe2017-10-02 13:46:50 -060085 FchParams_env->Sata.SataIdeMode = FALSE;
Martin Rothc450fbe2017-10-02 13:46:50 -060086
87 /* Platform updates */
88 platform_FchParams_env(FchParams_env);
89
90 printk(BIOS_DEBUG, "Done\n");
91 }
92
93 return AGESA_SUCCESS;
94}
95
Richard Spiegel271b8a52018-11-06 16:32:28 -070096AGESA_STATUS agesa_ReadSpd(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Martin Rothc450fbe2017-10-02 13:46:50 -060097{
Marc Jonesa9f72772017-11-16 18:47:36 -070098 uint8_t spd_address;
99 int err;
100 DEVTREE_CONST struct device *dev;
101 DEVTREE_CONST struct soc_amd_stoneyridge_config *conf;
102 AGESA_READ_SPD_PARAMS *info = ConfigPtr;
Martin Rothc450fbe2017-10-02 13:46:50 -0600103
104 if (!ENV_ROMSTAGE)
Marc Jonesa9f72772017-11-16 18:47:36 -0700105 return AGESA_UNSUPPORTED;
Martin Rothc450fbe2017-10-02 13:46:50 -0600106
Kyösti Mälkkie7377552018-06-21 16:20:55 +0300107 dev = pcidev_path_on_root(DCT_DEVFN);
Marc Jonesa9f72772017-11-16 18:47:36 -0700108 if (dev == NULL)
109 return AGESA_ERROR;
Martin Rothc450fbe2017-10-02 13:46:50 -0600110
Marc Jonesa9f72772017-11-16 18:47:36 -0700111 conf = dev->chip_info;
112 if (conf == NULL)
113 return AGESA_ERROR;
Martin Rothc450fbe2017-10-02 13:46:50 -0600114
Marc Jonesa9f72772017-11-16 18:47:36 -0700115 if (info->SocketId >= ARRAY_SIZE(conf->spd_addr_lookup))
116 return AGESA_ERROR;
117 if (info->MemChannelId >= ARRAY_SIZE(conf->spd_addr_lookup[0]))
118 return AGESA_ERROR;
119 if (info->DimmId >= ARRAY_SIZE(conf->spd_addr_lookup[0][0]))
120 return AGESA_ERROR;
121
122 spd_address = conf->spd_addr_lookup
123 [info->SocketId][info->MemChannelId][info->DimmId];
124 if (spd_address == 0)
125 return AGESA_ERROR;
126
127 err = mainboard_read_spd(spd_address, (void *)info->Buffer,
128 CONFIG_DIMM_SPD_SIZE);
129
130 /* Read the SPD if the mainboard didn't fill the buffer */
131 if (err || (*info->Buffer == 0))
132 err = sb_read_spd(spd_address, (void *)info->Buffer,
133 CONFIG_DIMM_SPD_SIZE);
134
135 if (err)
136 return AGESA_ERROR;
137
138 return AGESA_SUCCESS;
139}
140
Richard Spiegel271b8a52018-11-06 16:32:28 -0700141AGESA_STATUS agesa_HaltThisAp(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Richard Spiegela9f49362018-03-05 08:11:50 -0700142{
143 AGESA_HALT_THIS_AP_PARAMS *info = ConfigPtr;
144 uint32_t flags = 0;
145
146 if (info->PrimaryCore == TRUE)
147 return AGESA_UNSUPPORTED; /* force normal path */
148 if (info->ExecWbinvd == TRUE)
149 flags |= 1;
150 if (info->CacheEn == TRUE)
151 flags |= 2;
152
153 ap_teardown_car(flags); /* does not return */
154
155 /* Should never reach here */
156 return AGESA_UNSUPPORTED;
157}
158
Marc Jonesa9f72772017-11-16 18:47:36 -0700159/* Allow mainboards to fill the SPD buffer */
Aaron Durbin64031672018-04-21 14:45:32 -0600160__weak int mainboard_read_spd(uint8_t spdAddress, char *buf,
Marc Jonesa9f72772017-11-16 18:47:36 -0700161 size_t len)
162{
163 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
164 return -1; /* SPD not read */
Martin Rothc450fbe2017-10-02 13:46:50 -0600165}