Home | History | Annotate | Download | only in I2CLibDxe
      1 /** @file
      2   Functions for accessing I2C registers.
      3 
      4   Copyright (c) 2004  - 2015, Intel Corporation. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials are licensed and made available under
      7   the terms and conditions of the BSD License that accompanies this distribution.
      8   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 #include <Library/DebugLib.h>
     17 #include <Library/TimerLib.h>
     18 #include <PchRegs/PchRegsPcu.h>
     19 #include <PchRegs.h>
     20 #include <PlatformBaseAddresses.h>
     21 #include <PchRegs/PchRegsLpss.h>
     22 #include <Library/I2CLib.h>
     23 #include <Protocol/GlobalNvsArea.h>
     24 #include <Library/UefiBootServicesTableLib.h>
     25 #include <I2CRegs.h>
     26 
     27 #define GLOBAL_NVS_OFFSET(Field)    (UINTN)((CHAR8*)&((EFI_GLOBAL_NVS_AREA*)0)->Field - (CHAR8*)0)
     28 
     29 #define PCIEX_BASE_ADDRESS  0xE0000000
     30 #define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
     31 #define MmPciAddress( Segment, Bus, Device, Function, Register ) \
     32          ((UINTN)PCI_EXPRESS_BASE_ADDRESS + \
     33          (UINTN)(Bus << 20) + \
     34          (UINTN)(Device << 15) + \
     35          (UINTN)(Function << 12) + \
     36          (UINTN)(Register) \
     37         )
     38 #define PCI_D31F0_REG_BASE             PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
     39 
     40 typedef struct _LPSS_PCI_DEVICE_INFO {
     41   UINTN        Segment;
     42   UINTN        BusNum;
     43   UINTN        DeviceNum;
     44   UINTN        FunctionNum;
     45   UINTN        Bar0;
     46   UINTN        Bar1;
     47 } LPSS_PCI_DEVICE_INFO;
     48 
     49 LPSS_PCI_DEVICE_INFO  mLpssPciDeviceList[] = {
     50   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1, PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC, 0xFE900000, 0xFE908000},
     51   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0, 0xFE910000, 0xFE918000},
     52   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1, 0xFE920000, 0xFE928000},
     53   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2, 0xFE930000, 0xFE938000},
     54   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3, 0xFE940000, 0xFE948000},
     55   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4, 0xFE950000, 0xFE958000},
     56   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5, 0xFE960000, 0xFE968000},
     57   {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6, 0xFE970000, 0xFE978000}
     58 };
     59 
     60 #define LPSS_PCI_DEVICE_NUMBER  sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI_DEVICE_INFO)
     61 
     62 STATIC UINTN mI2CBaseAddress = 0;
     63 STATIC UINT16 mI2CSlaveAddress = 0;
     64 
     65 UINT16 mI2cMode=B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE ;
     66 
     67 UINTN mI2cNvsBaseAddress[] = {
     68         GLOBAL_NVS_OFFSET(LDMA2Addr),
     69         GLOBAL_NVS_OFFSET(I2C1Addr),
     70         GLOBAL_NVS_OFFSET(I2C2Addr),
     71         GLOBAL_NVS_OFFSET(I2C3Addr),
     72         GLOBAL_NVS_OFFSET(I2C4Addr),
     73         GLOBAL_NVS_OFFSET(I2C5Addr),
     74         GLOBAL_NVS_OFFSET(I2C6Addr),
     75         GLOBAL_NVS_OFFSET(I2C7Addr)
     76       };
     77 
     78 /**
     79   This function get I2Cx controller base address (BAR0).
     80 
     81   @param I2cControllerIndex  Bus Number of I2C controller.
     82 
     83   @return I2C BAR.
     84 **/
     85 UINTN
     86 GetI2cBarAddr(
     87   IN    UINT8 I2cControllerIndex
     88   )
     89 {
     90   EFI_STATUS           Status;
     91   EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
     92   UINTN  AcpiBaseAddr;
     93   UINTN  PciMmBase=0;
     94 
     95   ASSERT(gBS!=NULL);
     96 
     97   Status = gBS->LocateProtocol (
     98                   &gEfiGlobalNvsAreaProtocolGuid,
     99                   NULL,
    100                   &GlobalNvsArea
    101                   );
    102 
    103   //
    104   // PCI mode from PEI ( Global NVS is not ready).
    105   //
    106   if (EFI_ERROR(Status)) {
    107     DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
    108     //
    109     // Global NVS is not ready.
    110     //
    111     return 0;
    112   }
    113 
    114   AcpiBaseAddr =  *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]);
    115 
    116   //
    117   //PCI mode from DXE (global NVS protocal) to LPSS OnReadytoBoot(swith to ACPI).
    118   //
    119   if(AcpiBaseAddr==0) {
    120     PciMmBase = MmPciAddress (
    121                   mLpssPciDeviceList[I2cControllerIndex + 1].Segment,
    122                   mLpssPciDeviceList[I2cControllerIndex + 1].BusNum,
    123                   mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum,
    124                   mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum,
    125                   0
    126                   );
    127     DEBUG((EFI_D_ERROR, "\nGetI2cBarAddr() I2C Device %x %x %x PciMmBase:%x\n", \
    128            mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, \
    129            mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, \
    130            mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum, PciMmBase));
    131 
    132     if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)    {
    133       if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) {
    134         //
    135         // Get the address allocted.
    136         //
    137         mLpssPciDeviceList[I2cControllerIndex + 1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
    138         mLpssPciDeviceList[I2cControllerIndex + 1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1);
    139       }
    140     }
    141     AcpiBaseAddr =mLpssPciDeviceList[I2cControllerIndex+1].Bar0;
    142   }
    143 
    144   //
    145   // ACPI mode from BDS: LPSS OnReadytoBoot
    146   //
    147   else {
    148     DEBUG ((EFI_D_INFO, "GetI2cBarAddr() NVS Varialable is updated by this LIB or LPSS  \n"));
    149   }
    150 
    151   DEBUG ((EFI_D_INFO, "GetI2cBarAddr() I2cControllerIndex+1 0x%x AcpiBaseAddr:0x%x \n", (I2cControllerIndex + 1), AcpiBaseAddr));
    152   return AcpiBaseAddr;
    153 }
    154 
    155 
    156 /**
    157   This function enables I2C controllers.
    158 
    159   @param I2cControllerIndex  Bus Number of I2C controllers.
    160 
    161   @return Result of the I2C initialization.
    162 **/
    163 EFI_STATUS
    164 ProgramPciLpssI2C (
    165   IN  UINT8 I2cControllerIndex
    166   )
    167 {
    168   UINT32                        PmcBase;
    169   UINTN                         PciMmBase=0;
    170   EFI_STATUS                    Status;
    171   EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
    172 
    173   UINT32 PmcFunctionDsiable[]= {
    174     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1,
    175     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2,
    176     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3,
    177     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4,
    178     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5,
    179     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6,
    180     B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7
    181   };
    182 
    183   DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n"));
    184 
    185   //
    186   // Set the VLV Function Disable Register to ZERO
    187   //
    188   PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR;
    189   if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2cControllerIndex]) {
    190     DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is disabled\n",I2cControllerIndex));
    191     return EFI_NOT_READY;
    192   }
    193 
    194   DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C()------------I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)));
    195 
    196   {
    197     PciMmBase = MmPciAddress (
    198                   mLpssPciDeviceList[I2cControllerIndex+1].Segment,
    199                   mLpssPciDeviceList[I2cControllerIndex+1].BusNum,
    200                   mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum,
    201                   mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum,
    202                   0
    203                   );
    204 
    205     DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  %x %x %x PciMmBase:%x\n", \
    206            mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \
    207            mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \
    208            mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase));
    209 
    210     if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)     {
    211       if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& B_PCH_LPSS_I2C_STSCMD_MSE)) {
    212         //
    213         // Get the address allocted.
    214         //
    215         mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
    216         mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR1);
    217         DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0, mLpssPciDeviceList[I2cControllerIndex+1].Bar1));
    218       } else {
    219 
    220         //
    221         // Program BAR 0
    222         //
    223         ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar0) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0));
    224         MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA));
    225 
    226         //
    227         // Program BAR 1
    228         //
    229         ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar1) && (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0));
    230         MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32) (mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
    231 
    232         //
    233         // Bus Master Enable & Memory Space Enable
    234         //
    235         MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32) (B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
    236         ASSERT (MmioRead32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 0xFFFFFFFF);
    237       }
    238 
    239       //
    240       // Release Resets
    241       //
    242       MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
    243 
    244       //
    245       // Activate Clocks
    246       //
    247       MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0
    248 
    249       DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
    250     }
    251 
    252     //
    253     // BDS: already switched to ACPI mode
    254     //
    255     else {
    256       ASSERT(gBS!=NULL);
    257       Status = gBS->LocateProtocol (
    258                       &gEfiGlobalNvsAreaProtocolGuid,
    259                       NULL,
    260                       &GlobalNvsArea
    261                       );
    262       if (EFI_ERROR(Status)) {
    263         DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
    264         //
    265         // gEfiGlobalNvsAreaProtocolGuid is not ready.
    266         //
    267         return 0;
    268       }
    269       mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 = *(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 1]);
    270       DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x \n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0));
    271     }
    272   }
    273 
    274   DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n"));
    275 
    276   return EFI_SUCCESS;
    277 }
    278 
    279 /**
    280   Disable I2C Bus.
    281 
    282   @param VOID.
    283 
    284   @return Result of the I2C disabling.
    285 **/
    286 RETURN_STATUS
    287 I2cDisable (
    288   VOID
    289   )
    290 {
    291   //
    292   // 0.1 seconds
    293   //
    294   UINT32 NumTries = 10000;
    295 
    296   MmioWrite32 ( mI2CBaseAddress + R_IC_ENABLE, 0 );
    297   while ( 0 != ( MmioRead32 ( mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
    298     MicroSecondDelay (10);
    299     NumTries --;
    300     if(0 == NumTries) {
    301       return RETURN_NOT_READY;
    302     }
    303   }
    304 
    305   return RETURN_SUCCESS;
    306 }
    307 
    308 /**
    309   Enable I2C Bus.
    310 
    311   @param VOID.
    312 
    313   @return Result of the I2C disabling.
    314 **/
    315 RETURN_STATUS
    316 I2cEnable (
    317   VOID
    318   )
    319 {
    320   //
    321   // 0.1 seconds
    322   //
    323   UINT32 NumTries = 10000;
    324 
    325   MmioWrite32 (mI2CBaseAddress + R_IC_ENABLE, 1);
    326 
    327   while (0 == (MmioRead32 (mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
    328     MicroSecondDelay (10);
    329     NumTries --;
    330     if(0 == NumTries){
    331        return RETURN_NOT_READY;
    332     }
    333   }
    334 
    335   return RETURN_SUCCESS;
    336 }
    337 
    338 /**
    339   Enable I2C Bus.
    340 
    341   @param VOID.
    342 
    343   @return Result of the I2C enabling.
    344 **/
    345 RETURN_STATUS
    346 I2cBusFrequencySet (
    347   IN UINTN BusClockHertz
    348   )
    349 {
    350   DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
    351 
    352   //
    353   //  Set the 100 KHz clock divider according to SV result and I2C spec
    354   //
    355   MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
    356   MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
    357 
    358   //
    359   //  Set the 400 KHz clock divider according to SV result and I2C spec
    360   //
    361   MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
    362   MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
    363 
    364   switch ( BusClockHertz ) {
    365     case 100 * 1000:
    366       MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
    367       mI2cMode = V_SPEED_STANDARD;
    368       break;
    369     case 400 * 1000:
    370       MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
    371       mI2cMode = V_SPEED_FAST;
    372       break;
    373     default:
    374       MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
    375       mI2cMode = V_SPEED_HIGH;
    376   }
    377 
    378   //
    379   //  Select the frequency counter,
    380   //  Enable restart condition,
    381   //  Enable master FSM, disable slave FSM.
    382   //
    383   mI2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
    384 
    385   return EFI_SUCCESS;
    386 }
    387 
    388 /**
    389   Initializes the host controller to execute I2C commands.
    390 
    391   @param I2cControllerIndex Index of I2C controller in LPSS device. 0 represents I2C0, which is PCI function 1 of LPSS device.
    392 
    393   @return EFI_SUCCESS       Opcode initialization on the I2C host controller completed.
    394   @return EFI_DEVICE_ERROR  Device error, operation failed.
    395 **/
    396 EFI_STATUS
    397 I2CInit (
    398   IN  UINT8  I2cControllerIndex,
    399   IN  UINT16 SlaveAddress
    400   )
    401 {
    402   EFI_STATUS Status=RETURN_SUCCESS;
    403   UINT32    NumTries = 0;
    404   UINTN    GnvsI2cBarAddr=0;
    405 
    406   //
    407   // Verify the parameters
    408   //
    409   if ((1023 < SlaveAddress) || (6 < I2cControllerIndex)) {
    410     Status =  RETURN_INVALID_PARAMETER;
    411     DEBUG((EFI_D_INFO,"I2CInit Exit with RETURN_INVALID_PARAMETER\r\n"));
    412     return Status;
    413   }
    414   MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
    415   mI2CSlaveAddress = SlaveAddress;
    416 
    417   //
    418   // 1.PEI: program and init ( before pci enumeration).
    419   // 2.DXE:update address and re-init ( after pci enumeration).
    420   // 3.BDS:update ACPI address and re-init ( after acpi mode is enabled).
    421   //
    422   if(mI2CBaseAddress == mLpssPciDeviceList[I2cControllerIndex + 1].Bar0) {
    423 
    424     //
    425     // I2CInit is already  called.
    426     //
    427     GnvsI2cBarAddr=GetI2cBarAddr(I2cControllerIndex);
    428 
    429     if((GnvsI2cBarAddr == 0)||(GnvsI2cBarAddr == mI2CBaseAddress)) {
    430       DEBUG((EFI_D_INFO,"I2CInit Exit with mI2CBaseAddress:%x == [%x].Bar0\r\n",mI2CBaseAddress,I2cControllerIndex+1));
    431       return RETURN_SUCCESS;
    432     }
    433   }
    434 
    435   Status=ProgramPciLpssI2C(I2cControllerIndex);
    436   if(Status!=EFI_SUCCESS) {
    437     return Status;
    438   }
    439 
    440 
    441   mI2CBaseAddress = (UINT32) mLpssPciDeviceList[I2cControllerIndex + 1].Bar0;
    442   DEBUG ((EFI_D_ERROR, "mI2CBaseAddress = 0x%x \n",mI2CBaseAddress));
    443 
    444   //
    445   // 1 seconds.
    446   //
    447   NumTries = 10000;
    448   while ((1 == ( MmioRead32 ( mI2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
    449     MicroSecondDelay(10);
    450     NumTries --;
    451     if(0 == NumTries) {
    452       DEBUG((EFI_D_INFO, "Try timeout\r\n"));
    453       return RETURN_DEVICE_ERROR;
    454     }
    455   }
    456 
    457   Status = I2cDisable();
    458   DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
    459   I2cBusFrequencySet(400 * 1000);
    460 
    461   MmioWrite32(mI2CBaseAddress + R_IC_INTR_MASK, 0x0);
    462   if (0x7f < SlaveAddress )
    463     SlaveAddress = ( SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
    464   MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
    465   MmioWrite32 ( mI2CBaseAddress + R_IC_RX_TL, 0);
    466   MmioWrite32 ( mI2CBaseAddress + R_IC_TX_TL, 0 );
    467   MmioWrite32 ( mI2CBaseAddress + R_IC_CON, mI2cMode);
    468   Status = I2cEnable();
    469 
    470   DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
    471   MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
    472 
    473   return EFI_SUCCESS;
    474 }
    475 
    476 /**
    477   Reads a Byte from I2C Device.
    478 
    479   @param  I2cControllerIndex             I2C Bus no to which the I2C device has been connected
    480   @param  SlaveAddress      Device Address from which the byte value has to be read
    481   @param  Offset            Offset from which the data has to be read
    482   @param  *Byte             Address to which the value read has to be stored
    483   @param  Start               Whether a RESTART is issued before the byte is sent or received
    484   @param  End                 Whether STOP is generated after a data byte is sent or received
    485 
    486   @return  EFI_SUCCESS       IF the byte value has been successfully read
    487   @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
    488 **/
    489 EFI_STATUS
    490 ByteReadI2CBasic(
    491   IN  UINT8 I2cControllerIndex,
    492   IN  UINT8 SlaveAddress,
    493   IN  UINTN ReadBytes,
    494   OUT UINT8 *ReadBuffer,
    495   IN  UINT8 Start,
    496   IN  UINT8 End
    497   )
    498 {
    499 
    500   EFI_STATUS Status;
    501   UINT32 I2cStatus;
    502   UINT16 ReceiveData;
    503   UINT8 *ReceiveDataEnd;
    504   UINT8 *ReceiveRequest;
    505   UINT16 RawIntrStat;
    506   UINT32 Count=0;
    507 
    508   Status = EFI_SUCCESS;
    509 
    510   ReceiveDataEnd = &ReadBuffer [ReadBytes];
    511   if( ReadBytes ) {
    512 
    513     ReceiveRequest = ReadBuffer;
    514     DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd - ReceiveRequest));
    515 
    516     while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) {
    517 
    518       //
    519       //  Check for NACK
    520       //
    521       RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
    522       if ( 0 != ( RawIntrStat & I2C_INTR_TX_ABRT )) {
    523         MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
    524         Status = RETURN_DEVICE_ERROR;
    525         DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been transferred\r\n",ReceiveDataEnd - ReceiveRequest));
    526         break;
    527       }
    528 
    529       //
    530       // Determine if another byte was received
    531       //
    532       I2cStatus = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
    533       if (0 != ( I2cStatus & STAT_RFNE )) {
    534         ReceiveData = (UINT16)MmioRead32 ( mI2CBaseAddress + R_IC_DATA_CMD );
    535         *ReadBuffer++ = (UINT8)ReceiveData;
    536         DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is received\r\n",ReceiveData));
    537       }
    538 
    539       if(ReceiveDataEnd == ReceiveRequest) {
    540         MicroSecondDelay ( FIFO_WRITE_DELAY );
    541         DEBUG((EFI_D_INFO,"ReceiveDataEnd==ReceiveRequest------------%x\r\n",I2cStatus & STAT_RFNE));
    542         Count++;
    543         if(Count<1024) {
    544           //
    545           // To avoid sys hung  without ul-pmc device  on RVP,
    546           // waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
    547           //
    548           continue;
    549         } else {
    550           break;
    551         }
    552       }
    553 
    554       //
    555       //  Wait until a read request will fit.
    556       //
    557       if (0 == (I2cStatus & STAT_TFNF)) {
    558         DEBUG((EFI_D_INFO,"Wait until a read request will fit\r\n"));
    559         MicroSecondDelay (10);
    560         continue;
    561       }
    562 
    563       //
    564       //  Issue the next read request.
    565       //
    566       if(End && Start) {
    567         MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
    568       } else if (!End && Start) {
    569         MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART);
    570       } else if (End && !Start) {
    571         MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
    572       } else if (!End && !Start) {
    573         MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
    574       }
    575       MicroSecondDelay (FIFO_WRITE_DELAY);
    576 
    577       ReceiveRequest += 1;
    578     }
    579   }
    580 
    581   return Status;
    582 }
    583 
    584 /**
    585   Writes a Byte to I2C Device.
    586 
    587   @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
    588   @param  SlaveAddress         Device Address from which the byte value has to be written
    589   @param  Offset               Offset from which the data has to be read
    590   @param  *Byte                Address to which the value written is stored
    591   @param  Start               Whether a RESTART is issued before the byte is sent or received
    592   @param  End                 Whether STOP is generated after a data byte is sent or received
    593 
    594   @return  EFI_SUCCESS         IF the byte value has been successfully written
    595   @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
    596 **/
    597 EFI_STATUS ByteWriteI2CBasic(
    598   IN  UINT8 I2cControllerIndex,
    599   IN  UINT8 SlaveAddress,
    600   IN  UINTN WriteBytes,
    601   IN  UINT8 *WriteBuffer,
    602   IN  UINT8 Start,
    603   IN  UINT8 End
    604   )
    605 {
    606 
    607   EFI_STATUS Status;
    608   UINT32 I2cStatus;
    609   UINT8 *TransmitEnd;
    610   UINT16 RawIntrStat;
    611   UINT32 Count=0;
    612 
    613   Status = EFI_SUCCESS;
    614 
    615   Status=I2CInit(I2cControllerIndex, SlaveAddress);
    616   if(Status!=EFI_SUCCESS)
    617     return Status;
    618 
    619   TransmitEnd = &WriteBuffer[WriteBytes];
    620   if( WriteBytes ) {
    621     DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n",TransmitEnd - WriteBuffer));
    622     while (TransmitEnd > WriteBuffer) {
    623       I2cStatus = MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
    624       RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
    625       if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
    626         MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT);
    627         Status = RETURN_DEVICE_ERROR;
    628         DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
    629         break;
    630       }
    631       if (0 == (I2cStatus & STAT_TFNF)) {
    632         //
    633         // If TX not full , will  send cmd  or continue to wait
    634         //
    635         MicroSecondDelay (FIFO_WRITE_DELAY);
    636         continue;
    637       }
    638 
    639       if(End && Start) {
    640         MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_RESTART|B_CMD_STOP);
    641       } else if (!End && Start) {
    642         MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_RESTART);
    643       } else if (End && !Start) {
    644         MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++)|B_CMD_STOP);
    645       } else if (!End && !Start ) {
    646         MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++));
    647       }
    648 
    649       //
    650       // Add a small delay to work around some odd behavior being seen.  Without this delay bytes get dropped.
    651       //
    652       MicroSecondDelay ( FIFO_WRITE_DELAY );//wait after send cmd
    653 
    654       //
    655       // Time out
    656       //
    657       while(1) {
    658         RawIntrStat = MmioRead16 ( mI2CBaseAddress + R_IC_RawIntrStat );
    659         if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
    660           MmioRead16 (mI2CBaseAddress + R_IC_CLR_TX_ABRT);
    661           Status = RETURN_DEVICE_ERROR;
    662           DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
    663         }
    664         if(0 == MmioRead16(mI2CBaseAddress + R_IC_TXFLR)) break;
    665 
    666         MicroSecondDelay (FIFO_WRITE_DELAY);
    667         Count++;
    668         if(Count<1024) {
    669           //
    670           // to avoid sys hung without ul-pmc device on RVP.
    671           // Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
    672           //
    673           continue;
    674         } else {
    675           break;
    676         }
    677       }//while( 1 )
    678     }
    679 
    680   }
    681 
    682   return Status;
    683 }
    684 
    685 /**
    686   Reads a Byte from I2C Device.
    687 
    688   @param  I2cControllerIndex   I2C Bus no to which the I2C device has been connected
    689   @param  SlaveAddress         Device Address from which the byte value has to be read
    690   @param  Offset               Offset from which the data has to be read
    691   @param  ReadBytes            Number of bytes to be read
    692   @param  *ReadBuffer          Address to which the value read has to be stored
    693 
    694   @return  EFI_SUCCESS       IF the byte value has been successfully read
    695   @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
    696 **/
    697 EFI_STATUS ByteReadI2C(
    698   IN  UINT8 I2cControllerIndex,
    699   IN  UINT8 SlaveAddress,
    700   IN  UINT8 Offset,
    701   IN  UINTN ReadBytes,
    702   OUT UINT8 *ReadBuffer
    703   )
    704 {
    705   EFI_STATUS          Status;
    706 
    707   DEBUG ((EFI_D_INFO, "ByteReadI2C:---offset:0x%x\n",Offset));
    708   Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,1,&Offset,TRUE,FALSE);
    709   Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress,ReadBytes,ReadBuffer,TRUE,TRUE);
    710 
    711   return Status;
    712 }
    713 
    714 /**
    715   Writes a Byte to I2C Device.
    716 
    717   @param  I2cControllerIndex  I2C Bus no to which the I2C device has been connected
    718   @param  SlaveAddress        Device Address from which the byte value has to be written
    719   @param  Offset              Offset from which the data has to be written
    720   @param  WriteBytes          Number of bytes to be written
    721   @param  *Byte               Address to which the value written is stored
    722 
    723   @return  EFI_SUCCESS       IF the byte value has been successfully read
    724   @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
    725 **/
    726 EFI_STATUS ByteWriteI2C(
    727   IN  UINT8 I2cControllerIndex,
    728   IN  UINT8 SlaveAddress,
    729   IN  UINT8 Offset,
    730   IN  UINTN WriteBytes,
    731   IN  UINT8 *WriteBuffer
    732   )
    733 {
    734   EFI_STATUS          Status;
    735 
    736   DEBUG ((EFI_D_INFO, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
    737   Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,1,&Offset,TRUE,FALSE);
    738   Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress,WriteBytes,WriteBuffer,FALSE,TRUE);
    739 
    740   return Status;
    741 }
    742