Exemplo n.º 1
0
/**
  OR a 32-bit MMIO register.

  OR the 32-bit MMIO register specified by Address with the value specified
  by Value and returns Value. This function must guarantee that all MMIO read
  and write operations are serialized.

  If 32-bit MMIO register operations are not supported, then ASSERT().
  If Address is not aligned on a 32-bit boundary, then ASSERT().

  @param  Address The MMIO register to write OR.
  @param  Value   The value to OR to the MMIO register.

  @return Value.

**/
UINT32
EFIAPI
I2CLibPeiMmioOr32 (
  IN      UINTN                     Address,
  IN      UINT32                    OrData
  )
{
  return I2CLibPeiMmioWrite32 (Address, I2CLibPeiMmioRead32(Address) | OrData);
}
Exemplo n.º 2
0
/**
  Initializes the host controller to execute I2C commands.

  @param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device.   
                                
  @return EFI_SUCCESS       Opcode initialization on the I2C host controller completed.
  @return EFI_DEVICE_ERROR  Device error, operation failed.
**/
EFI_STATUS
I2CInit (
  UINT8 I2cControllerIndex, 
  UINT16 SlaveAddress
  )
{
  EFI_STATUS   Status;
  UINT32       NumTries = 0;
  UINTN        I2CBaseAddress;
  UINT16       I2cMode;
  UINTN        PciMmBase=0;


  PciMmBase = MmPciAddress (
                0,
                DEFAULT_PCI_BUS_NUMBER_PCH,
                PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
                (I2cControllerIndex + 1),
                0
                );

  I2CBaseAddress = I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);

  //
  //  Verify the parameters
  //
  if (1023 < SlaveAddress ) {
    Status =  EFI_INVALID_PARAMETER;
    DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status));
    return Status;
  }

  if(I2CBaseAddress ==  (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE)) {
    return EFI_SUCCESS;
  }
  ProgramPciLpssI2C();

  I2CBaseAddress = (UINT32) (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * PCI_CONFIG_SPACE_SIZE);
  DEBUG ((EFI_D_ERROR, "I2CBaseAddress = 0x%x \n",I2CBaseAddress));
  NumTries = 10000; // 1 seconds
  while ((1 == ( I2CLibPeiMmioRead32 ( I2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
    MicroSecondDelay(10);
    NumTries --;
    if(0 == NumTries)
      return EFI_DEVICE_ERROR;
  }

  Status = I2cDisable (I2cControllerIndex);
  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));

  I2cBusFrequencySet(I2CBaseAddress, 400 * 1000, &I2cMode);//Set I2cMode

  I2CLibPeiMmioWrite16(I2CBaseAddress + R_IC_INTR_MASK, 0x0);
  if (0x7F < SlaveAddress) {
    SlaveAddress = (SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
  }
  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TAR, (UINT16) SlaveAddress );
  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_RX_TL, 0);
  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TX_TL, 0 );
  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_CON, I2cMode);

  Status = I2cEnable(I2cControllerIndex);
  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
  I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
  
  return EFI_SUCCESS;
}
Exemplo n.º 3
0
/**
  Programe all I2C controllers on LPSS. 
  
  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..

  @param   VOID

  @return  EFI_SUCCESS
**/
EFI_STATUS
ProgramPciLpssI2C (
  VOID
  )
{
  UINT32       PmcBase;
  UINT32       DevID;
  UINTN        PciMmBase=0;
  UINTN        Index;
  UINTN        Bar0;
  UINTN        Bar1;
  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() Start\n"));
  
  //
  // Set the VLV Function Disable Register to ZERO
  //
  PmcBase         = I2CLibPeiMmioRead32(PciD31F0RegBase + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
  
  if(I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)&
      (B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2
       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5
       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)) {
    I2CLibPeiMmioWrite32(
      PmcBase+R_PCH_PMC_FUNC_DIS,
      I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& \
      ~(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 \
        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 \
        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6|B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)
      );
    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n"));
  }

  for(Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) {

    PciMmBase = MmPciAddress (
                  0,
                  DEFAULT_PCI_BUS_NUMBER_PCH,
                  PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
                  Index,
                  0
                  );
    DevID =  I2CLibPeiMmioRead32(PciMmBase);

    Bar0 = PEI_TEPM_LPSS_DMA_BAR + (Index * PCI_CONFIG_SPACE_SIZE);
    Bar1 = Bar0 + 0x8000;

    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  Function=%x DevID=%08x\n", Index, DevID));
    
    //
    // Check if device present
    //
    if (DevID  != 0xFFFFFFFF)  {
      if(!(I2CLibPeiMmioRead32 (PciMmBase + R_PCH_LPSS_I2C_STSCMD) & B_PCH_LPSS_I2C_STSCMD_MSE)) {
        //
        // Program BAR 0
        //
        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32)(Bar0 & B_PCH_LPSS_I2C_BAR_BA));
        
        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR)));
        
        //
        // Program BAR 1
        //
        I2CLibPeiMmioWrite32 ((UINTN)(PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32)(Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32(PciMmBase+R_PCH_LPSS_I2C_BAR1)));
        
        //
        // Bus Master Enable & Memory Space Enable
        //
        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32)(B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
      }
      
      //
      // Release Resets
      //
      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPIO_I2C_MEM_RESETS, (B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
      
      //
      // Activate Clocks
      //
      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPSS_I2C_MEM_PCP, 0x80020003);//No use for A0

      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
    }

  }
  
  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n"));

  return EFI_SUCCESS;
}