1 /** @file 2 UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller 3 MMIO base, to upper layer UFS drivers. 4 5 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR> 6 Copyright (c) 2016 - 2017, Linaro Ltd. All rights reserved. 7 8 This program and the accompanying materials 9 are licensed and made available under the terms and conditions of the BSD License 10 which accompanies this distribution. The full text of the license may be found at 11 http://opensource.org/licenses/bsd-license.php. 12 13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 15 16 **/ 17 18 #include "DwUfsHcDxe.h" 19 20 #include <IndustryStandard/Pci.h> 21 22 #include <Protocol/PciIo.h> 23 24 // 25 // Ufs Host Controller Driver Binding Protocol Instance 26 // 27 EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding = { 28 UfsHcDriverBindingSupported, 29 UfsHcDriverBindingStart, 30 UfsHcDriverBindingStop, 31 0x10, 32 NULL, 33 NULL 34 }; 35 36 // 37 // Template for Ufs host controller private data. 38 // 39 UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = { 40 UFS_HC_PRIVATE_DATA_SIGNATURE, // Signature 41 NULL, // Handle 42 { // UfsHcProtocol 43 UfsHcGetMmioBar, 44 UfsHcAllocateBuffer, 45 UfsHcFreeBuffer, 46 UfsHcMap, 47 UfsHcUnmap, 48 UfsHcFlush, 49 UfsHcMmioRead, 50 UfsHcMmioWrite, 51 UfsHcPhyInit, 52 UfsHcPhySetPowerMode, 53 }, 54 0 // RegBase 55 }; 56 57 STATIC 58 EFI_STATUS 59 DwUfsDmeSet ( 60 IN UINTN RegBase, 61 IN UINT16 Attr, 62 IN UINT16 Index, 63 IN UINT32 Value 64 ) 65 { 66 UINT32 Data; 67 68 Data = MmioRead32 (RegBase + UFS_HC_STATUS_OFFSET); 69 if ((Data & UFS_HC_HCS_UCRDY) == 0) { 70 return EFI_NOT_READY; 71 } 72 MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, ~0); 73 MmioWrite32 (RegBase + UFS_HC_UCMD_ARG1_OFFSET, (Attr << 16) | Index); 74 MmioWrite32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET, 0); 75 MmioWrite32 (RegBase + UFS_HC_UCMD_ARG3_OFFSET, Value); 76 MmioWrite32 (RegBase + UFS_HC_UIC_CMD_OFFSET, UFS_UIC_DME_SET); 77 do { 78 Data = MmioRead32 (RegBase + UFS_HC_IS_OFFSET); 79 if (Data & UFS_HC_IS_UE) { 80 return EFI_DEVICE_ERROR; 81 } 82 } while ((Data & UFS_HC_IS_UCCS) == 0); 83 MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS); 84 Data = MmioRead32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET); 85 if (Data) { 86 return EFI_DEVICE_ERROR; 87 } 88 return EFI_SUCCESS; 89 } 90 91 STATIC 92 EFI_STATUS 93 DwUfsDmeGet ( 94 IN UINTN RegBase, 95 IN UINT16 Attr, 96 IN UINT16 Index, 97 OUT UINT32 *Value 98 ) 99 { 100 UINT32 Data; 101 102 Data = MmioRead32 (RegBase + UFS_HC_STATUS_OFFSET); 103 if ((Data & UFS_HC_HCS_UCRDY) == 0) { 104 return EFI_NOT_READY; 105 } 106 MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, ~0); 107 MmioWrite32 (RegBase + UFS_HC_UCMD_ARG1_OFFSET, (Attr << 16) | Index); 108 MmioWrite32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET, 0); 109 MmioWrite32 (RegBase + UFS_HC_UCMD_ARG3_OFFSET, 0); 110 MmioWrite32 (RegBase + UFS_HC_UIC_CMD_OFFSET, UFS_UIC_DME_GET); 111 do { 112 Data = MmioRead32 (RegBase + UFS_HC_IS_OFFSET); 113 if (Data & UFS_HC_IS_UE) { 114 return EFI_DEVICE_ERROR; 115 } 116 } while ((Data & UFS_HC_IS_UCCS) == 0); 117 MmioWrite32 (RegBase + UFS_HC_IS_OFFSET, UFS_HC_IS_UCCS); 118 Data = MmioRead32 (RegBase + UFS_HC_UCMD_ARG2_OFFSET); 119 if (Data) { 120 return EFI_DEVICE_ERROR; 121 } 122 *Value = MmioRead32 (RegBase + UFS_HC_UCMD_ARG3_OFFSET); 123 return EFI_SUCCESS; 124 } 125 126 /** 127 Get the MMIO base of the UFS host controller. 128 129 @param[in] This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. 130 @param[out] MmioBar The MMIO base address of UFS host controller. 131 132 @retval EFI_SUCCESS The operation succeeds. 133 @retval others The operation fails. 134 **/ 135 EFI_STATUS 136 EFIAPI 137 UfsHcGetMmioBar ( 138 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 139 OUT UINTN *MmioBar 140 ) 141 { 142 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 143 144 if ((This == NULL) || (MmioBar == NULL)) { 145 return EFI_INVALID_PARAMETER; 146 } 147 148 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); 149 *MmioBar = Private->RegBase; 150 return EFI_SUCCESS; 151 } 152 153 /** 154 Provides the UFS controller-specific addresses needed to access system memory. 155 156 @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. 157 @param Operation Indicates if the bus master is going to read or write to system memory. 158 @param HostAddress The system memory address to map to the UFS controller. 159 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes 160 that were mapped. 161 @param DeviceAddress The resulting map address for the bus master UFS controller to use to 162 access the hosts HostAddress. 163 @param Mapping A resulting value to pass to Unmap(). 164 165 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. 166 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. 167 @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 168 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 169 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. 170 171 **/ 172 EFI_STATUS 173 EFIAPI 174 UfsHcMap ( 175 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 176 IN EDKII_UFS_HOST_CONTROLLER_OPERATION Operation, 177 IN VOID *HostAddress, 178 IN OUT UINTN *NumberOfBytes, 179 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 180 OUT VOID **Mapping 181 ) 182 { 183 DMA_MAP_OPERATION DmaOperation; 184 185 if ((This == NULL) || (HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) || (Mapping == NULL)) { 186 return EFI_INVALID_PARAMETER; 187 } 188 189 if (Operation == EdkiiUfsHcOperationBusMasterRead) { 190 DmaOperation = MapOperationBusMasterRead; 191 } else if (Operation == EdkiiUfsHcOperationBusMasterWrite) { 192 DmaOperation = MapOperationBusMasterWrite; 193 } else if (Operation == EdkiiUfsHcOperationBusMasterCommonBuffer) { 194 DmaOperation = MapOperationBusMasterCommonBuffer; 195 } else { 196 return EFI_INVALID_PARAMETER; 197 } 198 199 if ((*NumberOfBytes & (BIT0 | BIT1)) != 0) { 200 *NumberOfBytes += BIT0 | BIT1; 201 *NumberOfBytes &= ~(BIT0 | BIT1); 202 } 203 204 return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping); 205 } 206 207 /** 208 Completes the Map() operation and releases any corresponding resources. 209 210 @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. 211 @param Mapping The mapping value returned from Map(). 212 213 @retval EFI_SUCCESS The range was unmapped. 214 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. 215 216 **/ 217 EFI_STATUS 218 EFIAPI 219 UfsHcUnmap ( 220 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 221 IN VOID *Mapping 222 ) 223 { 224 if ((This == NULL) || (Mapping == NULL)) { 225 return EFI_INVALID_PARAMETER; 226 } 227 228 return DmaUnmap (Mapping); 229 } 230 231 /** 232 Allocates pages that are suitable for an EfiUfsHcOperationBusMasterCommonBuffer 233 mapping. 234 235 @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. 236 @param Type This parameter is not used and must be ignored. 237 @param MemoryType The type of memory to allocate, EfiBootServicesData or 238 EfiRuntimeServicesData. 239 @param Pages The number of pages to allocate. 240 @param HostAddress A pointer to store the base system memory address of the 241 allocated range. 242 @param Attributes The requested bit mask of attributes for the allocated range. 243 244 @retval EFI_SUCCESS The requested memory pages were allocated. 245 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are 246 MEMORY_WRITE_COMBINE and MEMORY_CACHED. 247 @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 248 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. 249 250 **/ 251 EFI_STATUS 252 EFIAPI 253 UfsHcAllocateBuffer ( 254 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 255 IN EFI_ALLOCATE_TYPE Type, 256 IN EFI_MEMORY_TYPE MemoryType, 257 IN UINTN Pages, 258 OUT VOID **HostAddress, 259 IN UINT64 Attributes 260 ) 261 { 262 if ((This == NULL) || (HostAddress == NULL)) { 263 return EFI_INVALID_PARAMETER; 264 } 265 266 return DmaAllocateBuffer (MemoryType, Pages, HostAddress); 267 } 268 269 /** 270 Frees memory that was allocated with AllocateBuffer(). 271 272 @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. 273 @param Pages The number of pages to free. 274 @param HostAddress The base system memory address of the allocated range. 275 276 @retval EFI_SUCCESS The requested memory pages were freed. 277 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages 278 was not allocated with AllocateBuffer(). 279 280 **/ 281 EFI_STATUS 282 EFIAPI 283 UfsHcFreeBuffer ( 284 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 285 IN UINTN Pages, 286 IN VOID *HostAddress 287 ) 288 { 289 if ((This == NULL) || (HostAddress == NULL)) { 290 return EFI_INVALID_PARAMETER; 291 } 292 293 return DmaFreeBuffer (Pages, HostAddress); 294 } 295 296 /** 297 Flushes all posted write transactions from the UFS bus to attached UFS device. 298 299 @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. 300 301 @retval EFI_SUCCESS The posted write transactions were flushed from the UFS bus 302 to attached UFS device. 303 @retval EFI_DEVICE_ERROR The posted write transactions were not flushed from the UFS 304 bus to attached UFS device due to a hardware error. 305 306 **/ 307 EFI_STATUS 308 EFIAPI 309 UfsHcFlush ( 310 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This 311 ) 312 { 313 ArmInstructionSynchronizationBarrier (); 314 ArmDataSynchronizationBarrier (); 315 return EFI_SUCCESS; 316 } 317 318 /** 319 Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space. 320 321 @param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance. 322 @param Width Signifies the width of the memory operations. 323 @param Offset The offset within the UFS Host Controller MMIO space to start the 324 memory operation. 325 @param Count The number of memory operations to perform. 326 @param Buffer For read operations, the destination buffer to store the results. 327 For write operations, the source buffer to write data from. 328 329 @retval EFI_SUCCESS The data was read from or written to the UFS host controller. 330 @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not 331 valid for the UFS Host Controller memory space. 332 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 333 @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 334 335 **/ 336 EFI_STATUS 337 EFIAPI 338 UfsHcMmioRead ( 339 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 340 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, 341 IN UINT64 Offset, 342 IN UINTN Count, 343 IN OUT VOID *Buffer 344 ) 345 { 346 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 347 UINTN Index; 348 349 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); 350 351 switch (Width) { 352 case EfiUfsHcWidthUint8: 353 for (Index = 0; Index < Count; Index++) { 354 *((UINT8 *)Buffer + Index) = MmioRead8 (Private->RegBase + Offset); 355 } 356 break; 357 case EfiUfsHcWidthUint16: 358 for (Index = 0; Index < Count; Index++) { 359 *((UINT16 *)Buffer + Index) = MmioRead16 (Private->RegBase + Offset); 360 } 361 break; 362 case EfiUfsHcWidthUint32: 363 for (Index = 0; Index < Count; Index++) { 364 *((UINT32 *)Buffer + Index) = MmioRead32 (Private->RegBase + Offset); 365 } 366 break; 367 case EfiUfsHcWidthUint64: 368 for (Index = 0; Index < Count; Index++) { 369 *((UINT64 *)Buffer + Index) = MmioRead64 (Private->RegBase + Offset); 370 } 371 break; 372 default: 373 return EFI_INVALID_PARAMETER; 374 } 375 376 return EFI_SUCCESS; 377 } 378 379 /** 380 Enable a UFS bus driver to access UFS MMIO registers in the UFS Host Controller memory space. 381 382 @param This A pointer to the EDKII_UFS_HOST_CONTROLLER_PROTOCOL instance. 383 @param Width Signifies the width of the memory operations. 384 @param Offset The offset within the UFS Host Controller MMIO space to start the 385 memory operation. 386 @param Count The number of memory operations to perform. 387 @param Buffer For read operations, the destination buffer to store the results. 388 For write operations, the source buffer to write data from. 389 390 @retval EFI_SUCCESS The data was read from or written to the UFS host controller. 391 @retval EFI_UNSUPPORTED The address range specified by Offset, Width, and Count is not 392 valid for the UFS Host Controller memory space. 393 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 394 @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 395 396 **/ 397 EFI_STATUS 398 EFIAPI 399 UfsHcMmioWrite ( 400 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 401 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, 402 IN UINT64 Offset, 403 IN UINTN Count, 404 IN OUT VOID *Buffer 405 ) 406 { 407 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 408 EFI_STATUS Status = EFI_SUCCESS; 409 UINTN Index; 410 411 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); 412 413 switch (Width) { 414 case EfiUfsHcWidthUint8: 415 for (Index = 0; Index < Count; Index++) { 416 Status = MmioWrite8 (Private->RegBase + Offset, *((UINT8 *)Buffer + Index)); 417 } 418 break; 419 case EfiUfsHcWidthUint16: 420 for (Index = 0; Index < Count; Index++) { 421 Status = MmioWrite16 (Private->RegBase + Offset, *((UINT16 *)Buffer + Index)); 422 } 423 break; 424 case EfiUfsHcWidthUint32: 425 for (Index = 0; Index < Count; Index++) { 426 Status = MmioWrite32 (Private->RegBase + Offset, *((UINT32 *)Buffer + Index)); 427 } 428 break; 429 case EfiUfsHcWidthUint64: 430 for (Index = 0; Index < Count; Index++) { 431 Status = MmioWrite64 (Private->RegBase + Offset, *((UINT64 *)Buffer + Index)); 432 } 433 break; 434 default: 435 return EFI_INVALID_PARAMETER; 436 } 437 438 return Status; 439 } 440 441 EFI_STATUS 442 EFIAPI 443 UfsHcPhyInit ( 444 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This 445 ) 446 { 447 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 448 EFI_STATUS Status; 449 UINT32 Data, Fsm0, Fsm1; 450 451 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); 452 DwUfsDmeSet (Private->RegBase, 0xd0c1, 0, 1); 453 DwUfsDmeSet (Private->RegBase, 0xd0c1, 0, 1); 454 DwUfsDmeSet (Private->RegBase, 0x156a, 0, 2); 455 DwUfsDmeSet (Private->RegBase, 0x8114, 0, 1); 456 DwUfsDmeSet (Private->RegBase, 0x8121, 0, 0x2d); 457 DwUfsDmeSet (Private->RegBase, 0x8122, 0, 1); 458 DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1); 459 DwUfsDmeSet (Private->RegBase, 0x800d, 4, 0x58); 460 DwUfsDmeSet (Private->RegBase, 0x800d, 5, 0x58); 461 DwUfsDmeSet (Private->RegBase, 0x800e, 4, 0xb); 462 DwUfsDmeSet (Private->RegBase, 0x800e, 5, 0xb); 463 DwUfsDmeSet (Private->RegBase, 0x8009, 4, 0x1); 464 DwUfsDmeSet (Private->RegBase, 0x8009, 5, 0x1); 465 DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1); 466 DwUfsDmeSet (Private->RegBase, 0x8113, 0, 1); 467 DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1); 468 DwUfsDmeSet (Private->RegBase, 0x0095, 4, 0x4a); 469 DwUfsDmeSet (Private->RegBase, 0x0095, 5, 0x4a); 470 DwUfsDmeSet (Private->RegBase, 0x0094, 4, 0x4a); 471 DwUfsDmeSet (Private->RegBase, 0x0094, 5, 0x4a); 472 DwUfsDmeSet (Private->RegBase, 0x008f, 4, 0x7); 473 DwUfsDmeSet (Private->RegBase, 0x008f, 5, 0x7); 474 DwUfsDmeSet (Private->RegBase, 0x000f, 0, 0x5); 475 DwUfsDmeSet (Private->RegBase, 0x000f, 1, 0x5); 476 DwUfsDmeSet (Private->RegBase, 0xd085, 0, 1); 477 478 Status = DwUfsDmeGet (Private->RegBase, 0xd0c1, 0, &Data); 479 ASSERT_EFI_ERROR (Status); 480 ASSERT (Data == 1); 481 482 DwUfsDmeSet (Private->RegBase, 0xd0c1, 0, 0); 483 for (;;) { 484 Status = DwUfsDmeGet (Private->RegBase, 0x0041, 0, &Fsm0); 485 ASSERT_EFI_ERROR (Status); 486 Status = DwUfsDmeGet (Private->RegBase, 0x0041, 1, &Fsm1); 487 ASSERT_EFI_ERROR (Status); 488 if ((Fsm0 == 1) && (Fsm1 == 1)) { 489 break; 490 } 491 } 492 493 MmioWrite32 (Private->RegBase + UFS_HC_HCLKDIV_OFFSET, 0xE4); 494 Data = MmioRead32 (Private->RegBase + UFS_HC_AHIT_OFFSET); 495 Data &= ~0x3FF; 496 MmioWrite32 (Private->RegBase + UFS_HC_AHIT_OFFSET, Data); 497 498 DwUfsDmeSet (Private->RegBase, 0x155e, 0, 0); 499 DwUfsDmeSet (Private->RegBase, 0xd0ab, 0, 0); 500 501 Status = DwUfsDmeGet (Private->RegBase, 0xd0ab, 0, &Data); 502 ASSERT_EFI_ERROR ((Status) && (Data == 0)); 503 504 DwUfsDmeSet (Private->RegBase, 0x2044, 0, 0); 505 DwUfsDmeSet (Private->RegBase, 0x2045, 0, 0); 506 DwUfsDmeSet (Private->RegBase, 0x2040, 0, 9); 507 return EFI_SUCCESS; 508 } 509 510 EFI_STATUS 511 EFIAPI 512 UfsHcPhySetPowerMode ( 513 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, 514 IN UINT32 DevQuirks 515 ) 516 { 517 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 518 UINT32 Data, TxLanes, RxLanes; 519 520 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); 521 522 if (DevQuirks & UFS_DEVICE_QUIRK_HOST_VS_DEBUGSAVECONFIGTIME) { 523 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "ufs: H**** device must set VS_DebugSaveConfigTime 0x10\n")); 524 /* VS_DebugSaveConfigTime */ 525 DwUfsDmeSet (Private->RegBase, 0xD0A0, 0x0, 0x10); 526 /* sync length */ 527 DwUfsDmeSet (Private->RegBase, 0x1556, 0x0, 0x48); 528 } 529 530 // PA_Tactive 531 DwUfsDmeGet (Private->RegBase, 0x15A8, 0, &Data); 532 if (Data < 7) { 533 DwUfsDmeSet (Private->RegBase, 0x15A8, 4, 7); 534 } 535 DwUfsDmeGet (Private->RegBase, 0x1561, 0, &TxLanes); 536 DwUfsDmeGet (Private->RegBase, 0x1581, 0, &RxLanes); 537 538 // PA TxSkip 539 DwUfsDmeSet (Private->RegBase, 0x155C, 0, 0); 540 // PA TxGear 541 DwUfsDmeSet (Private->RegBase, 0x1568, 0, 3); 542 // PA RxGear 543 DwUfsDmeSet (Private->RegBase, 0x1583, 0, 3); 544 // PA HSSeries 545 DwUfsDmeSet (Private->RegBase, 0x156A, 0, 2); 546 // PA TxTermination 547 DwUfsDmeSet (Private->RegBase, 0x1569, 0, 1); 548 // PA RxTermination 549 DwUfsDmeSet (Private->RegBase, 0x1584, 0, 1); 550 // PA Scrambling 551 DwUfsDmeSet (Private->RegBase, 0x1585, 0, 0); 552 // PA ActiveTxDataLines 553 DwUfsDmeSet (Private->RegBase, 0x1560, 0, TxLanes); 554 // PA ActiveRxDataLines 555 DwUfsDmeSet (Private->RegBase, 0x1580, 0, RxLanes); 556 // PA_PWRModeUserData0 = 8191 557 DwUfsDmeSet (Private->RegBase, 0x15B0, 0, 8191); 558 // PA_PWRModeUserData1 = 65535 559 DwUfsDmeSet (Private->RegBase, 0x15B1, 0, 65535); 560 // PA_PWRModeUserData2 = 32767 561 DwUfsDmeSet (Private->RegBase, 0x15B2, 0, 32767); 562 // DME_FC0ProtectionTimeOutVal = 8191 563 DwUfsDmeSet (Private->RegBase, 0xD041, 0, 8191); 564 // DME_TC0ReplayTimeOutVal = 65535 565 DwUfsDmeSet (Private->RegBase, 0xD042, 0, 65535); 566 // DME_AFC0ReqTimeOutVal = 32767 567 DwUfsDmeSet (Private->RegBase, 0xD043, 0, 32767); 568 // PA_PWRModeUserData3 = 8191 569 DwUfsDmeSet (Private->RegBase, 0x15B3, 0, 8191); 570 // PA_PWRModeUserData4 = 65535 571 DwUfsDmeSet (Private->RegBase, 0x15B4, 0, 65535); 572 // PA_PWRModeUserData5 = 32767 573 DwUfsDmeSet (Private->RegBase, 0x15B5, 0, 32767); 574 // DME_FC1ProtectionTimeOutVal = 8191 575 DwUfsDmeSet (Private->RegBase, 0xD044, 0, 8191); 576 // DME_TC1ReplayTimeOutVal = 65535 577 DwUfsDmeSet (Private->RegBase, 0xD045, 0, 65535); 578 // DME_AFC1ReqTimeOutVal = 32767 579 DwUfsDmeSet (Private->RegBase, 0xD046, 0, 32767); 580 581 DwUfsDmeSet (Private->RegBase, 0x1571, 0, 0x11); 582 do { 583 Data = MmioRead32(Private->RegBase + UFS_HC_IS_OFFSET); 584 } while ((Data & UFS_INT_UPMS) == 0); 585 MmioWrite32(Private->RegBase + UFS_HC_IS_OFFSET, UFS_INT_UPMS); 586 Data = MmioRead32(Private->RegBase + UFS_HC_STATUS_OFFSET); 587 if ((Data & HCS_UPMCRS_MASK) == HCS_PWR_LOCAL) { 588 DEBUG ((DEBUG_INFO, "ufs: change power mode success\n")); 589 } else { 590 DEBUG ((DEBUG_ERROR, "ufs: HCS.UPMCRS error, HCS:0x%x\n", Data)); 591 } 592 return EFI_SUCCESS; 593 } 594 595 /** 596 Tests to see if this driver supports a given controller. If a child device is provided, 597 it further tests to see if this driver supports creating a handle for the specified child device. 598 599 This function checks to see if the driver specified by This supports the device specified by 600 ControllerHandle. Drivers will typically use the device path attached to 601 ControllerHandle and/or the services from the bus I/O abstraction attached to 602 ControllerHandle to determine if the driver supports ControllerHandle. This function 603 may be called many times during platform initialization. In order to reduce boot times, the tests 604 performed by this function must be very small, and take as little time as possible to execute. This 605 function must not change the state of any hardware devices, and this function must be aware that the 606 device specified by ControllerHandle may already be managed by the same driver or a 607 different driver. This function must match its calls to AllocatePages() with FreePages(), 608 AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). 609 Since ControllerHandle may have been previously started by the same driver, if a protocol is 610 already in the opened state, then it must not be closed with CloseProtocol(). This is required 611 to guarantee the state of ControllerHandle is not modified by this function. 612 613 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. 614 @param[in] ControllerHandle The handle of the controller to test. This handle 615 must support a protocol interface that supplies 616 an I/O abstraction to the driver. 617 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This 618 parameter is ignored by device drivers, and is optional for bus 619 drivers. For bus drivers, if this parameter is not NULL, then 620 the bus driver must determine if the bus controller specified 621 by ControllerHandle and the child controller specified 622 by RemainingDevicePath are both supported by this 623 bus driver. 624 625 @retval EFI_SUCCESS The device specified by ControllerHandle and 626 RemainingDevicePath is supported by the driver specified by This. 627 @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and 628 RemainingDevicePath is already being managed by the driver 629 specified by This. 630 @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and 631 RemainingDevicePath is already being managed by a different 632 driver or an application that requires exclusive access. 633 Currently not implemented. 634 @retval EFI_UNSUPPORTED The device specified by ControllerHandle and 635 RemainingDevicePath is not supported by the driver specified by This. 636 **/ 637 EFI_STATUS 638 EFIAPI 639 UfsHcDriverBindingSupported ( 640 IN EFI_DRIVER_BINDING_PROTOCOL *This, 641 IN EFI_HANDLE Controller, 642 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 643 ) 644 { 645 EFI_STATUS Status; 646 BOOLEAN UfsHcFound; 647 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath = NULL; 648 EFI_PCI_IO_PROTOCOL *PciIo = NULL; 649 PCI_TYPE00 PciData; 650 651 ParentDevicePath = NULL; 652 UfsHcFound = FALSE; 653 654 // 655 // UfsHcDxe is a device driver, and should ingore the 656 // "RemainingDevicePath" according to EFI spec 657 // 658 Status = gBS->OpenProtocol ( 659 Controller, 660 &gEfiDevicePathProtocolGuid, 661 (VOID *) &ParentDevicePath, 662 This->DriverBindingHandle, 663 Controller, 664 EFI_OPEN_PROTOCOL_BY_DRIVER 665 ); 666 if (EFI_ERROR (Status)) { 667 // 668 // EFI_ALREADY_STARTED is also an error 669 // 670 return Status; 671 } 672 // 673 // Close the protocol because we don't use it here 674 // 675 gBS->CloseProtocol ( 676 Controller, 677 &gEfiDevicePathProtocolGuid, 678 This->DriverBindingHandle, 679 Controller 680 ); 681 682 // 683 // Now test the EfiPciIoProtocol 684 // 685 Status = gBS->OpenProtocol ( 686 Controller, 687 &gEfiPciIoProtocolGuid, 688 (VOID **) &PciIo, 689 This->DriverBindingHandle, 690 Controller, 691 EFI_OPEN_PROTOCOL_BY_DRIVER 692 ); 693 if (EFI_ERROR (Status)) { 694 return Status; 695 } 696 // 697 // Now further check the PCI header: Base class (offset 0x0B) and 698 // Sub Class (offset 0x0A). This controller should be an UFS controller 699 // 700 Status = PciIo->Pci.Read ( 701 PciIo, 702 EfiPciIoWidthUint8, 703 0, 704 sizeof (PciData), 705 &PciData 706 ); 707 if (EFI_ERROR (Status)) { 708 gBS->CloseProtocol ( 709 Controller, 710 &gEfiPciIoProtocolGuid, 711 This->DriverBindingHandle, 712 Controller 713 ); 714 return EFI_UNSUPPORTED; 715 } 716 717 // 718 // Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points. 719 // 720 gBS->CloseProtocol ( 721 Controller, 722 &gEfiPciIoProtocolGuid, 723 This->DriverBindingHandle, 724 Controller 725 ); 726 727 // 728 // Examine UFS Host Controller PCI Configuration table fields 729 // 730 if (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) { 731 if (PciData.Hdr.ClassCode[1] == 0x09 ) { //UFS Controller Subclass 732 UfsHcFound = TRUE; 733 } 734 } 735 736 if (!UfsHcFound) { 737 return EFI_UNSUPPORTED; 738 } 739 740 return Status; 741 } 742 743 /** 744 Starts a device controller or a bus controller. 745 746 The Start() function is designed to be invoked from the EFI boot service ConnectController(). 747 As a result, much of the error checking on the parameters to Start() has been moved into this 748 common boot service. It is legal to call Start() from other locations, 749 but the following calling restrictions must be followed or the system behavior will not be deterministic. 750 1. ControllerHandle must be a valid EFI_HANDLE. 751 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned 752 EFI_DEVICE_PATH_PROTOCOL. 753 3. Prior to calling Start(), the Supported() function for the driver specified by This must 754 have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. 755 756 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. 757 @param[in] ControllerHandle The handle of the controller to start. This handle 758 must support a protocol interface that supplies 759 an I/O abstraction to the driver. 760 @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This 761 parameter is ignored by device drivers, and is optional for bus 762 drivers. For a bus driver, if this parameter is NULL, then handles 763 for all the children of Controller are created by this driver. 764 If this parameter is not NULL and the first Device Path Node is 765 not the End of Device Path Node, then only the handle for the 766 child device specified by the first Device Path Node of 767 RemainingDevicePath is created by this driver. 768 If the first Device Path Node of RemainingDevicePath is 769 the End of Device Path Node, no child handle is created by this 770 driver. 771 772 @retval EFI_SUCCESS The device was started. 773 @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. 774 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 775 @retval Others The driver failded to start the device. 776 777 **/ 778 EFI_STATUS 779 EFIAPI 780 UfsHcDriverBindingStart ( 781 IN EFI_DRIVER_BINDING_PROTOCOL *This, 782 IN EFI_HANDLE Controller, 783 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 784 ) 785 { 786 EFI_STATUS Status; 787 EFI_PCI_IO_PROTOCOL *PciIo; 788 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 789 UINT64 Supports; 790 UINT8 BarIndex; 791 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; 792 UINT32 BaseAddress; 793 794 PciIo = NULL; 795 Private = NULL; 796 Supports = 0; 797 BarDesc = NULL; 798 BaseAddress = PcdGet32 (PcdDwUfsHcDxeBaseAddress); 799 800 // 801 // Now test and open the EfiPciIoProtocol 802 // 803 Status = gBS->OpenProtocol ( 804 Controller, 805 &gEfiPciIoProtocolGuid, 806 (VOID **) &PciIo, 807 This->DriverBindingHandle, 808 Controller, 809 EFI_OPEN_PROTOCOL_BY_DRIVER 810 ); 811 // 812 // Status == 0 - A normal execution flow, SUCCESS and the program proceeds. 813 // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates 814 // that the protocol has been opened and should be treated as a 815 // normal condition and the program proceeds. The Protocol will not 816 // opened 'again' by this call. 817 // Status != ALREADY_STARTED - Error status, terminate program execution 818 // 819 if (EFI_ERROR (Status)) { 820 // 821 // EFI_ALREADY_STARTED is also an error 822 // 823 return Status; 824 } 825 826 //BaseAddress = PcdGet32 (PcdDwUfsHcDxeBaseAddress); 827 Private = AllocateCopyPool (sizeof (UFS_HOST_CONTROLLER_PRIVATE_DATA), &gUfsHcTemplate); 828 if (Private == NULL) { 829 Status = EFI_OUT_OF_RESOURCES; 830 goto Done; 831 } 832 833 Private->RegBase = (UINTN)BaseAddress; 834 Private->PciIo = PciIo; 835 836 for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) { 837 Status = PciIo->GetBarAttributes ( 838 PciIo, 839 BarIndex, 840 NULL, 841 (VOID**) &BarDesc 842 ); 843 if (Status == EFI_UNSUPPORTED) { 844 continue; 845 } else if (EFI_ERROR (Status)) { 846 goto Done; 847 } 848 849 if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) { 850 Private->BarIndex = BarIndex; 851 FreePool (BarDesc); 852 break; 853 } 854 855 FreePool (BarDesc); 856 } 857 858 Status = PciIo->Attributes ( 859 PciIo, 860 EfiPciIoAttributeOperationGet, 861 0, 862 &Private->PciAttributes 863 ); 864 865 if (EFI_ERROR (Status)) { 866 goto Done; 867 } 868 869 Status = PciIo->Attributes ( 870 PciIo, 871 EfiPciIoAttributeOperationSupported, 872 0, 873 &Supports 874 ); 875 876 if (!EFI_ERROR (Status)) { 877 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; 878 Status = PciIo->Attributes ( 879 PciIo, 880 EfiPciIoAttributeOperationEnable, 881 Supports, 882 NULL 883 ); 884 } else { 885 goto Done; 886 } 887 888 /// 889 /// Install UFS_HOST_CONTROLLER protocol 890 /// 891 Status = gBS->InstallProtocolInterface ( 892 &Controller, 893 &gEdkiiUfsHostControllerProtocolGuid, 894 EFI_NATIVE_INTERFACE, 895 (VOID*)&(Private->UfsHc) 896 ); 897 898 Done: 899 if (EFI_ERROR (Status)) { 900 if ((Private != NULL) && (Private->PciAttributes != 0)) { 901 // 902 // Restore original PCI attributes 903 // 904 Status = PciIo->Attributes ( 905 PciIo, 906 EfiPciIoAttributeOperationSet, 907 Private->PciAttributes, 908 NULL 909 ); 910 ASSERT_EFI_ERROR (Status); 911 } 912 gBS->CloseProtocol ( 913 Controller, 914 &gEfiPciIoProtocolGuid, 915 This->DriverBindingHandle, 916 Controller 917 ); 918 if (Private != NULL) { 919 FreePool (Private); 920 } 921 } 922 923 return Status; 924 } 925 926 /** 927 Stops a device controller or a bus controller. 928 929 The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). 930 As a result, much of the error checking on the parameters to Stop() has been moved 931 into this common boot service. It is legal to call Stop() from other locations, 932 but the following calling restrictions must be followed or the system behavior will not be deterministic. 933 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this 934 same driver's Start() function. 935 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid 936 EFI_HANDLE. In addition, all of these handles must have been created in this driver's 937 Start() function, and the Start() function must have called OpenProtocol() on 938 ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. 939 940 @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. 941 @param[in] ControllerHandle A handle to the device being stopped. The handle must 942 support a bus specific I/O protocol for the driver 943 to use to stop the device. 944 @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. 945 @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL 946 if NumberOfChildren is 0. 947 948 @retval EFI_SUCCESS The device was stopped. 949 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. 950 951 **/ 952 EFI_STATUS 953 EFIAPI 954 UfsHcDriverBindingStop ( 955 IN EFI_DRIVER_BINDING_PROTOCOL *This, 956 IN EFI_HANDLE Controller, 957 IN UINTN NumberOfChildren, 958 IN EFI_HANDLE *ChildHandleBuffer 959 ) 960 { 961 EFI_STATUS Status; 962 UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; 963 EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc; 964 965 /// 966 /// Get private data 967 /// 968 Status = gBS->OpenProtocol ( 969 Controller, 970 &gEdkiiUfsHostControllerProtocolGuid, 971 (VOID **) &UfsHc, 972 This->DriverBindingHandle, 973 Controller, 974 EFI_OPEN_PROTOCOL_GET_PROTOCOL 975 ); 976 977 if (EFI_ERROR (Status)) { 978 return EFI_DEVICE_ERROR; 979 } 980 981 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (UfsHc); 982 983 Status = gBS->UninstallProtocolInterface ( 984 Controller, 985 &gEdkiiUfsHostControllerProtocolGuid, 986 &(Private->UfsHc) 987 ); 988 if (!EFI_ERROR (Status)) { 989 // 990 // Restore original PCI attributes 991 // 992 Status = Private->PciIo->Attributes ( 993 Private->PciIo, 994 EfiPciIoAttributeOperationSet, 995 Private->PciAttributes, 996 NULL 997 ); 998 ASSERT_EFI_ERROR (Status); 999 1000 // 1001 // Close protocols opened by UFS host controller driver 1002 // 1003 gBS->CloseProtocol ( 1004 Controller, 1005 &gEfiPciIoProtocolGuid, 1006 This->DriverBindingHandle, 1007 Controller 1008 ); 1009 1010 FreePool (Private); 1011 } 1012 1013 return Status; 1014 } 1015 1016 /** 1017 The entry point for UFS host controller driver, used to install this driver on the ImageHandle. 1018 1019 @param[in] ImageHandle The firmware allocated handle for this driver image. 1020 @param[in] SystemTable Pointer to the EFI system table. 1021 1022 @retval EFI_SUCCESS Driver loaded. 1023 @retval other Driver not loaded. 1024 1025 **/ 1026 EFI_STATUS 1027 EFIAPI 1028 UfsHcDriverEntry ( 1029 IN EFI_HANDLE ImageHandle, 1030 IN EFI_SYSTEM_TABLE *SystemTable 1031 ) 1032 { 1033 EFI_STATUS Status; 1034 1035 Status = EfiLibInstallDriverBindingComponentName2 ( 1036 ImageHandle, 1037 SystemTable, 1038 &gUfsHcDriverBinding, 1039 ImageHandle, 1040 &gUfsHcComponentName, 1041 &gUfsHcComponentName2 1042 ); 1043 ASSERT_EFI_ERROR (Status); 1044 1045 return Status; 1046 } 1047