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