blob: 11289bb81b27790aa814e4634bb683c2e42aa8f6 [file] [log] [blame]
Arthur Heymansadee6a62023-07-14 19:42:40 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2
Martin Rothf643a4d2023-09-27 16:46:46 -06003#include <FCH/Common/FchCommonCfg.h>
Arthur Heymans62389ab2023-07-14 20:11:15 +02004#include <FCH/Common/FchCore/FchSata/FchSata.h>
Arthur Heymans81ceea12023-07-14 19:56:03 +02005#include <RcMgr/DfX/RcManager4-api.h>
Arthur Heymansadee6a62023-07-14 19:42:40 +02006#include <amdblocks/reset.h>
7#include <bootstate.h>
8#include <cbmem.h>
Arthur Heymans81ceea12023-07-14 19:56:03 +02009#include <cpu/cpu.h>
Martin Rothf643a4d2023-09-27 16:46:46 -060010#include <device/device.h>
11#include <soc/soc_chip.h>
Arthur Heymansadee6a62023-07-14 19:42:40 +020012#include <xSIM-api.h>
13#include "opensil_console.h"
Arthur Heymans5f6cf612023-07-14 22:37:03 +020014#include "opensil.h"
Arthur Heymansadee6a62023-07-14 19:42:40 +020015
Arthur Heymans5f6cf612023-07-14 22:37:03 +020016void SIL_STATUS_report(const char *function, const int status)
Arthur Heymansadee6a62023-07-14 19:42:40 +020017{
18 const int log_level = status == SilPass ? BIOS_DEBUG : BIOS_ERR;
19 const char *error_string = "Unkown error";
20
21 const struct error_string_entry {
22 SIL_STATUS status;
23 const char *string;
24 } errors[] = {
25 {SilPass, "SilPass"},
26 {SilUnsupportedHardware, "SilUnsupportedHardware"},
27 {SilUnsupported, "SilUnsupported"},
28 {SilInvalidParameter, "SilInvalidParameter"},
29 {SilAborted, "SilAborted"},
30 {SilOutOfResources, "SilOutOfResources"},
31 {SilNotFound, "SilNotFound"},
32 {SilOutOfBounds, "SilOutOfBounds"},
33 {SilDeviceError, "SilDeviceError"},
34 {SilResetRequestColdImm, "SilResetRequestColdImm"},
35 {SilResetRequestColdDef, "SilResetRequestColdDef"},
36 {SilResetRequestWarmImm, "SilResetRequestWarmImm"},
37 {SilResetRequestWarmDef, "SilResetRequestWarmDef"},
38 };
39
40 int i;
41 for (i = 0; i < ARRAY_SIZE(errors); i++) {
42 if (errors[i].status == status)
43 error_string = errors[i].string;
44 }
45 printk(log_level, "%s returned %d (%s)\n", function, status, error_string);
46}
47
Arthur Heymans81ceea12023-07-14 19:56:03 +020048static void setup_rc_manager_default(void)
49{
50 DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0);
51 /* Let openSIL distribute the resources to the different PCI roots */
52 rc_mgr_input_block->SetRcBasedOnNv = false;
53
54 /* Currently 1P is the only supported configuration */
55 rc_mgr_input_block->SocketNumber = 1;
56 rc_mgr_input_block->RbsPerSocket = 4; /* PCI root bridges per socket */
57 rc_mgr_input_block->McptEnable = true;
58 rc_mgr_input_block->PciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS;
59 rc_mgr_input_block->BottomMmioReservedForPrimaryRb = 4ull * GiB - 32 * MiB;
60 rc_mgr_input_block->MmioSizePerRbForNonPciDevice = 16 * MiB;
61 /* MmioAbove4GLimit will be adjusted down in openSIL */
62 rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(cpu_phys_address_size());
63 rc_mgr_input_block->Above4GMmioSizePerRbForNonPciDevice = 0;
64}
65
Martin Rothf643a4d2023-09-27 16:46:46 -060066#define NUM_XHCI_CONTROLLERS 2
67static void configure_usb(void)
68{
Felix Heldd123f8d2023-12-15 10:57:30 +010069 const struct soc_amd_genoa_poc_config *soc_config = config_of_soc();
Martin Rothf643a4d2023-09-27 16:46:46 -060070 const struct soc_usb_config *usb = &soc_config->usb;
71
72 FCHUSB_INPUT_BLK *fch_usb_data = SilFindStructure(SilId_FchUsb, 0);
73 fch_usb_data->Xhci0Enable = usb->xhci0_enable;
74 fch_usb_data->Xhci1Enable = usb->xhci1_enable;
75 fch_usb_data->Xhci2Enable = false; /* there's no XHCI2 on this SoC */
76 for (int i = 0; i < NUM_XHCI_CONTROLLERS; i++) {
77 memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb20OcPin, &usb->usb2_oc_pins[i],
78 sizeof(fch_usb_data->XhciOCpinSelect[i].Usb20OcPin));
79 memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb31OcPin, &usb->usb3_oc_pins[i],
80 sizeof(fch_usb_data->XhciOCpinSelect[i].Usb31OcPin));
81 }
82 fch_usb_data->XhciOcPolarityCfgLow = usb->polarity_cfg_low;
83 fch_usb_data->Usb3PortForceGen1 = usb->usb3_force_gen1.raw;
84
85 /* Instead of overwriting the whole OemUsbConfigurationTable, only copy the relevant
86 fields to the pre-populated data structure */
87 fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->usb31_phy_enable;
88 if (usb->usb31_phy_enable)
89 memcpy(&fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort, usb->usb31_phy,
90 sizeof(fch_usb_data->OemUsbConfigurationTable.Usb31PhyPort));
91 fch_usb_data->OemUsbConfigurationTable.Usb31PhyEnable = usb->s1_usb31_phy_enable;
92 if (usb->s1_usb31_phy_enable)
93 memcpy(&fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort, usb->s1_usb31_phy,
94 sizeof(fch_usb_data->OemUsbConfigurationTable.S1Usb31PhyPort));
95}
96
Arthur Heymans62389ab2023-07-14 20:11:15 +020097#define NUM_SATA_CONTROLLERS 4
98static void configure_sata(void)
99{
100 FCHSATA_INPUT_BLK *fch_sata_data = SilFindStructure(SilId_FchSata, 0);
101 FCH_SATA2 *fch_sata_defaults = GetFchSataData();
102 for (int i = 0; i < NUM_SATA_CONTROLLERS; i++) {
103 fch_sata_data[i] = fch_sata_defaults[i];
104 fch_sata_data[i].SataSetMaxGen2 = false;
105 fch_sata_data[i].SataMsiEnable = true;
106 fch_sata_data[i].SataEspPort = 0xFF;
107 fch_sata_data[i].SataRasSupport = true;
108 fch_sata_data[i].SataDevSlpPort1Num = 1;
109 fch_sata_data[i].SataMsiEnable = true;
110 fch_sata_data[i].SataControllerAutoShutdown = true;
111 fch_sata_data[i].SataRxPolarity = 0xFF;
112 }
113}
114
Felix Helddc12a382024-01-16 00:50:46 +0100115void setup_opensil(void)
Arthur Heymansadee6a62023-07-14 19:42:40 +0200116{
117 const SIL_STATUS debug_ret = SilDebugSetup(HostDebugService);
118 SIL_STATUS_report("SilDebugSetup", debug_ret);
119 const size_t mem_req = xSimQueryMemoryRequirements();
120 void *buf = cbmem_add(CBMEM_ID_AMD_OPENSIL, mem_req);
121 assert(buf);
122 /* We run all openSIL timepoints in the same stage so using TP1 as argument is fine. */
123 const SIL_STATUS assign_mem_ret = xSimAssignMemoryTp1(buf, mem_req);
124 SIL_STATUS_report("xSimAssignMemory", assign_mem_ret);
Arthur Heymans81ceea12023-07-14 19:56:03 +0200125
126 setup_rc_manager_default();
Martin Rothf643a4d2023-09-27 16:46:46 -0600127 configure_usb();
Arthur Heymans62389ab2023-07-14 20:11:15 +0200128 configure_sata();
Felix Helde5197e12024-01-22 18:17:57 +0100129 configure_mpio();
Arthur Heymansadee6a62023-07-14 19:42:40 +0200130}
131
Felix Helddc12a382024-01-16 00:50:46 +0100132void opensil_entry(SIL_TIMEPOINT timepoint)
Arthur Heymansadee6a62023-07-14 19:42:40 +0200133{
134 SIL_STATUS ret;
135 SIL_TIMEPOINT tp = (uintptr_t)timepoint;
136
137 switch (tp) {
138 case SIL_TP1:
139 ret = InitializeSiTp1();
140 break;
141 case SIL_TP2:
142 ret = InitializeSiTp2();
143 break;
144 case SIL_TP3:
145 ret = InitializeSiTp3();
146 break;
147 default:
Felix Heldc7be0782023-12-13 23:09:48 +0100148 printk(BIOS_ERR, "Unknown openSIL timepoint\n");
Arthur Heymansadee6a62023-07-14 19:42:40 +0200149 return;
150 }
151 char opensil_function[16];
152 snprintf(opensil_function, sizeof(opensil_function), "InitializeSiTp%d", tp);
153 SIL_STATUS_report(opensil_function, ret);
154 if (ret == SilResetRequestColdImm || ret == SilResetRequestColdDef) {
Felix Heldc7be0782023-12-13 23:09:48 +0100155 printk(BIOS_INFO, "openSIL requested a cold reset");
Arthur Heymansadee6a62023-07-14 19:42:40 +0200156 do_cold_reset();
157 } else if (ret == SilResetRequestWarmImm || ret == SilResetRequestWarmDef) {
Felix Heldc7be0782023-12-13 23:09:48 +0100158 printk(BIOS_INFO, "openSIL requested a warm reset");
Arthur Heymansadee6a62023-07-14 19:42:40 +0200159 do_warm_reset();
160 }
161}
162
Felix Helddc12a382024-01-16 00:50:46 +0100163/* TODO: also call timepoints 2 and 3 from coreboot. Are they NOOP? */