]> git.proxmox.com Git - mirror_edk2.git/blobdiff - QuarkPlatformPkg/Platform/Pei/PlatformInit/PlatformEarlyInit.c
ArmPkg/CompilerIntrinsicsLib: Add uread, uwrite GCC assembly sources
[mirror_edk2.git] / QuarkPlatformPkg / Platform / Pei / PlatformInit / PlatformEarlyInit.c
index 32ae3e089189d2537ea14391c6f10bd0f4d96dbe..afc6e71d5f16621646d3905703ed7a5a06ad32e6 100644 (file)
@@ -6,15 +6,9 @@ This PEIM initialize platform for MRC, following action is performed,
 4. Calls MRC to initialize memory and install a PPI notify to do post memory initialization.\r
 This file contains the main entrypoint of the PEIM.\r
 \r
-Copyright (c) 2013 Intel Corporation.\r
+Copyright (c) 2013 - 2016 Intel Corporation.\r
 \r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -142,7 +136,7 @@ SetLanControllerMacAddr (
   SaveBarReg = PciRead32 (DevPcieAddr + R_IOH_MAC_MEMBAR);\r
 \r
   //\r
-  // Use predefined tempory memory resource\r
+  // Use predefined temporary memory resource\r
   //\r
   PciWrite32 ( DevPcieAddr + R_IOH_MAC_MEMBAR, Bar0);\r
   PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);\r
@@ -192,6 +186,271 @@ SetLanControllerMacAddr (
   PciWrite16 (DevPcieAddr + PCI_COMMAND_OFFSET, SaveCmdReg);\r
 }\r
 \r
