]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkPlatformPkg/Platform/Dxe/PlatformInit/PlatformConfig.c
QuarkPlatformPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkPlatformPkg / Platform / Dxe / PlatformInit / PlatformConfig.c
1 /** @file
2 Essential platform configuration.
3
4 Copyright (c) 2013 Intel Corporation.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8
9 **/
10
11 #include "PlatformInitDxe.h"
12
13 //
14 // The protocols, PPI and GUID defintions for this module
15 //
16
17 //
18 // The Library classes this module consumes
19 //
20
21 //
22 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
23 // Workaround to make default SMRAM UnCachable
24 //
25 #define SMM_DEFAULT_SMBASE 0x30000 // Default SMBASE address
26 #define SMM_DEFAULT_SMBASE_SIZE_BYTES 0x10000 // Size in bytes of default SMRAM
27
28 BOOLEAN mMemCfgDone = FALSE;
29 UINT8 ChipsetDefaultMac [6] = {0xff,0xff,0xff,0xff,0xff,0xff};
30
31 VOID
32 EFIAPI
33 PlatformInitializeUart0MuxGalileo (
34 VOID
35 )
36 /*++
37
38
39 Routine Description:
40
41 This is the routine to initialize UART0 for DBG2 support. The hardware used in this process is a
42 Legacy Bridge (Legacy GPIO), I2C controller, a bi-directional MUX and a Cypress CY8C9540A chip.
43
44 Arguments:
45
46 None.
47
48 Returns:
49
50 None.
51
52 --*/
53 {
54 EFI_STATUS Status;
55 EFI_I2C_DEVICE_ADDRESS I2CSlaveAddress;
56 UINTN Length;
57 UINT8 Buffer[2];
58
59 if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {
60 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;
61 } else {
62 I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;
63 }
64
65 //
66 // Set GPIO_SUS<2> as an output, raise voltage to Vdd.
67 //
68 PlatformLegacyGpioSetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, 2, TRUE);
69
70 //
71 // Select Port 3
72 //
73 Length = 2;
74 Buffer[0] = 0x18; //sub-address
75 Buffer[1] = 0x03; //data
76
77 Status = I2cWriteMultipleByte (
78 I2CSlaveAddress,
79 EfiI2CSevenBitAddrMode,
80 &Length,
81 &Buffer
82 );
83 ASSERT_EFI_ERROR (Status);
84
85 //
86 // Set "Pin Direction" bit4 and bit5 as outputs
87 //
88 Length = 2;
89 Buffer[0] = 0x1C; //sub-address
90 Buffer[1] = 0xCF; //data
91
92 Status = I2cWriteMultipleByte (
93 I2CSlaveAddress,
94 EfiI2CSevenBitAddrMode,
95 &Length,
96 &Buffer
97 );
98 ASSERT_EFI_ERROR (Status);
99
100 //
101 // Lower GPORT3 bit4 and bit5 to Vss
102 //
103 Length = 2;
104 Buffer[0] = 0x0B; //sub-address
105 Buffer[1] = 0xCF; //data
106
107 Status = I2cWriteMultipleByte (
108 I2CSlaveAddress,
109 EfiI2CSevenBitAddrMode,
110 &Length,
111 &Buffer
112 );
113 ASSERT_EFI_ERROR (Status);
114 }
115
116 VOID
117 EFIAPI
118 PlatformInitializeUart0MuxGalileoGen2 (
119 VOID
120 )
121 /*++
122
123
124 Routine Description:
125
126 This is the routine to initialize UART0 on GalileoGen2. The hardware used in this process is
127 I2C controller and the configuring the following IO Expander signal.
128
129 EXP1.P1_5 should be configured as an output & driven high.
130 EXP1.P0_0 should be configured as an output & driven high.
131 EXP0.P1_4 should be configured as an output, driven low.
132 EXP1.P0_1 pullup should be disabled.
133 EXP0.P1_5 Pullup should be disabled.
134
135 Arguments:
136
137 None.
138
139 Returns:
140
141 None.
142
143 --*/
144
145 {
146 //
147 // EXP1.P1_5 should be configured as an output & driven high.
148 //
149 PlatformPcal9555GpioSetDir (
150 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
151 13, // P1-5.
152 TRUE
153 );
154 PlatformPcal9555GpioSetLevel (
155 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
156 13, // P1-5.
157 TRUE
158 );
159
160 //
161 // EXP1.P0_0 should be configured as an output & driven high.
162 //
163 PlatformPcal9555GpioSetDir (
164 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
165 0, // P0_0.
166 TRUE
167 );
168 PlatformPcal9555GpioSetLevel (
169 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
170 0, // P0_0.
171 TRUE
172 );
173
174 //
175 // EXP0.P1_4 should be configured as an output, driven low.
176 //
177 PlatformPcal9555GpioSetDir (
178 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
179 12, // P1-4.
180 FALSE
181 );
182 PlatformPcal9555GpioSetLevel ( // IO Expander 0.
183 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // P1-4
184 12,
185 FALSE
186 );
187
188 //
189 // EXP1.P0_1 pullup should be disabled.
190 //
191 PlatformPcal9555GpioDisablePull (
192 GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR, // IO Expander 1.
193 1 // P0-1.
194 );
195
196 //
197 // EXP0.P1_5 Pullup should be disabled.
198 //
199 PlatformPcal9555GpioDisablePull (
200 GALILEO_GEN2_IOEXP0_7BIT_SLAVE_ADDR, // IO Expander 0.
201 13 // P1-5.
202 );
203 }
204
205 VOID
206 EFIAPI
207 PlatformConfigOnSmmConfigurationProtocol (
208 IN EFI_EVENT Event,
209 IN VOID *Context
210 )
211 /*++
212
213 Routine Description:
214
215 Function runs in PI-DXE to perform platform specific config when
216 SmmConfigurationProtocol is installed.
217
218 Arguments:
219 Event - The event that occured.
220 Context - For EFI compatiblity. Not used.
221
222 Returns:
223 None.
224 --*/
225
226 {
227 EFI_STATUS Status;
228 UINT32 NewValue;
229 UINT64 BaseAddress;
230 UINT64 SmramLength;
231 VOID *SmmCfgProt;
232
233 Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, &SmmCfgProt);
234 if (Status != EFI_SUCCESS){
235 DEBUG ((DEBUG_INFO, "gEfiSmmConfigurationProtocolGuid triggered but not valid.\n"));
236 return;
237 }
238 if (mMemCfgDone) {
239 DEBUG ((DEBUG_INFO, "Platform DXE Mem config already done.\n"));
240 return;
241 }
242
243 //
244 // Disable eSram block (this will also clear/zero eSRAM)
245 // We only use eSRAM in the PEI phase. Disable now that we are in the DXE phase
246 //
247 NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK);
248 NewValue |= BLOCK_DISABLE_PG;
249 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK, NewValue);
250
251 //
252 // Update HMBOUND to top of DDR3 memory and LOCK
253 // We disabled eSRAM so now we move HMBOUND down to top of DDR3
254 //
255 QNCGetTSEGMemoryRange (&BaseAddress, &SmramLength);
256 NewValue = (UINT32)(BaseAddress + SmramLength);
257 DEBUG ((EFI_D_INFO,"Locking HMBOUND at: = 0x%8x\n",NewValue));
258 QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG, (NewValue | HMBOUND_LOCK));
259
260 //
261 // Lock IMR5 now that HMBOUND is locked (legacy S3 region)
262 //
263 NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL);
264 NewValue |= IMR_LOCK;
265 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR5+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
266
267 //
268 // Lock IMR6 now that HMBOUND is locked (ACPI Reclaim/ACPI/Runtime services/Reserved)
269 //
270 NewValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL);
271 NewValue |= IMR_LOCK;
272 QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_IMR6+QUARK_NC_MEMORY_MANAGER_IMRXL, NewValue);
273
274 //
275 // Disable IMR2 memory protection (RMU Main Binary)
276 //
277 QncImrWrite (
278 QUARK_NC_MEMORY_MANAGER_IMR2,
279 (UINT32)(IMRL_RESET & ~IMR_EN),
280 (UINT32)IMRH_RESET,
281 (UINT32)IMRX_ALL_ACCESS,
282 (UINT32)IMRX_ALL_ACCESS
283 );
284
285 //
286 // Disable IMR3 memory protection (Default SMRAM)
287 //
288 QncImrWrite (
289 QUARK_NC_MEMORY_MANAGER_IMR3,
290 (UINT32)(IMRL_RESET & ~IMR_EN),
291 (UINT32)IMRH_RESET,
292 (UINT32)IMRX_ALL_ACCESS,
293 (UINT32)IMRX_ALL_ACCESS
294 );
295
296 //
297 // Disable IMR4 memory protection (eSRAM).
298 //
299 QncImrWrite (
300 QUARK_NC_MEMORY_MANAGER_IMR4,
301 (UINT32)(IMRL_RESET & ~IMR_EN),
302 (UINT32)IMRH_RESET,
303 (UINT32)IMRX_ALL_ACCESS,
304 (UINT32)IMRX_ALL_ACCESS
305 );
306
307 //
308 // RTC:28208 - System hang/crash when entering probe mode(ITP) when relocating SMBASE
309 // Workaround to make default SMRAM UnCachable
310 //
311 Status = gDS->SetMemorySpaceAttributes (
312 (EFI_PHYSICAL_ADDRESS) SMM_DEFAULT_SMBASE,
313 SMM_DEFAULT_SMBASE_SIZE_BYTES,
314 EFI_MEMORY_WB
315 );
316 ASSERT_EFI_ERROR (Status);
317
318 mMemCfgDone = TRUE;
319 }
320
321 VOID
322 EFIAPI
323 PlatformConfigOnSpiReady (
324 IN EFI_EVENT Event,
325 IN VOID *Context
326 )
327 /*++
328
329 Routine Description:
330
331 Function runs in PI-DXE to perform platform specific config when SPI
332 interface is ready.
333
334 Arguments:
335 Event - The event that occured.
336 Context - For EFI compatiblity. Not used.
337
338 Returns:
339 None.
340
341 --*/
342 {
343 EFI_STATUS Status;
344 VOID *SpiReadyProt = NULL;
345 EFI_PLATFORM_TYPE Type;
346 EFI_BOOT_MODE BootMode;
347
348 BootMode = GetBootModeHob ();
349
350 Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt);
351 if (Status != EFI_SUCCESS){
352 DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n"));
353 return;
354 }
355
356 //
357 // Lock regions SPI flash.
358 //
359 PlatformFlashLockPolicy (FALSE);
360
361 //
362 // Configurations and checks to be done when DXE tracing available.
363 //
364
365 //
366 // Platform specific Signal routing.
367 //
368
369 //
370 // Skip any signal not needed for recovery and flash update.
371 //
372 if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) {
373
374 //
375 // Galileo Platform UART0 support.
376 //
377 Type = (EFI_PLATFORM_TYPE)PcdGet16 (PcdPlatformType);
378 if (Type == Galileo) {
379 //
380 // Use MUX to connect out UART0 pins.
381 //
382 PlatformInitializeUart0MuxGalileo ();
383 }
384
385 //
386 // GalileoGen2 Platform UART0 support.
387 //
388 if (Type == GalileoGen2) {
389 //
390 // Use route out UART0 pins.
391 //
392 PlatformInitializeUart0MuxGalileoGen2 ();
393 }
394 }
395 }
396
397 EFI_STATUS
398 EFIAPI
399 CreateConfigEvents (
400 VOID
401 )
402 /*++
403
404 Routine Description:
405
406 Arguments:
407 None
408
409 Returns:
410 EFI_STATUS
411
412 --*/
413 {
414 EFI_EVENT EventSmmCfg;
415 EFI_EVENT EventSpiReady;
416 VOID *RegistrationSmmCfg;
417 VOID *RegistrationSpiReady;
418
419 //
420 // Schedule callback for when SmmConfigurationProtocol installed.
421 //
422 EventSmmCfg = EfiCreateProtocolNotifyEvent (
423 &gEfiSmmConfigurationProtocolGuid,
424 TPL_CALLBACK,
425 PlatformConfigOnSmmConfigurationProtocol,
426 NULL,
427 &RegistrationSmmCfg
428 );
429 ASSERT (EventSmmCfg != NULL);
430
431 //
432 // Schedule callback to setup SPI Flash Policy when SPI interface ready.
433 //
434 EventSpiReady = EfiCreateProtocolNotifyEvent (
435 &gEfiSmmSpiReadyProtocolGuid,
436 TPL_CALLBACK,
437 PlatformConfigOnSpiReady,
438 NULL,
439 &RegistrationSpiReady
440 );
441 ASSERT (EventSpiReady != NULL);
442 return EFI_SUCCESS;
443 }