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