4 * NB library functions.
8 * @xrefitem bom "File Content Label" "Release Content"
11 * @e \$Revision:$ @e \$Date:$
14 /*****************************************************************************
16 * Copyright (C) 2012 Advanced Micro Devices, Inc.
17 * All rights reserved.
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 * * Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * * Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
27 * its contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
33 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
34 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 ***************************************************************************/
43 /*----------------------------------------------------------------------------------------
44 * M O D U L E S U S E D
45 *----------------------------------------------------------------------------------------
48 #include "NbPlatform.h"
49 #include "amdDebugOutLib.h"
51 /*----------------------------------------------------------------------------------------
52 * D E F I N I T I O N S A N D M A C R O S
53 *----------------------------------------------------------------------------------------
57 /*----------------------------------------------------------------------------------------
58 * T Y P E D E F S A N D S T R U C T U R E S
59 *----------------------------------------------------------------------------------------
62 /*----------------------------------------------------------------------------------------
63 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
64 *----------------------------------------------------------------------------------------
67 /*----------------------------------------------------------------------------------------
68 * E X P O R T E D F U N C T I O N S
69 *----------------------------------------------------------------------------------------
72 /*----------------------------------------------------------------------------------------*/
74 * Get silicon type and revision info.
78 * @param[in] NbConfigPtr configuration structure pointer.
79 * @retval NB_INFO Northbrige Info Structure.
81 /*----------------------------------------------------------------------------------------*/
83 LibNbGetRevisionInfo (
84 IN AMD_NB_CONFIG *NbConfigPtr
91 LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x8, AccessWidth8, &RevisionId, NbConfigPtr);
92 RevisionInfo.Revision = RevisionId;
93 LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x2, AccessWidth16, &DeviceId, NbConfigPtr);
96 RevisionInfo.Type = NB_RD890TV;
99 RevisionInfo.Type = NB_RX780;
102 RevisionInfo.Type = NB_RD780;
105 RevisionInfo.Type = NB_SR5690;
108 RevisionInfo.Type = NB_RD890;
111 RevisionInfo.Type = NB_SR5670;
114 RevisionInfo.Type = NB_SR5650;
117 RevisionInfo.Type = NB_990FX;
118 LibNbPciIndexRead (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG7D, AccessWidth32, &PrivateId, NbConfigPtr);
119 PrivateId = (PrivateId >> 21) & 0x0f;
120 if (PrivateId == 1) {
121 RevisionInfo.Type = NB_990FX;
123 if (PrivateId == 2) {
124 RevisionInfo.Type = NB_990X;
126 if (PrivateId == 3) {
127 RevisionInfo.Type = NB_970;
131 RevisionInfo.Type = NB_UNKNOWN;
137 /*----------------------------------------------------------------------------------------*/
143 * @param[in] CallBackId Callback ID.
144 * @param[in] Data Callback specific data.
145 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
147 /*----------------------------------------------------------------------------------------*/
150 IN UINT32 CallBackId,
152 IN OUT AMD_NB_CONFIG *NbConfigPtr
156 CALLOUT_ENTRY CallBackPtr = GET_BLOCK_CONFIG_PTR (NbConfigPtr)->StandardHeader.CalloutPtr;
158 Status = AGESA_UNSUPPORTED;
159 if (CallBackPtr != NULL) {
160 CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack CallBackId = 0x%x\n", CallBackId));
161 Status = (*CallBackPtr) (CallBackId, Data, GET_BLOCK_CONFIG_PTR (NbConfigPtr));
162 CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack Return = 0x%x\n", Status));
168 /*----------------------------------------------------------------------------------------*/
174 * @param[in] SystemApi Pointer to System API
175 * @param[in] ConfigPtr Northbridge block configuration structure pointer.
177 /*----------------------------------------------------------------------------------------*/
180 IN SYSTEM_API SystemApi,
181 IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
184 API_WORKSPACE Workspace;
187 LibAmdMemFill (&Workspace, 0, sizeof (API_WORKSPACE), (AMD_CONFIG_PARAMS *)&(ConfigPtr->StandardHeader));
188 Workspace.ConfigPtr = ConfigPtr;
189 Workspace.Status = AGESA_SUCCESS;
190 for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
191 ConfigPtr->Northbridges[NorthbridgeId].ConfigPtr = &Workspace.ConfigPtr;
193 if (SystemApi != NULL) {
194 (*SystemApi)(ConfigPtr);
196 return Workspace.Status;
199 /*----------------------------------------------------------------------------------------*/
205 * @param[in] NbApi Pointer to NB API
206 * @param[in] ConfigPtr Northbridge block configuration structure pointer
208 /*----------------------------------------------------------------------------------------*/
212 IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr
218 Status = AGESA_SUCCESS;
219 for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) {
220 AMD_NB_CONFIG *NbConfigPtr = &ConfigPtr->Northbridges[NorthbridgeId];
221 ConfigPtr->CurrentNorthbridge = NorthbridgeId;
222 if (!LibNbIsDevicePresent (NbConfigPtr->NbPciAddress, NbConfigPtr)) {
223 REPORT_EVENT (AGESA_WARNING, GENERAL_ERROR_NB_NOT_PRESENT, 0 , 0, 0, 0, NbConfigPtr);
227 Status = (*NbApi) (NbConfigPtr);
228 if (Status == AGESA_FATAL) {
236 /*----------------------------------------------------------------------------------------*/
238 * Write PCI register.
242 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
243 * @param[in] Width Access width.
244 * @param[in] Value Pointer to new register value.
245 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
247 /*----------------------------------------------------------------------------------------*/
252 IN ACCESS_WIDTH Width,
254 IN AMD_NB_CONFIG *NbConfigPtr
257 PCI_ADDR DeviceAddress;
258 DeviceAddress.AddressValue = Address;
259 LibAmdPciWrite (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
263 /*----------------------------------------------------------------------------------------*/
269 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
270 * @param[in] Width Access width.
271 * @param[in] Value Pointer to save register value.
272 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
275 /*----------------------------------------------------------------------------------------*/
279 IN ACCESS_WIDTH Width,
281 IN AMD_NB_CONFIG *NbConfigPtr
284 PCI_ADDR DeviceAddress;
285 DeviceAddress.AddressValue = Address;
286 LibAmdPciRead (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
289 /*----------------------------------------------------------------------------------------*/
291 * Read/Modify/Write PCI register
295 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
296 * @param[in] Width Access width.
297 * @param[in] Mask AND Mask.
298 * @param[in] Data OR Mask.
299 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
301 /*----------------------------------------------------------------------------------------*/
305 IN ACCESS_WIDTH Width,
308 IN AMD_NB_CONFIG *NbConfigPtr
312 LibNbPciRead (Address, Width, &Value, NbConfigPtr);
313 Value = (Value & Mask) | Data;
314 LibNbPciWrite (Address, Width, &Value, NbConfigPtr);
317 /*----------------------------------------------------------------------------------------*/
319 * Read PCI Index/Data Address space
323 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
324 * @param[in] Index Index Address.
325 * @param[in] Width Access width of Index/Data register.
326 * @param[in] Value Pointer to save register value.
327 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
329 /*----------------------------------------------------------------------------------------*/
335 IN ACCESS_WIDTH Width,
337 IN AMD_NB_CONFIG *NbConfigPtr
341 IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81)));
342 LibNbPciWrite (Address, Width, &Index, NbConfigPtr);
343 LibNbPciRead (Address + IndexOffset, Width, Value, NbConfigPtr);
346 /*----------------------------------------------------------------------------------------*/
348 * Write PCI Index/Data Address space
352 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
353 * @param[in] Index Index Address.
354 * @param[in] Width Access width of Index/Data register.
355 * @param[in] Value Pointer to save register value.
356 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
358 /*----------------------------------------------------------------------------------------*/
364 IN ACCESS_WIDTH Width,
366 IN AMD_NB_CONFIG *NbConfigPtr
370 IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81)));
371 LibNbPciWrite (Address, Width, &Index, NbConfigPtr);
372 LibNbPciWrite (Address + IndexOffset , Width, Value, NbConfigPtr);
375 /*----------------------------------------------------------------------------------------*/
377 * Read/Modify/Write PCI Index/Data Address space
381 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
382 * @param[in] Index Index Address.
383 * @param[in] Width Access width of Index/Data register.
384 * @param[in] Mask AND Mask.
385 * @param[in] Data OR Mask.
386 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
388 /*----------------------------------------------------------------------------------------*/
394 IN ACCESS_WIDTH Width,
397 IN AMD_NB_CONFIG *NbConfigPtr
401 LibNbPciIndexRead (Address, Index, Width, &Value, NbConfigPtr);
402 Value = (Value & Mask) | Data;
403 LibNbPciIndexWrite (Address, Index, Width, &Value, NbConfigPtr);
406 /*----------------------------------------------------------------------------------------*/
408 * Program table of indirect register.
412 * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue
413 * @param[in] Index Index Address. Index address OR with INDIRECT_REG_ENTRY.Register
414 * @param[in] pTable Pointer to indirect register table.
415 * @param[in] Length Number of entry in indirect register table.
416 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
418 /*----------------------------------------------------------------------------------------*/
420 LibNbIndirectTableInit (
423 IN INDIRECT_REG_ENTRY *pTable,
425 IN AMD_NB_CONFIG *NbConfigPtr
429 for (i = 0; i < Length; i++) {
430 LibNbPciIndexRMW (Address, Index | pTable[i].Register , AccessS3SaveWidth32, pTable[i].Mask, pTable[i].Data, NbConfigPtr);
434 /*----------------------------------------------------------------------------------------*/
436 * Find PCI capability pointer
443 /*----------------------------------------------------------------------------------------*/
446 LibNbFindPciCapability (
448 IN UINT8 CapabilityId,
449 IN AMD_NB_CONFIG *NbConfigPtr
453 UINT8 CurrentCapabilityId;
455 Device.AddressValue = Address;
456 CapabilityPtr = 0x34;
457 if (!LibNbIsDevicePresent (Device, NbConfigPtr)) {
460 while (CapabilityPtr != 0) {
461 LibNbPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, NbConfigPtr);
463 LibNbPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, NbConfigPtr);
464 if (CurrentCapabilityId == CapabilityId) break;
468 return CapabilityPtr;
470 /*----------------------------------------------------------------------------------------*/
472 * Find PCIe extended capability pointer
479 /*----------------------------------------------------------------------------------------*/
482 LibNbFindPcieExtendedCapability (
484 IN UINT16 ExtendedCapabilityId,
485 IN AMD_NB_CONFIG *NbConfigPtr
488 UINT16 CapabilityPtr;
489 UINT32 ExtendedCapabilityIdBlock;
490 if (LibNbFindPciCapability (Address, 0x10, NbConfigPtr) != 0) {
491 CapabilityPtr = 0x100;
492 LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr);
493 if (ExtendedCapabilityIdBlock != 0 && (UINT16)ExtendedCapabilityIdBlock != 0xffff) {
495 if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) {
496 return CapabilityPtr;
498 CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff);
499 LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr);
500 } while (CapabilityPtr != 0);
507 /*----------------------------------------------------------------------------------------*/
513 * @param[in] Address IO Port address.
514 * @param[in] Width Access width
515 * @param[in] Value Pointer to save IO port value;
516 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
518 /*----------------------------------------------------------------------------------------*/
523 IN ACCESS_WIDTH Width,
525 IN AMD_NB_CONFIG *NbConfigPtr
528 LibAmdIoRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
531 /*----------------------------------------------------------------------------------------*/
537 * @param[in] Address IO Port address.
538 * @param[in] Width Access width
539 * @param[in] Value Pointer to new IO port value
540 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
545 IN ACCESS_WIDTH Width,
547 IN AMD_NB_CONFIG *NbConfigPtr
550 LibAmdIoWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
554 /*----------------------------------------------------------------------------------------*/
556 * Read/Modify/Write IO space
560 * @param[in] Address IO Port address.
561 * @param[in] Width Access width
562 * @param[in] Mask AND Mask
563 * @param[in] Data OR Mask
564 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
566 /*----------------------------------------------------------------------------------------*/
571 IN ACCESS_WIDTH Width,
574 IN AMD_NB_CONFIG *NbConfigPtr
578 LibNbIoRead (Address, Width, &Value, NbConfigPtr);
579 Value = (Value & Mask) | Data;
580 LibNbIoWrite (Address, Width, &Value, NbConfigPtr);
584 /*----------------------------------------------------------------------------------------*/
586 * Read CPU HT link Phy register
590 * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
591 * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
592 * @param[in] Register Register address.
593 * @param[in] Value Pointer to save register value
594 * @param[in] NbConfigPtr Northbridge configuration block pointer.
596 /*----------------------------------------------------------------------------------------*/
599 LibNbCpuHTLinkPhyRead (
604 IN AMD_NB_CONFIG *NbConfigPtr
608 PCI_ADDR CpuPciAddress;
611 CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0);
612 LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | ((Register & 0xfe00)?BIT29:0), NbConfigPtr);
614 LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr);
615 } while ((Data & BIT31) == 0);
616 LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr);
619 /*----------------------------------------------------------------------------------------*/
621 * Write CPU HT link Phy register
625 * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
626 * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
627 * @param[in] Register Register address.
628 * @param[in] Value Pointer to new register value
629 * @param[in] NbConfigPtr Northbridge configuration block pointer.
631 /*----------------------------------------------------------------------------------------*/
634 LibNbCpuHTLinkPhyWrite (
639 IN AMD_NB_CONFIG *NbConfigPtr
643 PCI_ADDR CpuPciAddress;
646 CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0);
647 LibNbPciWrite (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr);
648 LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | BIT30 | ((Register & 0xfe00)?BIT29:0), NbConfigPtr);
650 LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr);
651 } while ((Data & BIT31) == 0);
655 /*----------------------------------------------------------------------------------------*/
657 * Read/Modify/Write CPU HT link Phy register
661 * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.)
662 * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.)
663 * @param[in] Register Register address.
664 * @param[in] Mask AND Mask.
665 * @param[in] Data OR Mask.
666 * @param[in] NbConfigPtr Northbridge configuration block pointer.
668 /*----------------------------------------------------------------------------------------*/
670 LibNbCpuHTLinkPhyRMW (
676 IN AMD_NB_CONFIG *NbConfigPtr
680 LibNbCpuHTLinkPhyRead (Node, Link, Register, &Value, NbConfigPtr);
681 Value = (Value & Mask) | Data;
682 LibNbCpuHTLinkPhyWrite (Node, Link, Register, &Value, NbConfigPtr);
686 /*----------------------------------------------------------------------------------------*/
688 * Enable Clock Config space access.
689 * Enable access to Clock Config Space at 0:0:1 PCI address.
692 * @param[in] pConfig Northbridge configuration block pointer.
694 /*----------------------------------------------------------------------------------------*/
697 LibNbEnableClkConfig (
698 IN AMD_NB_CONFIG *pConfig
701 LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, BIT0, pConfig);
704 /*----------------------------------------------------------------------------------------*/
706 * Disable Clock Config space access.
707 * Disable access to Clock Config Space at 0:0:1 PCI address.
710 * @param[in] pConfig Northbridge configuration block pointer.
712 /*----------------------------------------------------------------------------------------*/
715 LibNbDisableClkConfig (
716 IN AMD_NB_CONFIG *pConfig
719 LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, 0x0 , pConfig);
723 /*----------------------------------------------------------------------------------------*/
725 * Check if PCI Device Present
729 * @param[in] Device Device PCI address.
730 * @param[in] NbConfigPtr Northbridge configuration block pointer.
732 * @retval TRUE Device present.
733 * @retval FALSE Device not present.
735 /*----------------------------------------------------------------------------------------*/
738 LibNbIsDevicePresent (
740 IN AMD_NB_CONFIG *NbConfigPtr
744 LibNbPciRead (Device.AddressValue, AccessWidth32, &VendorId, NbConfigPtr);
745 return (VendorId == 0xffffffff)?FALSE:TRUE;
747 /*----------------------------------------------------------------------------------------*/
749 * Check if IOMMU enabled
753 * @param[in] NbConfigPtr Northbridge configuration block pointer.
755 * @retval TRUE IOMMU not enabled.
756 * @retval FALSE IOMMU not enabled.
758 /*----------------------------------------------------------------------------------------*/
760 LibNbIsIommuEnabled (
761 IN AMD_NB_CONFIG *NbConfigPtr
764 PCI_ADDR IommuAddress;
765 IommuAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue;
766 IommuAddress.Address.Function = 2;
767 if (LibNbIsDevicePresent (IommuAddress, NbConfigPtr)) {
769 LibNbPciRead (IommuAddress.AddressValue | 0x44, AccessWidth8, &Value, NbConfigPtr);
770 if ((Value & BIT0) != 0) {
777 /*----------------------------------------------------------------------------------------*/
779 * Reverse bit in DWORD.
780 * Reverse bits in bitfield inside DWORD.
783 * @param[in] Data Value to reverse.
784 * @param[in] StartBit Start bit.
785 * @param[in] StopBit Stop bit.
786 * @retval Reversed Value.
788 /*----------------------------------------------------------------------------------------*/
802 while (StartBit < StopBit) {
803 Bitr = Data & (1 << StartBit );
804 Bitl = Data & (1 << StopBit );
805 Distance = StopBit - StartBit;
806 Data = (Data & ((UINT32)~(Bitl | Bitr))) | (Bitr << Distance ) | (Bitl >> Distance);
812 /*----------------------------------------------------------------------------------------*/
818 * @retval 0xXX00000 CPU family.
827 CpuidRead (0x1, &Cpuid);
828 return Cpuid.EAX_Reg & 0xff00000;
832 /*----------------------------------------------------------------------------------------*/
834 * Load Firmware block
838 * @param[in] Address Address to load firmware
839 * @param[in] Size Firmware block size
840 * @param[in] FirmwareBlockPtr Pointer to firmware block
841 * @param[in] NbConfigPtr Northbridge configuration block pointer.
845 LibNbLoadMcuFirmwareBlock (
848 IN UINT32 *FirmwareBlockPtr,
849 IN AMD_NB_CONFIG *NbConfigPtr
853 PCI_ADDR ClkPciAddress;
856 Selector = (Address >= 0x200)?0x0000000:0x10000;
857 ClkPciAddress = NbConfigPtr->NbPciAddress;
858 ClkPciAddress.Address.Function = 1;
859 LibNbEnableClkConfig (NbConfigPtr);
860 for (i = 0; i < Size; i++) {
861 LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address + (i * 4)), AccessWidth32, &FirmwareBlockPtr[i], NbConfigPtr);
863 LibNbDisableClkConfig (NbConfigPtr);
866 /*----------------------------------------------------------------------------------------*/
868 * Read SMU firmware ram
872 * @param[in] Address Address to read
873 * @param[in] NbConfigPtr Northbridge configuration block pointer.
879 IN AMD_NB_CONFIG *NbConfigPtr
883 PCI_ADDR ClkPciAddress;
886 Selector = (Address >= 0x200) ? 0x0000000 : 0x10000;
887 ClkPciAddress = NbConfigPtr->NbPciAddress;
888 ClkPciAddress.Address.Function = 1;
889 LibNbEnableClkConfig (NbConfigPtr);
890 LibNbPciIndexRead (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address), AccessWidth32, &Value, NbConfigPtr);
891 LibNbDisableClkConfig (NbConfigPtr);
895 /*----------------------------------------------------------------------------------------*/
901 * @param[in] Operation Set/Reset MCU controller
902 * @param[in] NbConfigPtr Northbridge configuration block pointer.
906 IN NB_MCU_MODE Operation,
907 IN AMD_NB_CONFIG *NbConfigPtr
910 PCI_ADDR ClkPciAddress;
913 Value = (Operation == AssertReset)?0x00000ee1:0x00000ee2;
914 ClkPciAddress = NbConfigPtr->NbPciAddress;
915 ClkPciAddress.Address.Function = 1;
916 CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "LibNbMcuControl Operation [0x%x]\n", Operation));
917 LibNbEnableClkConfig (NbConfigPtr);
918 LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, 0x00030000, AccessWidth32, &Value, NbConfigPtr);
919 LibNbDisableClkConfig (NbConfigPtr);
922 /*----------------------------------------------------------------------------------------*/
924 * Read/Modify/Write memory space
928 * @param[in] Address Memory address.
929 * @param[in] Width Access width
930 * @param[in] Mask AND Mask
931 * @param[in] Data OR Mask
932 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
934 /*----------------------------------------------------------------------------------------*/
939 IN ACCESS_WIDTH Width,
942 IN AMD_NB_CONFIG *NbConfigPtr
946 LibNbMemRead (Address, Width, &Value, NbConfigPtr);
947 Value = (Value & Mask) | Data;
948 LibNbMemWrite (Address, Width, &Value, NbConfigPtr);
951 /*----------------------------------------------------------------------------------------*/
957 * @param[in] Address Memory address.
958 * @param[in] Width Access width
959 * @param[in] Value Pointer to memory to store value
960 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
962 /*----------------------------------------------------------------------------------------*/
967 IN ACCESS_WIDTH Width,
969 IN AMD_NB_CONFIG *NbConfigPtr
972 LibAmdMemRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
975 /*----------------------------------------------------------------------------------------*/
981 * @param[in] Address Memory address.
982 * @param[in] Width Access width
983 * @param[in] Value Pointer to memory to get value
984 * @param[in] NbConfigPtr Northbridge configuration structure pointer.
986 /*----------------------------------------------------------------------------------------*/
991 IN ACCESS_WIDTH Width,
993 IN AMD_NB_CONFIG *NbConfigPtr
996 LibAmdMemWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr)));
999 /*----------------------------------------------------------------------------------------*/
1005 * @param[in] This Pointer to PCI topology scan protocol
1006 * @param[in] Bridge Address of PCI to PCI bridge to scan.
1010 LibNbScanPciBridgeBuses (
1011 IN PCI_SCAN_PROTOCOL *This,
1021 CIMX_ASSERT (This != NULL);
1022 if (This->ScanBus == NULL) {
1023 return SCAN_FINISHED;
1025 LibNbPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &MinBus, This->pConfig);
1026 LibNbPciRead (Bridge.AddressValue | 0x1A, AccessWidth8, &MaxBus, This->pConfig);
1027 if (MinBus == 0 || MaxBus == 0) {
1028 return SCAN_FINISHED;
1030 CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Scan bridge %d:%d:%d \n", Bridge.Address.Bus, Bridge.Address.Device, Bridge.Address.Function));
1031 for (CurrentBus = MinBus; CurrentBus <= MaxBus; CurrentBus++) {
1032 Device.AddressValue = MAKE_SBDFO (0, CurrentBus, 0, 0, 0);
1033 Status = This->ScanBus (This, Device);
1035 return SCAN_FINISHED;
1039 /*----------------------------------------------------------------------------------------*/
1045 * @param[in] This Pointer to PCI topology scan protocol
1046 * @param[in] Device Pci address device to start bus scan from
1048 /*----------------------------------------------------------------------------------------*/
1051 IN PCI_SCAN_PROTOCOL *This,
1056 UINT32 CurrentDevice;
1057 CIMX_ASSERT (This != NULL);
1058 if (This->ScanDevice == NULL) {
1059 return SCAN_FINISHED;
1061 for (CurrentDevice = Device.Address.Device; CurrentDevice <= 0x1f; CurrentDevice++) {
1062 Device.Address.Device = CurrentDevice;
1063 if (LibNbIsDevicePresent (Device, This->pConfig)) {
1064 Status = This->ScanDevice (This, Device);
1065 if (Status == SCAN_STOP_BUS_ENUMERATION) {
1071 return SCAN_FINISHED;
1074 /*----------------------------------------------------------------------------------------*/
1080 * @param[in] This Pointer to PCI topology scan protocol
1081 * @param[in] Device Pci address device to scan
1083 /*----------------------------------------------------------------------------------------*/
1086 LibNbScanPciDevice (
1087 IN PCI_SCAN_PROTOCOL *This,
1093 UINT32 CurrentFunction;
1095 CIMX_ASSERT (This != NULL);
1096 if (This->ScanFunction == NULL) {
1097 return SCAN_FINISHED;
1099 LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Header, This->pConfig);
1100 MaxFunction = (Header & 0x80)?7:0;
1101 for (CurrentFunction = Device.Address.Function; CurrentFunction <= MaxFunction; CurrentFunction++) {
1102 Device.Address.Function = CurrentFunction;
1103 if (LibNbIsDevicePresent (Device, This->pConfig)) {
1104 CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Scan function %d:%d:%d \n", Device.Address.Bus, Device.Address.Device, Device.Address.Function));
1105 Status = This->ScanFunction (This, Device);
1106 if (Status == SCAN_STOP_DEVICE_ENUMERATION || Status == SCAN_STOP_BUS_ENUMERATION) {
1111 return SCAN_FINISHED;
1114 /*----------------------------------------------------------------------------------------*/
1116 * Set default Indexes
1119 * @param[in] NbConfigPtr Northbridge configuration block pointer.
1121 /*----------------------------------------------------------------------------------------*/
1124 LibNbSetDefaultIndexes (
1125 IN AMD_NB_CONFIG *NbConfigPtr
1128 PCI_ADDR PciAddress;
1130 LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
1131 LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);
1132 LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, SB_CORE, NbConfigPtr);
1133 PciAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue;
1134 for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) {
1135 PciAddress.Address.Device = PortId;
1136 LibNbPciRMW (PciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr);