1 /** @file 2 PCH Smbus Executive Code (common PEI/DXE/SMM code) 3 4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> 5 SPDX-License-Identifier: BSD-2-Clause-Patent 6 7 **/ 8 #include <Uefi/UefiBaseType.h> 9 #include <Library/IoLib.h> 10 #include <Library/DebugLib.h> 11 #include <Library/TimerLib.h> 12 #include <IndustryStandard/SmBus.h> 13 #include <IndustryStandard/Pci30.h> 14 #include <PchAccess.h> 15 #include <Library/MmPciLib.h> 16 #include <Library/PchSmbusCommonLib.h> 17 18 /** 19 Get SMBUS IO Base address 20 21 22 @retval UINT32 The SMBUS IO Base Address 23 **/ 24 UINT32 25 SmbusGetIoBase ( 26 VOID 27 ) 28 { SHNDecoder_new(PyTypeObject * type,PyObject * args,PyObject * kwds)29 UINT32 SmbusIoBase; 30 31 SmbusIoBase = MmioRead32 ( 32 MmPciBase ( 33 DEFAULT_PCI_BUS_NUMBER_PCH, 34 PCI_DEVICE_NUMBER_PCH_SMBUS, 35 PCI_FUNCTION_NUMBER_PCH_SMBUS) 36 + R_PCH_SMBUS_BASE) & B_PCH_SMBUS_BASE_BAR; 37 38 ASSERT (SmbusIoBase != B_PCH_SMBUS_BASE_BAR && SmbusIoBase != 0); 39 SHNDecoder_init(decoders_SHNDecoder * self,PyObject * args,PyObject * kwds)40 return SmbusIoBase; 41 } 42 43 /** 44 This function provides a standard way to read PCH Smbus IO registers. 45 46 @param[in] Offset Register offset from Smbus base IO address. 47 48 @retval UINT8 Returns data read from IO. 49 **/ 50 UINT8 51 EFIAPI 52 SmbusIoRead ( 53 IN UINT8 Offset 54 ) 55 { 56 return IoRead8 (SmbusGetIoBase () + Offset); 57 } 58 59 /** 60 This function provides a standard way to write PCH Smbus IO registers. 61 62 @param[in] Offset Register offset from Smbus base IO address. 63 @param[in] Data Data to write to register. 64 65 **/ 66 VOID 67 EFIAPI 68 SmbusIoWrite ( 69 IN UINT8 Offset, 70 IN UINT8 Data 71 ) 72 { 73 /// 74 /// Write New Value 75 /// 76 IoWrite8 (SmbusGetIoBase () + Offset, Data); 77 return; 78 } 79 80 /** 81 This function provides a standard way to check if an SMBus transaction has 82 completed. 83 84 @param[in] StsReg Not used for input. On return, contains the 85 value of the SMBus status register. 86 87 @retval TRUE Transaction is complete 88 @retval FALSE Otherwise. 89 **/ 90 BOOLEAN 91 EFIAPI 92 IoDone ( 93 IN UINT8 *StsReg 94 ) 95 { 96 /// 97 /// Wait for IO to complete 98 /// 99 UINTN StallIndex; 100 UINTN StallTries; SHNDecoder_dealloc(decoders_SHNDecoder * self)101 102 StallTries = STALL_TIME / STALL_PERIOD; 103 104 for (StallIndex = 0; StallIndex < StallTries; StallIndex++) { 105 *StsReg = SmbusIoRead (R_PCH_SMBUS_HSTS); 106 if (*StsReg & (B_PCH_SMBUS_INTR | B_PCH_SMBUS_BYTE_DONE_STS | B_PCH_SMBUS_DERR | B_PCH_SMBUS_BERR)) { 107 return TRUE; 108 } else { 109 MicroSecondDelay (STALL_PERIOD); 110 } 111 } 112 113 return FALSE; 114 } 115 116 /** 117 Check if it's ok to use the bus. 118 119 SHNDecoder_close(decoders_SHNDecoder * self,PyObject * args)120 @retval EFI_SUCCESS SmBus is acquired and it's safe to send commands. 121 @retval EFI_TIMEOUT SmBus is busy, it's not safe to send commands. 122 **/ 123 EFI_STATUS 124 AcquireBus ( 125 VOID 126 ) 127 { 128 UINT8 StsReg; 129 130 StsReg = 0; 131 StsReg = SmbusIoRead (R_PCH_SMBUS_HSTS); 132 if (StsReg & B_PCH_SMBUS_IUS) { 133 return EFI_TIMEOUT; 134 } else if (StsReg & B_PCH_SMBUS_HBSY) { 135 /// 136 /// Clear Status Register and exit 137 /// 138 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); 139 return EFI_TIMEOUT; 140 } else { 141 /// 142 /// Clear out any odd status information (Will Not Clear In Use) 143 /// 144 SmbusIoWrite (R_PCH_SMBUS_HSTS, StsReg); 145 return EFI_SUCCESS; 146 } 147 } 148 149 /** 150 This function provides a standard way to execute Smbus protocols SHNDecoder_sample_rate(decoders_SHNDecoder * self,void * closure)151 as defined in the SMBus Specification. The data can either be of 152 the Length byte, word, or a block of data. The resulting transaction will be 153 either the SMBus Slave Device accepts this transaction or this function 154 returns with an error 155 156 @param[in] SlaveAddress Smbus Slave device the command is directed at 157 @param[in] Command Slave Device dependent 158 @param[in] Operation Which SMBus protocol will be used 159 @param[in] PecCheck Defines if Packet Error Code Checking is to be used 160 @param[in, out] Length How many bytes to read. Must be 0 <= Length <= 32 depending on Operation 161 It will contain the actual number of bytes read/written. 162 @param[in, out] Buffer Contain the data read/written. 163 164 @retval EFI_SUCCESS The operation completed successfully. 165 @exception EFI_UNSUPPORTED The operation is unsupported. 166 167 @retval EFI_INVALID_PARAMETER Length or Buffer is NULL for any operation besides 168 quick read or quick write. 169 @retval EFI_TIMEOUT The transaction did not complete within an internally 170 specified timeout period, or the controller is not 171 available for use. 172 @retval EFI_DEVICE_ERROR There was an Smbus error (NACK) during the operation. 173 This could indicate the slave device is not present 174 or is in a hung condition. 175 **/ 176 EFI_STATUS 177 SmbusExec ( 178 IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress, 179 IN EFI_SMBUS_DEVICE_COMMAND Command, 180 IN EFI_SMBUS_OPERATION Operation, 181 IN BOOLEAN PecCheck, 182 IN OUT UINTN *Length, 183 IN OUT VOID *Buffer 184 ) 185 { 186 EFI_STATUS Status; 187 UINT8 AuxcReg; 188 UINT8 AuxStsReg; 189 UINT8 SmbusOperation; 190 UINT8 StsReg; 191 UINT8 SlvAddrReg; 192 UINT8 HostCmdReg; 193 UINT8 BlockCount; 194 BOOLEAN BufferTooSmall; 195 UINTN Index; 196 UINTN BusIndex; 197 UINT8 *CallBuffer; 198 UINT8 SmbusHctl; 199 UINT32 Timeout; 200 201 CallBuffer = Buffer; 202 BlockCount = 0; 203 204 /// 205 /// For any operations besides quick read & write, the pointers to 206 /// Length and Buffer must not be NULL. 207 /// 208 if ((Operation != EfiSmbusQuickRead) && (Operation != EfiSmbusQuickWrite)) { 209 if ((Length == NULL) || (Buffer == NULL)) { 210 return EFI_INVALID_PARAMETER; 211 } 212 } 213 /// 214 /// See if its ok to use the bus based upon INUSE_STS bit. 215 /// 216 Status = AcquireBus (); 217 if (EFI_ERROR (Status)) { 218 return Status; 219 } 220 /// 221 /// This is the main operation loop. If the operation results in a Smbus 222 /// collision with another master on the bus, it attempts the requested 223 /// transaction again at least BUS_TRIES attempts. 224 /// 225 for (BusIndex = 0; BusIndex < BUS_TRIES; BusIndex++) { 226 /// 227 /// Operation Specifics (pre-execution) 228 /// 229 Status = EFI_SUCCESS; 230 SmbusOperation = V_PCH_SMBUS_SMB_CMD_QUICK; 231 SlvAddrReg = (UINT8) ((SlaveAddress.SmbusDeviceAddress << 1) | 1); 232 HostCmdReg = (UINT8) Command; 233 AuxcReg = 0; 234 235 switch (Operation) { 236 237 case EfiSmbusQuickWrite: 238 SlvAddrReg--; 239 240 /// 241 /// The "break;" command is not present here to allow code execution 242 /// do drop into the next case, which contains common code to this case. 243 /// 244 case EfiSmbusQuickRead: 245 if (PecCheck == TRUE) { 246 Status = EFI_UNSUPPORTED; 247 } 248 break; 249 250 case EfiSmbusSendByte: 251 HostCmdReg = CallBuffer[0]; 252 SlvAddrReg--; 253 254 /// 255 /// The "break;" command is not present here to allow code execution 256 /// do drop into the next case, which contains common code to this case. 257 /// 258 case EfiSmbusReceiveByte: 259 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE; 260 if (*Length < 1) { 261 Status = EFI_BUFFER_TOO_SMALL; 262 } 263 264 *Length = 1; 265 break; 266 267 case EfiSmbusWriteByte: 268 SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]); 269 SlvAddrReg--; 270 *Length = 1; 271 272 /// 273 /// The "break;" command is not present here to allow code execution 274 /// do drop into the next case, which contains common code to this case. 275 /// 276 case EfiSmbusReadByte: 277 if (*Length < 1) { 278 Status = EFI_BUFFER_TOO_SMALL; 279 } else if (*Length == 1) { 280 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA; 281 } else if (*Length <= 256) { 282 if (PecCheck == TRUE) { 283 /// 284 /// The I2C Read command with either PEC_EN or AAC bit set 285 /// produces undefined results. 286 /// 287 Status = EFI_UNSUPPORTED; 288 } 289 290 SmbusOperation = V_PCH_SMBUS_SMB_CMD_IIC_READ; 291 } else { 292 Status = EFI_INVALID_PARAMETER; 293 } 294 295 break; 296 297 case EfiSmbusReadWord: 298 SmbusOperation = V_PCH_SMBUS_SMB_CMD_WORD_DATA; 299 if (*Length < 2) { 300 Status = EFI_BUFFER_TOO_SMALL; 301 } 302 303 *Length = 2; 304 break; 305 306 case EfiSmbusWriteWord: 307 SmbusOperation = V_PCH_SMBUS_SMB_CMD_WORD_DATA; 308 SlvAddrReg--; 309 SmbusIoWrite (R_PCH_SMBUS_HD1, CallBuffer[1]); 310 SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]); 311 if (*Length < 2) { 312 Status = EFI_BUFFER_TOO_SMALL; 313 } 314 315 *Length = 2; 316 break; 317 318 case EfiSmbusWriteBlock: 319 SmbusIoWrite (R_PCH_SMBUS_HD0, *(UINT8 *) Length); 320 SlvAddrReg--; 321 BlockCount = (UINT8) (*Length); 322 323 /// 324 /// The "break;" command is not present here to allow code execution 325 /// do drop into the next case, which contains common code to this case. 326 /// 327 case EfiSmbusReadBlock: 328 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK; 329 if ((*Length < 1) || (*Length > 32)) { 330 Status = EFI_INVALID_PARAMETER; 331 break; 332 } 333 334 AuxcReg |= B_PCH_SMBUS_E32B; 335 break; 336 337 case EfiSmbusProcessCall: 338 SmbusOperation = V_PCH_SMBUS_SMB_CMD_PROCESS_CALL; 339 SmbusIoWrite (R_PCH_SMBUS_HD1, CallBuffer[1]); 340 SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]); 341 if (*Length < 2) { 342 Status = EFI_BUFFER_TOO_SMALL; 343 } 344 345 *Length = 2; 346 break; 347 348 case EfiSmbusBWBRProcessCall: 349 /// 350 /// The write byte count cannot be zero or more than 351 /// 32 bytes. 352 /// 353 if ((*Length < 1) || (*Length > 32)) { 354 Status = EFI_INVALID_PARAMETER; 355 break; 356 } 357 358 SmbusIoWrite (R_PCH_SMBUS_HD0, *(UINT8 *) Length); 359 BlockCount = (UINT8) (*Length); 360 SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS; 361 362 AuxcReg |= B_PCH_SMBUS_E32B; 363 break; 364 365 default: 366 Status = EFI_INVALID_PARAMETER; 367 break; 368 } 369 370 if (EFI_ERROR (Status)) { 371 break; 372 } 373 374 if (PecCheck == TRUE) { 375 AuxcReg |= B_PCH_SMBUS_AAC; 376 } 377 /// 378 /// Set Auxiliary Control register 379 /// 380 SmbusIoWrite (R_PCH_SMBUS_AUXC, AuxcReg); 381 382 /// 383 /// Reset the pointer of the internal buffer 384 /// 385 SmbusIoRead (R_PCH_SMBUS_HCTL); 386 387 /// 388 /// Now that the 32 byte buffer is turned on, we can write th block data 389 /// into it 390 /// 391 if ((Operation == EfiSmbusWriteBlock) || (Operation == EfiSmbusBWBRProcessCall)) { 392 for (Index = 0; Index < BlockCount; Index++) { 393 /// 394 /// Write next byte 395 /// 396 SmbusIoWrite (R_PCH_SMBUS_HBD, CallBuffer[Index]); 397 } 398 } 399 /// 400 /// Set SMBus slave address for the device to send/receive from 401 /// 402 SmbusIoWrite (R_PCH_SMBUS_TSA, SlvAddrReg); 403 404 /// 405 /// For I2C read, send DATA1 register for the offset (address) 406 /// within the serial memory chips 407 /// 408 if ((Operation == EfiSmbusReadByte) && (*Length > 1)) { 409 SmbusIoWrite (R_PCH_SMBUS_HD1, HostCmdReg); 410 } else { 411 /// 412 /// Set Command register 413 /// 414 SmbusIoWrite (R_PCH_SMBUS_HCMD, HostCmdReg); 415 } 416 /// 417 /// Set Control Register (Initiate Operation, Interrupt disabled) 418 /// 419 SmbusIoWrite (R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START)); 420 421 /// 422 /// Wait for IO to complete 423 /// 424 if (!IoDone (&StsReg)) { 425 Status = EFI_TIMEOUT; 426 break; 427 } else if (StsReg & B_PCH_SMBUS_DERR) { 428 AuxStsReg = SmbusIoRead (R_PCH_SMBUS_AUXS); 429 if (AuxStsReg & B_PCH_SMBUS_CRCE) { 430 Status = EFI_CRC_ERROR; 431 } else { 432 Status = EFI_DEVICE_ERROR; 433 } 434 break; 435 } else if (StsReg & B_PCH_SMBUS_BERR) { 436 /// 437 /// Clear the Bus Error for another try 438 /// 439 Status = EFI_DEVICE_ERROR; 440 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR); 441 /// 442 /// Clear Status Registers 443 /// 444 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); 445 SmbusIoWrite (R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE); 446 /// 447 /// If bus collision happens, stall some time, then try again 448 /// Here we choose 10 milliseconds to avoid MTCP transfer. 449 /// 450 MicroSecondDelay (STALL_PERIOD); 451 continue; 452 } 453 /// 454 /// successfull completion 455 /// Operation Specifics (post-execution) 456 /// 457 switch (Operation) { 458 459 case EfiSmbusReadWord: 460 /// 461 /// The "break;" command is not present here to allow code execution 462 /// do drop into the next case, which contains common code to this case. 463 /// 464 case EfiSmbusProcessCall: 465 CallBuffer[1] = SmbusIoRead (R_PCH_SMBUS_HD1); 466 CallBuffer[0] = SmbusIoRead (R_PCH_SMBUS_HD0); 467 break; 468 469 case EfiSmbusReadByte: 470 if (*Length > 1) { 471 for (Index = 0; Index < *Length; Index++) { 472 /// 473 /// Read the byte 474 /// 475 CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD); 476 /// 477 /// After receiving byte n-1 (1-base) of the message, the 478 /// software will then set the LAST BYTE bit. The software 479 /// will then clear the BYTE_DONE_STS bit. 480 /// 481 if (Index == ((*Length - 1) - 1)) { 482 SmbusHctl = SmbusIoRead (R_PCH_SMBUS_HCTL) | (UINT8) B_PCH_SMBUS_LAST_BYTE; 483 SmbusIoWrite (R_PCH_SMBUS_HCTL, SmbusHctl); 484 } else if (Index == (*Length - 1)) { 485 /// 486 /// Clear the LAST BYTE bit after receiving byte n (1-base) of the message 487 /// 488 SmbusHctl = SmbusIoRead (R_PCH_SMBUS_HCTL) & (UINT8) ~B_PCH_SMBUS_LAST_BYTE; 489 SmbusIoWrite (R_PCH_SMBUS_HCTL, SmbusHctl); 490 } 491 /// 492 /// Clear the BYTE_DONE_STS bit 493 /// 494 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS); 495 /// 496 /// Check BYTE_DONE_STS bit to know if it has completed transmission 497 /// of a byte. No need to check it for the last byte. 498 /// 499 if (Index < (*Length - 1)) { 500 /// 501 /// If somehow board operates at 10Khz, it will take 0.9 ms (9/10Khz) for another byte. 502 /// Add 10 us delay for a loop of 100 that the total timeout is 1 ms to take care of 503 /// the slowest case. 504 /// 505 for (Timeout = 0; Timeout < 100; Timeout++) { 506 if ((SmbusIoRead (R_PCH_SMBUS_HSTS) & (UINT8) B_PCH_SMBUS_BYTE_DONE_STS) != 0) { 507 break; 508 } 509 /// 510 /// Delay 10 us 511 /// 512 MicroSecondDelay (STALL_PERIOD); 513 } 514 515 if (Timeout >= 100) { 516 Status = EFI_TIMEOUT; 517 break; 518 } 519 } 520 } 521 break; 522 } 523 524 case EfiSmbusReceiveByte: 525 CallBuffer[0] = SmbusIoRead (R_PCH_SMBUS_HD0); 526 break; 527 528 case EfiSmbusWriteBlock: 529 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS); 530 break; 531 532 case EfiSmbusReadBlock: 533 BufferTooSmall = FALSE; 534 /// 535 /// Find out how many bytes will be in the block 536 /// 537 BlockCount = SmbusIoRead (R_PCH_SMBUS_HD0); 538 if (*Length < BlockCount) { 539 BufferTooSmall = TRUE; 540 } else { 541 for (Index = 0; Index < BlockCount; Index++) { 542 /// 543 /// Read the byte 544 /// 545 CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD); 546 } 547 } 548 549 *Length = BlockCount; 550 if (BufferTooSmall) { 551 Status = EFI_BUFFER_TOO_SMALL; 552 } 553 break; 554 555 case EfiSmbusBWBRProcessCall: 556 /// 557 /// Find out how many bytes will be in the block 558 /// 559 BlockCount = SmbusIoRead (R_PCH_SMBUS_HD0); 560 /// 561 /// The read byte count cannot be zero. 562 /// 563 if (BlockCount < 1) { 564 Status = EFI_BUFFER_TOO_SMALL; 565 break; 566 } 567 /// 568 /// The combined data payload (the write byte count + the read byte count) 569 /// must not exceed 32 bytes 570 /// 571 if (((UINT8) (*Length) + BlockCount) > 32) { 572 Status = EFI_DEVICE_ERROR; 573 break; 574 } 575 576 for (Index = 0; Index < BlockCount; Index++) { 577 /// 578 /// Read the byte 579 /// 580 CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD); 581 } 582 583 *Length = BlockCount; 584 break; 585 586 default: 587 break; 588 }; 589 590 if ((StsReg & B_PCH_SMBUS_BERR) && (Status != EFI_BUFFER_TOO_SMALL)) { 591 /// 592 /// Clear the Bus Error for another try 593 /// 594 Status = EFI_DEVICE_ERROR; 595 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR); 596 /// 597 /// If bus collision happens, stall some time, then try again 598 /// Here we choose 10 milliseconds to avoid MTCP transfer. 599 /// 600 MicroSecondDelay (STALL_PERIOD); 601 continue; 602 } else { 603 break; 604 } 605 } 606 /// 607 /// Clear Status Registers and exit 608 /// 609 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); 610 SmbusIoWrite (R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE); 611 SmbusIoWrite (R_PCH_SMBUS_AUXC, 0); 612 return Status; 613 } 614 615 /** 616 This function initializes the Smbus Registers. 617 618 **/ 619 VOID 620 InitializeSmbusRegisters ( read_qlpc(BitstreamReader * bs,unsigned block_length,a_int * previous_samples,a_int * means,a_int * samples)621 VOID 622 ) 623 { 624 UINTN SmbusRegBase; 625 626 SmbusRegBase = MmPciBase ( 627 DEFAULT_PCI_BUS_NUMBER_PCH, 628 PCI_DEVICE_NUMBER_PCH_SMBUS, 629 PCI_FUNCTION_NUMBER_PCH_SMBUS 630 ); 631 /// 632 /// Enable the Smbus I/O Enable 633 /// 634 MmioOr8 (SmbusRegBase + PCI_COMMAND_OFFSET, (UINT8) EFI_PCI_COMMAND_IO_SPACE); 635 636 /// 637 /// Enable the Smbus host controller 638 /// 639 MmioAndThenOr8 ( 640 SmbusRegBase + R_PCH_SMBUS_HOSTC, 641 (UINT8) (~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)), 642 B_PCH_SMBUS_HOSTC_HST_EN 643 ); 644 645 SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL); 646 }