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