Home | History | Annotate | Download | only in BoardGpios
      1 /** @file
      2   Gpio setting for multiplatform..
      3 
      4   Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials are licensed and made available under
      8   the terms and conditions of the BSD License that accompanies this distribution.
     10   The full text of the license may be found at
     12   http://opensource.org/licenses/bsd-license.php.
     14 
     16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     20 
     22 
     24 **/
     25 
     26 #include <BoardGpios.h>
     27 #include <Guid/SetupVariable.h>
     28 
     29 //
     30 //AlpineValley platform ocde begin
     31 //
     32 #define AV_SC_REG_GPIOS_MUXES_SEL0 0x48
     33 #define AV_SC_REG_GPIOS_MUXES_SEL1 0x4C
     34 #define AV_SC_REG_GPIOS_MUXES_SEL2 0x50
     35 #define AV_SC_REG_GPIOS_MUXES_EN0  0x54
     36 #define AV_SC_REG_GPIOS_MUXES_EN1  0x58
     37 #define AV_SC_REG_GPIOS_MUXES_EN2  0x5C
     38 //
     39 //AlpineValley platform code end
     40 //
     41 
     42 EFI_GUID  gPeiSmbusPpiGuid               = EFI_PEI_SMBUS_PPI_GUID;
     43 
     44 /**
     45   @param None
     46 
     47   @retval EFI_SUCCESS    The function completed successfully.
     48 
     49 **/
     50 EFI_STATUS
     51 ConfigurePlatformSysCtrlGpio (
     52   IN EFI_PEI_SERVICES                   **PeiServices,
     53   IN EFI_PEI_NOTIFY_DESCRIPTOR          *NotifyDescriptor,
     54   IN VOID                               *SmbusPpi
     55   )
     56 {
     57   //
     58   //AlpineValley platform code begin
     59   //
     60   // Initialize GPIO Settings:
     61   //
     62   UINT32        Status;
     63   EFI_PLATFORM_INFO_HOB               *PlatformInfoHob;
     64 
     65    DEBUG ((EFI_D_INFO, "ConfigurePlatformSysCtrlGpio()...\n"));
     66 
     67   //
     68   // Obtain Platform Info from HOB.
     69   //
     70   Status = GetPlatformInfoHob ((const EFI_PEI_SERVICES **)PeiServices, &PlatformInfoHob);
     71   ASSERT_EFI_ERROR (Status);
     72 
     73   //
     74   // The GPIO settings are dependent upon the platform.  Obtain the Board ID through
     75   // the EC to determine the current platform.
     76   //
     77    DEBUG ((EFI_D_INFO, "Platform Flavor | Board ID = 0x%X | 0x%X\n", PlatformInfoHob->PlatformFlavor, PlatformInfoHob->BoardId));
     78 
     79 
     80 
     81   Status = (**PeiServices).LocatePpi (
     82                             (const EFI_PEI_SERVICES **)PeiServices,
     83                             &gPeiSmbusPpiGuid,
     84                             0,
     85                             NULL,
     86                             (void **)&SmbusPpi
     87                             );
     88   ASSERT_EFI_ERROR (Status);
     89 
     90   //
     91   // Select/modify the GPIO initialization data based on the Board ID.
     92   //
     93   switch (PlatformInfoHob->BoardId)
     94   {
     95     default:
     96       Status = EFI_SUCCESS;
     97 
     98       //
     99       // Do nothing for other RVP boards.
    100       //
    101       break;
    102   }
    103   return Status;
    104 }
    105 
    106 static EFI_PEI_NOTIFY_DESCRIPTOR    mNotifyList[] = {
    107   {
    108     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
    109     &gEfiPeiSmbusPpiGuid,
    110     ConfigurePlatformSysCtrlGpio
    111   }
    112 };
    113 
    114 EFI_STATUS
    115 InstallPlatformSysCtrlGPIONotify (
    116   IN CONST EFI_PEI_SERVICES           **PeiServices
    117   )
    118 {
    119   EFI_STATUS                    Status;
    120 
    121   DEBUG ((EFI_D_INFO, "InstallPlatformSysCtrlGPIONotify()...\n"));
    122 
    123   Status = (*PeiServices)->NotifyPpi(PeiServices, &mNotifyList[0]);
    124   ASSERT_EFI_ERROR (Status);
    125   return EFI_SUCCESS;
    126 
    127 }
    128 
    129 #define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3             BIT3 // UART IRQ3 Enable
    130 
    131 /**
    132   Returns the Correct GPIO table for Mobile/Desktop respectively.
    133   Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
    134 
    135   @param PeiServices             General purpose services available to every PEIM.
    136   @param PlatformInfoHob         PlatformInfoHob pointer with PlatformFlavor specified.
    137   @param BoardId                 BoardId ID as determined through the EC.
    138 
    139   @retval EFI_SUCCESS            The function completed successfully.
    140   @retval EFI_DEVICE_ERROR       KSC fails to respond.
    141 
    142 **/
    143 EFI_STATUS
    144 MultiPlatformGpioTableInit (
    145   IN CONST EFI_PEI_SERVICES     **PeiServices,
    146   IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
    147   )
    148 {
    149   EFI_STATUS                      Status;
    150   EFI_PEI_READ_ONLY_VARIABLE2_PPI *PeiReadOnlyVarPpi;
    151   UINTN                           VarSize;
    152   SYSTEM_CONFIGURATION            SystemConfiguration;
    153 
    154   DEBUG ((EFI_D_INFO, "MultiPlatformGpioTableInit()...\n"));
    155 
    156   //
    157   // Select/modify the GPIO initialization data based on the Board ID.
    158   //
    159   switch (PlatformInfoHob->BoardId) {
    160 
    161   case BOARD_ID_MINNOW2: // Minnow2
    162   case BOARD_ID_MINNOW2_TURBOT:
    163    Status = (**PeiServices).LocatePpi (
    164                              PeiServices,
    165                              &gEfiPeiReadOnlyVariable2PpiGuid,
    166                              0,
    167                              NULL,
    168                              (void **)&PeiReadOnlyVarPpi
    169                              );
    170     ASSERT_EFI_ERROR (Status);
    171 
    172     VarSize = sizeof (SYSTEM_CONFIGURATION);
    173     Status = PeiReadOnlyVarPpi->GetVariable (
    174                                   PeiReadOnlyVarPpi,
    175                                   PLATFORM_SETUP_VARIABLE_NAME,
    176                                   &gEfiSetupVariableGuid,
    177                                   NULL,
    178                                   &VarSize,
    179                                   &SystemConfiguration
    180                                   );
    181 
    182      if (SystemConfiguration.GpioWakeCapability == 1) {
    183       PlatformInfoHob->PlatformCfioData     = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData2;
    184      }
    185      else {
    186       PlatformInfoHob->PlatformCfioData     = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2CfioInitData;
    187      }
    188 
    189      PlatformInfoHob->PlatformGpioData_NC  = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_NC[0];
    190      PlatformInfoHob->PlatformGpioData_SC  = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SC[0];
    191      PlatformInfoHob->PlatformGpioData_SUS = (EFI_PHYSICAL_ADDRESS)(UINTN) &mMinnow2_GpioInitData_SUS[0];
    192      break;
    193 
    194   }
    195 
    196   return EFI_SUCCESS;
    197 }
    198 
    199 UINT32
    200 GPIORead32 (
    201   IN  UINT32 mmio_conf
    202   )
    203 {
    204   UINT32 conf_val;
    205   UINT32 i;
    206   conf_val = MmioRead32(mmio_conf);
    207   for(i=0;i<5;i++){
    208     if(conf_val == 0xffffffff)
    209       conf_val = MmioRead32(mmio_conf);
    210       else
    211         break;
    212   }
    213 
    214   return conf_val;
    215 }
    216 
    217 /**
    218 
    219   Set GPIO CONF0 and PAD_VAL registers for NC/SC/SUS GPIO clusters
    220 
    221   @param Gpio_Mmio_Offset          GPIO_SCORE_OFFSET or GPIO_NCORE_OFFSET or GPIO_SSUS_OFFSET.
    222   @param Gpio_Pin_Num              Pin numbers to config for each GPIO clusters.
    223   @param Gpio_Conf_Data            GPIO_CONF_PAD_INIT data array for each GPIO clusters.
    224 
    225 **/
    226 VOID
    227 InternalGpioConfig (
    228   IN UINT32             Gpio_Mmio_Offset,
    229   IN UINT32             Gpio_Pin_Num,
    230   GPIO_CONF_PAD_INIT*   Gpio_Conf_Data
    231   )
    232 {
    233   UINT32    index;
    234   UINT32    mmio_conf0;
    235   UINT32    mmio_padval;
    236   PAD_CONF0 conf0_val;
    237   PAD_VAL   pad_val;
    238 
    239   //
    240   // GPIO WELL -- Memory base registers
    241   //
    242 
    243   // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
    244   // GPIO write 0x01001002 to IOBASE + Gpio_Mmio_Offset + 0x0900
    245   //
    246   for(index=0; index < Gpio_Pin_Num; index++)
    247   {
    248   	//
    249     // Calculate the MMIO Address for specific GPIO pin CONF0 register pointed by index.
    250     //
    251     mmio_conf0 = IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_CONF0 + Gpio_Conf_Data[index].offset * 16;
    252     mmio_padval= IO_BASE_ADDRESS + Gpio_Mmio_Offset + R_PCH_CFIO_PAD_VAL   + Gpio_Conf_Data[index].offset * 16;
    253 
    254 #ifdef EFI_DEBUG
    255     DEBUG ((EFI_D_INFO, "%s, ", Gpio_Conf_Data[index].pad_name));
    256 
    257 #endif
    258     DEBUG ((EFI_D_INFO, "Usage = %d, Func# = %d, IntType = %d, Pull Up/Down = %d, MMIO Base = 0x%08x, ",
    259       Gpio_Conf_Data[index].usage,
    260       Gpio_Conf_Data[index].func,
    261       Gpio_Conf_Data[index].int_type,
    262       Gpio_Conf_Data[index].pull,
    263       mmio_conf0));
    264 
    265     //
    266     // Step 1: PadVal Programming.
    267     //
    268     pad_val.dw = GPIORead32(mmio_padval);
    269 
    270     //
    271     // Config PAD_VAL only for GPIO (Non-Native) Pin
    272     //
    273     if(Native != Gpio_Conf_Data[index].usage)
    274     {
    275       pad_val.dw &= ~0x6; // Clear bits 1:2
    276       pad_val.dw |= (Gpio_Conf_Data[index].usage & 0x6);  // Set bits 1:2 according to PadVal
    277 
    278         //
    279         // set GPO default value
    280         //
    281         if(Gpio_Conf_Data[index].usage == GPO && Gpio_Conf_Data[index].gpod4 != NA)
    282         {
    283         pad_val.r.pad_val = Gpio_Conf_Data[index].gpod4;
    284         }
    285     }
    286 
    287 
    288     DEBUG ((EFI_D_INFO, "Set PAD_VAL = 0x%08x, ", pad_val.dw));
    289 
    290     MmioWrite32(mmio_padval, pad_val.dw);
    291 
    292     //
    293     // Step 2: CONF0 Programming
    294     // Read GPIO default CONF0 value, which is assumed to be default value after reset.
    295     //
    296     conf0_val.dw = GPIORead32(mmio_conf0);
    297 
    298     //
    299     // Set Function #
    300     //
    301     conf0_val.r.Func_Pin_Mux = Gpio_Conf_Data[index].func;
    302 
    303     if(GPO == Gpio_Conf_Data[index].usage)
    304     {
    305       //
    306       // If used as GPO, then internal pull need to be disabled.
    307       //
    308       conf0_val.r.Pull_assign = 0;  // Non-pull
    309     }
    310     else
    311     {
    312       //
    313       // Set PullUp / PullDown
    314       //
    315       if(P_20K_H == Gpio_Conf_Data[index].pull)
    316       {
    317         conf0_val.r.Pull_assign = 0x1;  // PullUp
    318         conf0_val.r.Pull_strength = 0x2;// 20K
    319       }
    320       else if(P_20K_L == Gpio_Conf_Data[index].pull)
    321       {
    322         conf0_val.r.Pull_assign = 0x2;  // PullDown
    323         conf0_val.r.Pull_strength = 0x2;// 20K
    324       }
    325       else if(P_10K_H == Gpio_Conf_Data[index].pull)
    326       {
    327         conf0_val.r.Pull_assign = 0x1; 	// PullUp
    328         conf0_val.r.Pull_strength = 0x1;// 10K
    329       }
    330       else if(P_10K_L == Gpio_Conf_Data[index].pull)
    331       {
    332         conf0_val.r.Pull_assign = 0x2; 	// PullDown
    333         conf0_val.r.Pull_strength = 0x1;// 10K
    334       }
    335       else if(P_2K_H == Gpio_Conf_Data[index].pull)
    336       {
    337         conf0_val.r.Pull_assign = 0x1;  // PullUp
    338         conf0_val.r.Pull_strength = 0x0;// 2K
    339       }
    340       else if(P_2K_L == Gpio_Conf_Data[index].pull)
    341       {
    342         conf0_val.r.Pull_assign = 0x2;  // PullDown
    343         conf0_val.r.Pull_strength = 0x0;// 2K
    344       }
    345       else if(P_NONE == Gpio_Conf_Data[index].pull)
    346       {
    347         conf0_val.r.Pull_assign = 0;	// Non-pull
    348       }
    349       else
    350       {
    351         ASSERT(FALSE);  // Invalid value
    352       }
    353     }
    354 
    355 
    356     //
    357     // Set INT Trigger Type
    358     //
    359     conf0_val.dw &= ~0x0f000000;  // Clear bits 27:24
    360 
    361     //
    362     // Set INT Trigger Type
    363     //
    364     if(TRIG_ == Gpio_Conf_Data[index].int_type)
    365     {
    366       //
    367       // Interrupt not capable, clear bits 27:24
    368       //
    369     }
    370     else
    371     {
    372       conf0_val.dw |= (Gpio_Conf_Data[index].int_type & 0x0f)<<24;
    373     }
    374 
    375     DEBUG ((EFI_D_INFO, "Set CONF0 = 0x%08x\n", conf0_val.dw));
    376 
    377     //
    378     // Write back the targeted GPIO config value according to platform (board) GPIO setting.
    379     //
    380     MmioWrite32 (mmio_conf0, conf0_val.dw);
    381   }
    382 
    383   //
    384   // A0 BIOS Spec doesn't mention it although X0 does. comment out now.
    385   // GPIO SCORE write 0x01001002 to IOBASE + 0x0900
    386   //
    387 }
    388 
    389 /**
    390   Returns the Correct GPIO table for Mobile/Desktop respectively.
    391   Before call it, make sure PlatformInfoHob->BoardId&PlatformFlavor is get correctly.
    392 
    393   @param PeiServices               General purpose services available to every PEIM.
    394   @param PlatformInfoHob           PlatformInfoHob pointer with PlatformFlavor specified.
    395   @param BoardId                   BoardId ID as determined through the EC.
    396 
    397   @retval EFI_SUCCESS              The function completed successfully.
    398   @retval EFI_DEVICE_ERROR         KSC fails to respond.
    399 
    400 **/
    401 EFI_STATUS
    402 MultiPlatformGpioProgram (
    403   IN CONST EFI_PEI_SERVICES     **PeiServices,
    404   IN EFI_PLATFORM_INFO_HOB      *PlatformInfoHob
    405   )
    406 {
    407 #if !_SIMIC_
    408   CFIO_INIT_STRUCT*           PlatformCfioDataPtr;
    409 
    410   PlatformCfioDataPtr = (CFIO_INIT_STRUCT *) (UINTN) PlatformInfoHob->PlatformCfioData;
    411   DEBUG ((EFI_D_INFO, "MultiPlatformGpioProgram()...\n"));
    412 
    413   //
    414   //  SCORE GPIO WELL -- IO base registers
    415   //
    416 
    417   //
    418   // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
    419   //
    420   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL, PlatformCfioDataPtr->Use_Sel_SC0);
    421 
    422   //
    423   // Set GP_LVL Register
    424   //
    425   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL , PlatformCfioDataPtr->GP_Lvl_SC0);
    426 
    427   //
    428   // GP_IO_SEL Register -> 1 = Input 0 = Output.  If Native Mode don't care
    429   //
    430   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL, PlatformCfioDataPtr->Io_Sel_SC0);
    431 
    432   //
    433   // GPIO Triger Positive Edge Enable Register
    434   //
    435   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TPE, PlatformCfioDataPtr->TPE_SC0);
    436 
    437   //
    438   //  GPIO Trigger Negative Edge Enable Register
    439   //
    440   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TNE, PlatformCfioDataPtr->TNE_SC0);
    441 
    442   //
    443   //  GPIO Trigger Status
    444   //
    445   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_TS, PlatformCfioDataPtr->TS_SC0);
    446 
    447   //
    448   // GPIO_USE_SEL2 Register -> 1 = GPIO 0 = Native
    449   //
    450   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL2, PlatformCfioDataPtr->Use_Sel_SC1);
    451 
    452   //
    453   // Set GP_LVL2 Register
    454   //
    455   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL2, PlatformCfioDataPtr->GP_Lvl_SC1);
    456 
    457   //
    458   // GP_IO_SEL2 Register -> 1 = Input 0 = Output.  If Native Mode don't care
    459   //
    460   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL2, PlatformCfioDataPtr->Io_Sel_SC1);
    461 
    462   //
    463   // GPIO_USE_SEL3 Register -> 1 = GPIO 0 = Native
    464   //
    465   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_USE_SEL3, PlatformCfioDataPtr->Use_Sel_SC2);
    466 
    467   //
    468   // Set GP_LVL3 Register
    469   //
    470   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL3, PlatformCfioDataPtr->GP_Lvl_SC2);
    471 
    472   //
    473   // GP_IO_SEL3 Register -> 1 = Input 0 = Output if Native Mode don't care
    474   //
    475   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_IO_SEL3, PlatformCfioDataPtr->Io_Sel_SC2);
    476 
    477   //
    478   //  SUS GPIO WELL -- IO base registers
    479   //
    480 
    481   //
    482   // GPIO_USE_SEL Register -> 1 = GPIO 0 = Native
    483   //
    484   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_USE_SEL, PlatformCfioDataPtr->Use_Sel_SS);
    485 
    486   //
    487   // Set GP_LVL Register
    488   //
    489   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_LVL , PlatformCfioDataPtr->GP_Lvl_SS);
    490 
    491   //
    492   // GP_IO_SEL Register -> 1 = Input 0 = Output.  If Native Mode don't care.
    493   //
    494   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_IO_SEL, PlatformCfioDataPtr->Io_Sel_SS);
    495 
    496   //
    497   // GPIO Triger Positive Edge Enable Register.
    498   //
    499   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TPE, PlatformCfioDataPtr->TPE_SS);
    500 
    501   //
    502   //  GPIO Trigger Negative Edge Enable Register.
    503   //
    504   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TNE, PlatformCfioDataPtr->TNE_SS);
    505 
    506   //
    507   //  GPIO Trigger Status.
    508   //
    509   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_TS, PlatformCfioDataPtr->TS_SS);
    510 
    511   //
    512   //  GPIO Wake Enable.
    513   //
    514   IoWrite32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SUS_WAKE_EN, PlatformCfioDataPtr->WE_SS);
    515 
    516   //
    517   // Config SC/NC/SUS GPIO Pins
    518   //
    519   switch (PlatformInfoHob->BoardId) {
    520     case BOARD_ID_MINNOW2:
    521     case BOARD_ID_MINNOW2_TURBOT:
    522       DEBUG ((EFI_D_INFO, "Start to config Minnow2 GPIO pins\n"));
    523       InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mMinnow2_GpioInitData_SC)/sizeof(mMinnow2_GpioInitData_SC[0]),   (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SC);
    524       InternalGpioConfig(GPIO_NCORE_OFFSET, sizeof(mMinnow2_GpioInitData_NC)/sizeof(mMinnow2_GpioInitData_NC[0]),   (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_NC);
    525       InternalGpioConfig(GPIO_SSUS_OFFSET,  sizeof(mMinnow2_GpioInitData_SUS)/sizeof(mMinnow2_GpioInitData_SUS[0]), (GPIO_CONF_PAD_INIT *) (UINTN) PlatformInfoHob->PlatformGpioData_SUS);
    526       break;
    527     default:
    528 
    529       break;
    530   }
    531 
    532    //
    533    // configure the CFIO Pnp settings
    534    //
    535    if (PlatformInfoHob->CfioEnabled) {
    536      if (PlatformInfoHob->BoardId == BOARD_ID_MINNOW2 || PlatformInfoHob->BoardId == BOARD_ID_MINNOW2_TURBOT){
    537        InternalGpioConfig(GPIO_SCORE_OFFSET, sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI)/sizeof(mNB_BB_FAB3_GpioInitData_SC_TRI[0]), (GPIO_CONF_PAD_INIT *) (UINTN)PlatformInfoHob->PlatformGpioData_SC_TRI);
    538      }
    539    }
    540 #else
    541    DEBUG ((EFI_D_INFO, "Skip MultiPlatformGpioProgram()...for SIMICS or HYB model\n"));
    542 #endif
    543   return EFI_SUCCESS;
    544 }
    545 
    546