blob: 7d03b32aec0893b83aa78dfbe5cfc8b96857a1fc [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
Arthur Heymansadee6a62023-07-14 19:42:40 +0200115static void setup_opensil(void *unused)
116{
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
132BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, setup_opensil, NULL);
133
134static void opensil_entry(void *timepoint)
135{
136 SIL_STATUS ret;
137 SIL_TIMEPOINT tp = (uintptr_t)timepoint;
138
139 switch (tp) {
140 case SIL_TP1:
141 ret = InitializeSiTp1();
142 break;
143 case SIL_TP2:
144 ret = InitializeSiTp2();
145 break;
146 case SIL_TP3:
147 ret = InitializeSiTp3();
148 break;
149 default:
Felix Heldc7be0782023-12-13 23:09:48 +0100150 printk(BIOS_ERR, "Unknown openSIL timepoint\n");
Arthur Heymansadee6a62023-07-14 19:42:40 +0200151 return;
152 }
153 char opensil_function[16];
154 snprintf(opensil_function, sizeof(opensil_function), "InitializeSiTp%d", tp);
155 SIL_STATUS_report(opensil_function, ret);
156 if (ret == SilResetRequestColdImm || ret == SilResetRequestColdDef) {
Felix Heldc7be0782023-12-13 23:09:48 +0100157 printk(BIOS_INFO, "openSIL requested a cold reset");
Arthur Heymansadee6a62023-07-14 19:42:40 +0200158 do_cold_reset();
159 } else if (ret == SilResetRequestWarmImm || ret == SilResetRequestWarmDef) {
Felix Heldc7be0782023-12-13 23:09:48 +0100160 printk(BIOS_INFO, "openSIL requested a warm reset");
Arthur Heymansadee6a62023-07-14 19:42:40 +0200161 do_warm_reset();
162 }
163}
164
165/* TODO: look into calling these functions from some SoC device operations instead of using
166 * BOOT_STATE_INIT_ENTRY */
167BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_EXIT, opensil_entry, (void *)SIL_TP1);
168/* TODO add other timepoints later. Are they NOOP? */