+/**\r
+  Initialize state of I2C GPIO expanders.\r
+\r
+  @param  PlatformType  Platform type for GPIO expander init.\r
+\r
+**/\r
+EFI_STATUS\r
+EarlyPlatformConfigGpioExpanders (\r
+  IN CONST EFI_PLATFORM_TYPE              PlatformType,\r
+  EFI_BOOT_MODE                           BootMode\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_I2C_DEVICE_ADDRESS  I2CSlaveAddress;\r
+  UINTN                   Length;\r
+  UINTN                   ReadLength;\r
+  UINT8                   Buffer[2];\r
+\r
+  //\r
+  // Configure GPIO expanders for Galileo Gen 2\r
+  // Route I2C pins to Arduino header\r
+  // Set all GPIO expander pins connected to the Reset Button as inputs\r
+  //\r
+  if (PlatformType == GalileoGen2) {\r
+    //\r
+    // Configure AMUX1_IN (EXP2.P1_4) as an output\r
+    //\r
+    PlatformPcal9555GpioSetDir (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      12,                                   // P1-4.\r
+      FALSE                                 // Configure as output\r
+      );\r
+\r
+    //\r
+    // Set AMUX1_IN(EXP2.P1_4) low to route I2C to Arduino Shield connector\r
+    //\r
+    PlatformPcal9555GpioSetLevel (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      12,                                   // P1-4. \r
+      FALSE                                 // Set pin low\r
+      );\r
+\r
+    //\r
+    // Configure Reset Button(EXP1.P1_7) as an input\r
+    //\r
+    PlatformPcal9555GpioSetDir (\r
+      GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.\r
+      15,                                   // P1-7.\r
+      TRUE\r
+      );\r
+\r
+    //\r
+    // Disable pullup on Reset Button(EXP1.P1_7)\r
+    //\r
+    PlatformPcal9555GpioDisablePull (\r
+      GALILEO_GEN2_IOEXP1_7BIT_SLAVE_ADDR,  // IO Expander 1.\r
+      15                                    // P1-7.\r
+      );\r
+\r
+    //\r
+    // Configure Reset Button(EXP2.P1_7) as an input\r
+    //\r
+    PlatformPcal9555GpioSetDir (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      15,                                   // P1-7.\r
+      TRUE\r
+      );\r
+\r
+    //\r
+    // Disable pullup on Reset Button(EXP2.P1_7)\r
+    //\r
+    PlatformPcal9555GpioDisablePull (\r
+      GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2.\r
+      15                                    // P1-7.\r
+      );\r
+\r
+    if (BootMode != BOOT_IN_RECOVERY_MODE) {\r
+      //\r
+      // Read state of Reset Button - EXP2.P1_7\r
+      // This GPIO is pulled high when the button is not pressed\r
+      // This GPIO reads low when button is pressed\r
+      //\r
+      if (!PlatformPcal9555GpioGetState (\r
+             GALILEO_GEN2_IOEXP2_7BIT_SLAVE_ADDR,  // IO Expander 2\r
+             15                                    // P1-7\r
+             )) {\r
+        DEBUG ((EFI_D_INFO, "  Force Recovery mode and reset\n"));\r
+\r
+        //\r
+        // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset\r
+        //\r
+        QNCAltPortWrite (\r
+          QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
+          QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
+          QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY\r
+          );\r
+        ResetWarm();\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Configure GPIO expanders for Galileo Gen 2\r
+  // Set all GPIO expander pins connected to the Reset Button as inputs\r
+  // Route I2C pins to Arduino header\r
+  //\r
+  if (PlatformType == Galileo) {\r
+    //\r
+    // Detect the I2C Slave Address of the GPIO Expander\r
+    //\r
+    if (PlatformLegacyGpioGetLevel (R_QNC_GPIO_RGLVL_RESUME_WELL, GALILEO_DETERMINE_IOEXP_SLA_RESUMEWELL_GPIO)) {\r
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2HI_7BIT_SLAVE_ADDR;\r
+    } else {\r
+      I2CSlaveAddress.I2CDeviceAddress = GALILEO_IOEXP_J2LO_7BIT_SLAVE_ADDR;\r
+    }\r
+    DEBUG ((EFI_D_INFO, "Galileo GPIO Expender Slave Address = %02x\n", I2CSlaveAddress.I2CDeviceAddress));\r
+\r
+    //\r
+    // Set I2C_MUX (GPORT1_BIT5) low to route I2C to Arduino Shield connector\r
+    //\r
+\r
+    //\r
+    // Select GPIO Expander GPORT1\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x18; //sub-address\r
+    Buffer[1] = 0x01; //data\r
+    Status = I2cWriteMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &Buffer\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Read "Pin Direction" of GPIO Expander GPORT1\r
+    //\r
+    Length = 1;\r
+    ReadLength = 1;\r
+    Buffer[1] = 0x1C;\r
+    Status = I2cReadMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &ReadLength,\r
+      &Buffer[1]\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Configure GPIO Expander GPORT1_BIT5 as an output\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x1C; //sub-address\r
+    Buffer[1] = (UINT8)(Buffer[1] & (~BIT5)); //data\r
+\r
+    Status = I2cWriteMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &Buffer\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Set GPIO Expander GPORT1_BIT5 low\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x09; //sub-address\r
+    Buffer[1] = (UINT8)(~BIT5); //data\r
+\r
+    Status = I2cWriteMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &Buffer\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Configure RESET_N_SHLD (GPORT5_BIT0) and SW_RESET_N_SHLD (GPORT5_BIT1) as inputs\r
+    //\r
+\r
+    //\r
+    // Select GPIO Expander GPORT5\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x18;\r
+    Buffer[1] = 0x05;\r
+    Status = I2cWriteMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &Buffer\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Read "Pin Direction" of GPIO Expander GPORT5\r
+    //\r
+    Length = 1;\r
+    ReadLength = 1;\r
+    Buffer[1] = 0x1C;\r
+    Status = I2cReadMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &ReadLength,\r
+      &Buffer[1]\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Configure GPIO Expander GPORT5_BIT0 and GPORT5_BIT1 as inputs\r
+    //\r
+    Length = 2;\r
+    Buffer[0] = 0x1C;\r
+    Buffer[1] = Buffer[1] | BIT0 | BIT1;\r
+    Status = I2cWriteMultipleByte (\r
+      I2CSlaveAddress,\r
+      EfiI2CSevenBitAddrMode,\r
+      &Length,\r
+      &Buffer\r
+      );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    if (BootMode != BOOT_IN_RECOVERY_MODE) {\r
+      //\r
+      // Read state of RESET_N_SHLD (GPORT5_BIT0)\r
+      //\r
+      Buffer[1] = 5;\r
+      Length = 1;\r
+      ReadLength = 1;\r
+      Status = I2cReadMultipleByte (\r
+                 I2CSlaveAddress,\r
+                 EfiI2CSevenBitAddrMode,\r
+                 &Length,\r
+                 &ReadLength,\r
+                 &Buffer[1]\r
+                 );\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      //\r
+      // Return the state of GPORT5_BIT0\r
+      //\r
+      if ((Buffer[1] & BIT0) == 0) {\r
+        DEBUG ((EFI_D_INFO, "  Force Recovery mode and reset\n"));\r
+\r
+        //\r
+        // Set 'B_CFG_STICKY_RW_FORCE_RECOVERY' sticky bit so we know we need to do a recovery following warm reset\r
+        //\r
+        QNCAltPortWrite (\r
+          QUARK_SCSS_SOC_UNIT_SB_PORT_ID,\r
+          QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW,\r
+          QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW) | B_CFG_STICKY_RW_FORCE_RECOVERY\r
+          );\r
+        ResetWarm();\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   This is the entrypoint of PEIM\r
 \r
@@ -304,6 +563,12 @@ PeiInitPlatform (
   DEBUG ((EFI_D_INFO, "Platform Erratas After MRC\n"));\r
   PlatformErratasPostMrc ();\r
 \r
+  //\r
+  //\r
+  //\r
+  DEBUG ((EFI_D_INFO, "EarlyPlatformConfigGpioExpanders ()\n"));\r
+  EarlyPlatformConfigGpioExpanders (PlatformType, BootMode);\r
+\r
   //\r
   // Now that all of the pre-permanent memory activities have\r
   // been taken care of, post a call-back for the permanent-memory\r
@@ -529,7 +794,7 @@ CheckForResetDueToErrors (
 \r
   //\r
   // Check if RMU reset system due to access violations.\r
-  // RMU updates a SOC Unit register before reseting the system.\r
+  // RMU updates a SOC Unit register before resetting the system.\r
   //\r
   RegValue = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW);\r
   if ((RegValue & B_CFG_STICKY_RW_VIOLATION) != 0) {\r
@@ -579,8 +844,8 @@ EarlyPlatformInit (
   //\r
   if (CheckForResetDueToErrors (TRUE)) {\r
     if(FeaturePcdGet (WaitIfResetDueToError)) {\r
-      DEBUG ((EFI_D_ERROR, "Press any key to continue.\n"));\r
-      PlatformDebugPortGetChar8 ();\r
+      DEBUG ((EFI_D_ERROR, "Wait 10 seconds.\n"));\r
+      MicroSecondDelay(10000000);\r
     }\r
   }\r
 \r
@@ -777,7 +1042,7 @@ EarlyPlatformGpioCtrlerInitAndManipulation (
   SaveBarReg = PciRead32 (DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister));\r
 \r
   //\r
-  // Use predefined tempory memory resource.\r
+  // Use predefined temporary memory resource.\r
   //\r
   PciWrite32 ( DevPcieAddr + PcdGet8 (PcdIohGpioBarRegister), IohGpioBase);\r
   PciWrite8 ( DevPcieAddr + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_MEMORY_SPACE);\r