diff options
author | Kerry Sheh <shekairui@gmail.com> | 2012-01-31 20:39:37 +0800 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2012-02-02 13:54:36 +0100 |
commit | 9292d89be84d6abf9257ddb872887d4f53b2a00e (patch) | |
tree | 9eaa548f1742745f57fc92a12734649fec8db1cd /src/vendorcode/amd/cimx | |
parent | 17670866a0d12839bc2a4c852210ccf11d3cb4b2 (diff) | |
download | coreboot-9292d89be84d6abf9257ddb872887d4f53b2a00e.tar.gz coreboot-9292d89be84d6abf9257ddb872887d4f53b2a00e.tar.bz2 coreboot-9292d89be84d6abf9257ddb872887d4f53b2a00e.zip |
RD890 Northbridge: AMD RD890/SR56X0 Northbridge CIMX code
Change-Id: If9908ffeb5b707a660db38dc44f5118347cbcc06
Signed-off-by: Kerry Sheh <kerry.she@amd.com>
Signed-off-by: Kerry Sheh <shekairui@gmail.com>
Reviewed-on: http://review.coreboot.org/557
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/vendorcode/amd/cimx')
66 files changed, 20136 insertions, 0 deletions
diff --git a/src/vendorcode/amd/cimx/Makefile.inc b/src/vendorcode/amd/cimx/Makefile.inc index bb9b78c88fca..36223127ec35 100644 --- a/src/vendorcode/amd/cimx/Makefile.inc +++ b/src/vendorcode/amd/cimx/Makefile.inc @@ -1,2 +1,3 @@ subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800) += sb800 subdirs-$(CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900) += sb900 +subdirs-$(CONFIG_NORTHBRIDGE_AMD_CIMX_RD890) += rd890 diff --git a/src/vendorcode/amd/cimx/rd890/HotplugFirmware.h b/src/vendorcode/amd/cimx/rd890/HotplugFirmware.h new file mode 100644 index 000000000000..a0b416fd68b5 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/HotplugFirmware.h @@ -0,0 +1,1397 @@ +/** + * @file + * + * SMU firmware. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 18962 \$ @e \$Date: 2009-09-07 20:35:39 -0700 (Mon, 07 Sep 2009) \$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + + +#ifndef _HOTPLUGFIRMWARE_H_ +#define _HOTPLUGFIRMWARE_H_ + +UINT32 DataBlock0[] = { + 0xbdff018e, + 0x16ceee15, + 0x1cce1807, + 0xa6082000, + 0x00a71800, + 0x8c081808, + 0xf3256716, + 0x270000cc, + 0x601cce0b, + 0x8308006f, + 0xf8260100, + 0x16bd098d, + 0x02fb2003, + 0xde1c0206, + 0x9f343c06, + 0xbd0fc606, + 0x06de0004, + 0xfece016f, + 0xe702c668, + 0x69fece00, + 0x1806de18, + 0x00e701e6, + 0xe764fece, + 0x18c4c600, + 0x1865fece, + 0xffc600e7, + 0x66fece18, + 0xce00e718, + 0x00e767fe, + 0x1806de18, + 0x1cf701e6, + 0xf704c600, + 0x06bd041c, + 0x06de18e0, + 0xf701e618, + 0xfece001c, + 0xf600e764, + 0xce18011c, + 0xe71865fe, + 0x021cf600, + 0xe766fece, + 0x031cf600, + 0x67fece18, + 0xf600e718, + 0xffce4b1c, + 0xf600e78e, + 0xffce4a1c, + 0xbd00e78d, + 0x00cc2b06, + 0x7efece01, + 0x07bd00ed, + 0x0200ce2b, + 0x7efece18, + 0xbd00efcd, + 0x00ce8407, + 0xfece1803, + 0x00efcd7e, + 0xe674fece, + 0x2601c100, + 0x06de181a, + 0x3701e618, + 0x081ccc34, + 0x31480fbd, + 0x6c06de31, + 0xc101e601, + 0xcee62307, + 0xce180400, + 0xefcd7efe, + 0x4b1cf600, + 0x1cf702ca, + 0x8effce4b, + 0xfece00e7, + 0x2600e675, + 0x0812bd03, + 0xfd8009bd, + 0x1c2a101c, + 0x180500ce, + 0xcd7efece, + 0x01c600ef, + 0xce540bbd, + 0xce180600, + 0xefcd7efe, + 0xfe200e00, + 0x0cbd01c6, + 0xbd01c690, + 0x00ce9a10, + 0xfece1807, + 0x00efcd7e, + 0x540bbd5f, + 0x180800ce, + 0xcd7efece, + 0xffce00ef, + 0xe701c68f, + 0x00ce0e00, + 0x00efcd09, + 0x274e1cf6, + 0x1cf75f29, + 0x0a00ce4e, + 0x7efece18, + 0xc600efcd, + 0x900cbd01, + 0x10bd00c6, + 0x0b00ce9a, + 0x7efece18, + 0xce00efcd, + 0x01c68fff, + 0xffce00e7, + 0xf700e687, + 0x01c54d1c, + 0x00ce1a27, + 0xfece180c, + 0x00efcd7e, + 0xbd5f1ccc, + 0x00cefa0a, + 0xfece180d, + 0x00efcd7e, + 0xe675fece, + 0x18a52600, + 0x1823f0ce, + 0x80c400e6, + 0x00cc9a27, + 0x7efece10, + 0x11bd00ed, + 0xf0ce181c, + 0x001c1823, + 0x1100cc80, + 0xed7efece, + 0x7c037e00, + 0x9f3c06de, + 0x3c08de06, + 0xd73c0ade, + 0x3d10ce0b, + 0xf0c400e6, + 0x0bd68f18, + 0x00dd8f18, + 0x01da8f18, + 0xdf3800e7, + 0x08df380a, + 0x3906df38, + 0x3c3c06de, + 0x08de069f, + 0x3c0ade3c, + 0x0bee06de, + 0x1cf70adf, + 0x06de1800, + 0x1809ee18, + 0x1cf700e6, + 0xf718c607, + 0xde18061c, + 0x08e61806, + 0x7f041cf7, + 0x007f0900, + 0xe006bd08, + 0xfdbe05bd, + 0x152a101c, + 0x1cf709d6, + 0x7f032006, + 0x06bd061c, + 0xfa05bde0, + 0x20101cfc, + 0x08de1877, + 0x240a9c18, + 0x1a06de54, + 0x081809ee, + 0xbd01ef1a, + 0x1cfd0e06, + 0xdcd82b10, + 0xffffc30a, + 0x2708931a, + 0xf708c638, + 0x06bd061c, + 0x06de18e0, + 0x1801ee18, + 0x1cf700e6, + 0xf718c607, + 0xde18061c, + 0x08e61806, + 0xbd041cf7, + 0x06dee006, + 0x1801ee1a, + 0x01ef1a08, + 0xdf0808de, + 0x250a9c08, + 0x1cf75fb6, + 0xe006bd06, + 0x1cf712c6, + 0xe006bd06, + 0x5ffa05bd, + 0xbd061cf7, + 0x5f4fe006, + 0x380adf38, + 0x383808df, + 0xde3906df, + 0x069f3c06, + 0xde3c08de, + 0x0cde3c0a, + 0xee06de3c, + 0x180cdf07, + 0xee1806de, + 0x0adf1809, + 0x7f09007f, + 0x1cf70800, + 0xf714c600, + 0xde18061c, + 0x06e61806, + 0xbd041cf7, + 0x05bde006, + 0x101cfdbe, + 0x09d6102a, + 0xbd061cf7, + 0x05bde006, + 0x101cfcfa, + 0xde185f20, + 0x0a9c1808, + 0x05bd3d24, + 0x0cde18e5, + 0x00df08de, + 0x00d38f18, + 0x1cf68f18, + 0x00e71804, + 0xffc30adc, + 0x08931aff, + 0x04c61d27, + 0xbd061cf7, + 0x14c6e006, + 0xbd061cf7, + 0xde18e006, + 0x18081808, + 0x9c1808df, + 0x5fc3250a, + 0xbd061cf7, + 0x12c6e006, + 0xbd061cf7, + 0x528de006, + 0x061cf75f, + 0x4fe006bd, + 0x0cdf385f, + 0x380adf38, + 0xdf3808df, + 0x06de3906, + 0xbd069f3c, + 0x1cf67306, + 0x2702c505, + 0x205f4f04, + 0x2708c510, + 0xffffcc05, + 0x04c50720, + 0xffcce527, + 0x06df38fe, + 0x3c06de39, + 0x06bd069f, + 0x051cf673, + 0xf62701c4, + 0xdf385f4f, + 0x06de3906, + 0x8d069f3c, + 0x051cf672, + 0xf72740c4, + 0xdf385f4f, + 0x06de3906, + 0x8d069f3c, + 0x061cf65e, + 0xf72701c5, + 0x042602c5, + 0x03205f4f, + 0x38faffcc, + 0xde3906df, + 0x069f3c06, + 0x001cf75f, + 0xf7041c7f, + 0x01c6051c, + 0x5f061cf7, + 0xbd071cf7, + 0x0e8de006, + 0x5f101cfd, + 0xbd061cf7, + 0xdf38e006, + 0x06de3906, + 0x8d069f3c, + 0x051cf616, + 0x042720c5, + 0x07205f4f, + 0xef2710c5, + 0x38fdffcc, + 0xde3906df, + 0x9f3c3c06, + 0x67fece06, + 0xfece00e6, + 0xc400e660, + 0x831a4f03, + 0x08270100, + 0x0200831a, + 0xe5201a27, + 0xe668fece, + 0x041cf700, + 0xe669fece, + 0x06de1800, + 0xce01e718, + 0x16206afe, + 0xe66cfece, + 0x041cf700, + 0xe66dfece, + 0x06de1800, + 0xce01e718, + 0x00e66efe, + 0xe602e718, + 0x071cf700, + 0x1806de18, + 0x1cf702e6, + 0x01e61806, + 0x38051cf7, + 0x3906df38, + 0x9f3c06de, + 0x001cf606, + 0xe764fece, + 0x071cf600, + 0xe763fece, + 0x061cf600, + 0xe762fece, + 0x051cf600, + 0xe761fece, + 0x60fece00, + 0xe7041cf6, + 0xc400e600, + 0xce0b2704, + 0x00e660fe, + 0xf72604c4, + 0xfece0920, + 0xc400e660, + 0x38f72704, + 0xde3906df, + 0x3c3c3c06, + 0x06de069f, + 0x0ec6026f, + 0x1806de18, + 0x183d02a6, + 0x1cc303ed, + 0x0100ce12, + 0x1808183c, + 0x0000ce3c, + 0x188f183c, + 0x05bd00e6, + 0x38383803, + 0x112600dd, + 0xee1a06de, + 0xc38f1803, + 0x8f181b1c, + 0xe71801c6, + 0x06de1800, + 0x18026c18, + 0x03c102e6, + 0x3838b823, + 0x3906df38, + 0x3c3c06de, + 0x069f343c, + 0x016f06de, + 0xde180ec6, + 0x01a61806, + 0x02ed183d, + 0x181b1cc3, + 0x00e6188f, + 0x712601c1, + 0x1806de18, + 0x1cc302ec, + 0x04ed1812, + 0x3c0200ce, + 0xc302ec18, + 0x3637171c, + 0x0400ce18, + 0x06de3c18, + 0x00e604ee, + 0xfd2c04bd, + 0x3838101c, + 0xce422b38, + 0x183c0200, + 0xec1806de, + 0x131cc302, + 0xcd3c3637, + 0x00e604ee, + 0xfd2c04bd, + 0x3838101c, + 0xce222b38, + 0x183c0200, + 0xec1806de, + 0x191cc302, + 0x00ce3637, + 0xee183c06, + 0x00e61804, + 0xfd2c04bd, + 0x3838101c, + 0x6c06de38, + 0xc101e601, + 0x7e032203, + 0x5f4f9007, + 0x38313838, + 0xde3906df, + 0x3c3c3c06, + 0xde069f3c, + 0x0ade3c08, + 0x3c0cde3c, + 0x01e706de, + 0x54545454, + 0x1cc34f54, + 0x188f1808, + 0x03e700e6, + 0x08c502ec, + 0x087e0326, + 0x5801e6eb, + 0x09d710c4, + 0x585801e6, + 0xe7585858, + 0x1880c401, + 0x1809d68f, + 0x1800dd8f, + 0x1801da8f, + 0xc401e68f, + 0x1800dd40, + 0x1801da8f, + 0xc401e68f, + 0x1800dd20, + 0xd701da8f, + 0xe68f180b, + 0x03c45403, + 0x02ec06e7, + 0xdd01c44f, + 0xa60ec608, + 0x0cdd3d06, + 0x0cd308dc, + 0x1cc304ed, + 0xd68f1813, + 0x00e7180b, + 0xc38f0cde, + 0x188f121c, + 0x180100ce, + 0x06de183c, + 0xc304ec18, + 0x3637131c, + 0x00c308dc, + 0x1808dd02, + 0x3c1808de, + 0x04bd00e6, + 0x101cfd2c, + 0x38383838, + 0xdf380cdf, + 0x08df380a, + 0x38383838, + 0xde3906df, + 0x02de3c00, + 0x3c04de3c, + 0x9f3c06de, + 0xf701c606, + 0xffce4e1c, + 0x38006f8f, + 0xdf3806df, + 0x02df3804, + 0x3b00df38, + 0xde3c00de, + 0x04de3c02, + 0x3c06de3c, + 0xb407069f, + 0x0e06bf00, + 0x3806df38, + 0xdf3804df, + 0x00df3802, + 0x3c00de3b, + 0xde3c02de, + 0x06de3c04, + 0x38069f3c, + 0xdf3806df, + 0x02df3804, + 0x3b00df38, + 0xde3c00de, + 0x04de3c02, + 0x3c06de3c, + 0xdf38069f, + 0x04df3806, + 0x3802df38, + 0xde3b00df, + 0x069f3c06, + 0x3906df38, + 0x3c3c06de, + 0x069f343c, + 0xde3c08de, + 0x0cde3c0a, + 0x6f06de3c, + 0x0dd75f01, + 0xdd081ccc, + 0xde04df02, + 0x1800e602, + 0xe71806de, + 0x04ec1805, + 0x08c504de, + 0x0a7e0326, + 0x05e61836, + 0x1803c454, + 0x06de02e7, + 0x05e68f18, + 0x8f1801c4, + 0xdf18054f, + 0x4f01db00, + 0xcc8f0fc4, + 0x15bd0100, + 0xc60bd7f1, + 0xa606de0e, + 0x08dd3d02, + 0xed1b1cc3, + 0x00e68f04, + 0x2d2601c1, + 0x00df184f, + 0x08d301d6, + 0x1806de18, + 0x1cc304ed, + 0x01c68f1c, + 0x06de00e7, + 0x1804ee1a, + 0x1e1cc38f, + 0x01e68f18, + 0xd600e718, + 0x270bd50d, + 0xfbffcc05, + 0x8f182f20, + 0x8f180dd6, + 0x8f0bd68f, + 0x8f1800df, + 0x0dd701da, + 0x04df8f18, + 0x180802de, + 0x6c1806de, + 0x01e61801, + 0x04de02df, + 0x032207c1, + 0x4f9d097e, + 0x0cdf385f, + 0x380adf38, + 0x383808df, + 0x06df3831, + 0x3c06de39, + 0x9f3c3c3c, + 0xe706de06, + 0xf7fec404, + 0xffce4a1c, + 0xde00e78d, + 0xc404e606, + 0xfa585801, + 0x01ca4b1c, + 0xce4b1cf7, + 0x00e78eff, + 0x1806de18, + 0xffce026f, + 0x1800e686, + 0xe71806de, + 0x05ec1806, + 0x052710c5, + 0xe71801c6, + 0x06de1802, + 0x27026d18, + 0x06e618e1, + 0xf64c1cf7, + 0x02c44b1c, + 0xf704e718, + 0xf75f4b1c, + 0xffce4a1c, + 0x04e6188e, + 0xffce00e7, + 0x00e75f8d, + 0xe686ffce, + 0x06de1800, + 0xc403e718, + 0x18032610, + 0x06de02e7, + 0xe826026d, + 0x1cf703e6, + 0x385f4f4c, + 0xdf383838, + 0x06de3906, + 0x069f3c3c, + 0x01c68f18, + 0x01e706de, + 0xe686ffce, + 0x4c1cf700, + 0xbd00e718, + 0x1cf62f08, + 0xf710ca4b, + 0xffce4b1c, + 0xce00e78e, + 0x00e687ff, + 0x1806de18, + 0x01c402e7, + 0xe7180326, + 0x6d06de01, + 0xe6e82601, + 0x4d1cf702, + 0xc44b1cf6, + 0x4b1cf702, + 0xe78effce, + 0x385f4f00, + 0x3906df38, + 0x3c3c06de, + 0x9f343c3c, + 0x3c08de06, + 0x026f06de, + 0x7e03265d, + 0xde18ee0b, + 0x02e61806, + 0x58585858, + 0x01e71858, + 0x10011c18, + 0xbd01e618, + 0x06de610a, + 0x02e6026c, + 0xde2307c1, + 0xde18026f, + 0x02e61806, + 0x58585858, + 0x01e71858, + 0x18011c18, + 0xbd01e618, + 0x06de610a, + 0x02e6026c, + 0xde2307c1, + 0xde18026f, + 0x02e61806, + 0x58585858, + 0x1808ca58, + 0x0abd01e7, + 0x6c06de61, + 0xc102e602, + 0x6fe32307, + 0x06de1802, + 0x5802e618, + 0x58585858, + 0xbd01e718, + 0x06de610a, + 0x02e6026c, + 0xe52307c1, + 0xde187620, + 0x026f1806, + 0xcd081cce, + 0xde1805ef, + 0x05ee1806, + 0x1800e618, + 0xe71806de, + 0x03ec1804, + 0x402708c5, + 0x5404e618, + 0xe71803c4, + 0x03ec1807, + 0xdd01c44f, + 0x0ec68f08, + 0x9600df8f, + 0x07e61801, + 0xc308d33d, + 0x8f18151c, + 0x02e606de, + 0x58585858, + 0x1801e758, + 0x01c400e6, + 0x01e701ea, + 0xe608011c, + 0x610abd01, + 0xcd06de18, + 0xcd0805ee, + 0x6c1805ef, + 0x02e61802, + 0x962307c1, + 0x3808df38, + 0x38313838, + 0xde3906df, + 0x069f3c06, + 0xdd3c08de, + 0x1a5f4f08, + 0x09240893, + 0x0100c301, + 0x2508931a, + 0x08df38f7, + 0x3906df38, + 0x303c06de, + 0xefffc38f, + 0x069f358f, + 0x05e706de, + 0x01ed5f4f, + 0x07e703ed, + 0x05e608e7, + 0x0cc60426, + 0xde1807e7, + 0x066f1806, + 0x06de0ec6, + 0xed3d06a6, + 0x1b1cc309, + 0xe6188f18, + 0x2701c100, + 0x560e7e03, + 0x1809ee1a, + 0x1c1cc38f, + 0xe6188f18, + 0x2701c100, + 0xf60d7e03, + 0x1809ee1a, + 0x1d1cc38f, + 0xe6188f18, + 0x2701c100, + 0x940d7e03, + 0x1cc309ec, + 0x00ce1812, + 0xce3c1802, + 0xd38f0300, + 0x183c8f06, + 0x180000ce, + 0x00e68f3c, + 0xfd0305bd, + 0x3838101c, + 0x7e032a38, + 0xde18560e, + 0x03e61806, + 0xe7180fc4, + 0x03e7180b, + 0xc404e618, + 0x0ce7180f, + 0xde04e718, + 0x09ee1a06, + 0x1cc38f18, + 0xe68f1815, + 0x180de70b, + 0x112600e1, + 0x1809ee1a, + 0x161cc38f, + 0x0ce68f18, + 0x2700e118, + 0x06de180d, + 0xc105e618, + 0x18032601, + 0x0ec6076f, + 0x06a606de, + 0xc310ed3d, + 0x188f151c, + 0xe61806de, + 0xde00e70d, + 0x10ee1a06, + 0x1cc38f18, + 0xe68f1816, + 0x530e7e04, + 0x1806de18, + 0x1cc309ec, + 0x0100ce12, + 0x0806de3c, + 0x183c0808, + 0x180000ce, + 0x00e68f3c, + 0xfd0305bd, + 0x3838101c, + 0x7e032a38, + 0x06de560e, + 0x0fc403e6, + 0xde1803e7, + 0x09eecd06, + 0x151cc38f, + 0x0ee7188f, + 0x0a2700e1, + 0xc105e618, + 0x18032601, + 0x0ec6076f, + 0x1806de18, + 0xc33d06a6, + 0x8f18151c, + 0x0ee606de, + 0xde185d20, + 0x09ec1806, + 0xce121cc3, + 0xde3c0100, + 0x08080806, + 0x00ce183c, + 0x8f3c1801, + 0x05bd00e6, + 0x101cfd03, + 0x2b383838, + 0xe606de39, + 0xe70fc403, + 0x06de1803, + 0x8f09eecd, + 0x8f161cc3, + 0xe10fe718, + 0x180a2700, + 0x01c105e6, + 0x6f180326, + 0x180ec607, + 0xa61806de, + 0x1cc33d06, + 0xde8f1816, + 0x180fe606, + 0xde1800e7, + 0x066c1806, + 0xc106e618, + 0x7e032203, + 0xe618b80c, + 0x260cc107, + 0x1801c607, + 0x062008e7, + 0x1806de18, + 0x06de076c, + 0x0326086d, + 0x30b20c7e, + 0x1100c38f, + 0xdf38358f, + 0x06de3906, + 0x3c3c3c3c, + 0xde069f3c, + 0x0ade3c08, + 0x3c0cde3c, + 0x08e706de, + 0x04e7036f, + 0xcd06de18, + 0xc38f03ee, + 0xe68f081c, + 0x06e71800, + 0x1803c454, + 0xe61801e7, + 0x58585808, + 0x0bd75858, + 0x4f05ec18, + 0x0cdd01c4, + 0xa6180ec6, + 0x08dd3d01, + 0x08d30cdc, + 0x18151cc3, + 0x00e6188f, + 0x02e706de, + 0x8f1801c4, + 0x8f180bd6, + 0x8f1800dd, + 0x0bd701da, + 0x0e6d8f18, + 0x02e62c26, + 0xc4585858, + 0x1800dd10, + 0x1801da8f, + 0x5802e68f, + 0x00dd08c4, + 0x01da8f18, + 0x02e68f18, + 0x02c45454, + 0x8f1800dd, + 0x0bd701da, + 0x0bd68f18, + 0xce610abd, + 0x00cc7efe, + 0x3800ed12, + 0xdf380cdf, + 0x08df380a, + 0x38383838, + 0x3906df38, + 0x3c3c06de, + 0xde069f34, + 0x02dd3c08, + 0xc44b1cf6, + 0x06de18fd, + 0x1801e718, + 0x188effce, + 0x06de00e7, + 0x585809e6, + 0xfa585858, + 0x1cf74a1c, + 0x8dffce4a, + 0x06de00e7, + 0x01ca01e6, + 0x184b1cf7, + 0x026f00e7, + 0xe686ffce, + 0x2710c400, + 0x1801c608, + 0xe71806de, + 0x06de1802, + 0x27026d18, + 0xf700e6e7, + 0xffce4c1c, + 0xf700e687, + 0x02de4d1c, + 0x3a09e618, + 0xf600e75f, + 0x02c44c1c, + 0x09d75858, + 0x1cf600e7, + 0x1804c44c, + 0x1809d68f, + 0x1800dd8f, + 0xd701da8f, + 0xd68f1809, + 0xf600e709, + 0x08c44c1c, + 0x00dd5454, + 0x01da8f18, + 0x8f1809d7, + 0x00e709d6, + 0xc44d1cf6, + 0xe709da01, + 0x1cf75f00, + 0x4a1cf74b, + 0xe78effce, + 0x8dffce00, + 0xffce00e7, + 0x1800e686, + 0xe71806de, + 0x2610c403, + 0x02e71803, + 0x026d06de, + 0x03e6e826, + 0x4f4c1cf7, + 0x08df385f, + 0xdf383138, + 0x06de3906, + 0x343c3c3c, + 0x06de069f, + 0x026f01e7, + 0x1803e75f, + 0x1a081cce, + 0x06de04ef, + 0x1804ee1a, + 0x08c400e6, + 0x03e62b27, + 0xffce2126, + 0xf700e687, + 0x01c54d1c, + 0x06de0f27, + 0x0abd8f08, + 0x1801c6fa, + 0xe71806de, + 0x6d06de03, + 0x18df2703, + 0x6f1806de, + 0x1a06de03, + 0x081804ee, + 0x6c04ef1a, + 0xc102e602, + 0x38b72307, + 0xdf383138, + 0x06de3906, + 0x9f3c3c3c, + 0xe706de06, + 0xc6026f01, + 0xa606de0e, + 0x03ed3d02, + 0x181b1cc3, + 0x00e6188f, + 0x502601c1, + 0x1803ee1a, + 0x1c1cc38f, + 0xe6188f18, + 0x2601c100, + 0x03ee1a16, + 0x1cc38f18, + 0xe68f181e, + 0x18343701, + 0x0ebd00e6, + 0xde31318e, + 0x03ee1a06, + 0x1cc38f18, + 0x188f181d, + 0x01c100e6, + 0xee1a1626, + 0xc38f1803, + 0x8f181f1c, + 0x343701e6, + 0xbd00e618, + 0x31318e0e, + 0x026c06de, + 0x03c102e6, + 0x38389123, + 0x3906df38, + 0x3c3c06de, + 0xde069f3c, + 0x0ade3c08, + 0x8dffce3c, + 0xcc01001c, + 0x36376000, + 0x3700fecc, + 0xbdfdc636, + 0x1cfd5715, + 0x5b1cff5d, + 0x378c00cc, + 0x375f4f36, + 0x6000cc36, + 0xfecc3637, + 0xc6363700, + 0xf814bdfd, + 0xfc06de18, + 0xed18591c, + 0x571cfc03, + 0x1801ed18, + 0x0add03ec, + 0xdd01ec18, + 0x840adc08, + 0x03ed18df, + 0xed1808dc, + 0x03eecd01, + 0x01eecd3c, + 0x6400cc3c, + 0xfecc3637, + 0xc6363700, + 0xf814bdfd, + 0xec72fece, + 0x6f0cbd00, + 0x3c591cfe, + 0x3c571cfe, + 0x376400cc, + 0x00fecc36, + 0xfdc63637, + 0xfef814bd, + 0xfe3c5d1c, + 0xcc3c5b1c, + 0x36376000, + 0x3700fecc, + 0xbdfdc636, + 0xce18f814, + 0x1d188dff, + 0xf0ce0100, + 0xfd00ec0e, + 0xfe18551c, + 0xfece551c, + 0xdd00ec70, + 0xd38f1800, + 0xce8f1800, + 0xef1a16f0, + 0xc38f3000, + 0x358f2400, + 0x380adf38, + 0x383808df, + 0x3906df38, + 0x3c3c06de, + 0x9f3c3c3c, + 0x3c08de06, + 0x183c0ade, + 0x5f4f06de, + 0x1803ed18, + 0xed1801ed, + 0x05ed1807, + 0x1c8dffce, + 0xfece0100, + 0x2700e676, + 0xbd137e03, + 0x374c00cc, + 0x00fecc36, + 0xfdc63637, + 0x185715bd, + 0xed1806de, + 0x01efcd03, + 0xdd03ec18, + 0x01ec180a, + 0x0adc08dd, + 0xca8f08de, + 0x08df8f02, + 0xdc03ed18, + 0x01ed1808, + 0x3c03eecd, + 0x3c01eecd, + 0x374c00cc, + 0x00fecc36, + 0xfdc63637, + 0xccf814bd, + 0x36378400, + 0x3700fecc, + 0xbdfdc636, + 0xde185715, + 0x07ed1806, + 0x1805efcd, + 0x0add07ec, + 0xdd05ec18, + 0xca0adc08, + 0x07ed1880, + 0xed1808dc, + 0x07eecd05, + 0x05eecd3c, + 0x8400cc3c, + 0xfecc3637, + 0xc6363700, + 0xf814bdfd, + 0x3701f0cc, + 0x375f4f36, + 0x1800cc36, + 0xfecc3637, + 0xc6363700, + 0xf814bdfd, + 0x3a20c630, + 0x77fece35, + 0x342600e6, + 0x370100cc, + 0x375f4f36, + 0x01f0cc36, + 0xfccc3637, + 0xc6363700, + 0xf814bdfd, + 0x36375f4f, + 0x00cc3637, + 0xcc363718, + 0x363700fe, + 0x14bdfdc6, + 0xc38f30f8, + 0x358f1000, + 0x1806de18, + 0x0add07ec, + 0xdd05ec18, + 0xc40adc08, + 0x07ed187f, + 0xed1808dc, + 0x07eecd05, + 0x05eecd3c, + 0x8400cc3c, + 0xfecc3637, + 0xc6363700, + 0xf814bdfd, + 0x1806de18, + 0x0add03ec, + 0xdd01ec18, + 0xde0adc08, + 0xfdc48f08, + 0x1808df8f, + 0x08dc03ed, + 0xcd01ed18, + 0xcd3c03ee, + 0xcc3c01ee, + 0x36374c00, + 0x3700fecc, + 0xbdfdc636, + 0xde18f814, + 0x03ec1806, + 0xec180add, + 0xdc08dd01, + 0x18078a0a, + 0x08dc03ed, + 0xcd01ed18, + 0xcd3c03ee, + 0xcc3c01ee, + 0x36374c00, + 0x3700fecc, + 0xbdfdc636, + 0x8f30f814, + 0x8f1800c3, + 0x6000cc35, + 0xfecc3637, + 0xc6363700, + 0x5715bdfd, + 0xff5d1cfd, + 0x00cc5b1c, + 0x4f36378c, + 0xcc36375f, + 0x36376000, + 0x3700fecc, + 0xbdfdc636, + 0x00ccf814, + 0xcc363764, + 0x363700fe, + 0x15bdfdc6, + 0x591cfd57, + 0xfe571cff, + 0xfe3c5d1c, + 0xcc3c5b1c, + 0x36376000, + 0x3700fecc, + 0xbdfdc636, + 0xffcef814, + 0x01001d8d, + 0x1c24f0ce, + 0xf0ce0300, + 0xfd00ec0e, + 0xfe18551c, + 0xfece551c, + 0xdd00ec70, + 0xd38f1800, + 0xce8f1800, + 0xef1a16f0, + 0x23f0ce00, + 0x3080001c, + 0x1800c38f, + 0xdf38358f, + 0x08df380a, + 0x38383838, + 0x3906df38, + 0x8a8cffb6, + 0x267f817f, + 0x038639f7, + 0x398cffb7, + 0xffb70186, + 0xa618398c, + 0x81048403, + 0x86042704, + 0x8604200f, + 0xa70020f0, + 0xce183905, + 0xe6180038, + 0x80ffce08, + 0xec1804e7, + 0xe703a700, + 0x02ec1802, + 0xf8c401a7, + 0x00e702ca, + 0x02cccc8d, + 0xe706a700, + 0x06ec1807, + 0x08e709a7, + 0xa704ec18, + 0x860ae70b, + 0x0ba71802, + 0x988da48d, + 0x38ce1839, + 0x08e61800, + 0xe780ffce, + 0x00ec1804, + 0x02e703a7, + 0xa702ec18, + 0xcaf8c401, + 0x8d00e704, + 0x0002cc8d, + 0x07e706a7, + 0xa7180486, + 0x6c14bd0b, + 0x395c14bd, + 0x343c06de, + 0x08de069f, + 0x3c0ade3c, + 0xde3c0cde, + 0x06de3c0e, + 0xde1801e7, + 0x08ec1806, + 0xec180add, + 0x1808dd06, + 0x0edd0cec, + 0xdd0aec18, + 0x0838ce0c, + 0xe701e618, + 0x0038ce00, + 0x02ed0adc, + 0x00ed08dc, + 0xdc0438ce, + 0xdc02ed0e, + 0xbd00ed0c, + 0xdf388614, + 0x0cdf380e, + 0x380adf38, + 0x383108df, + 0xde3906df, + 0x9f343c06, + 0x3c08de06, + 0xde3c0ade, + 0x0ede3c0c, + 0xe706de3c, + 0x06de1801, + 0xdd08ec18, + 0x06ec180a, + 0x38ce08dd, + 0x01e61808, + 0x38ce00e7, + 0xed0adc00, + 0xed08dc02, + 0xc514bd00, + 0xdd83ffcc, + 0xde0edc02, + 0x00ce180c, + 0x183c8d08, + 0xde1804df, + 0x00ea1802, + 0x0cdf0edd, + 0xdf180918, + 0x1800de00, + 0xde1802df, + 0x7fff8c04, + 0x0cded722, + 0xdf183818, + 0x1838180e, + 0x38180cdf, + 0x180adf18, + 0x08df1838, + 0x18381831, + 0x183906df, + 0x1fc44f8f, + 0x09278f18, + 0x49598f05, + 0x2609188f, + 0x064f39f7, + 0x10008c39, + 0x008c0a2c, + 0x05042700, + 0x39fc2609, + 0x0e395f4f, + 0x00fc203e, + 0x00ffffc0, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00007400, + 0x07070000, + 0x00010f0f, + 0x75000000, + 0x00000000, + 0x0f0f0707, + 0x00000000, + 0x00007600, + 0x07070000, + 0x00000f0f, + 0x77000000, + 0x00000000, + 0x0f0f0707, + 0x00000000, + 0x00000000, + 0x01000100, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 +}; + +UINT32 DataBlock1[] = { + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41094109, + 0x41095c09, + 0x41094109, + 0xfb084109, + 0x41092009, + 0x00020002, + 0x00020002 +}; + +SMU_FIRMWARE_BLOCK FmBlockArray[] = { + { + 0x200, + 0x51a, + &DataBlock0[0] + }, + { + 0xffc0, + 0x10, + &DataBlock1[0] + } +}; + +SMU_FIRMWARE_HEADER Fm = { + { + 0x0, 0x0 + }, + 2, + &FmBlockArray[0] +}; +#endif + diff --git a/src/vendorcode/amd/cimx/rd890/Makefile.inc b/src/vendorcode/amd/cimx/rd890/Makefile.inc new file mode 100644 index 000000000000..8a05570f6d28 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/Makefile.inc @@ -0,0 +1,118 @@ +#***************************************************************************** +# +# Copyright (C) 2012 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of Advanced Micro Devices, Inc. nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#***************************************************************************** + +# CIMX Root directory +CIMX_ROOT = $(src)/vendorcode/amd/cimx + +NB_CIMX_INC = -I$(src)/mainboard/$(MAINBOARDDIR) +NB_CIMX_INC += -I$(src)/northbridge/amd/cimx/rd890 +NB_CIMX_INC += -I$(CIMX_ROOT)/rd890 + +romstage-y += amdAcpiIvrs.c +romstage-y += amdAcpiLib.c +romstage-y += amdAcpiMadt.c +romstage-y += amdDebugOutLib.c +romstage-y += amdSbLib.c +#romstage-y += nbDispatcher.c +romstage-y += nbEventLog.c +romstage-y += nbHtInit.c +romstage-y += nbHtInterface.c +romstage-y += nbInit.c +romstage-y += nbInitializer.c +romstage-y += nbInterface.c +romstage-y += nbIoApic.c +romstage-y += nbIommu.c +romstage-y += nbLib.c +romstage-y += nbMaskedMemoryInit.c +romstage-y += nbMiscInit.c +romstage-y += nbModuleInfo.c +romstage-y += nbPcieAspm.c +romstage-y += nbPcieCplBuffers.c +romstage-y += nbPcieEarlyHwLib.c +romstage-y += nbPcieHotplug.c +romstage-y += nbPcieInitEarly.c +romstage-y += nbPcieInitLate.c +romstage-y += nbPcieLateHwLib.c +romstage-y += nbPcieLib.c +romstage-y += nbPcieLinkWidth.c +romstage-y += nbPciePllControl.c +romstage-y += nbPciePortRemap.c +#romstage-y += nbPcieRecovery.c +romstage-y += nbPcieSb.c +romstage-y += nbPcieWorkarounds.c +romstage-y += nbPowerOnReset.c +#romstage-y += nbRecovery.c +#romstage-y += nbRecoveryInitializer.c +romstage-y += nbMaskedMemoryInit32.S + +ramstage-y += amdAcpiIvrs.c +ramstage-y += amdAcpiLib.c +ramstage-y += amdAcpiMadt.c +ramstage-y += amdDebugOutLib.c +ramstage-y += amdSbLib.c +#ramstage-y += nbDispatcher.c +ramstage-y += nbEventLog.c +ramstage-y += nbHtInit.c +ramstage-y += nbHtInterface.c +ramstage-y += nbInit.c +ramstage-y += nbInitializer.c +ramstage-y += nbInterface.c +ramstage-y += nbIoApic.c +ramstage-y += nbIommu.c +ramstage-y += nbLib.c +ramstage-y += nbMaskedMemoryInit.c +ramstage-y += nbMiscInit.c +ramstage-y += nbModuleInfo.c +ramstage-y += nbPcieAspm.c +ramstage-y += nbPcieCplBuffers.c +ramstage-y += nbPcieEarlyHwLib.c +ramstage-y += nbPcieHotplug.c +ramstage-y += nbPcieInitEarly.c +ramstage-y += nbPcieInitLate.c +ramstage-y += nbPcieLateHwLib.c +ramstage-y += nbPcieLib.c +ramstage-y += nbPcieLinkWidth.c +ramstage-y += nbPciePllControl.c +ramstage-y += nbPciePortRemap.c +#ramstage-y += nbPcieRecovery.c +ramstage-y += nbPcieSb.c +ramstage-y += nbPcieWorkarounds.c +ramstage-y += nbPowerOnReset.c +#ramstage-y += nbRecovery.c +#ramstage-y += nbRecoveryInitializer.c +ramstage-y += nbMaskedMemoryInit32.S + +NB_CIMX_CFLAGS = +export CIMX_ROOT +export NB_CIMX_INC +export NB_CIMX_CFLAGS +CC := $(CC) $(NB_CIMX_CFLAGS) $(NB_CIMX_INC) + +####################################################################### + diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c new file mode 100644 index 000000000000..c710bf06fe97 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.c @@ -0,0 +1,236 @@ +/** + * @file + * + * ACPI common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdAcpiLib.h" +#include "amdAcpiIvrs.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get first block entry in an IVRS (IOMMU) table + * + * + * + * @param[in] IoVirtualizationEntryType Type of IVHD or IVMD entry (IVHD = 0x10, IVMD = 0x20-0x22, any = 0xFF)) + * @param[in] Pointer to IVRS ACPI table + * + */ +VOID* +LibAmdGetFirstIvrsBlockEntry ( + IN UINT8 IoVirtualizationEntryType, + IN VOID *IvrsPtr + ) +{ + // Start at IVRS pointer + 48 (48 is always the size of IVRS header) + UINT8* BlockPtr; + // If our pointer is not to an IVRS, return error + +// if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != 'SRVI') return NULL; + if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != Int32FromChar ('S', 'R', 'V', 'I')) return NULL; + BlockPtr = (UINT8*)IvrsPtr + 48; + // Search each entry incrementing by it's size field in offset 2 until + // we reach the end of the IVRS + do { + if (*BlockPtr == IoVirtualizationEntryType) { + return BlockPtr; + } + BlockPtr += *((UINT16*) (BlockPtr + 2)); + } while (BlockPtr < (UINT8*)IvrsPtr + ((DESCRIPTION_HEADER*)IvrsPtr)->Length); + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get next block entry in an IVRS (IOMMU) table + * + * + * + * @param[in] IoVirtualizationEntryType Type of IVHD or IVMD entry (IVHD = 0x10, IVMD = 0x20-0x22, any = 0xFF)) + * @param[in] CurrentStructurePtr Pointer to current IVHD or IVMD block in IVRS + * @param[in] IvrsPtr Pointer to IVRS table + * + */ + +VOID* +LibAmdGetNextIvrsBlockEntry ( + IN UINT8 IoVirtualizationEntryType, + IN VOID* CurrentStructurePtr, + IN VOID* IvrsPtr + ) +{ + // Start at the current device entry + // Start searching after the current entry + UINT8* BlockPtr; + // If our pointer is not to an IVRS, return error +// if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != 'SRVI') return NULL; + if (((DESCRIPTION_HEADER*)IvrsPtr)->Signature != Int32FromChar ('S', 'R', 'V', 'I')) return NULL; + + BlockPtr = (UINT8*)CurrentStructurePtr + *((UINT16*) ((UINT8*)CurrentStructurePtr + 2)); + + // Search each entry incrementing by it's size field in offset 2 until + // we reach the end of the IVRS + while (BlockPtr < ((UINT8*)IvrsPtr + ((DESCRIPTION_HEADER*)IvrsPtr)->Length)) { + if (*BlockPtr == IoVirtualizationEntryType) { + return BlockPtr; + } + BlockPtr += *((UINT16*) (BlockPtr + 2)); + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get pointer to first Device Entry of an IVHD + * + * + * + * @param[in] IoVirtualizationEntryType Type of IVHD device entry to search for. (0xFF returns next entry of any type) + * Typical values: 4 byte entries (0-63), 8 byte entries (64-127) + * @param[in] IvhdBlockPtr Pointer to current IVHD block + * + */ +VOID* +LibAmdGetFirstDeviceEntry ( + IN UINT8 DeviceEntryType, + IN VOID* IvhdBlockPtr + ) +{ + // Start at IVHD pointer + 24 (24 is always the size of IVHD header) + // Not much we can do do validate an IVHD input, the only field we know for sure is the type + UINT8 *EntryPtr; + UINT16 IvhdSize; + EntryPtr = (UINT8*)IvhdBlockPtr + 24; + IvhdSize = *(UINT16*) ((UINT8*)IvhdBlockPtr + 2); + // Search each entry incrementing by it's type field until the end of the IVHD + // Types 0-63 are 4 byte size, 64-127 are 8 byte size + do { + if (*EntryPtr == DeviceEntryType) { + return EntryPtr; + } + if (*EntryPtr < 64) { + EntryPtr += 4; + } else if ((*EntryPtr >= 64) && (*EntryPtr < 128)) { + EntryPtr += 8; + } else { + ASSERT (TRUE); + return NULL; + } + } while (EntryPtr < ((UINT8*)IvhdBlockPtr + IvhdSize)); + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get pointer to Next Device Entry of an IVHD + * + * + * + * + * @param[in] IoVirtualizationEntryType Type of IVHD entry. (0xFF returns next entry of any type) + * Typical values: 4 byte entries (0-63), 8 byte entries (64-127) + * @param[in] CurrentStructurePtr Pointer to current device entry in IVHD block + * @param[in] IvhdBlockPtr Pointer to current IVHD block + */ +VOID* +LibAmdGetNextDeviceEntry ( + IN UINT8 DeviceEntryType, + IN VOID* CurrentDeviceEntry, + IN VOID* IvhdBlockPtr + ) +{ + UINT8 *EntryPtr; + UINT16 IvhdSize; + // Start at IVHD pointer + 24 (24 is always the size of IVHD header) + // Not much we can do do validate an IVHD input, the only field we know for sure is the type + EntryPtr = CurrentDeviceEntry; + + if ((*EntryPtr != 0) && (*EntryPtr < 64)) { + EntryPtr += 4; + } else if ((*EntryPtr >= 64) && (*EntryPtr < 128)) { + EntryPtr += 8; + } + IvhdSize = *(UINT16*) ((UINT8*)IvhdBlockPtr + 2); + // Search each entry incrementing by it's type field until the end of the IVHD + // Types 0-63 are 4 byte size, 64-127 are 8 byte size + while (EntryPtr < ((UINT8*)IvhdBlockPtr + IvhdSize)) { + if (*EntryPtr == DeviceEntryType) { + return EntryPtr; + } + if (*EntryPtr < 64) { + EntryPtr += 4; + } else if ((*EntryPtr >= 64) && (*EntryPtr < 128)) { + EntryPtr += 8; + } else { + ASSERT (TRUE); + return NULL; + } + } + return NULL; +}
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h new file mode 100644 index 000000000000..4d62c17319e0 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdAcpiIvrs.h @@ -0,0 +1,77 @@ +/** + * @file + * + * ACPI common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _AMDACPIIVRS_H_ +#define _AMDACPIIVRS_H_ + +//#ifndef ASSERT +//#define ASSERT +//#endif + + +VOID* +LibAmdGetFirstIvrsBlockEntry ( + IN UINT8 IoVirtualizationEntryType, + IN VOID* IvrsPtr +); + +VOID* +LibAmdGetNextIvrsBlockEntry ( + IN UINT8 IoVirtualizationEntryType, + IN VOID* CurrentStructurePtr, + IN VOID* IvrsPtr +); + +VOID* +LibAmdGetFirstDeviceEntry ( + IN UINT8 DeviceEntryType, + IN VOID* IvhdBlockPtr +); + +VOID* +LibAmdGetNextDeviceEntry ( + IN UINT8 DeviceEntryType, + IN VOID* CurrentDeviceEntry, + IN VOID* IvhdBlockPtr +); +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiLib.c b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.c new file mode 100644 index 000000000000..60b5ffe71b04 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.c @@ -0,0 +1,186 @@ +/** + * @file + * + * ACPI common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdAcpiLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get ACPI table. + * + * + * + * @param[in] Signature ACPI table signature + * + */ + +AGESA_STATUS +LibAmdGetAcpiTable ( + IN UINT32 Signature, + IN VOID **TablePtr, + IN UINTN *TableHandle + ) +{ + UINT32 i; + UINT32* RsdPtr; + UINT32* Rsdt; + DESCRIPTION_HEADER* CurrentTable; + + RsdPtr = (UINT32*) (UINTN)0xe0000; + Rsdt = NULL; + + do { +// if (*RsdPtr == ' DSR' && *(RsdPtr + 1) == ' RTP') { + if ((*RsdPtr == Int32FromChar (' ', 'D', 'S', 'R')) && (*(RsdPtr+1) == Int32FromChar (' ', 'R', 'T', 'P'))) { + Rsdt = (UINT32*) (UINTN) (((RSDP*)RsdPtr)->RsdtAddress); + break; + } + RsdPtr += 4; + } while (RsdPtr <= (UINT32*) ((UINTN)0xffff0)); + if (Rsdt != NULL && LibAmdGetAcpiTableChecksum (Rsdt) == 0) { + for (i = 0; i < (((DESCRIPTION_HEADER*)Rsdt)->Length - sizeof (DESCRIPTION_HEADER)) / 4; i++) { + CurrentTable = (DESCRIPTION_HEADER*) (UINTN)*(UINT32*) ((UINT8*)Rsdt + sizeof (DESCRIPTION_HEADER) + i*4); + if (CurrentTable->Signature == Signature) { + *TablePtr = CurrentTable; + return AGESA_SUCCESS; + } + } + } + return AGESA_UNSUPPORTED; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set ACPI table. + * + * + * + * @param[in] Signature ACPI table signature + * + */ + +AGESA_STATUS +LibAmdSetAcpiTable ( + IN VOID *TablePtr, + IN BOOLEAN Checksum, + IN UINTN *TableHandle + ) +{ + if (Checksum) { + LibAmdUpdateAcpiTableChecksum (TablePtr); + } + return AGESA_SUCCESS; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Get ACPI table checksum + * + * + * + * @param[in] Pointer to ACPI table + * + */ + +UINT8 +LibAmdGetAcpiTableChecksum ( + IN VOID *TablePtr + ) +{ + UINT32 i; + UINT8 Checksum; + + Checksum = 0; + + for (i = 0; i < ((DESCRIPTION_HEADER*)TablePtr)->Length; i++) { + Checksum = Checksum + *(UINT8*) ((UINT8*)TablePtr + i); + } + return Checksum; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Update ACPI table checksum + * + * + * + * @param[in] Pointer to ACPI table + * + */ + +VOID +LibAmdUpdateAcpiTableChecksum ( + IN VOID *TablePtr + ) +{ + UINT8 Checksum; + Checksum = 0; + ((DESCRIPTION_HEADER*)TablePtr)->Checksum = 0; + Checksum = LibAmdGetAcpiTableChecksum (TablePtr); + ((DESCRIPTION_HEADER*)TablePtr)->Checksum = 0x100 - Checksum; +} diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiLib.h b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.h new file mode 100644 index 000000000000..46ad04faea51 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdAcpiLib.h @@ -0,0 +1,136 @@ +/** + * @file + * + * ACPI common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _AMDACPILIB_H_ +#define _AMDACPILIB_H_ + +#ifndef ASSERT + #define ASSERT +#endif + +#pragma pack(push, 1) + +///Header for RSDP table +typedef struct _RSDP { + UINT64 Signature; ///< signature + UINT8 Checksum; ///< 8 bit checksum + UINT8 OEMID[6]; ///< OEM identifier + UINT8 Revision; ///< revision + UINT32 RsdtAddress; ///< pointer to rsdt + UINT32 Length; ///< length of RSDP + UINT64 XsdtAddress; ///< pointer to xsdt + UINT8 ExtendedChecksum; ///< checksum of xsdt + UINT8 Reserved[3]; ///< reserved +} RSDP; + +///Header for general ACPI table +typedef struct _DESCRIPTION_HEADER { + UINT32 Signature; ///< signature + UINT32 Length; ///< length + UINT8 Revision; ///< revision + UINT8 Checksum; ///< 8 bit checksum + UINT8 OEMID[6]; ///< OEM identifier + UINT8 OEMTableID[8]; ///< OEM table identifier + UINT32 OEMRevision; ///< OEM revision + UINT32 CreatorID; ///< table creator identifier + UINT32 CreatorRevision; ///< table revision +} DESCRIPTION_HEADER; + +///IO APIC struct in MADT table +typedef struct { + UINT8 Type; ///< type + UINT8 Length; ///< length + UINT8 ApicId; ///< Apic Id + UINT8 Reserved; ///< reserved + UINT32 IoApicBase; ///< IO APIC base address + UINT32 GlobalInterruptBase; ///< Global Interrupt Base +} MADT_IO_APIC_STRUCT; + +///Local APIC struct in MADT table +typedef struct { + UINT8 Type; ///< type + UINT8 Length; ///< length + UINT8 AcpiProcessorId; ///< ACPI Processor ID + UINT8 ApicId; ///< Apic Id + UINT32 Flags; ///< Flags +} MADT_LOCAL_APIC_STRUCT; + +///Local SAPIC struct in MADT table +typedef struct { + UINT8 Type; ///< type + UINT8 Length; ///< length + UINT8 ApicId; ///< Apic Id + UINT8 Reserved; ///< reserved + UINT32 GlobalInterruptBase; ///< Global Interrupt Base + UINT64 IoApicBase; ///< IO SAPIC base address +} MADT_IO_SAPIC_STRUCT; + +#pragma pack(pop) + +AGESA_STATUS +LibAmdSetAcpiTable ( + IN VOID *TablePtr, + IN BOOLEAN Checksum, + IN UINTN *TableHandle + ); + +AGESA_STATUS +LibAmdGetAcpiTable ( + IN UINT32 Signature, + IN VOID **TablePtr, + IN UINTN *TableHandle + ); + + +VOID +LibAmdUpdateAcpiTableChecksum ( + IN VOID* TablePtr +); + +UINT8 +LibAmdGetAcpiTableChecksum ( + IN VOID* TablePtr +); + + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c new file mode 100644 index 000000000000..daf2c1feb358 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.c @@ -0,0 +1,148 @@ +/** + * @file + * + * ACPI common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdAcpiLib.h" +#include "amdAcpiMadt.h" +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get first block entry in an IVRS (IOMMU) table + * + * + * + * @param[in] StructureType Type of structure entry to find (APIC = 1, 0xFF = next structure) + * @param[in] MadtPtr Pointer to MADT ACPI table + * + */ + +VOID* +LibAmdGetFirstMadtStructure ( + IN UINT8 StructureType, + IN VOID *MadtPtr + ) +{ + // Start at MADT pointer + 48 (48 is always the size of IVRS header) + UINT8* BlockPtr; + + // If our pointer is not to an IVRS, return error +// if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != 'CIPA') { + if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != Int32FromChar ('C', 'I', 'P', 'A')) { + return NULL; + } + BlockPtr = (UINT8*)MadtPtr + 44; + + // Search each entry incrementing by it's size field in offset 2 until + // we reach the end of the IVRS + do { + if (*BlockPtr == StructureType) { + return BlockPtr; + } + BlockPtr += *(BlockPtr + 1); + } while (BlockPtr < (UINT8*)MadtPtr + ((DESCRIPTION_HEADER*)MadtPtr)->Length); + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get next block entry in an IVRS (IOMMU) table + * + * + * + * @param[in] StructureType Type of structure entry to find (APIC = 1, ..., 0xFF = next structure) + * @param[in] CurrentStructurePtr Pointer to current structure in IVRS + * @param[in] MadtPtr Pointer to MADT ACPI table + * + */ + +VOID* +LibAmdGetNextMadtStructure ( + IN UINT8 StructureType, + IN VOID *CurrentStructurePtr, + IN VOID *MadtPtr + ) +{ + UINT8 *BlockPtr; + BlockPtr = (UINT8*)CurrentStructurePtr + (*(UINT8*) ((UINT8*)CurrentStructurePtr + 1)); + + // If our pointer is not to an IVRS, return error +// if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != 'CIPA') { + if (((DESCRIPTION_HEADER*)MadtPtr)->Signature != Int32FromChar ('C', 'I', 'P', 'A')) { + return NULL; + } + + // Search each entry incrementing by it's size field in offset 2 until + // we reach the end of the IVRS + while (BlockPtr < ((UINT8*)MadtPtr + ((DESCRIPTION_HEADER*)MadtPtr)->Length)) { + if (*BlockPtr == StructureType) { + return BlockPtr; + } + BlockPtr += *(BlockPtr + 1); + } + return NULL; +} diff --git a/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h new file mode 100644 index 000000000000..9f0aa73b5af5 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdAcpiMadt.h @@ -0,0 +1,66 @@ +/** + * @file + * + * ACPI common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _AMDACPIMADT_H_ +#define _AMDACPIMADT_H_ + +//#ifndef ASSERT +//#define ASSERT +//#endif + + + +VOID* +LibAmdGetFirstMadtStructure ( + IN UINT8 StructureType, + IN VOID* MadtPtr +); + +VOID* +LibAmdGetNextMadtStructure ( + IN UINT8 StructureType, + IN VOID* CurrentStructurePtr, + IN VOID* MadtPtr +); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c new file mode 100644 index 000000000000..f40852b7e5f6 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.c @@ -0,0 +1,436 @@ +/** + * @file + * + * Debug out functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "amdDebugOutLib.h" +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define COM_BASE_ADDRESS 0x3f8 +#define DIVISOR 115200 +#define LF 0x0a +#define CR 0x0d + +typedef CHAR8 *va_list; +#ifndef _INTSIZEOF +#define _INTSIZEOF(n)( (sizeof(n) + sizeof(UINTN) - 1) & ~(sizeof(UINTN) - 1) ) +#endif +#ifndef va_start +#define va_start(ap, v) ( ap = (va_list)&(v) + _INTSIZEOF(v) ) +#endif +#ifndef va_arg +#define va_arg(ap, t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) +#endif +#ifndef va_end +#define va_end(ap) ( ap = (va_list)0 ) +#endif + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +typedef struct { + UINT8 Index; + CHAR8 Buffer[256]; +} StringBuffer; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +VOID +SendByteToBuffer ( + IN OUT StringBuffer *Buffer, + IN CHAR8 Data + ); + +VOID +SendStringToBuffer ( + OUT StringBuffer *Buffer, + IN CHAR8 *pstr + ); + +VOID +SendBufferToDebugOut ( + IN CHAR8* Buffer + ); + +VOID +ItoA ( + IN UINT32 Value, + IN UINTN Radix, + OUT CHAR8 *pstr + ); + +VOID +SendBufferToHdtOut ( + IN CHAR8* Buffer + ); + +VOID +SendBufferToSerialOut ( + IN CHAR8* Buffer + ); + +VOID +InitDebugOut (VOID); + +VOID +InitSerialOut (VOID); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Send format string to debug out + * + * + * + * @param[in] pConfig + * + */ + +VOID +LibAmdTraceDebug ( + IN UINT32 Level, + IN CHAR8 *Format, + IN ... + ) +{ + CHAR8 TemBuffer[16]; + UINT8 Index; + StringBuffer Buffer; + va_list ArgList; + if (Level == 0) { + return; + } + Buffer.Index = 0; + Index = 1; + va_start (ArgList, Format); + while (Index != 0) { + if (*Format == 0) break; + if (*Format == '%') { + INT32 Radix; + Radix = 0; + if (*(Format + 1) == 'd' || *(Format + 1) == 'D') { + Radix = 10; + } + if (*(Format + 1) == 'x' || *(Format + 1) == 'X' ) { + Radix = 16; + } + if (Radix != 0) { + ItoA (va_arg (ArgList, INT32), Radix, TemBuffer); + SendStringToBuffer (&Buffer, TemBuffer); + Format += 2; + continue; + } + } + SendByteToBuffer (&Buffer, *Format); + if (*(Format) == 0x0a) SendByteToBuffer (&Buffer, 0x0d); + Format++; + } + SendBufferToDebugOut (&Buffer.Buffer[0]); + va_end (ArgList); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Write string to message buffer + * + * + * + * @param[in] pConfig + * + */ + +VOID +SendStringToBuffer ( + OUT StringBuffer *Buffer, + IN CHAR8 *pstr + ) +{ + while (*pstr != 0) { + SendByteToBuffer (Buffer, *pstr); + pstr++; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write byte to message buffer + * + * + * + * @param[in] pConfig + * + */ + +VOID +SendByteToBuffer ( + IN OUT StringBuffer *Buffer, + IN CHAR8 Data + ) +{ + if (Buffer->Index < 255) { + Buffer->Buffer[Buffer->Index] = Data; + Buffer->Buffer[++Buffer->Index] = 0; + } else { + SendBufferToDebugOut (Buffer->Buffer); + Buffer->Index = 0; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Integer To String + * + * + * + * @param[in] pConfig + * + */ + +VOID +ItoA ( + IN UINT32 Value, + IN UINTN Radix, + OUT CHAR8 *pstr + ) +{ + CHAR8 *tsptr; + CHAR8 *rsptr; + CHAR8 ch1; + CHAR8 ch2; + UINTN Reminder; + + tsptr = pstr; + rsptr = pstr; +//Create String + do { + Reminder = Value % Radix; + Value = Value / Radix; + if (Reminder < 0xa) { + *tsptr = (UINT8)Reminder + '0'; + } else { + *tsptr = (UINT8)Reminder - 0xa + 'a'; + } + tsptr++; + } while (Value != 0); +//Reverse String + *tsptr = 0; + tsptr--; + while (tsptr > rsptr) { + ch1 = *tsptr; + ch2 = *rsptr; + *rsptr = ch1; + *tsptr = ch2; + tsptr--; + rsptr++; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init debug Output + * + * + * + * @param[in] pConfig + * + */ +VOID +InitDebugOut ( + VOID + ) +{ +#ifdef SERIAL_OUT_SUPPORT + InitSerialOut (); +#endif +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Serial Output + * + * + * + * @param[in] pConfig + * + */ +VOID +InitSerialOut ( + VOID + ) +{ + UINT8 Data; + UINT16 Divisor; + + Data = 0x87; + LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x3, &Data, NULL); + Divisor = 115200 / DIVISOR; + Data = (UINT8) (Divisor & 0xFF); + LibAmdIoWrite (AccessWidth8 , COM_BASE_ADDRESS + 0x00, &Data, NULL); + Data = (UINT8) (Divisor >> 8); + LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x01, &Data, NULL); + Data = 0x07; + LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x3, &Data, NULL); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init HDT Output + * + * + * + * @param[in] pConfig + * + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Send Buffer to debug Output + * + * + * + * @param[in] pConfig + * + */ +VOID +SendBufferToDebugOut ( + IN CHAR8* Buffer + ) +{ +#ifdef HDT_OUT_SUPPORT + SendBufferToHdtOut (Buffer); +#endif + +#ifdef SERIAL_OUT_SUPPORT + SendBufferToSerialOut (Buffer); +#endif +} + +#ifdef HDT_OUT_SUPPORT +/*----------------------------------------------------------------------------------------*/ +/** + * Send Buffer to debug Output + * + * + * + * @param[in] pConfig + * + */ +VOID +SendBufferToHdtOut ( + IN CHAR8* Buffer + ) +{ + UINT32 Dr0Reg; + UINT32 Dr7Reg; + UINT32 Cr4Reg; + UINT64 MsrCurrentValue; + UINT64 MsrNewValue; + + // Save the CPU debug registers for restoration at the end of the routine + LibAmdMsrRead (0xC001100A, &MsrCurrentValue, NULL); + LibAmdReadCpuReg (DR0_REG, &Dr0Reg); + LibAmdReadCpuReg (DR7_REG, &Dr7Reg); + LibAmdReadCpuReg (CR4_REG, &Cr4Reg); + + //Modify the registers for HDT out + LibAmdWriteCpuReg (DR0_REG, 0x8F0); + LibAmdWriteCpuReg (DR7_REG, 0x20402); + LibAmdWriteCpuReg (CR4_REG, Cr4Reg | 0x8); + MsrNewValue = MsrCurrentValue | BIT0; + LibAmdMsrWrite (0xC001100A, &MsrNewValue, NULL); + + //HDT out + LibAmdIoWrite (AccessWidth32, 0x8F0, &Buffer, NULL); + + // Restore the CPU debug registers + LibAmdWriteCpuReg (CR4_REG, Cr4Reg); + LibAmdWriteCpuReg (DR7_REG, Dr7Reg); + LibAmdWriteCpuReg (DR0_REG, Dr0Reg); + LibAmdMsrWrite (0xC001100A, &MsrCurrentValue, NULL); +} +#endif +/*----------------------------------------------------------------------------------------*/ +/** + * Send Buffer to debug Output + * + * + * + * @param[in] pConfig + * + */ +VOID +SendBufferToSerialOut ( + IN CHAR8* Buffer + ) +{ + UINT8 Status; + UINT32 Count; + + Count = 10000; + while (*Buffer != 0) { + do { + LibAmdIoRead (AccessWidth8, COM_BASE_ADDRESS + 0x05, &Status, NULL); + if (Status == 0xff) return; + // Loop port is ready + } while ((Status & 0x20) == 0 && (--Count) != 0); + LibAmdIoWrite (AccessWidth8, COM_BASE_ADDRESS + 0x00, Buffer, NULL); + Buffer++; + } +} diff --git a/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h new file mode 100644 index 000000000000..3458b80b11ad --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdDebugOutLib.h @@ -0,0 +1,54 @@ +/** + * @file + * + * Debug out functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _AMDDEBUGOUTLIB_H_ +#define _AMDDEBUGOUTLIB_H_ + +VOID +LibAmdTraceDebug ( + IN UINT32 Level, + IN CHAR8 *Format, + IN ... + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/amdSbLib.c b/src/vendorcode/amd/cimx/rd890/amdSbLib.c new file mode 100644 index 000000000000..22b7fb17df09 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdSbLib.c @@ -0,0 +1,216 @@ +/** + * @file + * + * SB common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "amdlib.h" +#include "amdSbLib.h" + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Stall + * + * + * + * @param[in] uSec + * + */ + +VOID +LibAmdSbStall ( + IN UINT32 uSec, + IN VOID *ConfigPtr + ) +{ + UINT16 AcpiTimerBaseAddress; + UINT32 StartTime; + UINT32 ElapsedTime; + SB_INFO SbInfo; + SbInfo = LibAmdSbGetRevisionInfo (ConfigPtr); + if (SbInfo.Type == SB_UNKNOWN) { + AcpiTimerBaseAddress = 0; + } else { + LibAmdSbPmioRead ((SbInfo.Type == SB_SB700) ? 0x24 : 0x64, AccessWidth16, &AcpiTimerBaseAddress, ConfigPtr); + } + if (AcpiTimerBaseAddress == 0) { + uSec = uSec / 2; + while (uSec != 0) { + LibAmdIoRead (AccessWidth8, 0x80, &StartTime, (AMD_CONFIG_PARAMS *)ConfigPtr); + uSec--; + } + } else { + LibAmdIoRead (AccessWidth32, AcpiTimerBaseAddress, &StartTime, (AMD_CONFIG_PARAMS *)ConfigPtr); + do { + LibAmdIoRead (AccessWidth32, AcpiTimerBaseAddress, &ElapsedTime, (AMD_CONFIG_PARAMS *)ConfigPtr); + if (ElapsedTime < StartTime) { + ElapsedTime = ElapsedTime + (0xFFFFFFFF - StartTime); + } else { + ElapsedTime = ElapsedTime - StartTime; + } + } while ((ElapsedTime*28/100)<uSec); //28/100 + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PMIO + * + * + * + * @param[in] uSec + * + */ + +VOID +LibAmdSbPmioRead ( + IN UINT8 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *ConfigPtr + ) +{ + UINT8 i; + if (Width > 0x80) { + Width -= 0x80; + } + for (i = 0; i <= Width; i++) { + LibAmdIoWrite (AccessWidth8, 0xCD6, &Address, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD6 + Address++; + LibAmdIoRead (AccessWidth8,0xCD7, (UINT8 *)Value + i, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD7 + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PMIO + * + * + * + * @param[in] uSec + * + */ + +VOID +LibAmdSbPmioWrite ( + IN UINT8 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *ConfigPtr + ) +{ + UINT8 i; + if (Width > 0x80) { + Width -= 0x80; + } + for (i = 0; i <= Width; i++) { + LibAmdIoWrite (AccessWidth8, 0xCD6, &Address, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD6 + Address++; + LibAmdIoWrite (AccessWidth8,0xCD7, (UINT8 *)Value + i, (AMD_CONFIG_PARAMS *)ConfigPtr); // SB_IOMAP_REGCD7 + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get SB Type + * + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +SB_INFO +LibAmdSbGetRevisionInfo ( + IN VOID *ConfigPtr + ) +{ + UINT32 DeviceId; + UINT8 RevisionId; + SB_INFO SbInfo; + PCI_ADDR SbSmbusAddress; + SbSmbusAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0x00); + LibAmdPciRead (AccessWidth32, SbSmbusAddress, &DeviceId, (AMD_CONFIG_PARAMS *)ConfigPtr); + SbInfo.Revision = SB_REV_UNKNOWN; + switch (DeviceId) { + case 0x43851002: + SbSmbusAddress.AddressValue = MAKE_SBDFO (0, 0, 0x14, 0, 0x08); + LibAmdPciRead (AccessWidth8, SbSmbusAddress, &RevisionId, (AMD_CONFIG_PARAMS *)ConfigPtr); + if (RevisionId >= 0x40) { + SbInfo.Type = SB_SB800; + } else { + SbInfo.Type = SB_SB700; + } + break; + default: + SbInfo.Type = SB_UNKNOWN; + } + return SbInfo; +} diff --git a/src/vendorcode/amd/cimx/rd890/amdSbLib.h b/src/vendorcode/amd/cimx/rd890/amdSbLib.h new file mode 100644 index 000000000000..b226dba6467a --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/amdSbLib.h @@ -0,0 +1,85 @@ +/** + * @file + * + * SB common library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: Common Library + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _AMDSBLIB_H_ +#define _AMDSBLIB_H_ + +VOID +LibAmdSbStall ( + IN UINT32 uSec, + IN VOID *ConfigPtr + ); + +VOID +LibAmdSbPmioRead ( + IN UINT8 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN VOID *ConfigPtr + ); + +VOID +LibAmdSbPmioWrite ( + IN UINT8 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN VOID *ConfigPtr + ); + +#define SB_SB800 0x02 +#define SB_SB700 0x01 +#define SB_UNKNOWN 0xFF +#define SB_REV_UNKNOWN 0xFF + +/// Southbridge info +typedef struct { + UINT8 Type; ///< SB Model (SB800/SB700/...) + UINT8 Revision; ///< SB Revision ID +} SB_INFO; + +SB_INFO +LibAmdSbGetRevisionInfo ( + IN VOID *ConfigPtr + ); + +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbDef.h b/src/vendorcode/amd/cimx/rd890/nbDef.h new file mode 100644 index 000000000000..8589adcfd239 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbDef.h @@ -0,0 +1,532 @@ +/** + * @file + * + * + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBDEF_H_ +#define _NBDEF_H_ + +#pragma pack (push, 1) + +AGESA_STATUS +AmdPowerOnResetInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbPowerOnResetInit ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +AmdHtInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbHtInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +AmdEarlyPostInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbEarlyPostInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +AmdMidPostInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbMidPostInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +AmdLatePostInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbLatePostInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +AmdPcieEarlyInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +PcieEarlyInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + + +AGESA_STATUS +AmdS3Init ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +AmdS3InitIommu ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbS3Init ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +AmdPcieLateInit ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +AmdPcieLateInitWa ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +AmdPcieValidatePortState ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +PcieLateInit ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +PcieLateInitWa ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +PcieValidatePortState ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +PcieLateInitPorts ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + + +AGESA_STATUS +AmdPcieS3Init ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +BOOLEAN +PcieLibCheckGen2Disabled ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibSetGen2Disabled ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ); + + +PCI_ADDR +PcieLibGetPortPciAddress ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibSetLinkCompliance ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + + +AGESA_STATUS +PcieLibInitValidateInput ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibSetPcieMmioBase ( + IN UINT16 PcieMmioBase, + IN UINT16 PcieMmioSize, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieCheckSelectedPorts ( + IN UINT16 SelectedPortMask, + IN AMD_NB_CONFIG *pConfig + ); + +PCIE_LINK_STATUS +PcieGetPortsLinkStatus ( + IN UINT16 SelectedPortMask, + IN OUT PCIE_LINK_STATUS *PortLinkStatus, + IN UINT32 Pooling, + IN AMD_NB_CONFIG *pConfig + ); + + +UINT16 +PcieFindPortsWithLinkStatus ( + IN PCIE_LINK_STATUS *PortLinkStatus, + IN PCIE_LINK_STATUS LinkStatus + ); + +AGESA_STATUS +PcieBrokenLaneWorkaround ( + IN UINT16 SelectedPortMask, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieGen2Workaround ( + IN UINT16 SelectedPortMask, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieMiscWorkaround ( + IN PCIE_LINK_STATUS *PortsLinkStatus, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieCheckVco ( + IN UINT16 SelectedPortMask, + IN PCIE_LINK_STATUS *PortsLinkStatus, + IN AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieLibPortTrainingControl ( + IN PORT PortId, + IN PCIE_LINK_TRAINING Operation, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibSetCoreConfiguration ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibCommonCoreInit ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +LINK_INFO +PcieLibGetPortLinkInfo ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibPowerOffPortLanes ( + IN PORT PortId, + IN PCIE_LINK_WIDTH Width, + IN AMD_NB_CONFIG *pConfig + ); + +BOOLEAN +PcieLibIsPortReversed ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig +); + +VOID +PcieLibPowerOffPll ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieInitSelectedPorts ( + IN UINT16 SelectedPortMask, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibCommonPortInit ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibSetLinkMode ( + IN PORT PortId, + IN PCIE_LINK_MODE Operation, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PciePreTrainingInit ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieInitPorts ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieAfterTrainingInit ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibUnHidePorts ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibHidePorts ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieLibRequestPciReset ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieLibResetSlot ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieLibManageTxClock ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibManageLclkClock ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibEnablePllPowerOffInL1 ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + + +CORE +PcieLibGetCoreId ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +UINT32 +PcieLibGetCoreAddress ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + + +AGESA_STATUS +AmdPcieInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +PcieLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ); + + +BOOLEAN +PcieLibIsValidPortId ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig +); + +BOOLEAN +PcieLibIsValidCoreId ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig +); + +VOID +PcieLibPreTrainingInit ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibMiscLateCoreSetting ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + + +AGESA_STATUS +PcieLateValidateConfiguration ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieForcePortsVisibleOrDisable ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +/* +VOID +PcieReportCoreDisableStatus ( + IN AMD_NB_CONFIG *NbConfigPtr + ); +*/ + +AGESA_STATUS +PcieLateInitCores ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieLateCommonPortInit ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieLibStrapModeControl ( + IN CORE CoreId, + IN PCIE_STRAP_MODE Operation, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibCoreAfterTrainingInit ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +PORT_STATIC_INFO* +PcieLibGetStaticPortInfo ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ); + +CORE_INFO* +PcieLibGetCoreInfo ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +PORT +PcieLibNativePortId ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieNbSbSetupVc ( + IN AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieLibLateInit ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieLibValidatePortStateInit ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieInitiateSoftwareGen2 ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieRecoveryInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +PCI_CORE_RESET +PcieLibCoreReset ( + IN CORE CoreId, + IN PCI_CORE_RESET Operation, + IN AMD_NB_CONFIG *pConfig + ); + + +PORT_INFO* +PcieLibGetPortInfo ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ); + +PCIE_DEVICE_TYPE +PcieGetDeviceType ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ); + +UINT8 +PcieLibGetActiveCoreMap ( + IN AMD_NB_CONFIG *pConfig + ); + +#pragma pack (pop) +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbDispatcher.c b/src/vendorcode/amd/cimx/rd890/nbDispatcher.c new file mode 100644 index 000000000000..16e86a1aaa47 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbDispatcher.c @@ -0,0 +1,201 @@ +/** + * @file + * + * Function dispatcher. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +extern AMD_MODULE_HEADER mNbModuleID; + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +CALLCONV +AmdNbDispatcher ( + IN OUT VOID*ConfigPtr + ) +{ + AGESA_STATUS Status; + IMAGE_ENTRY ImageEntry; + ImageEntry = NULL; + Status = AGESA_UNSUPPORTED; + CIMX_INIT_TRACE ((ConfigPtr)); + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), "CIMx - RD890 Entry \n")); + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), " Funcid = %x Callout = %x\n", ((AMD_CONFIG_PARAMS*)ConfigPtr)->Func, ((AMD_CONFIG_PARAMS*)ConfigPtr)->CalloutPtr)); + +#ifdef B1_IMAGE + // 1. Try to execute any B1 specific functions + switch (((AMD_CONFIG_PARAMS*)ConfigPtr)->Func) { + #ifdef B1_IMAGE + // B1 ONLY Functions + // + // + #endif + default: + break; + } +#endif + + // 2. If not B1 specific function but we are B1, see if we can find B2 instead +#ifdef B1_IMAGE + if (Status == AGESA_UNSUPPORTED) { + UINTN ImageStart; + UINTN ImageEnd; + AMD_IMAGE_HEADER* AltImagePtr; + ImageStart = 0xFFF00000; + ImageEnd = 0xFFFFFFFF; + AltImagePtr = (AMD_IMAGE_HEADER*) (UINTN) ((AMD_CONFIG_PARAMS*)ConfigPtr)->AltImageBasePtr; + + if ((UINTN)AltImagePtr != 0xFFFFFFFF) { + if (AltImagePtr != NULL) { + ImageStart = (UINT32) (UINTN)AltImagePtr; + ImageEnd = ImageStart + 4; + } + // Locate/test image base that matches this component + AltImagePtr = LibAmdLocateImage ((VOID*)ImageStart, (VOID*)ImageEnd, 4096, CIMX_NB_ID); + if (AltImagePtr != NULL) { + //Invoke alternative Image + ImageEntry = (IMAGE_ENTRY) (UINTN) ((UINT8*) AltImagePtr + AltImagePtr->EntryPointAddress); + Status = (*ImageEntry) (ConfigPtr); + } + } + } +#endif + if (Status == AGESA_UNSUPPORTED) { + // 3. Try to execute any other functions + switch (((AMD_CONFIG_PARAMS*)ConfigPtr)->Func) { + +#if defined (B1_IMAGE) || defined (B2_IMAGE) +// B1 & B2 Functions + case PH_AmdPowerOnResetInit: + Status = LibSystemApiCall (AmdPowerOnResetInit, ConfigPtr); + break; + case PH_AmdPcieEarlyInit: + Status = LibSystemApiCall (AmdPcieEarlyInit, ConfigPtr); + break; + case PH_AmdInitializer: + Status = LibSystemApiCall (AmdInitializer, ConfigPtr); + break; +#endif +#ifdef B2_IMAGE +// B2 Functions + case PH_AmdNbHtInit : + Status = LibSystemApiCall (AmdHtInit, ConfigPtr); + break; + case PH_AmdEarlyPostInit : + LibSystemApiCall (AmdMaskedMemoryInit, ConfigPtr); + Status = LibSystemApiCall (AmdEarlyPostInit, ConfigPtr); + break; + case PH_AmdMidPostInit : + Status = LibSystemApiCall (AmdMidPostInit, ConfigPtr); + break; + case PH_AmdLatePostInit : + Status = LibSystemApiCall (AmdPcieLateInit, ConfigPtr); + Status = LibSystemApiCall (AmdLatePostInit, ConfigPtr); + Status = LibSystemApiCall (AmdPcieLateInitWa, ConfigPtr); + break; + case PH_AmdPcieValidatePortState : + Status = LibSystemApiCall (AmdPcieValidatePortState, ConfigPtr); + break; + case PH_AmdPcieLateInit : + Status = LibSystemApiCall (AmdPcieLateInit, ConfigPtr); + break; + case PH_AmdNbLateInit : + Status = LibSystemApiCall (AmdLatePostInit, ConfigPtr); + break; + case PH_AmdS3Init : + LibSystemApiCall (AmdMaskedMemoryInit, ConfigPtr); + Status = LibSystemApiCall (AmdS3InitIommu, ConfigPtr); + Status = LibSystemApiCall (AmdPcieS3Init, ConfigPtr); + Status = LibSystemApiCall (AmdS3Init, ConfigPtr); + Status = LibSystemApiCall (AmdPcieLateInitWa, ConfigPtr); + break; + case PH_AmdNbS3Init : + LibSystemApiCall (AmdMaskedMemoryInit, ConfigPtr); + Status = LibSystemApiCall (AmdS3Init, ConfigPtr); + break; + case PH_AmdPcieS3Init : + Status = LibSystemApiCall (AmdS3InitIommu, ConfigPtr); + Status = LibSystemApiCall (AmdPcieS3Init, ConfigPtr); + break; +#endif +#ifdef B3_IMAGE +// B3 Functions +#endif + default: + break; + } + } + + // 4. Try next dispatcher if possible, and we have not already got status back + if ((mNbModuleID.NextBlock != NULL) && (Status == AGESA_UNSUPPORTED)) { + MODULE_ENTRY ModuleEntry; + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), "CIMx - RD890 control goes to next Module \n")); + ModuleEntry = mNbModuleID.NextBlock->ModuleDispatcher; + Status = (*ModuleEntry) (ConfigPtr); + } + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_TRACE_ALL), "CIMx - RD890 Exit\n")); + return Status; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbEventLog.c b/src/vendorcode/amd/cimx/rd890/nbEventLog.c new file mode 100644 index 000000000000..4c228b0f7b66 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbEventLog.c @@ -0,0 +1,106 @@ + +/** + * @file + * + * + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * This function logs NB events into a callback. + * + * + * + * @param[in] EventClass + * @param[in] EventInfo + * @param[in] DataParam1 + * @param[in] DataParam2 + * @param[in] DataParam3 + * @param[in] DataParam4 + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +LibNbEventLog ( + IN UINTN EventClass, + IN UINT32 EventInfo, + IN UINT32 DataParam1, + IN UINT32 DataParam2, + IN UINT32 DataParam3, + IN UINT32 DataParam4, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_EVENT Event; + Event.EventClass = EventClass; + Event.EventInfo = EventInfo; + Event.DataParam1 = DataParam1; + Event.DataParam2 = DataParam2; + Event.DataParam3 = DataParam3; + Event.DataParam4 = DataParam4; + if (EventClass > ((API_WORKSPACE*)NbConfigPtr->ConfigPtr)->Status) { + ((API_WORKSPACE*)NbConfigPtr->ConfigPtr)->Status = EventClass; + } + LibNbCallBack (PHCB_AmdReportEvent, (UINTN)&Event, NbConfigPtr); +} diff --git a/src/vendorcode/amd/cimx/rd890/nbEventLog.h b/src/vendorcode/amd/cimx/rd890/nbEventLog.h new file mode 100644 index 000000000000..cf313fa7f2f1 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbEventLog.h @@ -0,0 +1,95 @@ + +/** + * @file + * + * + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBEVENTLOG_H_ +#define _NBEVENTLOG_H_ + +#pragma pack(push, 1) + +/** + * Event + * + */ +typedef struct { + UINTN EventClass; /**< Event Class. + * @li <b>AGESA_WARNING</b> + * @li <b>AGESA_ERROR</b> + * @li <b>AGESA_FATAL</b> + */ + UINT32 EventInfo; /**< Event Info. + * This parameter used as event identifier + */ + UINT32 DataParam1; ///< Event specific data + UINT32 DataParam2; ///< Event specific data + UINT32 DataParam3; ///< Event specific data + UINT32 DataParam4; ///< Event specific data +} AGESA_EVENT; + + +#define PCIE_ERROR_HOTPLUG_INIT 0x20010100 +#define PCIE_ERROR_TRAINING_FAIL 0x20010200 +#define PCIE_ERROR_CORE_CONFIGURATION 0x20010300 +#define PCIE_ERROR_BROKEN_LINE 0x20010400 +#define PCIE_ERROR_GEN2_FAIL 0x20010500 +#define PCIE_ERROR_VCO_NEGOTIATON 0x20010600 +#define PCIE_ERROR_DEVICE_REMAP 0x20010700 +#define GENERAL_ERROR_BAD_CONFIGURATION 0x20000100 +#define GENERAL_ERROR_NB_NOT_PRESENT 0x20000200 +#define GENERAL_ERROR_LOCATE_ACPI_TABLE 0x20000300 + + +VOID +LibNbEventLog ( + IN UINTN EventClass, + IN UINT32 EventInfo, + IN UINT32 DataParam1, + IN UINT32 DataParam2, + IN UINT32 DataParam3, + IN UINT32 DataParam4, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +#pragma pack(pop) + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbHtInit.c b/src/vendorcode/amd/cimx/rd890/nbHtInit.c new file mode 100644 index 000000000000..687219a35941 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbHtInit.c @@ -0,0 +1,626 @@ +/** + * @file + * + * HT Initialization + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ +#define LINK_BUFFERS_IFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0xF) +#define LINK_BUFFERS_NFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0x11) +#define SUBLINK_BUFFERS_IFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0xF) +#define SUBLINK_BUFFERS_NFCM ((1 << 31) + (1 << 25) + (8 << 20) + (1 << 18) + (1 << 8) + (6 << 5) + 0x11) + +typedef VOID DUMMY_CALL (VOID); + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +VOID +NbInitRasParityMacro ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +UINT8 IBIASCodeTable[] = { +//0.2G 0.5G 0.6G + 0x44, 0x00, 0x44, 0x00, 0xb6, +//0.8G 1.0G 1.2G 1.4G 1.6G + 0x44, 0x96, 0xb6, 0x23, 0x44, +//1.8G 2.0G 2.2G 2.4G 2.6G + 0x64, 0x96, 0xA6, 0xb6, 0xc6 +}; + + + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Init at early post. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +HtLibEarlyInit ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT32 Value; + PCI_ADDR ClkPciAddress; + PCI_ADDR CpuPciAddress; + PCI_ADDR LinkPciAddress; + HT_CONFIG *pHtConfig; + UINT8 CpuHtSpeed; + UINT8 NbHtSpeed; + HT_INACTIVE_LANE_STATE InLnSt; + BOOLEAN IsIfcmEnabled; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibEarlyInit Enter\n")); + pHtConfig = GET_HT_CONFIG_PTR (pConfig); + Status = AGESA_SUCCESS; + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Device = 1; + CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, 0); + LinkPciAddress.AddressValue = MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, ((pConfig->NbHtPath.LinkID & 0xF0) > 0x10)?4:0, 0); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), " Node %d Link %d PciAddress %x\n", pConfig->NbHtPath.NodeID, pConfig->NbHtPath.LinkID, LinkPciAddress.AddressValue)); + LibNbEnableClkConfig (pConfig); +//Get Ht Speed Info + LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x89), AccessWidth8, &CpuHtSpeed, pConfig); + LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REGD1 , AccessWidth8, &NbHtSpeed, pConfig); + NbHtSpeed &= 0xf; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), " Ht speed Cpu %x Nb %x\n", CpuHtSpeed, NbHtSpeed)); +//Set IBIAS code + LibNbPciRMW (ClkPciAddress.AddressValue | NB_CLK_REGD8, AccessWidth16, (UINT32)~(0x3ff), ((UINT8*)FIX_PTR_ADDR (&IBIASCodeTable[0], NULL))[(pHtConfig->HtReferenceClock / 200)*CpuHtSpeed], pConfig); + if (CpuHtSpeed > HT_FREQUENCY_1000M) { + UINT8 T0Time; + UINT8 ForceFullT0; +//Enable Protocol checker + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG1E, AccessWidth32, 0, 0x7FFFFFFC, pConfig); +//Set NB Transmitter Deemphasis + if ((pHtConfig->NbTransmitterDeemphasis & 0x80) == 0) { + LibHtSetNbTransmitterDeemphasis (pHtConfig->NbTransmitterDeemphasis, pConfig); + } + LibNbPciRead (CpuPciAddress.AddressValue | 0x16C, AccessWidth32, &Value, pConfig); + T0Time = (UINT8) (Value & 0x3F); + ForceFullT0 = (UINT8) ((Value >> 13) & 0x7); +//Enable LS State and set T0Time + //T0Time = 0x14; //2us + if (pHtConfig->LSx < HtLinkStateSkipInit) { + if (pHtConfig->LSx == HtLinkStateSameAsCpu) { + LibNbPciRead ( + CpuPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170), + AccessWidth32, + &Value, + pConfig + ); + if ((Value & BIT8) != 0) { + pHtConfig->LSx = HtLinkStateLS2; + } else { + pHtConfig->LSx = HtLinkStateLS1; + } + } else { + if (pHtConfig->LSx >= HtLinkStateLS2) { + T0Time = 0x26; //12us + ForceFullT0 = 0x6; + } else { + T0Time = 0x14; //2us + ForceFullT0 = 0x0; + } + } + if (CpuHtSpeed == NbHtSpeed) { + LibHtEnableLxState (pHtConfig->LSx, pConfig); + } + } +//Set up InLnSt + //Match CPU InLnSt except for HT3 LS1 + LibNbPciRead ( + CpuPciAddress.AddressValue | 0x16C, + AccessWidth32, + &Value, + pConfig + ); + InLnSt = (Value >> 6) & 0x3; + + // Do not enable HT3 LS1 with InLnSt == 0x1 (PHY_OFF) as per errata 9 + if (pHtConfig->LSx == HtLinkStateLS1) { + if (InLnSt == InactiveLaneStateSameAsPhyOff) { + InLnSt = InactiveLaneStateCadCtrlDrivelToLogic0; + } + } + LibNbPciRMW ( + pConfig->NbPciAddress.AddressValue | NB_PCI_REGA0, + AccessWidth8, + 0x00, + T0Time | (InLnSt << 6), + pConfig + ); + LibNbPciRMW ( + CpuPciAddress.AddressValue | 0x16C, + AccessWidth16, + (UINT32)(~((0x7 << 13) + 0x3f)), + T0Time | (ForceFullT0 << 13), + pConfig + ); + // Disable command throtling + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | (NB_PCI_REGAC + 1), AccessWidth8, (UINT32)~BIT6, BIT6, pConfig); + LibNbPciRMW (CpuPciAddress.AddressValue | 0x168, AccessWidth16, (UINT32)~BIT10, BIT10, pConfig); + // Enables strict TM4 detection + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessWidth32, (UINT32)~BIT22, BIT22, pConfig); + } else { + //Set Link Tristate + if (pHtConfig->HtLinkTriState < HtLinkTriStateSkip) { + if (pHtConfig->HtLinkTriState == HtLinkTriStateSameAsCpu) { + LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x84), AccessWidth16, &Value, pConfig); + if ((Value & BIT13) != 0) { + pHtConfig->HtLinkTriState = HtLinkTriStateCadCtl; + LibNbPciRead ( + CpuPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170), + AccessWidth16, + &Value, + pConfig + ); + if ((Value & BIT8) != 0) { + pHtConfig->HtLinkTriState = HtLinkTriStateCadCtlClk; + } + } + } + if (pHtConfig->HtLinkTriState >= HtLinkTriStateCadCtl) { + UINT16 TriStateValue; + TriStateValue = 0; + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGC8, AccessWidth16 , (UINT32)~BIT13, BIT13, pConfig); + LibNbPciRMW (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x84), AccessWidth16, (UINT32)~(BIT13), BIT13, pConfig); + if (pHtConfig->HtLinkTriState == HtLinkTriStateCadCtlClk) { + TriStateValue = BIT8; + } + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGAC, AccessWidth16, (UINT32)~BIT8, TriStateValue, pConfig); + if (LibNbGetCpuFamily () != 0x0) { + LibNbPciRMW ( + CpuPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170), + AccessWidth16, + (UINT32)~(BIT8), + TriStateValue, + pConfig + ); + } + } + } + LibNbPciRMW ( + pConfig->NbPciAddress.AddressValue | NB_PCI_REGA0, + AccessWidth8, + 0x3f, + InactiveLaneStateSameAsPhyOff << 6, + pConfig + ); + } + //Enable 64bit address mode + + if ((pHtConfig->HtExtendedAddressSupport & 0x80) == 0) { + LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x85), AccessWidth8, &Value, pConfig); + if (pHtConfig->HtExtendedAddressSupport == HtExtAddressingSameAsCpu) { + Value &= BIT7; + } else { + Value = (pHtConfig->HtExtendedAddressSupport == HtExtAddressingEnable)? BIT7 : 0; + } + LibNbPciRMW (((pConfig->NbPciAddress.AddressValue) | (NB_PCI_REGC8 + 1)), AccessWidth8, 0x7C, Value, pConfig); + LibNbPciRMW (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x85), AccessWidth8, 0x7F, Value, pConfig); + } + + // Check if IFCM enabled in CPU + LibNbPciRead (LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x85), AccessWidth8, &Value, pConfig); + IsIfcmEnabled = (Value & BIT4) ? TRUE:FALSE; + if (IsIfcmEnabled) { + // Enable Isoc in chipset + LibNbPciRMW (((pConfig->NbPciAddress.AddressValue) | (NB_PCI_REGC8 + 1)), AccessWidth8, 0xFC, BIT4, pConfig); + } + + if (pHtConfig->LinkBufferOptimization == ON) { + BOOLEAN IsConnectedToSublink; + IsConnectedToSublink = (pConfig->NbHtPath.LinkID & 0xF0) > 0 ? TRUE:FALSE; + if (IsConnectedToSublink) { + Value = IsIfcmEnabled ? SUBLINK_BUFFERS_IFCM : SUBLINK_BUFFERS_NFCM; + } else { + Value = IsIfcmEnabled ? LINK_BUFFERS_IFCM : LINK_BUFFERS_NFCM; + } + LibNbPciRMW ( + LinkPciAddress.AddressValue | (HT_PATH_LINK_ID (pConfig->NbHtPath) * 32 + 0x90), + AccessWidth32, + 0x0, + Value, + pConfig + ); + } + NbInitRasParityMacro (pConfig); + LibNbDisableClkConfig (pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibEarlyInit Exit [0x%x]\n", Status)); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set NB transmitter deemphasis level. + * + * + * @param[in] NbDeemphasisLevel NB Deemphasis level See HT_CONFIG::NbTransmitterDeemphasis + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +LibHtSetNbTransmitterDeemphasis ( + IN UINT8 NbDeemphasisLevel, + IN AMD_NB_CONFIG *pConfig + ) +{ + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGA7, AccessWidth8, (UINT32)~0x07, NbDeemphasisLevel + BIT7, pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable LSx state + * + * + * + * @param[in] LSx LS State to enable. See HT_CONFIG::LSx + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +LibHtEnableLxState ( + IN UINT8 LSx, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + UINT32 NbLSx; + UINT32 CpuLSx; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), " Enable HT LS%d\n", LSx)); + switch (LSx) { + case 0: + Value = LS0; + break; + case 1: + Value = LS1; + break; + case 2: + Value = LS2; + break; + case 3: + Value = LS3; + break; + default: + Value = 0; + CIMX_ASSERT (FALSE); + return; + } + NbLSx = (Value << 7); + CpuLSx = (LSx >= 2)?BIT8:0; + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REGAC, AccessWidth16, (UINT32)~(BIT7 + BIT8), NbLSx, pConfig); + LibNbPciRMW ( + MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x170), + AccessWidth32, + (UINT32)~BIT8, + CpuLSx, + pConfig + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * NB validate HY Input parameters + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +HtLibInitValidateInput ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + HT_CONFIG *pHtConfig; + NB_INFO NbInfo; + + Status = AGESA_SUCCESS; + pHtConfig = GET_HT_CONFIG_PTR (pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + if (pHtConfig == NULL || NbInfo.Type == NB_UNKNOWN) { + return AGESA_FATAL; + } + if (pHtConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) { + Status = HtLibInitializer (pConfig); + } + return Status; +} + +UINT8 SmuWaBasePeriod[] = { + 0x1F, //HT 200Mhz + 0x00, + 0x1F, //HT 400Mhz + 0x00, + 0x17, //HT 600Mhz + 0x1F, //HT 800Mhz + 0x27, //HT 1000Mhz + 0x2E, //HT 1200Mhz + 0x36, //HT 1400Mhz + 0x3E, //HT 1600Mhz + 0x46, //HT 1800Mhz + 0x4E, //HT 2000Mhz + 0x55, //HT 2200Mhz + 0x5D, //HT 2400Mhz + 0x65 //HT 2600Mhz +}; + +UINT8 SmuWaBaseDelay[] = { + 0x3, //HT 200Mhz + 0x0, + 0x3, //HT 400Mhz + 0x0, + 0x2, //HT 600Mhz + 0x3, //HT 800Mhz + 0x3, //HT 1000Mhz + 0x4, //HT 1200Mhz + 0x5, //HT 1400Mhz + 0x6, //HT 1600Mhz + 0x7, //HT 1800Mhz + 0x7, //HT 2000Mhz + 0x8, //HT 2200Mhz + 0x9, //HT 2400Mhz + 0xA //HT 2600Mhz +}; + +UINT8 SmuWaPeriod10us[] = { + 120, + 100, + 90, + 80 +}; + +UINT8 SmuWaDelay1us[] = { + 0x0, //HT 200Mhz + 0x0, + 0x0, //HT 400Mhz + 0x0, + 0x0, //HT 600Mhz + 0x0, //HT 800Mhz + 0x0, //HT 1000Mhz + 0x0, //HT 1200Mhz + 0x2, //HT 1400Mhz + 0x2, //HT 1600Mhz + 0x2, //HT 1800Mhz + 0x3, //HT 2000Mhz + 0x3, //HT 2200Mhz + 0x4, //HT 2400Mhz + 0x4 //HT 2600Mhz +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Get SMU wa data + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * @retval SMU wa data + */ + +UINT32 +LibHtGetSmuWaData ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 NorthbridgeId; + UINT8 NorthbridgeIndex; + UINT8 NbHtSpeed; + UINT16 SmuWaPeriod; + UINT16 SmuWaDelay; + AMD_NB_CONFIG_BLOCK *ConfigPtr; + NorthbridgeIndex = 0; + ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig); + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + AMD_NB_CONFIG *NbConfigPtr = &ConfigPtr->Northbridges[NorthbridgeId]; + if (LibNbIsDevicePresent (NbConfigPtr->NbPciAddress, NbConfigPtr)) { + if (pConfig == NbConfigPtr) { + LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REGD1 , AccessWidth8, &NbHtSpeed, pConfig); + NbHtSpeed &= 0xf; + SmuWaPeriod = SmuWaPeriod10us [NorthbridgeIndex] * SmuWaBasePeriod [NbHtSpeed]; + SmuWaDelay = SmuWaDelay1us [NbHtSpeed] * SmuWaBaseDelay [NbHtSpeed]; + return ((SmuWaPeriod & 0xFF) << 8) | ((SmuWaPeriod & 0xFF00) >> 8) | ((SmuWaDelay & 0xFF) << 24) | ((SmuWaDelay & 0xFF00) << 8); + } + NorthbridgeIndex++; + } + } + return 0; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init RAS macro + * + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +VOID +NbInitRasParityMacro ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR CpuPciAddress; + UINT32 SaveBase; + UINT32 SaveLimit; + UINT32 Value; + UINT32 Base; + UINT32 Limit; + UINT32 Index; + UINT64 SaveTom; + UINT64 Value64; + DUMMY_CALL *RetAddr; + UINT8 Node; + CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0); +//Set TOM + LibAmdMsrRead (0xC001001a, &SaveTom, (AMD_CONFIG_PARAMS *)NbConfigPtr); + Value64 = 0x40000000; + LibAmdMsrWrite (0xC001001a, &Value64, (AMD_CONFIG_PARAMS *)NbConfigPtr); +//Set mmio + LibNbPciRead (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &SaveBase, NbConfigPtr); + LibNbPciRead (CpuPciAddress.AddressValue | 0x84, AccessWidth32, &SaveLimit, NbConfigPtr); + Limit = ((0x50000000 - 1) >> 8) & (~ 0xFF); + Limit |= NbConfigPtr->NbHtPath.NodeID | (HT_PATH_LINK_ID (NbConfigPtr->NbHtPath) << 4) | (HT_PATH_SUBLINK_ID (NbConfigPtr->NbHtPath) << 6); + Base = ((0x40000000 >> 8) & (~ 0xFF)) | 0x3; + for (Node = 0; Node < 8; Node++) { + CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18 + Node, 1, 0); + if (LibNbIsDevicePresent (CpuPciAddress, NbConfigPtr)) { + LibNbPciWrite (CpuPciAddress.AddressValue | 0x84, AccessWidth32, &Limit, NbConfigPtr); + LibNbPciWrite (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &Base, NbConfigPtr); + } else { + break; + } + } +//set Scan + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT27, BIT27, NbConfigPtr); + RetAddr = (DUMMY_CALL* ) (UINTN) 0x40000000; + *((UINT8*) (UINTN) RetAddr) = 0xC3; + for (Index = 0; Index < 64; Index++) { + RetAddr (); + RetAddr = (DUMMY_CALL*) (UINTN) ((UINT8*) (UINTN) RetAddr + 64); + } +//Reset scan + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT27, 0x0, NbConfigPtr); + Value = 0; +// Restore MMIO Map + for (Node = 0; Node < 8; Node++) { + CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18 + Node, 1, 0); + if (LibNbIsDevicePresent (CpuPciAddress, NbConfigPtr)) { + LibNbPciWrite (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &Value, NbConfigPtr); + LibNbPciWrite (CpuPciAddress.AddressValue | 0x84, AccessWidth32, &SaveLimit, NbConfigPtr); + LibNbPciWrite (CpuPciAddress.AddressValue | 0x80, AccessWidth32, &SaveBase, NbConfigPtr); + } else { + break; + } + } +// Restore TOM + LibAmdMsrWrite (0xC001001a, &SaveTom, (AMD_CONFIG_PARAMS *)NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for all NB. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdHtInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (HtLibInitializer, ConfigPtr); + return Status; +} +/*----------------------------------------------------------------------------------------*/ +/** + * HT config structure initializer + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +HtLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + HT_CONFIG *pHtConfig; + + pHtConfig = GET_HT_CONFIG_PTR (pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibInitializer Enter\n")); + if (pHtConfig == NULL) { + return AGESA_WARNING; + } + if (pHtConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) { + return AGESA_SUCCESS; + } + LibAmdMemFill (pHtConfig, 0, sizeof (HT_CONFIG), (AMD_CONFIG_PARAMS *)&(pHtConfig->sHeader)); + pHtConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER; + pHtConfig->HtExtendedAddressSupport = HtExtAddressingSameAsCpu; + pHtConfig->HtLinkTriState = HtLinkTriStateSameAsCpu; + pHtConfig->HtReferenceClock = 200; +// Select LS State + pHtConfig->LSx = HtLinkStateSameAsCpu; + pHtConfig->LinkBufferOptimization = OFF; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBHT_TRACE), "[NBHT]HtLibInitializer Exit\n")); + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbHtInit.h b/src/vendorcode/amd/cimx/rd890/nbHtInit.h new file mode 100644 index 000000000000..1f8c23d18165 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbHtInit.h @@ -0,0 +1,126 @@ +/** + * @file + * + * HT definitions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +#ifndef _NBHTINIT_H_ +#define _NBHTINIT_H_ + +///HT link inactive lane +typedef enum { + InactiveLaneStateCadCtrlDrivelToLogic0 = 0, ///< No clock + InactiveLaneStateSameAsPhyOff, ///< Same as PHY OFF + InactiveLaneStateSameAsOperational, ///< Same as operational + InactiveLaneStateSameAsDisconnected, ///< Same as disconnected +} HT_INACTIVE_LANE_STATE; + +AGESA_STATUS +HtLibEarlyInit ( + IN OUT AMD_NB_CONFIG *pConfig + ); + + +AGESA_STATUS +HtLibInitValidateInput ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +LibHtSetNbTransmitterDeemphasis ( + IN UINT8 NbDeemphasisLevel, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +LibHtEnableLxState ( + IN UINT8 LSx, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +AmdHtInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +HtLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +UINT32 +LibHtGetSmuWaData ( + IN AMD_NB_CONFIG *pConfig + ); + +#define LS1 0 +#define LS0 1 +#define LS2 2 +#define LS3 3 + +/// HT link state +typedef enum { + HtLinkStateLS0 = 0, ///< LS0 + HtLinkStateLS1, ///< LS1 + HtLinkStateLS2, ///< LS2 + HtLinkStateLS3, ///< LS3 + HtLinkStateSameAsCpu, ///< Same as set on CPU + HtLinkStateSkipInit = 0x80 ///< Skip initialization +} HT_LS_STATE; + +/// HT Link Tri-state +typedef enum { + HtLinkTriStateCadCtl = 1, ///< control/data + HtLinkTriStateCadCtlClk, ///< CAD clk + HtLinkTriStateSameAsCpu, ///< Same as set on CPU + HtLinkTriStateSkip = 0x80 ///< Skip initialization +} HT_LINK_TRISTATE; + +/// HT Link Tri-state +typedef enum { + HtExtAddressingDisable = 0, ///< Disable ext addressing + HtExtAddressingEnable, ///< Enable Ext addressing + HtExtAddressingSameAsCpu, ///< Set Ext addressing as on CPU + HtExtAddressingSkip = 0x80 ///< Skip initialization +} HT_EXT_ADDRESSING; + +#define HT_PATH_LINK_ID(htPath) (htPath.LinkID & 0xf) +#define HT_PATH_SUBLINK_ID(htPath) (((htPath.LinkID & 0xf0) == 0) ? 0 : (((htPath.LinkID & 0xf0) >> 4) - 1)) + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbHtInterface.c b/src/vendorcode/amd/cimx/rd890/nbHtInterface.c new file mode 100644 index 000000000000..ecb5e0df57c1 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbHtInterface.c @@ -0,0 +1,125 @@ +/** + * @file + * + * HT Init interfaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Early system wide HT init + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ + +AGESA_STATUS +AmdHtInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NBHT_TRACE), "[NBHT]AmdHtInit Enter\n")); + Status = LibNbApiCall (NbHtInit, ConfigPtr); + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NBHT_TRACE), "[NBHT]AmdHtInit Exit [0x%x]\n", Status)); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Early Nb HT init. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ + +AGESA_STATUS +NbHtInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBHT_TRACE), "[NBHT]NbHtInit Enter\n")); + Status = HtLibInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0 , 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + Status = HtLibEarlyInit (NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBHT_TRACE), "[NBHT]NbHtInit Exit [0x%x]\n", Status)); + return Status; +} + diff --git a/src/vendorcode/amd/cimx/rd890/nbInit.c b/src/vendorcode/amd/cimx/rd890/nbInit.c new file mode 100644 index 000000000000..8a5c5dba967d --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbInit.c @@ -0,0 +1,417 @@ +/** + * @file + * + * NB Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Early post validate input parameters + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibEarlyPostInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + NB_CONFIG *pNbConfig; + NB_INFO NbInfo; + + Status = AGESA_SUCCESS; + NbInfo = LibNbGetRevisionInfo (pConfig); + if (NbInfo.Type == NB_UNKNOWN) { + return AGESA_FATAL; + } + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) { + Status = NbLibInitializer (pConfig); + } + if (pNbConfig->SysMemoryTomBelow4G == 0) { + Status = AGESA_FATAL; + } + //pNbConfig->sHeader.InitializerID = PH_AmdEarlyPostInit; + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Mid/Late post validate input parameters + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibPostInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + NB_CONFIG *pNbConfig; + NB_INFO NbInfo; + + NbInfo = LibNbGetRevisionInfo (pConfig); + Status = AGESA_SUCCESS; + if (NbInfo.Type == NB_UNKNOWN) { + return AGESA_FATAL; + } + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) { + Status = AGESA_FATAL; + } + //pNbConfig = GET_NB_CONFIG_PTR (pConfig); + //if (pNbConfig->sHeader.InitializerID != PH_AmdEarlyPostInit) { + // return AGESA_FATAL; + //} + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Prepare NB to boot to OS. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibPrepareToOS ( + IN AMD_NB_CONFIG *pConfig + ) +{ + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, 0xffffffff, BIT7, pConfig); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Multiple NB support + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +NbMultiNbIocInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (GET_BLOCK_CONFIG_PTR (pConfig)->NumberOfNorthbridges > 0) { + if (pConfig->NbPciAddress.AddressValue == 0) { + //Primary NB + Value = BIT3 + (HT_INTERRUPT_ENCODING_OFFSET << 4); + } else { + //Secondary NB + Value = BIT2 + (HT_INTERRUPT_ENCODING_OFFSET << 4); + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~((0x7f << 2) + BIT28) , Value, pConfig); + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~(BIT9 + BIT10 + BIT28), pNbConfig->P2PMode << 9, pConfig); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set NB SSID/SVID. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +NbLibSetSSID ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->SSID == 0xffffffff) { + LibNbPciRead (pConfig->NbPciAddress.AddressValue, AccessWidth32, &pNbConfig->SSID, pConfig); + } + if (pNbConfig->SSID != 0) { + LibNbPciWrite (pConfig->NbPciAddress.AddressValue | NB_PCI_REG50, AccessS3SaveWidth32, &pNbConfig->SSID, pConfig); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Setup UnitId clamping + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +NbLibSetupClumping ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT16 ClumpingCapability; + UINT16 Value; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + Value = 0; + if (LibNbGetCpuFamily () == CPU_FAMILY_NPT) { + return; + } + LibNbPciRead (pConfig->NbPciAddress.AddressValue | NB_PCI_REG58, AccessS3SaveWidth16, &ClumpingCapability, pConfig); + if ((ClumpingCapability & BIT3) != 0 && + (pNbConfig->UnitIdClumping & DEV3_CLUMPING) != 0 && + !LibNbIsDevicePresent (PcieLibGetPortPciAddress (3, pConfig), pConfig)) { + Value |= BIT3; + } + if ((ClumpingCapability & BIT12) != 0 && + (pNbConfig->UnitIdClumping & DEV12_CLUMPING) != 0 && + !LibNbIsDevicePresent (PcieLibGetPortPciAddress (12, pConfig), pConfig)) { + Value |= BIT12; + } + if (Value != 0) { + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG5C, AccessS3SaveWidth16, 0xffff, Value, pConfig); + LibNbPciRMW (MAKE_SBDFO (0, 0, pConfig->NbHtPath.NodeID + 0x18, 0, HT_PATH_LINK_ID (pConfig->NbHtPath) * 4 + HT_PATH_SUBLINK_ID (pConfig->NbHtPath) * 0x10 + 0x110), AccessS3SaveWidth16, 0xffff, Value, pConfig); + } +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set top of memory in NB. + * NB will not pass to CPU any upstream DMA request to address above TOM and TOM2 + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLibSetTopOfMemory ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + UINT32 RD890_TOM2; + UINT32 RD890_TOM3; + + RD890_TOM2 = 0; + RD890_TOM3 = 0; + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig->SysMemoryTomBelow4G != 0) { + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG90, AccessS3SaveWidth32, 0, ((UINT32)pNbConfig->SysMemoryTomBelow4G) << 20, pConfig); + } + if (pNbConfig->SysMemoryTomAbove4G != 0) { + if ((pNbConfig->SysMemoryTomAbove4G - 1) <= 0xfffff) { + RD890_TOM2 = pNbConfig->SysMemoryTomAbove4G; + } else { + RD890_TOM2 = (UINT32) (0xFD00000000 >> 20); + RD890_TOM3 = pNbConfig->SysMemoryTomAbove4G; + } + } + if (RD890_TOM2 != 0) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG31, AccessS3SaveWidth32, 0, (RD890_TOM2 >> 12), pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG30, AccessS3SaveWidth32, 0, (RD890_TOM2 << 20) | 1, pConfig); + } + if (RD890_TOM3 != 0) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4E, AccessS3SaveWidth32, 0, ((UINT32)pNbConfig->SysMemoryTomAbove4G >> 2) | BIT31, pConfig); + } + return AGESA_SUCCESS; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Loget COre APic ID and dtore to scratch + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +NbLibGetCore0ApicId ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT64 Value; + UINT32 Apic20; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + LibAmdMsrRead (0x0000001B, &Value, (AMD_CONFIG_PARAMS *)pConfig); + LibNbMemRead ((Value & 0xfffffffff000) + 0x20, AccessWidth32, &Apic20, pConfig); + pNbConfig->Reserved = (UINT16) (Apic20 >> 24); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Direct NMI message to Core 0 + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +NbLibSetNmiRouting ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + NB_MISC_REG12, + AccessS3SaveWidth32, + 0x00ffffff, + (UINT32)pNbConfig->Reserved << 24, + pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for all NB. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdNbInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (NbLibInitializer, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB config structure initializer + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +NbLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT64 Value64; + NB_CONFIG *pNbConfig; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + if (pNbConfig == NULL) { + return AGESA_WARNING; + } + if (pNbConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) { + return AGESA_SUCCESS; + } + LibAmdMemFill (pNbConfig, 0, sizeof (NB_CONFIG), (AMD_CONFIG_PARAMS *)&(pNbConfig->sHeader)); + pNbConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER; + // Get TOM and TOM2 + LibAmdMsrRead (0xC001001a, &Value64, (AMD_CONFIG_PARAMS *)pConfig); + pNbConfig->SysMemoryTomBelow4G = (UINT16) (Value64 >> 20); + LibAmdMsrRead (0xC0010010, &Value64, (AMD_CONFIG_PARAMS *)pConfig); + if ((Value64 & BIT21) != 0) { + LibAmdMsrRead (0xC001001d, &Value64, (AMD_CONFIG_PARAMS *)pConfig); + pNbConfig->SysMemoryTomAbove4G = (UINT32) (Value64 >> 20); + } + pNbConfig->P2PMode = 1; + pNbConfig->UnitIdClumping = 3; + return AGESA_SUCCESS; +} + + diff --git a/src/vendorcode/amd/cimx/rd890/nbInit.h b/src/vendorcode/amd/cimx/rd890/nbInit.h new file mode 100644 index 000000000000..36a83f8b9b46 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbInit.h @@ -0,0 +1,107 @@ +/** + * @file + * + * NB definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBINIT_H_ +#define _NBINIT_H_ + + +VOID +NbLibSetSSID ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +NbLibSetupClumping ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbLibSetTopOfMemory ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbLibEarlyPostInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbLibPostInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbLibPrepareToOS ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +NbMultiNbIocInit ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +AmdNbInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +#ifndef HT_INTERRUPT_ENCODING_OFFSET + #define HT_INTERRUPT_ENCODING_OFFSET 0x2 +#endif + +VOID +NbLibSetNmiRouting ( + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbLibGetCore0ApicId ( + IN AMD_NB_CONFIG *pConfig + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbInitializer.c b/src/vendorcode/amd/cimx/rd890/nbInitializer.c new file mode 100644 index 000000000000..ab4a0041a8bb --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbInitializer.c @@ -0,0 +1,133 @@ +/** + * @file + * + * NB Post Init interfaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +AmdInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for all NB. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (NbInitializer, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB structure initializer. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbInitializer Enter\n")); + Status = MiscInitializer (NbConfigPtr); + if (Status == AGESA_FATAL) { + return Status; + } + Status = HtLibInitializer (NbConfigPtr); + if (Status == AGESA_FATAL) { + return Status; + } + Status = PcieLibInitializer (NbConfigPtr); + if (Status == AGESA_FATAL) { + return Status; + } + Status = NbLibInitializer (NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbInitializer Exit\n")); + return Status; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbInitializer.h b/src/vendorcode/amd/cimx/rd890/nbInitializer.h new file mode 100644 index 000000000000..0ae6d16b4033 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbInitializer.h @@ -0,0 +1,57 @@ +/** + * @file + * + * NB Post Init interfaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +#ifndef _NBINITIALIZER_H_ +#define _NBINITIALIZER_H_ + + +AGESA_STATUS +AmdInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbInterface.c b/src/vendorcode/amd/cimx/rd890/nbInterface.c new file mode 100644 index 000000000000..7d41b2605348 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbInterface.c @@ -0,0 +1,312 @@ +/** + * @file + * + * NB Post Init interfaces + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd Init all NB at early POST. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdEarlyPostInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (NbEarlyPostInit, ConfigPtr); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Init at early post. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbEarlyPostInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbEarlyPostInit Enter\n")); + + Status = NbLibEarlyPostInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + NbLibSetTopOfMemory (NbConfigPtr); + NbLibSetupClumping (NbConfigPtr); + NbMultiNbIocInit (NbConfigPtr); +#ifndef EPREADY_WORKAROUND_DISABLED + PcieEpReadyWorkaround (NbConfigPtr); +#endif + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbEarlyPostInit Exit [ %x]\n", Status)); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd Init all NB at mid POST. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdMidPostInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (NbMidPostInit, ConfigPtr); +#ifndef IOMMU_SUPPORT_DISABLE + NbIommuInit (ConfigPtr); +#endif + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Init at mid POST. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbMidPostInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMidPostInit Enter\n")); + Status = NbLibPostInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + NbLibSetIOAPIC (NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMidPostInit Exit [ %x]\n", Status)); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd Init all NB at late POST. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdLatePostInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (NbLatePostInit, ConfigPtr); +#ifndef IOMMU_SUPPORT_DISABLE + NbIommuAcpiFixup (ConfigPtr); +#endif + return Status; +} +/*----------------------------------------------------------------------------------------*/ +/** + * NB Init at late post. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbLatePostInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbLatePostInit Enter\n")); + Status = NbLibPostInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + NbLibGetCore0ApicId (NbConfigPtr); + NbLibSetNmiRouting (NbConfigPtr); + NbLibSetSSID (NbConfigPtr); + Status = NbLibPrepareToOS (NbConfigPtr); + LibNbSetDefaultIndexes (NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbLatePostInit Exit [ %x]\n", Status)); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd Init all NB at S3 Resume. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdS3InitIommu ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + +#ifndef IOMMU_SUPPORT_DISABLE + NbIommuInitS3 (ConfigPtr); +#endif + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd Init all NB at S3 Resume. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdS3Init ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (NbS3Init, ConfigPtr); + + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Init at S3 + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbS3Init ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbS3Init Enter\n")); + Status = NbLibPostInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + Status = NbLibSetTopOfMemory (NbConfigPtr); + NbLibSetupClumping (NbConfigPtr); + NbMultiNbIocInit (NbConfigPtr); + NbLibSetSSID (NbConfigPtr); + NbLibSetIOAPIC (NbConfigPtr); + NbLibSetNmiRouting (NbConfigPtr); + Status = NbLibPrepareToOS (NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbS3Init Exit [%x]\n", Status)); + return Status; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbIoApic.c b/src/vendorcode/amd/cimx/rd890/nbIoApic.c new file mode 100644 index 000000000000..045883def827 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbIoApic.c @@ -0,0 +1,194 @@ +/** + * @file + * + * NB IOAPIC Initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*! \var APIC_DEVICE_INFO gDefaultApicDeviceInfoTable[] + * \brief Default IO APIC interrupt mapping + * \details + * @li Interrupt Info for HT referenced as gDefaultApicDeviceInfoTable[0] + * @li Interrupt Info for IOMMU referenced as gDefaultApicDeviceInfoTable[1] + * @li Interrupt Info for device 2 referenced as gDefaultApicDeviceInfoTable[2] + * @li Interrupt Info for device 3 referenced as gDefaultApicDeviceInfoTable[3] + * @li ... + * @li Interrupt Info for device 13 can be referenced as gDefaultApicDeviceInfoTable[13] + */ +CONST APIC_DEVICE_INFO gDefaultApicDeviceInfoTable[] = { +// Group Swizzling Port Int Pin + {0, 0, 31}, //HT + {0, 0, 31}, //IOMMU + {0, ABCD, 28}, //Dev2 Grp0 [Int - 0..3] + {1, ABCD, 28}, //Dev3 Grp1 [Int - 4..7] + {5, ABCD, 28}, //Dev4 Grp5 [Int - 20..23] + {5, CDAB, 28}, //Dev5 Grp5 [Int - 20..23] + {6, BCDA, 29}, //Dev6 Grp6 [Int - 24..27] + {6, CDAB, 29}, //Dev7 Grp6 [Int - 24..27] + {0, 0, 0 }, // Reserved + {6, ABCD, 29}, //Dev9 Grp6 [Int - 24..27] + {5, BCDA, 30}, //Dev10 Grp5 [Int - 20..23] + {2, ABCD, 30}, //Dev11 Grp2 [Int - 8..11] + {3, ABCD, 30}, //Dev12 Grp3 [Int - 12..15] + {4, ABCD, 30} //Dev13 Grp4 [Int - 16..19] +}; + +CONST APIC_REGISTER_INFO gApicRegisterInfoTable[] = { + {0, NB_IOAPICCFG_REG03, 0, NB_IOAPICCFG_REG06}, //Dev2 + {8, NB_IOAPICCFG_REG03, 8, NB_IOAPICCFG_REG06}, //Dev3 + {16, NB_IOAPICCFG_REG03, 16, NB_IOAPICCFG_REG06}, //Dev4 + {24, NB_IOAPICCFG_REG03, 24, NB_IOAPICCFG_REG06}, //Dev5 + {0, NB_IOAPICCFG_REG04, 0, NB_IOAPICCFG_REG07}, //Dev6 + {8, NB_IOAPICCFG_REG04, 8, NB_IOAPICCFG_REG07}, //Dev7 + {0, 0, 0, 0 }, //Dev8 + {16, NB_IOAPICCFG_REG04, 24 ,NB_IOAPICCFG_REG07}, //Dev9 + {24, NB_IOAPICCFG_REG04, 0 ,NB_IOAPICCFG_REG08}, //Dev10 + {0, NB_IOAPICCFG_REG05, 8 ,NB_IOAPICCFG_REG08}, //Dev11 + {8, NB_IOAPICCFG_REG05, 16 ,NB_IOAPICCFG_REG08}, //Dev12 + {16, NB_IOAPICCFG_REG05, 24 ,NB_IOAPICCFG_REG08}, //Dev13 +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Configure IO APIC + * Enable IO APIC base address decoding. Enable default forwarding interrupt to SB + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +NbLibSetIOAPIC ( + IN AMD_NB_CONFIG *pConfig + ) +{ + NB_CONFIG *pNbConfig; + PORT PortId; + APIC_DEVICE_INFO ApicDeviceInfoTable[sizeof (gDefaultApicDeviceInfoTable) / sizeof (APIC_DEVICE_INFO)]; + APIC_REGISTER_INFO *pApicRegisterInfoTable; + + pNbConfig = GET_NB_CONFIG_PTR (pConfig); + pApicRegisterInfoTable = (APIC_REGISTER_INFO*)FIX_PTR_ADDR (&gApicRegisterInfoTable[0], NULL); + if (pNbConfig->IoApicBaseAddress != 0 ) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), "[NB]NbLibSetIOAPIC\n")); + //Copy default routing to local memory buffer + LibAmdMemCopy (&ApicDeviceInfoTable, (APIC_DEVICE_INFO*)FIX_PTR_ADDR (&gDefaultApicDeviceInfoTable[0], NULL), sizeof (ApicDeviceInfoTable), (AMD_CONFIG_PARAMS *)&(pNbConfig->sHeader)); + //Callback to platform BIOS to update + LibNbCallBack (PHCB_AmdUpdateApicInterruptMapping, (UINTN)&ApicDeviceInfoTable, pConfig); + //Setup base address + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " Apic Base %x\n", (UINT32)pNbConfig->IoApicBaseAddress & 0xffffff00)); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, NB_IOAPICCFG_REG01, AccessS3SaveWidth32, (UINT32) (0xff), (UINT32)pNbConfig->IoApicBaseAddress & 0xffffff00, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, NB_IOAPICCFG_REG02, AccessS3SaveWidth32, 0x0, ((UINT32*)&pNbConfig->IoApicBaseAddress)[1] , pConfig); + //Setup interrupt mapping + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + PCI_ADDR Port; + APIC_REGISTER_INFO RegisterInfo; + APIC_DEVICE_INFO PortInfo; + PORT NativePortId; + if (PortId == 8 || !PcieLibIsValidPortId (PortId, pConfig)) { + continue; + } + NativePortId = PcieLibNativePortId (PortId, pConfig); + Port = PcieLibGetPortPciAddress (PortId, pConfig); + RegisterInfo = pApicRegisterInfoTable[NativePortId - MIN_PORT_ID]; + PortInfo = ApicDeviceInfoTable[Port.Address.Device]; + //Setup routing for EP + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, + RegisterInfo.EpRoutingRegister, + AccessS3SaveWidth32, + 0xFFFFFFFF, + (PortInfo.Group | (PortInfo.Swizzle << 4)) << RegisterInfo.EpRoutingOffset, + pConfig + ); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " EP Routing Dev[%d] NativePortId[%d] PortId[%d] Group - %d Swizzle - %d\n", Port.Address.Device, NativePortId, PortId, PortInfo.Group, PortInfo.Swizzle)); + //Setup routing for RC + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, + RegisterInfo.RcRoutingRegister, + AccessS3SaveWidth32, + 0xFFFFFFFF, + (PortInfo.Pin) << RegisterInfo.RcRoutingOffset, + pConfig + ); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " RC Routing Dev[%d] NativeDev[%d] Pin - %d \n", Port.Address.Device, NativePortId, PortInfo.Pin)); + + } + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, + NB_IOAPICCFG_REG09, + AccessS3SaveWidth32, + 0x0, + ApicDeviceInfoTable[0].Pin | (ApicDeviceInfoTable[1].Pin << 8), + pConfig + ); + //Enable IO API MMIO decoding and configure features + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_IOAPICCFG_INDEX, NB_IOAPICCFG_REG00, AccessS3SaveWidth32, 0x0 , 0x1f , pConfig); + } +} diff --git a/src/vendorcode/amd/cimx/rd890/nbIoApic.h b/src/vendorcode/amd/cimx/rd890/nbIoApic.h new file mode 100644 index 000000000000..f2ba8944d283 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbIoApic.h @@ -0,0 +1,52 @@ +/** + * @file + * + * NB IOAPIC Initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +#ifndef _NBIOAPIC_H_ +#define _NBIOAPIC_H_ + + +VOID +NbLibSetIOAPIC ( + IN AMD_NB_CONFIG *pConfig + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbIommu.c b/src/vendorcode/amd/cimx/rd890/nbIommu.c new file mode 100644 index 000000000000..705b1a82fdff --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbIommu.c @@ -0,0 +1,1737 @@ +/** + * @file + * + * Routines for IOMMU. + * + * Implement the IOMMU init and ACPI feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" +#include "amdSbLib.h" + +#define Int32FromChar(a,b,c,d) ((a) << 0 | (b) << 8 | (c) << 16 | (d) << 24) + +/*---------------------------------------------------------------------------------------- + * R D 8 9 0 / S D A T A + *---------------------------------------------------------------------------------------- + */ + +// IOMMU Initialization + +INDIRECT_REG_ENTRY +CONST +STATIC +IommuL1Table[] = { + // 01. 0x0C [30:28]=7 L1VirtOrderQueues Increase maximum number virtual queues + // for all devices + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP1 | L1REG_0C, 0x8FFFFFFF, 0x70000000 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP2 | L1REG_0C, 0x8FFFFFFF, 0x70000000 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_SB | L1REG_0C, 0x8FFFFFFF, 0x70000000 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3A | L1REG_0C, 0x8FFFFFFF, 0x70000000 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3B | L1REG_0C, 0x8FFFFFFF, 0x70000000 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_VC1 | L1REG_0C, 0x8FFFFFFF, 0x70000000 }, + // 02. 0x07 [11] L1DEBUG_1 Multiple error logs possible + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP1 | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP2 | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5}, + { L1CFG_SEL_WR_EN | L1CFG_SEL_SB | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5}, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3A | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5}, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3B | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5}, + { L1CFG_SEL_WR_EN | L1CFG_SEL_VC1 | L1REG_07, (UINT32)~(BIT8 + BIT9 + BIT10), BIT11 + BIT5}, + // 02. 0x06 [0] L1DEBUG_0 Phantom function disable + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP1 | L1REG_06, (UINT32)~BIT0, 0 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP2 | L1REG_06, (UINT32)~BIT0, 0 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_SB | L1REG_06, (UINT32)~BIT0, 0 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3A | L1REG_06, (UINT32)~BIT0, 0 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_GPP3B | L1REG_06, (UINT32)~BIT0, 0 }, + { L1CFG_SEL_WR_EN | L1CFG_SEL_VC1 | L1REG_06, (UINT32)~BIT0, 0 } +}; + +INDIRECT_REG_ENTRY +CONST +STATIC +IommuL2Table[] = { + // 01. 0x0C [29]=1 IFifoClientPriority Set attribute to VC1 L1 client high priority + { L2CFG_SEL_WR_EN | L2REG_0C, 0xD0000000, 0x20000000 }, + // 02. 0x10 [9:8]=2 DTCInvalidationSel DTC cache invalidation sequential precise + { L2CFG_SEL_WR_EN | L2REG_10, 0xFFFFFC00, 0x00000200 }, + // 03. 0x14 [9:8]=2 ITCInvalidationSel ... cache invalidation sequential precise + { L2CFG_SEL_WR_EN | L2REG_14, 0xFFFFFC00, 0x00000200 }, + // 04. 0x18 [9:8]=2 IPTCAInvalidationSel ... cache invalidation sequential precise + { L2CFG_SEL_WR_EN | L2REG_18, 0xFFFFFC00, 0x00000200 }, + // 05. 0x1C [9:8]=2 IPTCBInvalidationSel ... cache invalidation sequential precise + { L2CFG_SEL_WR_EN | L2REG_1C, 0xFFFFFC00, 0x00000200 }, + // 06. 0x50 [9:8]=2 PDCInvalidationSel ... cache invalidation sequential precise + { L2CFG_SEL_WR_EN | L2REG_50, 0xFFFFFC00, 0x00000200 }, + // 07. 0x10 [4]=1 DTCParityEn DTC cache parity protection + { L2CFG_SEL_WR_EN | L2REG_10, (UINT32)~BIT4, BIT4 }, + // 08. 0x14 [4]=1 ITCParityEn ... cache parity protection + { L2CFG_SEL_WR_EN | L2REG_14, (UINT32)~BIT4, BIT4 }, + // 09. 0x18 [4]=1 PTCAParityEn ... cache parity protection + { L2CFG_SEL_WR_EN | L2REG_18, (UINT32)~BIT4, BIT4 }, + // 10. 0x1C [4]=1 PTCBParityEn ... cache parity protection + { L2CFG_SEL_WR_EN | L2REG_1C, (UINT32)~BIT4, BIT4 }, + // 11. 0x50 [4]=1 PDCParityEn ... cache parity protection + { L2CFG_SEL_WR_EN | L2REG_50, (UINT32)~BIT4, BIT4 }, + // 12. 0x80 [0]=1 ERRRuleLock0 Lock fault detection rule sets + // 0x30 [0]=1 ERRRuleLock1 + { L2CFG_SEL_WR_EN | L2REG_80, (UINT32)~BIT0, BIT0 }, + { L2CFG_SEL_WR_EN | L2REG_30, (UINT32)~BIT0, BIT0 }, + // 13. 0x56 [2]=0 L2_CP_CONTROL Disable CP flush on invalidation + // 0x56 [1]=1 L2_CP_CONTROL Enable CP flush on wait + { L2CFG_SEL_WR_EN | L2REG_56, 0xFFFFFFF9, BIT1 }, + // A21 + { L2CFG_SEL_WR_EN | L2REG_06, 0xFFFFFFFF, BIT6 + BIT7 + BIT5 + BIT8 }, + { L2CFG_SEL_WR_EN | L2REG_47, 0xFFFFFFFF, BIT1 + BIT3 + BIT0 + BIT4 + BIT5 }, + { L2CFG_SEL_WR_EN | L2REG_07, 0xFFFFFFFF, BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT8 + BIT6}, + +}; + +// IOMMU ACPI Initialization + +IOMMU_IVRS_HEADER +STATIC +RD890S_DfltHeader = { +// 'SRVI', + Int32FromChar ('S', 'R', 'V', 'I'), + 48, + 1, + 0, + {'A', 'M', 'D', ' ', ' ', 0}, + {'R', 'D', '8', '9', '0', 'S', 0, 0}, + {'1', ' ', ' ', 0}, + {'A','M','D',' '}, + {'1', ' ', ' ', 0}, + 0, + 0 +}; + +IOMMU_EXCLUSIONTABLE +STATIC +RD890S_DfltExclusion = { + sizeof (UINTN) + sizeof (IOMMU_EXCLUSIONRANGE) * 0, + {{0, 0}} +}; + +IOMMU_DEVICELIST +STATIC +RD890S_DfltDevices = { + (sizeof (UINT16) + sizeof (UINT16) * 12), + { + DEVICEID_NB, // Type 2 entry, Device 0, Func 0 <-- NB all functions + DEVICEID_GPP1_0, // Type 2 entry, Device 2, Func 0 <-- GPP1 port 0 + DEVICEID_GPP1_1, // Type 2 entry, Device 3, Func 0 <-- GPP1 port 1 + DEVICEID_GPP3A_0, // Type 2 entry, Device 4, Func 0 <-- GPP3a port 0 + DEVICEID_GPP3A_1, // Type 2 entry, Device 5, Func 0 <-- GPP3a port 1 + DEVICEID_GPP3A_2, // Type 2 entry, Device 6, Func 0 <-- GPP3a port 2 + DEVICEID_GPP3A_3, // Type 2 entry, Device 7, Func 0 <-- GPP3a port 3 + DEVICEID_GPP3A_4, // Type 2 entry, Device 9, Func 0 <-- GPP3a port 4 + DEVICEID_GPP3A_5, // Type 2 entry, Device A, Func 0 <-- GPP3a port 5 + DEVICEID_GPP2_0, // Type 2 entry, Device B, Func 0 <-- GPP2 port 0 + DEVICEID_GPP2_1, // Type 2 entry, Device C, Func 0 <-- GPP2 port 1 + DEVICEID_GPP3B_0, // Type 2 entry, Device D, Func 0 <-- GPP3b port 0 + } +}; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- +*/ + +// IOMMU Library + +BOOLEAN +NbIommuEnabled ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +BOOLEAN +IommuCheckEnable ( + IN PCI_ADDR IommuPciAddress, + IN AMD_NB_CONFIG *pConfig + ); + +BOOLEAN +IommuCheckHp ( + IN UINT16 DeviceId, + IN AMD_NB_CONFIG *pConfig + ); + +BOOLEAN +IommuCheckPhantom ( + IN UINT16 DeviceId, + IN AMD_NB_CONFIG *pConfig + ); + +UINT32 +IommuGetL1 ( + IN UINT16 DeviceId + ); + +UINT8 +IommuGetLog2 ( + IN UINT32 Value + ); + +VOID +IommuRecordBusDevFuncInfo ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN UINT16 DeviceId, + IN AMD_NB_CONFIG *pConfig + ); + + +AGESA_STATUS +IommuInit ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuInitL2CacheControl ( + IN IOMMU_PCI_TOPOLOGY *PciPtr, + IN OUT AMD_NB_CONFIG *pConfig +); + +VOID +IommuPlaceHeader ( + IN OUT VOID *BufferPtr, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuPlaceIvhdAndScanDevices ( + IN OUT VOID *BufferPtr, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuPlaceIvmdAndExclusions ( + IN OUT VOID *BufferPtr, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuIvhdNorthbridgeDevices ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuIvhdSouthbridgeDevices ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuIvhdApicsAndHpets ( + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN OUT AMD_NB_CONFIG *pConfig + ); + +VOID +IommuCreateDeviceEntry ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN UINT16 DeviceId, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +IommuCreate4ByteEntry ( + IN UINT8 Type, + IN UINT8 Data, + IN UINT16 Word1, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr + ); + +VOID +IommuCreate8ByteEntry ( + IN UINT8 Type, + IN UINT8 Data, + IN UINT16 Word1, + IN UINT8 Byte4, + IN UINT16 Word5, + IN UINT8 Byte7, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr + ); + +VOID +IommuFinalizeIvrs ( + IN OUT VOID *BufferPtr, + IN AMD_NB_CONFIG *pConfig + ); + +// IOMMU ACPI Final + +UINT64 +IommuGetApicBaseAddress ( + IN VOID *DevicePtr, + IN AMD_NB_CONFIG *pConfig + ); + +UINT8 +IommuGetApicId ( + IN UINT64 BaseAddress, + IN VOID *MadtPtr, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +NbIommuHwInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuHwTopologyInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +IommuTopologyInit ( + IN OUT AMD_NB_CONFIG *pConfig + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if IOMMU enable on platform + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table created + * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found + * @retval AGESA_ERROR IOMMU initialization failed. + * + */ +BOOLEAN +NbIommuEnabled ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + UINT8 NorthbridgeId; + BOOLEAN Result; + Result = FALSE; + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + if (ConfigPtr->Northbridges[NorthbridgeId].pNbConfig->IommuBaseAddress != 0) { + Result = TRUE; + break; + } + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Iommu Initialization for all NB in system. + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table created + * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found + * @retval AGESA_ERROR IOMMU initialization failed. + * + */ +AGESA_STATUS +NbIommuInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = AGESA_SUCCESS; + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInit Enter\n")); + + if (NbIommuEnabled (ConfigPtr)) { + NbIommuHwInit (ConfigPtr); + NbIommuAcpiInit (ConfigPtr); + NbIommuHwTopologyInit (ConfigPtr); + } else { + Status = AGESA_UNSUPPORTED; + } + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInit Exit [Status = 0x%x]\n", Status)); + return Status; +} + + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Iommu Initialization for all NB in system. + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table created + * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found + * @retval AGESA_ERROR IOMMU initialization failed. + * + */ +AGESA_STATUS +NbIommuInitS3 ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = AGESA_SUCCESS; + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInitS3 Enter\n")); + + if (NbIommuEnabled (ConfigPtr)) { + NbIommuHwInit (ConfigPtr); + NbIommuHwTopologyInit (ConfigPtr); + } else { + Status = AGESA_UNSUPPORTED; + } + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuInitS3 Exit [Status = 0x%x]\n", Status)); + return Status; +} + + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Iommu HW Initialization for all NB in system. + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table created + * @retval AGESA_ERROR IOMMU initialization failed. + * + */ +AGESA_STATUS +NbIommuHwInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + UINT8 NorthbridgeId; + AMD_NB_CONFIG *pConfig; + + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + pConfig = &ConfigPtr->Northbridges[NorthbridgeId]; + ConfigPtr->CurrentNorthbridge = NorthbridgeId; + IommuInit (pConfig); + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Iommu HW Initialization for all NB in system. + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table created + * @retval AGESA_ERROR IOMMU initialization failed. + * + */ +AGESA_STATUS +NbIommuHwTopologyInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + UINT8 NorthbridgeId; + AMD_NB_CONFIG *pConfig; + + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + pConfig = &ConfigPtr->Northbridges[NorthbridgeId]; + ConfigPtr->CurrentNorthbridge = NorthbridgeId; + IommuTopologyInit (pConfig); + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Iommu Initialization for all NB in system. + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table created + * @retval AGESA_UNSUPPORTED IOMMU not enabled or not found + * @retval AGESA_ERROR IOMMU initialization failed. + * + */ +AGESA_STATUS +NbIommuAcpiInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + UINT8 NorthbridgeId; + AGESA_STATUS Status; + AMD_NB_CONFIG *pConfig; + NB_BUFFER_PARAMS Ivrs; + UINTN IvrsHandle; + + Status = AGESA_SUCCESS; + Ivrs.BufferLength = 0; + Ivrs.BufferHandle = IVRS_HANDLE; + Ivrs.BufferPtr = NULL; + pConfig = &ConfigPtr->Northbridges[0]; + ConfigPtr->CurrentNorthbridge = 0; + IvrsHandle = 0; + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiInit Enter\n")); + + // Get a buffer for IVRS + Ivrs.BufferLength = IVRS_BUFFER_SIZE; + Status = LibNbCallBack (PHCB_AmdAllocateBuffer, (UINTN)&Ivrs, &ConfigPtr->Northbridges[0]); + if (Status != AGESA_SUCCESS || Ivrs.BufferPtr == NULL) { + // Table creation failed + return AGESA_ERROR; + } + + // Clear buffer before using + LibAmdMemFill (Ivrs.BufferPtr, 0, Ivrs.BufferLength, (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + + // PLACE OUR ACPI IVRS TABLE + // 1. Create IVRS header + // 2. For each northbridge place IVHD + // 3. For northbridge 0 only, place IVMD exclusion entries + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + pConfig = &ConfigPtr->Northbridges[NorthbridgeId]; + ConfigPtr->CurrentNorthbridge = NorthbridgeId; + if (NorthbridgeId == 0) { + IommuPlaceHeader (Ivrs.BufferPtr, pConfig); + } + IommuPlaceIvhdAndScanDevices (Ivrs.BufferPtr, pConfig); + IommuPlaceIvmdAndExclusions (Ivrs.BufferPtr, pConfig); + } + IommuFinalizeIvrs (Ivrs.BufferPtr, pConfig); + + LibAmdSetAcpiTable (Ivrs.BufferPtr, TRUE, &IvrsHandle); + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiInit [IVRS TableAddress = 0x%x]\n", (UINT32)(Ivrs.BufferPtr))); + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiInit Exit [Status = 0x%x]\n", Status)); + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Iommu IVRS fixup for APICS + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * @retval AGESA_SUCCESS IOMMU initialized and table patched, or no patching required + * @retval AGESA_ERROR IOMMU enabled but no previously generated IVRC table found. + * + */ +AGESA_STATUS +NbIommuAcpiFixup ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + UINT8 ApicId; + UINT64 ApicBaseAddress; + UINT8 NorthbridgeId; + BOOLEAN IommuFound; + VOID *DevicePtr; + VOID *IvhdPtr; + VOID *IvrsPtr; + VOID *MadtPtr; + AMD_NB_CONFIG *pConfig; + PCI_ADDR IommuPciAddress; + UINTN IvrsHandle; + + + pConfig = &ConfigPtr->Northbridges[0]; + IommuFound = FALSE; + ApicId = 0xFF; + ApicBaseAddress = 0; + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup Enter\n")); + + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + pConfig = &ConfigPtr->Northbridges[NorthbridgeId]; + ConfigPtr->CurrentNorthbridge = NorthbridgeId; + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + if (IommuCheckEnable (IommuPciAddress, pConfig)) { + IommuFound = TRUE; + } + } + + // Any Iommus enabled? If no, we don't need to patch anything + if (!IommuFound) { + return AGESA_SUCCESS; + } + + // Check for an IVRS + // Check IVRS for a type 10 block (IVHD) + // Check for an MADT + // If these conditions fail, abort + +// Status = LibAmdGetAcpiTable ('SRVI', &IvrsPtr, &IvrsHandle); + Status = LibAmdGetAcpiTable (Int32FromChar ('S', 'R', 'V', 'I'), &IvrsPtr, &IvrsHandle); + if (Status != AGESA_SUCCESS) { +// REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, 'SRVI', 0, 0, 0, pConfig); + REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, Int32FromChar ('S', 'R', 'V', 'I'), 0, 0, 0, pConfig); + return AGESA_ERROR; + } + +// Status = LibAmdGetAcpiTable ('CIPA', &MadtPtr, NULL); + Status = LibAmdGetAcpiTable (Int32FromChar ('C', 'I', 'P', 'A'), &MadtPtr, NULL); + if (Status != AGESA_SUCCESS) { +// REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, 'CIPA', 0, 0, 0, pConfig); + REPORT_EVENT (AGESA_ERROR, GENERAL_ERROR_LOCATE_ACPI_TABLE, Int32FromChar ('C', 'I', 'P', 'A'), 0, 0, 0, pConfig); + return AGESA_ERROR; + } + + IvhdPtr = LibAmdGetFirstIvrsBlockEntry (TYPE_IVHD, IvrsPtr); + if (IvhdPtr == NULL) { + return AGESA_ERROR; + } + + // An IVRS can contain one or more IVHD entries (one per IOMMU) + // Each IVHD entry can contain one or more APIC entries + + while (IvhdPtr != NULL) { + DevicePtr = LibAmdGetFirstDeviceEntry (DE_SPECIAL, IvhdPtr); + do { + // Be sure to only fix APIC entries + if (*(UINT8*) ((UINT8*)DevicePtr + DE_SPECIAL_VARIETY) == VARIETY_IOAPIC) { + ApicBaseAddress = IommuGetApicBaseAddress (DevicePtr, pConfig); + ApicId = IommuGetApicId (ApicBaseAddress, MadtPtr, pConfig); + *(UINT8*)((UINT8*)DevicePtr + DE_SPECIAL_ID) = ApicId; + } + DevicePtr = LibAmdGetNextDeviceEntry (DE_SPECIAL, DevicePtr, IvhdPtr); + } while (DevicePtr != NULL); + + IvhdPtr = LibAmdGetNextIvrsBlockEntry (TYPE_IVHD, IvhdPtr, IvrsPtr); + } + + LibAmdSetAcpiTable (IvrsPtr, TRUE, &IvrsHandle); + + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup [IVRS TableAddress = 0x%x]\n", (UINT32)IvrsPtr)); + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup [APIC TableAddress = 0x%x]\n", (UINT32)MadtPtr)); + CIMX_TRACE ((TRACE_DATA (ConfigPtr, CIMX_NB_TRACE), "[NBIOMMU]NbIommuAcpiFixup Exit\n")); + + return AGESA_SUCCESS; +} + +/*---------------------------------------------------------------------------------------- + * P R I V A T E + *---------------------------------------------------------------------------------------- + */ +UINT32 IommuMmioInitTable[] = { + 0x8, 0x0, + 0xC, 0x08000000, + 0x10, 0x0, + 0x14, 0x08000000, + 0x2000, 0x0, + 0x2008, 0x0 +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Nb Iommu Initialization. + * + * @param[in] pConfig Northbridge configuration pointer + * @retval AGESA_SUCCESS IOMMU enable and initialized succesfully. + * @retval AGESA_UNSUPPORTED IOMMU not initialized. + */ +AGESA_STATUS +IommuInit ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT8 CapBase; + PCI_ADDR IommuPciAddress; + UINTN i; + + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + + // If the base address = 0, don't enable IOMMU + if (pConfig->pNbConfig->IommuBaseAddress == 0) { + return AGESA_UNSUPPORTED; + } + + // NBMISCIND:0x75 IOC_FEATURE_CNTL_10_0[10]=1 + // 0=disable + // 1=enable + + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG75, AccessS3SaveWidth32, (UINT32)~(BIT28), BIT0, pConfig); + + // Get Capabilities pointer 32h (points to 40h) - capability ID 0x0F. Not found, we have no IOMMU. + CapBase = LibNbFindPciCapability (IommuPciAddress.AddressValue, IOMMU_CAPID, pConfig); + if (CapBase == 0) { + return AGESA_UNSUPPORTED; + } + + // IOMMU_ADAPTER_ID_W - RW - 32 bits - nbconfigfunc2:0x68 + // SUBSYSTEM_VENDOR_ID_W 15:0 0x0 Sets the subsystem vendor ID register header + // SUBSYSTEM_ID_W 31:16 0x0 Sets the subsystem ID register in the configuration header + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), "[NBIOMMU]Iommu Device Found [PCI Address = 0x%x]\n", IommuPciAddress.AddressValue)); + if (pConfig->pNbConfig->SSID == PCI_INVALID) { + LibNbPciRead (IommuPciAddress.AddressValue, AccessWidth32, &pConfig->pNbConfig->SSID, pConfig); + } + if (pConfig->pNbConfig->SSID) { + LibNbPciWrite (IommuPciAddress.AddressValue | 0x68, AccessS3SaveWidth32, &pConfig->pNbConfig->SSID, pConfig); + } + + // Get Capabilities pointer 32h (points to 40h) - capability ID 0x0F + // Set Cap_Offset+04h [31:14] Base Address Low [31:14] + // Set Cap_Offset+08h [31:0] Base Address High [64:32] + // Set Cap_Offset+04h [0] Enable + LibNbPciRMW ((IommuPciAddress.AddressValue | (CapBase + 8)), AccessS3SaveWidth32, 0x0, ((UINT32*)&pConfig->pNbConfig->IommuBaseAddress)[1], pConfig); + LibNbPciRMW ((IommuPciAddress.AddressValue | (CapBase + 4)), AccessS3SaveWidth32, 0x0, ((UINT32*)&pConfig->pNbConfig->IommuBaseAddress)[0], pConfig); + + // Enable zeroing of address for zero-byte reads when IOMMU enabled + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG01, AccessS3SaveWidth32, (UINT32)~(BIT8 | BIT9), BIT8, pConfig); + + // 8.3.1 L1 Initialization + LibNbIndirectTableInit (IommuPciAddress.AddressValue | L1CFG_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR(&IommuL1Table[0],NULL), + (sizeof (IommuL1Table) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + + // 8.3.3.1 L2 Common Initialization + LibNbIndirectTableInit (IommuPciAddress.AddressValue | L2CFG_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR(&IommuL2Table[0], NULL), + (sizeof (IommuL2Table) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + //Configure PDC cache to 12-way set associative cache for A21 + if (LibNbGetRevisionInfo (pConfig).Revision > NB_REV_A11) { + LibNbPciIndexRMW (IommuPciAddress.AddressValue | L2CFG_INDEX, L2CFG_SEL_WR_EN | L2REG_52, AccessS3SaveWidth32, 0x0, 0xF0000002 , pConfig); + } + // Start and lock the Iommu settings + LibNbPciRMW ((IommuPciAddress.AddressValue | (CapBase + 4)), AccessS3SaveWidth32, 0xFFFFFFFF, (UINT32)BIT0, pConfig); + + //Reset IOMMU MMIO registers on system reset + for (i = 0; i < (sizeof (IommuMmioInitTable) / sizeof (UINT32)); i = i + 2) { + LibNbMemRMW (pConfig->pNbConfig->IommuBaseAddress + IommuMmioInitTable[i], AccessS3SaveWidth32, 0x0, IommuMmioInitTable[i + 1], pConfig); + } + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Iommu Initialization of topology specific data. + * + * @param[in] pConfig Northbridge configuration pointer + * @retval AGESA_SUCCESS IOMMU enable and initialized succesfully. + * @retval AGESA_UNSUPPORTED IOMMU not initialized. + */ +AGESA_STATUS +IommuTopologyInit ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + // Set L2 Caches Hash Control based on maximum bus, device, function + IommuInitL2CacheControl ((IOMMU_PCI_TOPOLOGY*) &pConfig->pNbConfig->IommuTpologyInfo, pConfig); + return AGESA_SUCCESS; +} + +L2_HASH_CONTROL HashControls[] = { + { + L2_DTC_CONTROL + }, + { + L2_ITC_CONTROL + }, + { + L2_PTC_A_CONTROL + }, + { + L2_PTC_B_CONTROL + }, + { + L2_PDC_CONTROL + } +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Set L2 Cache Hash Control based on maximum Bus, Dev, Function found + * + * @param[in] PciPtr Array of bus, device, function + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +IommuInitL2CacheControl ( + IN IOMMU_PCI_TOPOLOGY *PciPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + PCI_ADDR IommuPciAddress; + UINTN i; + UINT8 FuncBitsUsed; + UINT8 DevBitsUsed; + UINT8 BusBitsUsed; + + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " L2Cache Init Max Bus = 0x%x Max Device = 0x%x Mux Func = 0x%x\n", PciPtr->MaxBus, PciPtr->MaxDevice, PciPtr->MaxFunction)); + + FuncBitsUsed = CIMX_MAX (IommuGetLog2 (PciPtr->MaxFunction + 1), 3); + DevBitsUsed = IommuGetLog2 (PciPtr->MaxDevice + 1); + BusBitsUsed = IommuGetLog2 (PciPtr->MaxBus + 1); + + for (i = 0; i < (sizeof (HashControls) / sizeof (L2_HASH_CONTROL)); i++) { + UINT8 NBits; + UINT8 NFuncBits; + UINT8 NDevBits; + UINT8 NBusBits; + LibNbPciIndexRead (IommuPciAddress.AddressValue | L2CFG_INDEX, L2CFG_SEL_WR_EN | HashControls[i].HashControl, AccessWidth32, &Value, pConfig); + NBits = (UINT8) (Value >> 28) - IommuGetLog2 ((Value >> 16) & 0xff); + NFuncBits = CIMX_MIN (NBits, 0x3); + NBits = NBits - NFuncBits; + NDevBits = CIMX_MIN ( NBits, DevBitsUsed + FuncBitsUsed - NFuncBits); + NBusBits = NBits - NDevBits; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " NBusBits = %d, NDevBits = %d, NFuncBits = %d \n", NBusBits, NDevBits, NFuncBits)); + LibNbPciIndexRMW ( + IommuPciAddress.AddressValue | L2CFG_INDEX, + L2CFG_SEL_WR_EN | (HashControls[i].HashControl + 1), + AccessS3SaveWidth32, + 0xFFFFFE00, + (NFuncBits | (NDevBits << 2) | (NBusBits << 5)) & 0x1FF, + pConfig + ); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check to see if current PCI Address is an IOMMU + * + * @param[in] IommuPciAddress PCI Address to check + * @param[in] pConfig Northbridge configuration structure pointer. + * @retval TRUE if Iommu is enabled and found + */ +BOOLEAN +IommuCheckEnable ( + IN PCI_ADDR IommuPciAddress, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 CapBase; + + if (pConfig->pNbConfig->IommuBaseAddress == 0x0) { + return FALSE; + } + CapBase = LibNbFindPciCapability (IommuPciAddress.AddressValue, IOMMU_CAPID, pConfig); + if (CapBase == 0) { + return FALSE; + } else { + return TRUE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check an RD890 PCIE bridge to see if hot plug is enabled + * + * @param[in] DeviceId Device Id to check + * @param[in] pConfig Northbridge configuration structure pointer. + * @retval TRUE if current device supports hotplug + */ +BOOLEAN +IommuCheckHp ( + IN UINT16 DeviceId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 PciData; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0); + + LibNbPciRead (PciAddress.AddressValue | NB_PCIP_REG6C, AccessWidth32, &PciData, pConfig); + + // Check for hot plug by reading PCIE_SLOT_CAP pcieConfigDev[13:2]:0x6C [6] HOTPLUG_CAPABLE + PciData &= BIT6; + if (PciData != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check a PCIE device to see if it supports phantom functions + * + * @param[in] DeviceId Device Id to check + * @param[in] pConfig Northbridge configuration structure pointer. + * @retval TRUE if current device supports phantom functions + */ +BOOLEAN +IommuCheckPhantom ( + IN UINT16 DeviceId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 PciData; + UINT8 PcieCapBase; + PCI_ADDR PciAddress; + + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0); + + // Check for phantom functions by reading PCIE Device Capabilities register (base + 4) [4:3] 0 = not supported + PcieCapBase = LibNbFindPciCapability (PciAddress.AddressValue, PCIE_CAPID, pConfig); + if (PcieCapBase != 0) { + LibNbPciRead (((PciAddress.AddressValue) | (PcieCapBase + 4)), AccessWidth32, &PciData, pConfig); + PciData &= PCIE_PHANTOMMASK; + if (PciData != 0) { + return TRUE; + } + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check to see if current PCI Address is a multi-port PCIE core + * + * @param[in] DeviceId 16-bit device id to check + * @retval L1 configuration select + */ +UINT32 +IommuGetL1 ( + IN UINT16 DeviceId + ) +{ + // This function translates an RD890 multi-port pci core to the offset of the L1 entry + // corresponding to it. An unknown device returns as invalid + switch (DeviceId) { + case DEVICEID_GPP1_0 : + return L1CFG_SEL_GPP1; + case DEVICEID_GPP1_1 : + return L1CFG_SEL_GPP1; + case DEVICEID_GPP2_0 : + return L1CFG_SEL_GPP2; + case DEVICEID_GPP2_1 : + return L1CFG_SEL_GPP2; + case DEVICEID_GPP3A_0 : + return L1CFG_SEL_GPP3A; + case DEVICEID_GPP3A_1 : + return L1CFG_SEL_GPP3A; + case DEVICEID_GPP3A_2 : + return L1CFG_SEL_GPP3A; + case DEVICEID_GPP3A_3 : + return L1CFG_SEL_GPP3A; + case DEVICEID_GPP3A_4 : + return L1CFG_SEL_GPP3A; + case DEVICEID_GPP3A_5 : + return L1CFG_SEL_GPP3A; + case DEVICEID_GPP3B_0 : + return L1CFG_SEL_GPP3B; + default: + return PCI_INVALID; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD Device Entries + * + * @param[in] Value Value to find the logarithm of + * @retval Logarithm of input Value + */ +UINT8 +IommuGetLog2 ( + IN UINT32 Value + ) +{ + UINT8 Result; + + Result = 0; + + // This code will round a 32bit value to the next highest power of 2 + Value--; + Value |= Value >> 1; + Value |= Value >> 2; + Value |= Value >> 4; + Value |= Value >> 8; + Value |= Value >> 16; + Value++; + + // Calculate the logarithm + while (Value >>= 1) { + Result++; + } + + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVRS Header for IOMMU ACPI table + * + * @param[in, out] BufferPtr Pointer to buffer to return IVRS. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +IommuPlaceHeader ( + IN OUT VOID *BufferPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + IOMMU_IVRS_HEADER *HeaderPtr; + HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr; + LibAmdMemCopy (HeaderPtr, &RD890S_DfltHeader, sizeof (IOMMU_IVRS_HEADER), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVMD (memory device) Create all IVMD entries for a single exclusion table + * + * @param[in, out] BufferPtr Pointer to text buffer to return IVRS + * @param[in] pConfig Northbridge configuration pointer + */ +VOID +IommuPlaceIvmdAndExclusions ( + IN OUT VOID *BufferPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT8 EntryCount; + UINT8 CurrentExclusion; + AGESA_STATUS Status; + IOMMU_EXCLUSIONTABLE *pExclusion; + IOMMU_IVRS_HEADER *HeaderPtr; + IOMMU_IVMD_ENTRY *IvmdPtr; + + pExclusion = &RD890S_DfltExclusion; + HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr; + IvmdPtr = (IOMMU_IVMD_ENTRY *)BufferPtr; + + Status = LibNbCallBack (PHCB_AmdGetExclusionTable, (UINTN)&pExclusion, pConfig); + if (Status == AGESA_SUCCESS) { + EntryCount = (UINT8) ((pExclusion->TableLength - sizeof (UINTN)) / sizeof (IOMMU_EXCLUSIONRANGE)); + for (CurrentExclusion = 0; CurrentExclusion < EntryCount; CurrentExclusion++) { + IvmdPtr = (IOMMU_IVMD_ENTRY*) ((UINT8*)HeaderPtr + HeaderPtr->Length); + IvmdPtr->Type = TYPE_IVMD_ALL; // 20h = All peripherals + IvmdPtr->Flags = 0x7; // Exclusion range + IvmdPtr->Length = 32; // 32 byte structure + IvmdPtr->DeviceId = 0; // Reserved for type 20h + IvmdPtr->AuxData = 0; // Reserved for type 20h + IvmdPtr->Reserved = 0; + IvmdPtr->BlockStartAddress = pExclusion->ExclusionRange[CurrentExclusion].Start; + IvmdPtr->BlockLength = pExclusion->ExclusionRange[CurrentExclusion].Length; + HeaderPtr->Length += 32; // Update size of IVRS + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD (hardware device) Entry for IOMMU ACPI table + * + * @param[in, out] BufferPtr Pointer to text buffer to return IVRS + * @param[in] pConfig Northbridge configuration pointer + */ +VOID +IommuPlaceIvhdAndScanDevices ( + IN OUT VOID *BufferPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + IOMMU_PCI_TOPOLOGY PciFlags; + IOMMU_IVRS_HEADER *HeaderPtr; + IOMMU_IVHD_ENTRY *IvhdPtr; + PCI_ADDR IommuPciAddress; + + HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr; + IvhdPtr = (IOMMU_IVHD_ENTRY *)BufferPtr; + //PciFlags.PhantomFunction = FALSE; + PciFlags.MaxBus = 0; + PciFlags.MaxDevice = 0; + PciFlags.MaxFunction = 0; + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + + IvhdPtr = (IOMMU_IVHD_ENTRY*) ((UINT8*)HeaderPtr + HeaderPtr->Length); + IvhdPtr->Type = TYPE_IVHD; // Hardware block + IvhdPtr->Flags = FLAGS_COHERENT | FLAGS_IOTLBSUP | FLAGS_ISOC | FLAGS_RESPASSPW | FLAGS_PASSPW; + IvhdPtr->Length = 24; // Length = 24 with no devices + IvhdPtr->DeviceId = (UINT16)((IommuPciAddress.AddressValue >> 12) & 0xFFFF); // Change 32 bit ID into 16 bit + IvhdPtr->CapabilityOffset = (UINT16) (LibNbFindPciCapability (IommuPciAddress.AddressValue, IOMMU_CAPID, pConfig)); + IvhdPtr->BaseAddress = pConfig->pNbConfig->IommuBaseAddress; + IvhdPtr->PciSegment = 0; + LibNbPciRead (IommuPciAddress.AddressValue | (IvhdPtr->CapabilityOffset + 0x10), AccessWidth32, &Value, pConfig); + IvhdPtr->IommuInfo = (UINT16)(Value & 0x1f); //Set MSInum. + IvhdPtr->IommuInfo |= ((0x13) << 8); //set UnitID + IvhdPtr->Reserved = 0; + + IommuIvhdNorthbridgeDevices (&PciFlags, IvhdPtr, pConfig); + if (IommuPciAddress.Address.Bus == 0) { + IommuIvhdSouthbridgeDevices (&PciFlags, IvhdPtr, pConfig); + } + IommuIvhdApicsAndHpets (IvhdPtr, pConfig); + pConfig->pNbConfig->IommuTpologyInfo = *((UINT32*) &PciFlags); + HeaderPtr->Length += IvhdPtr->Length; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD Device Entries + * + * @param[in, out] PciPtr Pci topology flags + * @param[in, out] IvhdPtr Pointer to IVHD where entry is appended + * @param[in] pConfig NB config block + */ +VOID +IommuIvhdNorthbridgeDevices ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT16 CurrentDevice; + UINT16 DeviceId; + UINT8 EntryCount; + IOMMU_DEVICELIST *pDevices; + PCI_ADDR NbPciAddress; + PCI_ADDR IommuPciAddress; + + pDevices = &RD890S_DfltDevices; + NbPciAddress = pConfig->NbPciAddress; + IommuPciAddress = pConfig->NbPciAddress; + + IommuPciAddress.Address.Function = NB_IOMMU; + EntryCount = (UINT8) ((pDevices->TableLength - sizeof (UINT16)) / sizeof (UINT16)); + + // Run RD890S device table, fixed for current bus + for (CurrentDevice = 0; CurrentDevice < EntryCount; CurrentDevice++) { + DeviceId = (UINT16) (NbPciAddress.Address.Bus << 8) | pDevices->Device[CurrentDevice]; + IommuCreateDeviceEntry (PciPtr, DeviceId, IvhdPtr, pConfig); + + // CHECK HOTPLUG OR PHANTOM FUNCTION SUPPORT + // For each device, reset PhantomEnable, but set it as a one-shot. If any device under the northbridge PCIE bridge + // device has phantom function support enabled, set the L1. Additionally, check the bridge for hotplug, and set the + // L1 if so. + + //PciPtr->PhantomFunction = FALSE; + //if (PciPtr->PhantomFunction || IommuCheckHp (DeviceId, pConfig)) { + // if (IommuGetL1 (DeviceId) != PCI_INVALID && LibNbGetRevisionInfo (pConfig).Revision != NB_REV_A11) { + // // Determine from deviceID which L1 + // LibNbPciIndexRMW (IommuPciAddress.AddressValue | L1CFG_INDEX, L1CFG_SEL_WR_EN | IommuGetL1 (DeviceId), AccessS3SaveWidth32, (UINT32)~BIT0, BIT0, pConfig); + // } + //} + //PciPtr->PhantomFunction = FALSE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD Device Entries + * + * @param[in, out] PciPtr PCI topology flags + * @param[in, out] IvhdPtr Pointer to IVHD where entry is appended + * @param[in] pConfig NB config structute + */ +VOID +IommuIvhdSouthbridgeDevices ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + UINT16 DeviceId; + PCI_ADDR IommuPciAddress; + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + + // Assume Device 0x10 Function 0 - Device 0x17 Function 7 belong to the SB + //PciPtr->PhantomFunction = FALSE; + for (DeviceId = (0x10 << 3); (DeviceId < (0x18 << 3)); DeviceId++) { + IommuCreateDeviceEntry (PciPtr, DeviceId, IvhdPtr, pConfig); + //if (PciPtr->PhantomFunction) { + // // Enable SB phantom enable + // LibNbPciIndexRMW (IommuPciAddress.AddressValue | L1CFG_INDEX, L1CFG_SEL_WR_EN | L1CFG_SEL_SB, AccessS3SaveWidth32, (UINT32)~BIT0, BIT0, pConfig); + //} + //PciPtr->PhantomFunction = FALSE; + } + +#if defined (IVHD_APIC_SUPPORT) || defined (IVHD_HPET_SUPPORT) + DeviceId = (SB_DEV << 3); // Bus 0 Dev 14 Func 0 +#endif + +#ifdef IVHD_APIC_SUPPORT + // Southbridge IOAPIC + IommuCreate8ByteEntry (DE_SPECIAL, DATA_ALLINTS, 0, 0xFF, DeviceId, VARIETY_IOAPIC, IvhdPtr); +#endif + +#ifdef IVHD_HPET_SUPPORT + // Southbridge HPET + IommuCreate8ByteEntry (DE_SPECIAL, DATA_ALLINTS, 0, 0, DeviceId, VARIETY_HPET, IvhdPtr); +#endif + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD Device Entries + * + * @param[in, out] IvhdPtr Pointer to buffer to return IVRS. + * @param[in] pConfig NB config structute + */ +VOID +IommuIvhdApicsAndHpets ( + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ +#ifdef IVHD_APIC_SUPPORT + PCI_ADDR PciAddress; + UINT16 DeviceId; + UINT32 PciData; + + PciAddress = pConfig->NbPciAddress; + + // Northbridge IOAPIC + DeviceId = (UINT16)((PciAddress.Address.Bus << 8)) | 1; // Bus X Dev 0 Func 0 + LibNbPciRead (PciAddress.AddressValue | 0x4C, AccessWidth32, &PciData, pConfig); + if (PciData & (UINT32)BIT1) { + IommuCreate8ByteEntry (DE_SPECIAL, DATA_NOINTS, 0, 0xFF, DeviceId, VARIETY_IOAPIC, IvhdPtr); + } +#endif +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD device entry (type 2 for single function or 3/4 for multifunction) at end of IVHD entry + * + * @param[in, out] PciPtr Pci topology flags + * @param[in] DeviceId DeviceID of entry to potentially create + * @param[in, out] IvhdPtr Pointer to IVHD + * @param[in] pConfig NB config structute + */ +VOID +IommuCreateDeviceEntry ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN UINT16 DeviceId, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr, + IN AMD_NB_CONFIG *pConfig + ) +{ + // 8 BYTE DEVICE ENTRY: + // [0] Type (0x2 = Device, 0x3 = Device Range Start, 0x4 = Device Range End + // [1] DeviceID LSB (Device/Function) + // [2] DeviceID MSB (Bus) + // [3] Data (0 = No legacy interrupts) + + // DEVICEID + // A 16 bit bus/device/function DeviceId consists of: + // [15:8] Bus + // [7:3] Device + // [2:0] Function + + PCI_ADDR PciAddress; + UINT32 PciData; + UINT8 DeviceCount; + UINT8 FunctionCount; + UINT8 PcieCapBase; + UINT8 PcixCapBase; + + BOOLEAN LegacyBridge; + BOOLEAN MultiFunction; + BOOLEAN SubFunction; + BOOLEAN DiscreteEntry; + UINT8 HighFunction; + UINT32 ClassCode; + UINT16 ExtendedCapabilityPtr; + SB_INFO SbInfo; + UINT8 SataEnableRegValue; + BOOLEAN SrIovDevice; + + PcieCapBase = 0; + PcixCapBase = 0; + LegacyBridge = FALSE; + MultiFunction = FALSE; + SubFunction = FALSE; + DiscreteEntry = FALSE; + HighFunction = 0; + SataEnableRegValue = 0; + SrIovDevice = FALSE; + + //For SB700, get combined mode status + SbInfo = LibAmdSbGetRevisionInfo ((pConfig == NULL)?NULL:GET_BLOCK_CONFIG_PTR (pConfig)); + if (SbInfo.Type == SB_SB700) { + LibNbPciRead (MAKE_SBDFO (0, 0, 0x14, 0, SATA_ENABLE_REG), AccessWidth8, &SataEnableRegValue , pConfig); + } + + + // If the device to check does not exist, exit + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0); + if (!LibNbIsDevicePresent (PciAddress, pConfig)) { + return; + }; + LibNbPciRead (PciAddress.AddressValue | PCI_CLASS, AccessWidth32, &ClassCode, pConfig); + ClassCode = (ClassCode >> 16) & 0xFFFF; // Keep class code and sub-class only + + // THREE STAGES TO THIS FUNCTION + // 1. Check for multifunction or special devices + // 2. Place device entry for the current device ID + // 3. If a bridge, decide if we need to traverse further + + // STEP 1 - CHECK FUNCTIONS ON THIS DEVICE + // To make decisions, we will need several pieces of information about this device not found with current SBDFO + // 1. Multifunction device - To determine if a device entry, or device range entry is needed - check function 0 only + // 2. DisableRange - We will create single entries a device containing a PCI or PCIE bridge + // 3. How many functions on this device? + + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, 0, 0); + LibNbPciRead (PciAddress.AddressValue | PCI_HEADER, AccessWidth32, &PciData, pConfig); + if ((PciData & PCI_MULTIFUNCTION) != 0) { + MultiFunction = TRUE; + } else { + DiscreteEntry = TRUE; + } + if ((DeviceId & 0x7) != 0 && MultiFunction) { + SubFunction = TRUE; + } + + if (MultiFunction) { + for (FunctionCount = 0; FunctionCount < 8; FunctionCount++) { + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, FunctionCount, 0); + LibNbPciRead (PciAddress.AddressValue | PCI_HEADER, AccessWidth32, &PciData, pConfig); + if (PciData != PCI_INVALID) { + HighFunction = FunctionCount; + } + LibNbPciRead (PciAddress.AddressValue | PCI_CLASS, AccessWidth32, &PciData, pConfig); + if (((PciData >> 16) & 0xFFFF) == PCI_BRIDGE_CLASS) { + DiscreteEntry = TRUE; + } + } + } + + // For SR IOV devices set for all functions to be available + if (MultiFunction && (!DiscreteEntry) && (!SubFunction)) { + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, 0, 0); + ExtendedCapabilityPtr = LibNbFindPcieExtendedCapability (PciAddress.AddressValue, 0x10, pConfig); + if (ExtendedCapabilityPtr != 0) { + SrIovDevice = TRUE; + } + } + // STEP 2 - PLACE DEVICE ENTRY + // We have already decided whether we should use discrete type2 entries, or ranged type3/4 entries + // Place each device entry at the end of the current IVHD + // In each case, increment the maximum bus/device/function for L2 cache control done after the IVHD is created + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), "[NBIOMMU]Placing Entry for Device [0x%x]\n", DeviceId)); + + //if (IommuCheckPhantom (DeviceId, pConfig)) { + // PciPtr->PhantomFunction = TRUE; + //} + + if (!MultiFunction || DiscreteEntry) { + //For Device 0x14, function 0, Set DATA_ALLINTS + if (DeviceId == (SB_DEV << 3)) { + IommuCreate4ByteEntry (DE_SELECT, DATA_ALLINTS, DeviceId, IvhdPtr); + } else if (DeviceId == DEVICEID_IDE) { + // For IDE device 0x14, function 1, first check if in combined mode + if (SataEnableRegValue & SATA_COMBINED_MODE) { + // Create Alias entry in combined mode + IommuCreate8ByteEntry (DE_ALIASSELECT, DATA_NOINTS, DEVICEID_IDE, 0, DEVICEID_SATA, 00, IvhdPtr); + } else { + //Create select entry if not in the combined mode + IommuCreate4ByteEntry (DE_SELECT, 0, DeviceId, IvhdPtr); + } + } else { + // For all other single function devices other than device 0x14, functions 0 or 1, create select entry + IommuCreate4ByteEntry (DE_SELECT, 0, DeviceId, IvhdPtr); + } + + // Record the largest bus, device, function which will be used as a mask by the Iommu L2 cache + // Record if phantom device present for current device. Only set it if present, do not clear. +// if (IommuCheckPhantom (DeviceId, pConfig)) { +// PciPtr->PhantomFunction = TRUE; +// } + IommuRecordBusDevFuncInfo (PciPtr, DeviceId, pConfig); + } + + if (MultiFunction && (!DiscreteEntry) && (!SubFunction)) { + + // This is a multifunction device without a bridge, so create a type 3 and 4 device entry + IommuCreate4ByteEntry (DE_START, 0, DeviceId, IvhdPtr); + if (SrIovDevice) { + IommuCreate4ByteEntry (DE_END, 0, (DeviceId | 0x00FF), IvhdPtr); + } else { + IommuCreate4ByteEntry (DE_END, 0, DeviceId + HighFunction, IvhdPtr); + } + + // Record the largest bus, device, function which will be used as a mask by the Iommu L2 cache + // Record if phantom device present for current device. Only set it if present, do not clear. +// if (IommuCheckPhantom (DeviceId, pConfig)) { +// PciPtr->PhantomFunction = TRUE; +// } + IommuRecordBusDevFuncInfo (PciPtr, DeviceId + HighFunction, pConfig); + } + + if (ClassCode == PCI_BRIDGE_CLASS) { + UINTN Type; + UINT32 BusData; + // STEP 3 - BRIDGE DEVICE + // These are treated a little differently. We already created the entry for the bridge itself... + // For a PCIe bridge, continue down the bridge device creating more entries until we find an endpoint + // For a PCI bridge, define the entire sub-bus range as belonging to this source id + // For a PCIX bridge, figure out which mode it is operating in + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, DeviceId & 0x7, 0); + LibNbPciRead (PciAddress.AddressValue | PCI_BUS, AccessWidth32, &BusData, pConfig); + PcieCapBase = LibNbFindPciCapability (PciAddress.AddressValue, PCIE_CAPID, pConfig); + PcixCapBase = LibNbFindPciCapability (PciAddress.AddressValue, PCIX_CAPID, pConfig); + + Type = 0; + if (PcieCapBase != 0) { + Type = 1; + LibNbPciRead (PciAddress.AddressValue | PcieCapBase, AccessWidth32, &PciData, pConfig); + PciData = (PciData >> 16) & PCIE_PORTMASK; // [7:4] are Device/Port type, 01 + if (PciData == PCIE_PCIE2PCIX) { + Type = 2; + } + } + if (PcixCapBase != 0) { + Type = 2; + } + + //For Hot plug capable devices, create 'Start of range' and 'End of range' IVRS'. + // This will override Type 1 and Type 2. + if (IommuCheckHp (DeviceId, pConfig)) { + Type = 3; + } + + switch (Type) { + case 0: + //PCI + IommuRecordBusDevFuncInfo (PciPtr, DeviceId, pConfig); + IommuCreate8ByteEntry (DE_ALIASSTART, DATA_NOINTS, (UINT16) (BusData & 0xFF00), 0, DeviceId, 0, IvhdPtr); + IommuCreate4ByteEntry (DE_END, 0, (UINT16) (((BusData & 0xFF0000) >> 8) + 0xFF), IvhdPtr); + break; + case 1: + //Pcie (non hot plug) + for (DeviceCount = 0; DeviceCount <= 0x1f; DeviceCount++) { + for (FunctionCount = 0; FunctionCount <= 0x7; FunctionCount++) { + IommuCreateDeviceEntry (PciPtr, ((UINT16) (BusData & 0xFF00)) | (DeviceCount << 3) | FunctionCount, IvhdPtr, pConfig); + } + } + break; + case 2: + //PCIx + IommuRecordBusDevFuncInfo (PciPtr, (UINT16) (BusData & 0xFF00), pConfig); + IommuCreate8ByteEntry (DE_ALIASSTART, DATA_NOINTS, (UINT16) ((BusData & 0xFF00) | ( 1 << 3)), 0, (UINT16) (BusData & 0xFF00), 0, IvhdPtr); + IommuCreate4ByteEntry (DE_END, 0, (UINT16) (((BusData & 0xFF0000) >> 8) + 0xFF), IvhdPtr); + break; + case 3: + //For Hot plug ports, set all devices and functions behind the secondary bus. + IommuCreate4ByteEntry (DE_START, 0, (UINT16) (BusData & 0xFF00), IvhdPtr); // Secondary bus, Device 0, Function 0 + IommuCreate4ByteEntry (DE_END, 0, (UINT16) ((BusData & 0xFF00) | (0x1F << 3) | 7), IvhdPtr); // Secondary bus, Device 1f, Function 7 + break; + default: + CIMX_ASSERT (FALSE); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Place IVHD device entry (type 2 for single function or 3/4 for multifunction) at end of IVHD entry + * + * @param[in, out] PciPtr Pci topology flags + * @param[in] DeviceId DeviceID + * @param[in] pConfig NB config structute + */ +VOID +IommuRecordBusDevFuncInfo ( + IN OUT IOMMU_PCI_TOPOLOGY *PciPtr, + IN UINT16 DeviceId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT16 ExtendedCapabilityPtr; + PCI_ADDR Device; + Device.AddressValue = MAKE_SBDFO (0, DeviceId >> 8, (DeviceId >> 3) & 0x1f, DeviceId & 0x7, 0); +#ifdef EXCLUDE_SB_DEVICE_FROM_L2_HASH + if ((UINT8)Device.Address.Bus == 0) { + AMD_NB_CONFIG_BLOCK *ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig); + if (ConfigPtr->PlatformType == ServerPlatform) { + return; + } + } +#endif + Device.AddressValue = MAKE_SBDFO (0, DeviceId >> 8, (DeviceId >> 3) & 0x1f, DeviceId & 0x7, 0); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NB_TRACE), " Device Data For L2 Hash Bus = 0x%x Device = 0x%x Func = 0x%x\n", Device.Address.Bus, Device.Address.Device, Device.Address.Function)); + ExtendedCapabilityPtr = LibNbFindPcieExtendedCapability (Device.AddressValue, 0x10, pConfig); + if (ExtendedCapabilityPtr != 0) { + UINT16 TotalVF; + LibNbPciRead (Device.AddressValue | (ExtendedCapabilityPtr + 0xE), AccessWidth16, &TotalVF, pConfig); + PciPtr->MaxFunction = CIMX_MAX (PciPtr->MaxFunction, TotalVF); + } + PciPtr->MaxBus = CIMX_MAX (PciPtr->MaxBus, (UINT8)Device.Address.Bus); + PciPtr->MaxDevice = CIMX_MAX (PciPtr->MaxDevice, (UINT8)Device.Address.Device); + PciPtr->MaxFunction = CIMX_MAX (PciPtr->MaxFunction, (UINT16) (UINT8)Device.Address.Function); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Append data entry to IVRS + * + * @param[in] Type IVRC entry type + * @param[in] Data IVRC entry data + * @param[in] Word1 IVRC entry data + * @param[in, out] IvhdPtr Current IVHD pointer + * + */ +VOID +IommuCreate4ByteEntry ( + IN UINT8 Type, + IN UINT8 Data, + IN UINT16 Word1, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr + ) +{ + UINT32 Buffer; + UINT16 AlignedDeviceEntryIndex; + UINT16 DeviceEntryIndex; + + Buffer = Type + (Word1 << 8) + (Data << 24); + DeviceEntryIndex = (IvhdPtr->Length - 24) / sizeof (UINT32); + AlignedDeviceEntryIndex = DeviceEntryIndex; + +#ifdef IVHD_MIN_8BYTE_ALIGNMENT + AlignedDeviceEntryIndex = (DeviceEntryIndex + 1) & 0xfffe; +#endif + + IvhdPtr->DeviceEntry[AlignedDeviceEntryIndex] = Buffer; + IvhdPtr->Length += (4 + (AlignedDeviceEntryIndex - DeviceEntryIndex) * 4); + CIMX_TRACE ((TRACE_DATA (NULL, CIMX_NB_TRACE), "[NBIOMMU]Added entry - [0x%x]\n", Buffer)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Append data entry to IVRS + * + * @param[in] Type IVRC entry type + * @param[in] Data IVRC entry data + * @param[in] Word1 IVRC entry data + * @param[in] Byte4 IVRC entry data + * @param[in] Word5 IVRC entry data + * @param[in] Byte7 IVRC entry data + * @param[in, out] IvhdPtr Current IVHD pointer + * + */ +VOID +IommuCreate8ByteEntry ( + IN UINT8 Type, + IN UINT8 Data, + IN UINT16 Word1, + IN UINT8 Byte4, + IN UINT16 Word5, + IN UINT8 Byte7, + IN OUT IOMMU_IVHD_ENTRY *IvhdPtr + ) +{ + UINT16 AlignedDeviceEntryIndex; + UINT16 DeviceEntryIndex; + UINT64 Buffer; + + Buffer = Type + (Word1 << 8) + ((UINT32)Data << 24); + ((UINT32*)&Buffer)[1] = Byte4 + (Word5 << 8) + (Byte7 << 24); + DeviceEntryIndex = (IvhdPtr->Length - 24) / sizeof (UINT32); + AlignedDeviceEntryIndex = DeviceEntryIndex; + +#if defined (IVHD_MIN_8BYTE_ALIGNMENT) || defined (IVHD_SIZE_ALIGNMENT) + AlignedDeviceEntryIndex = (DeviceEntryIndex + 1) & 0xfffe; +#endif + IvhdPtr->DeviceEntry[AlignedDeviceEntryIndex] = ((UINT32*)&Buffer)[0]; + IvhdPtr->DeviceEntry[AlignedDeviceEntryIndex + 1] = ((UINT32*)&Buffer)[1]; + IvhdPtr->Length += (8 + (AlignedDeviceEntryIndex - DeviceEntryIndex) * 4); + CIMX_TRACE ((TRACE_DATA (NULL, CIMX_NB_TRACE), "[NBIOMMU]Added entry - [0x%llx]\n", Buffer)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set checksum, IvInfo, finish IVRS table + * + * @param[in, out] BufferPtr Pointer to text buffer to return IVRS. + * @param[in, out] pConfig Northbridge configuration structure pointer. + * + */ +VOID +IommuFinalizeIvrs ( + IN OUT VOID *BufferPtr, + IN AMD_NB_CONFIG *pConfig + ) +{ + IOMMU_IVRS_HEADER *HeaderPtr; + PCI_ADDR IommuPciAddress; + UINT32 PciData; + + HeaderPtr = (IOMMU_IVRS_HEADER *)BufferPtr; + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + + // Find common IvInfo (largest shared) 0x50 + // [22] = ATS Translation Reserved + // [21:15] = VA Size + // [14:8] = PA Size + + LibNbPciRead (IommuPciAddress.AddressValue | RD890S_CAP_MISC, AccessWidth32, &PciData, pConfig); + PciData &= (IVINFO_ATSMASK | IVINFO_VAMASK | IVINFO_PAMASK); + HeaderPtr->IvInfo = PciData; + + //LibAmdUpdateAcpiTableChecksum (HeaderPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Nb Iommu Fixup of IVRS APIC entries + * + * @param[in] DevicePtr Pointer to current device entry + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +UINT64 +IommuGetApicBaseAddress ( + IN VOID *DevicePtr, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR PciAddress; + UINT16 DeviceId; + UINT32 Data; + + // If no pointer provided, return no base address + if (DevicePtr == NULL) { + return 0; + } + + // Special entry can be IOAPIC or other(HPET). We only care about the IOAPIC. + if (*(UINT8*) ((UINT8*)DevicePtr + DE_SPECIAL_VARIETY) != VARIETY_IOAPIC) { + return 0; + } + + DeviceId = *(UINT16*) ((UINT8*)DevicePtr + DE_DEVICEID); + PciAddress.AddressValue = MAKE_SBDFO (0, (DeviceId >> 8) & 0xFF, (DeviceId >> 3) & 0x1F, 0, 0); + + // An APIC entry will only be created for AMD northbridge or southbridges, so + // we can assume PCI dev/func = 0, 0 will be a northbridge IOAPIC device + // and any other will be a southbridge IOAPIC device. If the device was not + // already enabled and known to be an AMD device, no entry would have been created. + + if ((PciAddress.Address.Device == NB_PCI_DEV) && (PciAddress.Address.Function == NB_HOST)) { + + // We have an AMD NB, check function 0 + Data = 1; + PciAddress.Address.Function = 0; + LibNbPciWrite (PciAddress.AddressValue | 0xF8, AccessS3SaveWidth32, &Data, pConfig); + LibNbPciRead (PciAddress.AddressValue | 0xFC, AccessWidth32, &Data, pConfig); + } else { + SB_INFO SbInfo; + SbInfo = LibAmdSbGetRevisionInfo ((pConfig == NULL)?NULL:GET_BLOCK_CONFIG_PTR (pConfig)); + if (SbInfo.Type == SB_SB700) { + PciAddress.Address.Function = 0; + LibNbPciRead (PciAddress.AddressValue | 0x74, AccessWidth32, &Data, pConfig); + } else { + LibAmdSbPmioRead ( 0x34, AccessWidth32, &Data, pConfig); + } + } + return ((UINT64) (Data & 0xFFFFFF00)); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Nb Iommu Fixup of IVRS APIC entries + * + * @param[in] BaseAddress Base address to match + * @param[in] MadtPtr Pointer to current device entry + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +UINT8 +IommuGetApicId ( + IN UINT64 BaseAddress, + IN VOID *MadtPtr, + IN AMD_NB_CONFIG *pConfig + ) +{ + VOID *EntryPtr; + + EntryPtr = LibAmdGetFirstMadtStructure (MADT_APIC_TYPE, MadtPtr); + + do { + // If our base address for a known device matches this MADT, get the APIC ID + if (*(UINT32*) ((UINT8*)EntryPtr + MADT_APIC_BASE) == (UINT32)BaseAddress) { + return *(UINT8*) ((UINT8*)EntryPtr + MADT_APIC_ID); + } + EntryPtr = LibAmdGetNextMadtStructure (MADT_APIC_TYPE, EntryPtr, MadtPtr); + } while (EntryPtr != NULL); + return 0xFF; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disconnect unused PCIe core from IOMMU block. + * + * @param[in] CoreId Pcie Core Id + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +NbIommuDisconnectPcieCore ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR IommuPciAddress; + UINT32 Value; + IommuPciAddress = pConfig->NbPciAddress; + IommuPciAddress.Address.Function = NB_IOMMU; + Value = 1 << ((0x4310 >> (CoreId * 4)) & 0xf); + LibNbPciIndexRMW (IommuPciAddress.AddressValue | L2CFG_INDEX, L2CFG_SEL_WR_EN | L2REG_46, AccessS3SaveWidth32, 0xFFFFFFFF, Value , pConfig); +} diff --git a/src/vendorcode/amd/cimx/rd890/nbIommu.h b/src/vendorcode/amd/cimx/rd890/nbIommu.h new file mode 100644 index 000000000000..7fc2c5c90897 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbIommu.h @@ -0,0 +1,326 @@ +/** + * @file + * + * Routines for IOMMU. + * + * Implement the IOMMU init and ACPI feature. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +// Identifying an IOMMU: +// RD890S - IOMMU present +// all other (including RD890) - IOMMU not present +// Class = System Base Peripheral (08h) +// Subclass = IOMMU (06h) +// Programming Interface Code = 0h +// Must reside on top/root complex PCI hierarchy +// There is always a NB device at bus 0 device 0 function 0 (fcn 2 for IOMMU) - device ID 0x5A23 + +// Inputs: +// From OEM: Get exclusion table +// From OEM: Get text buffer + +// Outputs: +// To OEM: Complete IVRS table for linking + +#ifndef _NBIOMMU_H_ +#define _NBIOMMU_H_ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +AGESA_STATUS +NbIommuInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuInitS3 ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuAcpiInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbIommuAcpiFixup ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +VOID +NbIommuDisconnectPcieCore ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +// IOMMU Architectural +#define IVRS_BUFFER_SIZE 0x2000 // Default 8KB allocated to table +//#define IVHD_MIN_8BYTE_ALIGNMENT // Align IVHD entries on 8 byte boundary +#define IVHD_SIZE_ALIGNMENT // Align IVHD entries on MOD entry-size boundary +#define IVHD_HPET_SUPPORT // Create HPET entries +#define IVHD_APIC_SUPPORT // Create IOAPIC entries + +// IOMMU Northbridge +#define RD890S_CAP_MISC 0x50 // RD890/S Capabilities Misc Info +#define NB_PCI_DEV 0 // PCI NB device number +#define NB_HOST 0 // Function 0 = NB HOST +#define NB_IOMMU 2 // Function 2 = IOMMU +#define SB_DEV 0x14 // PCI SB device number +#define SB_SMBUS 3 // Function 3 = SMBUS +#define SB_SATA 0x11 // SB SATA +#define SATA_ENABLE_REG 0xAD // Dev. 0x14, Func 0, Reg 0xAD for SATA combined mode +#define SATA_COMBINED_MODE BIT3 // Bit 3 of SB_ENABLE_REG., 1 = Combined mode + +#define IOMMU_CAP_HEADER_OFFSET 0x00 +#define IOMMU_BASE_LOW_OFFSET 0x04 +#define IOMMU_BASE_HIGH_OFFSET 0x08 +#define IOMMU_RANGE_OFFSET 0x0C +#define IOMMU_MISC_OFFSET 0x10 + +#define DEVICEID_NB ((0 << 8) + (NB_PCI_DEV << 3) + NB_HOST) +#define DEVICEID_IOMMU ((0 << 8) + (NB_PCI_DEV << 3) + NB_IOMMU) +#define DEVICEID_GPP1_0 ((0 << 8) + (0x2 << 3) + 0) +#define DEVICEID_GPP1_1 ((0 << 8) + (0x3 << 3) + 0) +#define DEVICEID_GPP2_0 ((0 << 8) + (0xB << 3) + 0) +#define DEVICEID_GPP2_1 ((0 << 8) + (0xC << 3) + 0) +#define DEVICEID_GPP3A_0 ((0 << 8) + (0x4 << 3) + 0) +#define DEVICEID_GPP3A_1 ((0 << 8) + (0x5 << 3) + 0) +#define DEVICEID_GPP3A_2 ((0 << 8) + (0x6 << 3) + 0) +#define DEVICEID_GPP3A_3 ((0 << 8) + (0x7 << 3) + 0) +#define DEVICEID_GPP3A_4 ((0 << 8) + (0x9 << 3) + 0) +#define DEVICEID_GPP3A_5 ((0 << 8) + (0xA << 3) + 0) +#define DEVICEID_GPP3B_0 ((0 << 8) + (0xD << 3) + 0) + +#define DEVICEID_SATA ((0 << 8) + (0x11 << 3) + 0) +#define DEVICEID_IDE ((0 << 8) + (0x14 << 3) + 1) + +#define L1CFG_INDEX 0xF8 +// There is an L1 for each device (6), which is selected by [19:16] of L1CFG_INDEX +// e.g. (LibNbPciIndexRead (Address | L1CFGIND, L1_REG_0C | L1_CFG_SEL, AccessWidth32, &Value, pConfig) +#define L1CFG_SEL_WR_EN 0x80000000 +#define L1CFG_SEL_GPP1 0x00000000 +#define L1CFG_SEL_GPP2 0x00010000 +#define L1CFG_SEL_SB 0x00020000 +#define L1CFG_SEL_GPP3A 0x00030000 +#define L1CFG_SEL_GPP3B 0x00040000 +#define L1CFG_SEL_VC1 0x00050000 +#define L1REG_06 0x6 +#define L1REG_0C 0xC +#define L1REG_0D 0xD +#define L1REG_07 0x7 +#define L1CFG_DATA 0xFC + +#define L2CFG_INDEX 0xF0 +// e.g. (LibNbPciIndexRead (Address | L2CFGIND, L2_REG_0C, AccessWidth16, &Value, pConfig) +#define L2CFG_SEL_WR_EN 0x100 +#define L2REG_06 0x6 +#define L2REG_07 0x7 +#define L2REG_0C 0xC +#define L2REG_10 0x10 +#define L2REG_11 0x11 +#define L2REG_14 0x14 +#define L2REG_15 0x15 +#define L2REG_18 0x18 +#define L2REG_19 0x19 +#define L2REG_1C 0x1C +#define L2REG_1D 0x1D +#define L2REG_46 0x46 +#define L2REG_47 0x47 +#define L2REG_50 0x50 +#define L2REG_51 0x51 +#define L2REG_52 0x52 +#define L2REG_56 0x56 +#define L2REG_30 0x30 +#define L2REG_80 0x80 +#define L2CFG_DATA 0xF4 + +// PCI/PCIe Architectural +#define PCIE_CAPID 0x10 +#define PCIE_PORTMASK 0xF0 // Device cap reg 2 +#define PCIE_PCIE2PCIX 0x70 // Device cap reg 2 +#define PCIE_PHANTOMMASK 0x18 // Device cap reg 4 +#define PCIX_CAPID 0x07 +#define IOMMU_CAPID 0x0F + +#define PCI_DVID 0x00 +#define PCI_INVALID 0xFFFFFFFF +#define PCI_CLASS 0x08 +#define PCI_HEADER 0x0C +#define PCI_MULTIFUNCTION 0x00800000 +#define PCI_BUS 0x18 +#define PCI_SUBMASK 0xFF0000 +#define PCI_SECMASK 0xFF00 +#define PCI_PRIMASK 0xFF +#define PCI_BRIDGE_CLASS 0x0604 + +// IVRS Table Access +#define TYPE_IVHD 0x10 +#define IVINFO_ATSMASK 0x00400000 // [22] = ATS +#define IVINFO_VAMASK 0x003F8000 // [21:15] = Virtual Address Size +#define IVINFO_PAMASK 0x00007F00 // [14:8] = Physical Address Size +#define FLAGS_COHERENT BIT5 +#define FLAGS_IOTLBSUP BIT4 +#define FLAGS_ISOC BIT3 +#define FLAGS_RESPASSPW BIT2 +#define FLAGS_PASSPW BIT1 + +#define TYPE_IVMD_ALL 0x20 +#define TYPE_IVMD_SELECT 0x21 +#define TYPE_IVMD_RANGE 0x22 + +#define DE_PAD4 1 +#define DE_BYTE0 0 +#define DE_BYTE1 1 +#define DE_BYTE2 2 +#define DE_BYTE3 3 +#define DE_SELECT 2 +#define DATA_NOINTS 0 +#define DATA_LINT_EINT_INIT BIT7 + BIT6 + BIT1 + BIT0 +#define DATA_ALLINTS 0xD7 +#define DE_START 3 +#define DE_END 4 +#define DE_PAD8 64 +#define DE_BYTE4 4 +#define DE_BYTE5 5 +#define DE_BYTE6 6 +#define DE_BYTE7 7 +#define DE_ALIASSELECT 66 +#define DE_ALIASSTART 67 +#define DE_SPECIAL 72 +#define VARIETY_IOAPIC 0x1 +#define VARIETY_HPET 0x2 +#define DE_SPECIAL_VARIETY 7 +#define DE_DEVICEID 5 +#define DE_SPECIAL_ID 4 + +// MADT Table Access +#define MADT_APIC_TYPE 0x1 +#define MADT_APIC_ID 0x2 +#define MADT_APIC_BASE 0x4 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + + +#pragma pack (push, 1) + +/// IVRS header +typedef struct { + UINT32 Signature; ///< see IOMMU specification for details + UINT32 Length; ///< see IOMMU specification for details + UINT8 Revision; ///< see IOMMU specification for details + UINT8 Checksum; ///< see IOMMU specification for details + CHAR8 OemId[6]; ///< see IOMMU specification for details + CHAR8 OemTableId[8]; ///< see IOMMU specification for details + CHAR8 OemRevision[4]; ///< see IOMMU specification for details + CHAR8 CreatorId[4]; ///< see IOMMU specification for details + CHAR8 CreatorRevision[4]; ///< see IOMMU specification for details + UINT32 IvInfo; ///< see IOMMU specification for details + UINT64 Reserved; ///< see IOMMU specification for details +} IOMMU_IVRS_HEADER; + +/// DeviceID +typedef struct { + UINT16 TableLength; ///< length of table + UINT16 Device[]; ///< DeviceID +} IOMMU_DEVICELIST; + +/// PCI Topology Based Settings +typedef struct { +// BOOLEAN PhantomFunction; ///< phantom functions present + UINT8 MaxBus; ///< max bus accumulator + UINT8 MaxDevice; ///< max device accumulator + UINT16 MaxFunction; ///< max function accumulator +} IOMMU_PCI_TOPOLOGY; + +/// IVHD for each hardware definition (i.e. # of northbridges) +typedef struct { + UINT8 Type; ///< see IOMMU specification for details + UINT8 Flags; ///< see IOMMU specification for details + UINT16 Length; ///< see IOMMU specification for details + UINT16 DeviceId; ///< see IOMMU specification for details + UINT16 CapabilityOffset; ///< see IOMMU specification for details + UINT64 BaseAddress; ///< see IOMMU specification for details + UINT16 PciSegment; ///< see IOMMU specification for details + UINT16 IommuInfo; ///< see IOMMU specification for details + UINT32 Reserved; ///< see IOMMU specification for details + UINT32 DeviceEntry[]; ///< see IOMMU specification for details +} IOMMU_IVHD_ENTRY; + +/// IVMD for each memory range +typedef struct { + UINT8 Type; ///< see IOMMU specification for details + UINT8 Flags; ///< see IOMMU specification for details + UINT16 Length; ///< see IOMMU specification for details + UINT16 DeviceId; ///< see IOMMU specification for details + UINT16 AuxData; ///< see IOMMU specification for details + UINT64 Reserved; ///< see IOMMU specification for details + UINT64 BlockStartAddress; ///< see IOMMU specification for details + UINT64 BlockLength; ///< see IOMMU specification for details +} IOMMU_IVMD_ENTRY; + +//#define IVRS_HANDLE 'SRVI' +#define IVRS_HANDLE Int32FromChar ('S', 'R', 'V', 'I') + +#define L2_DTC_CONTROL 0x10 +#define L2_ITC_CONTROL 0x14 +#define L2_PTC_A_CONTROL 0x18 +#define L2_PTC_B_CONTROL 0x1C +#define L2_PDC_CONTROL 0x50 + +#define EXCLUDE_SB_DEVICE_FROM_L2_HASH + +/// L2 cache init +typedef struct { + UINT8 HashControl; ///<Control regsiter block address +} L2_HASH_CONTROL; + +#pragma pack (pop) + +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbLib.c b/src/vendorcode/amd/cimx/rd890/nbLib.c new file mode 100644 index 000000000000..5862768bb0a2 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbLib.c @@ -0,0 +1,1138 @@ +/** + * @file + * + * NB library functions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Get silicon type and revision info. + * + * + * + * @param[in] NbConfigPtr configuration structure pointer. + * @retval NB_INFO Northbrige Info Structure. + */ +/*----------------------------------------------------------------------------------------*/ +NB_INFO +LibNbGetRevisionInfo ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + NB_INFO RevisionInfo; + UINT16 DeviceId; + UINT8 RevisionId; + UINT32 PrivateId; + LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x8, AccessWidth8, &RevisionId, NbConfigPtr); + RevisionInfo.Revision = RevisionId; + LibNbPciRead (NbConfigPtr->NbPciAddress.AddressValue | 0x2, AccessWidth16, &DeviceId, NbConfigPtr); + switch (DeviceId) { + case 0x5956: + RevisionInfo.Type = NB_RD890TV; + break; + case 0x5957: + RevisionInfo.Type = NB_RX780; + break; + case 0x5958: + RevisionInfo.Type = NB_RD780; + break; + case 0x5A10: + RevisionInfo.Type = NB_SR5690; + break; + case 0x5A11: + RevisionInfo.Type = NB_RD890; + break; + case 0x5A12: + RevisionInfo.Type = NB_SR5670; + break; + case 0x5A13: + RevisionInfo.Type = NB_SR5650; + break; + case 0x5A14: + RevisionInfo.Type = NB_990FX; + LibNbPciIndexRead (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG7D, AccessWidth32, &PrivateId, NbConfigPtr); + PrivateId = (PrivateId >> 21) & 0x0f; + if (PrivateId == 1) { + RevisionInfo.Type = NB_990FX; + } + if (PrivateId == 2) { + RevisionInfo.Type = NB_990X; + } + if (PrivateId == 3) { + RevisionInfo.Type = NB_970; + } + break; + default: + RevisionInfo.Type = NB_UNKNOWN; + CIMX_ASSERT (FALSE); + } + return RevisionInfo; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Call Back routine. + * + * + * + * @param[in] CallBackId Callback ID. + * @param[in] Data Callback specific data. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +LibNbCallBack ( + IN UINT32 CallBackId, + IN OUT UINTN Data, + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + CALLOUT_ENTRY CallBackPtr = GET_BLOCK_CONFIG_PTR (NbConfigPtr)->StandardHeader.CalloutPtr; + + Status = AGESA_UNSUPPORTED; + if (CallBackPtr != NULL) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack CallBackId = 0x%x\n", CallBackId)); + Status = (*CallBackPtr) (CallBackId, Data, GET_BLOCK_CONFIG_PTR (NbConfigPtr)); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NBLIB]LibNbCallBack Return = 0x%x\n", Status)); + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Call Back routine. + * + * + * + * @param[in] SystemApi Pointer to System API + * @param[in] ConfigPtr Northbridge block configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +LibSystemApiCall ( + IN SYSTEM_API SystemApi, + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + API_WORKSPACE Workspace; + UINT8 NorthbridgeId; + + LibAmdMemFill (&Workspace, 0, sizeof (API_WORKSPACE), (AMD_CONFIG_PARAMS *)&(ConfigPtr->StandardHeader)); + Workspace.ConfigPtr = ConfigPtr; + Workspace.Status = AGESA_SUCCESS; + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + ConfigPtr->Northbridges[NorthbridgeId].ConfigPtr = &Workspace.ConfigPtr; + } + if (SystemApi != NULL) { + (*SystemApi)(ConfigPtr); + } + return Workspace.Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Call Back routine. + * + * + * + * @param[in] NbApi Pointer to NB API + * @param[in] ConfigPtr Northbridge block configuration structure pointer + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +LibNbApiCall ( + IN NB_API NbApi, + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + UINT8 NorthbridgeId; + AGESA_STATUS Status; + + Status = AGESA_SUCCESS; + for (NorthbridgeId = 0; NorthbridgeId <= ConfigPtr->NumberOfNorthbridges; NorthbridgeId++) { + AMD_NB_CONFIG *NbConfigPtr = &ConfigPtr->Northbridges[NorthbridgeId]; + ConfigPtr->CurrentNorthbridge = NorthbridgeId; + if (!LibNbIsDevicePresent (NbConfigPtr->NbPciAddress, NbConfigPtr)) { + REPORT_EVENT (AGESA_WARNING, GENERAL_ERROR_NB_NOT_PRESENT, 0 , 0, 0, 0, NbConfigPtr); + continue; + } + if (NbApi != NULL) { + Status = (*NbApi) (NbConfigPtr); + if (Status == AGESA_FATAL) { + break; + } + } + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCI register. + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Width Access width. + * @param[in] Value Pointer to new register value. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbPciWrite ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR DeviceAddress; + DeviceAddress.AddressValue = Address; + LibAmdPciWrite (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr))); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCI register + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Width Access width. + * @param[in] Value Pointer to save register value. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +LibNbPciRead ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR DeviceAddress; + DeviceAddress.AddressValue = Address; + LibAmdPciRead (Width, DeviceAddress, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr))); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCI register + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Width Access width. + * @param[in] Mask AND Mask. + * @param[in] Data OR Mask. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +VOID +LibNbPciRMW ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + LibNbPciRead (Address, Width, &Value, NbConfigPtr); + Value = (Value & Mask) | Data; + LibNbPciWrite (Address, Width, &Value, NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read PCI Index/Data Address space + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Index Index Address. + * @param[in] Width Access width of Index/Data register. + * @param[in] Value Pointer to save register value. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbPciIndexRead ( + IN UINT32 Address, + IN UINT32 Index, + IN ACCESS_WIDTH Width, + OUT UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 IndexOffset; + IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81))); + LibNbPciWrite (Address, Width, &Index, NbConfigPtr); + LibNbPciRead (Address + IndexOffset, Width, Value, NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write PCI Index/Data Address space + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Index Index Address. + * @param[in] Width Access width of Index/Data register. + * @param[in] Value Pointer to save register value. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbPciIndexWrite ( + IN UINT32 Address, + IN UINT32 Index, + IN ACCESS_WIDTH Width, + IN UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 IndexOffset; + IndexOffset = (1 << ((Width < 0x80)? (Width - 1): (Width - 0x81))); + LibNbPciWrite (Address, Width, &Index, NbConfigPtr); + LibNbPciWrite (Address + IndexOffset , Width, Value, NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write PCI Index/Data Address space + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Index Index Address. + * @param[in] Width Access width of Index/Data register. + * @param[in] Mask AND Mask. + * @param[in] Data OR Mask. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbPciIndexRMW ( + IN UINT32 Address, + IN UINT32 Index, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + LibNbPciIndexRead (Address, Index, Width, &Value, NbConfigPtr); + Value = (Value & Mask) | Data; + LibNbPciIndexWrite (Address, Index, Width, &Value, NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Program table of indirect register. + * + * + * + * @param[in] Address Compressed PCIE address identical to PCI_ADDR.AddressValue + * @param[in] Index Index Address. Index address OR with INDIRECT_REG_ENTRY.Register + * @param[in] pTable Pointer to indirect register table. + * @param[in] Length Number of entry in indirect register table. + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +VOID +LibNbIndirectTableInit ( + IN UINT32 Address, + IN UINT32 Index, + IN INDIRECT_REG_ENTRY *pTable, + IN UINTN Length, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINTN i; + for (i = 0; i < Length; i++) { + LibNbPciIndexRMW (Address, Index | pTable[i].Register , AccessS3SaveWidth32, pTable[i].Mask, pTable[i].Data, NbConfigPtr); + } +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Find PCI capability pointer + * + * + * + * + * + */ +/*----------------------------------------------------------------------------------------*/ + +UINT8 +LibNbFindPciCapability ( + IN UINT32 Address, + IN UINT8 CapabilityId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT8 CapabilityPtr; + UINT8 CurrentCapabilityId; + PCI_ADDR Device; + Device.AddressValue = Address; + CapabilityPtr = 0x34; + if (!LibNbIsDevicePresent (Device, NbConfigPtr)) { + return 0; + } + while (CapabilityPtr != 0) { + LibNbPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, NbConfigPtr); + if (CapabilityPtr) { + LibNbPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, NbConfigPtr); + if (CurrentCapabilityId == CapabilityId) break; + CapabilityPtr++; + } + } + return CapabilityPtr; +} +/*----------------------------------------------------------------------------------------*/ +/* + * Find PCIe extended capability pointer + * + * + * + * + * + */ +/*----------------------------------------------------------------------------------------*/ + +UINT16 +LibNbFindPcieExtendedCapability ( + IN UINT32 Address, + IN UINT16 ExtendedCapabilityId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT16 CapabilityPtr; + UINT32 ExtendedCapabilityIdBlock; + if (LibNbFindPciCapability (Address, 0x10, NbConfigPtr) != 0) { + CapabilityPtr = 0x100; + LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr); + if (ExtendedCapabilityIdBlock != 0 && (UINT16)ExtendedCapabilityIdBlock != 0xffff) { + do { + if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) { + return CapabilityPtr; + } + CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff); + LibNbPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, NbConfigPtr); + } while (CapabilityPtr != 0); + } + } + return 0; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read IO space + * + * + * + * @param[in] Address IO Port address. + * @param[in] Width Access width + * @param[in] Value Pointer to save IO port value; + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbIoRead ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + LibAmdIoRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr))); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write IO space + * + * + * + * @param[in] Address IO Port address. + * @param[in] Width Access width + * @param[in] Value Pointer to new IO port value + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +VOID +LibNbIoWrite ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + LibAmdIoWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr))); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write IO space + * + * + * + * @param[in] Address IO Port address. + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Data OR Mask + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbIoRMW ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + LibNbIoRead (Address, Width, &Value, NbConfigPtr); + Value = (Value & Mask) | Data; + LibNbIoWrite (Address, Width, &Value, NbConfigPtr); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read CPU HT link Phy register + * + * + * + * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.) + * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.) + * @param[in] Register Register address. + * @param[in] Value Pointer to save register value + * @param[in] NbConfigPtr Northbridge configuration block pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbCpuHTLinkPhyRead ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT16 Register, + OUT UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Data; + PCI_ADDR CpuPciAddress; + UINT8 LinkId; + LinkId = Link & 0xf; + CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0); + LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | ((Register & 0xfe00)?BIT29:0), NbConfigPtr); + do { + LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr); + } while ((Data & BIT31) == 0); + LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write CPU HT link Phy register + * + * + * + * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.) + * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.) + * @param[in] Register Register address. + * @param[in] Value Pointer to new register value + * @param[in] NbConfigPtr Northbridge configuration block pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbCpuHTLinkPhyWrite ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT16 Register, + IN UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Data; + PCI_ADDR CpuPciAddress; + UINT8 LinkId; + LinkId = Link & 0xf; + CpuPciAddress.AddressValue = MAKE_SBDFO (0, 0, Node, 4, 0); + LibNbPciWrite (CpuPciAddress.AddressValue | (LinkId * 8 + 0x184), AccessWidth32, Value, NbConfigPtr); + LibNbPciRMW (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, 0x0, Register | BIT30 | ((Register & 0xfe00)?BIT29:0), NbConfigPtr); + do { + LibNbPciRead (CpuPciAddress.AddressValue | (LinkId * 8 + 0x180), AccessWidth32, &Data, NbConfigPtr); + } while ((Data & BIT31) == 0); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write CPU HT link Phy register + * + * + * + * @param[in] Node Node device Address (0x18 - Node 0, 0x19 - Mode 1 etc.) + * @param[in] Link HT Link ID (0 - Link 0, 1 - Link 1 etc.) + * @param[in] Register Register address. + * @param[in] Mask AND Mask. + * @param[in] Data OR Mask. + * @param[in] NbConfigPtr Northbridge configuration block pointer. + */ +/*----------------------------------------------------------------------------------------*/ +VOID +LibNbCpuHTLinkPhyRMW ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT16 Register, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + LibNbCpuHTLinkPhyRead (Node, Link, Register, &Value, NbConfigPtr); + Value = (Value & Mask) | Data; + LibNbCpuHTLinkPhyWrite (Node, Link, Register, &Value, NbConfigPtr); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable Clock Config space access. + * Enable access to Clock Config Space at 0:0:1 PCI address. + * + * + * @param[in] pConfig Northbridge configuration block pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbEnableClkConfig ( + IN AMD_NB_CONFIG *pConfig + ) +{ + LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, BIT0, pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Disable Clock Config space access. + * Disable access to Clock Config Space at 0:0:1 PCI address. + * + * + * @param[in] pConfig Northbridge configuration block pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbDisableClkConfig ( + IN AMD_NB_CONFIG *pConfig + ) +{ + LibNbPciRMW (NB_SBDFO | NB_PCI_REG4C, AccessS3SaveWidth8, (UINT32)~BIT0, 0x0 , pConfig); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if PCI Device Present + * + * + * + * @param[in] Device Device PCI address. + * @param[in] NbConfigPtr Northbridge configuration block pointer. + * + * @retval TRUE Device present. + * @retval FALSE Device not present. + */ +/*----------------------------------------------------------------------------------------*/ + +BOOLEAN +LibNbIsDevicePresent ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 VendorId; + LibNbPciRead (Device.AddressValue, AccessWidth32, &VendorId, NbConfigPtr); + return (VendorId == 0xffffffff)?FALSE:TRUE; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Check if IOMMU enabled + * + * + * + * @param[in] NbConfigPtr Northbridge configuration block pointer. + * + * @retval TRUE IOMMU not enabled. + * @retval FALSE IOMMU not enabled. + */ +/*----------------------------------------------------------------------------------------*/ +BOOLEAN +LibNbIsIommuEnabled ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR IommuAddress; + IommuAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue; + IommuAddress.Address.Function = 2; + if (LibNbIsDevicePresent (IommuAddress, NbConfigPtr)) { + UINT8 Value; + LibNbPciRead (IommuAddress.AddressValue | 0x44, AccessWidth8, &Value, NbConfigPtr); + if ((Value & BIT0) != 0) { + return TRUE; + } + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Reverse bit in DWORD. + * Reverse bits in bitfield inside DWORD. + * + * + * @param[in] Data Value to reverse. + * @param[in] StartBit Start bit. + * @param[in] StopBit Stop bit. + * @retval Reversed Value. + */ +/*----------------------------------------------------------------------------------------*/ + +UINT32 +LibNbBitReverse ( + IN UINT32 Data, + IN UINT8 StartBit, + IN UINT8 StopBit + ) +{ + + UINT32 Bitr; + UINT32 Bitl; + UINT32 Distance; + + while (StartBit < StopBit) { + Bitr = Data & (1 << StartBit ); + Bitl = Data & (1 << StopBit ); + Distance = StopBit - StartBit; + Data = (Data & ((UINT32)~(Bitl | Bitr))) | (Bitr << Distance ) | (Bitl >> Distance); + StartBit++; + StopBit--; + } + return Data; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Read CPU family + * + * + * + * @retval 0xXX00000 CPU family. + * + */ +UINT32 +LibNbGetCpuFamily ( + VOID + ) +{ + CPUID_DATA Cpuid; + CpuidRead (0x1, &Cpuid); + return Cpuid.EAX_Reg & 0xff00000; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Load Firmware block + * + * + * + * @param[in] Address Address to load firmware + * @param[in] Size Firmware block size + * @param[in] FirmwareBlockPtr Pointer to firmware block + * @param[in] NbConfigPtr Northbridge configuration block pointer. + * + */ +VOID +LibNbLoadMcuFirmwareBlock ( + IN UINT16 Address, + IN UINT16 Size, + IN UINT32 *FirmwareBlockPtr, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 i; + PCI_ADDR ClkPciAddress; + UINT32 Selector; + + Selector = (Address >= 0x200)?0x0000000:0x10000; + ClkPciAddress = NbConfigPtr->NbPciAddress; + ClkPciAddress.Address.Function = 1; + LibNbEnableClkConfig (NbConfigPtr); + for (i = 0; i < Size; i++) { + LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address + (i * 4)), AccessWidth32, &FirmwareBlockPtr[i], NbConfigPtr); + } + LibNbDisableClkConfig (NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read SMU firmware ram + * + * + * + * @param[in] Address Address to read + * @param[in] NbConfigPtr Northbridge configuration block pointer. + * + */ +UINT32 +LibNbReadMcuRam ( + IN UINT16 Address, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + PCI_ADDR ClkPciAddress; + UINT32 Selector; + + Selector = (Address >= 0x200) ? 0x0000000 : 0x10000; + ClkPciAddress = NbConfigPtr->NbPciAddress; + ClkPciAddress.Address.Function = 1; + LibNbEnableClkConfig (NbConfigPtr); + LibNbPciIndexRead (ClkPciAddress.AddressValue | MC_CLK_INDEX, Selector | (Address), AccessWidth32, &Value, NbConfigPtr); + LibNbDisableClkConfig (NbConfigPtr); + return Value; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * MCU Control + * + * + * + * @param[in] Operation Set/Reset MCU controller + * @param[in] NbConfigPtr Northbridge configuration block pointer. + */ +VOID +LibNbMcuControl ( + IN NB_MCU_MODE Operation, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR ClkPciAddress; + UINT32 Value; + + Value = (Operation == AssertReset)?0x00000ee1:0x00000ee2; + ClkPciAddress = NbConfigPtr->NbPciAddress; + ClkPciAddress.Address.Function = 1; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "LibNbMcuControl Operation [0x%x]\n", Operation)); + LibNbEnableClkConfig (NbConfigPtr); + LibNbPciIndexWrite (ClkPciAddress.AddressValue | MC_CLK_INDEX, 0x00030000, AccessWidth32, &Value, NbConfigPtr); + LibNbDisableClkConfig (NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read/Modify/Write memory space + * + * + * + * @param[in] Address Memory address. + * @param[in] Width Access width + * @param[in] Mask AND Mask + * @param[in] Data OR Mask + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbMemRMW ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + LibNbMemRead (Address, Width, &Value, NbConfigPtr); + Value = (Value & Mask) | Data; + LibNbMemWrite (Address, Width, &Value, NbConfigPtr); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Read memory space + * + * + * + * @param[in] Address Memory address. + * @param[in] Width Access width + * @param[in] Value Pointer to memory to store value + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbMemRead ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + LibAmdMemRead (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr))); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Write memory space + * + * + * + * @param[in] Address Memory address. + * @param[in] Width Access width + * @param[in] Value Pointer to memory to get value + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbMemWrite ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + LibAmdMemWrite (Width, Address, Value, (AMD_CONFIG_PARAMS *)((NbConfigPtr == NULL)?NULL:GET_BLOCK_CONFIG_PTR (NbConfigPtr))); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Scan Pci Bridge + * + * + * + * @param[in] This Pointer to PCI topology scan protocol + * @param[in] Bridge Address of PCI to PCI bridge to scan. + */ + +SCAN_STATUS +LibNbScanPciBridgeBuses ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Bridge + ) +{ + SCAN_STATUS Status; + UINT8 CurrentBus; + UINT8 MinBus; + UINT8 MaxBus; + PCI_ADDR Device; + + CIMX_ASSERT (This != NULL); + if (This->ScanBus == NULL) { + return SCAN_FINISHED; + } + LibNbPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &MinBus, This->pConfig); + LibNbPciRead (Bridge.AddressValue | 0x1A, AccessWidth8, &MaxBus, This->pConfig); + if (MinBus == 0 || MaxBus == 0) { + return SCAN_FINISHED; + } + 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)); + for (CurrentBus = MinBus; CurrentBus <= MaxBus; CurrentBus++) { + Device.AddressValue = MAKE_SBDFO (0, CurrentBus, 0, 0, 0); + Status = This->ScanBus (This, Device); + } + return SCAN_FINISHED; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Scan Pci Bus + * + * + * + * @param[in] This Pointer to PCI topology scan protocol + * @param[in] Device Pci address device to start bus scan from + */ +/*----------------------------------------------------------------------------------------*/ +SCAN_STATUS +LibNbScanPciBus ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Device + ) +{ + SCAN_STATUS Status; + UINT32 CurrentDevice; + CIMX_ASSERT (This != NULL); + if (This->ScanDevice == NULL) { + return SCAN_FINISHED; + } + for (CurrentDevice = Device.Address.Device; CurrentDevice <= 0x1f; CurrentDevice++) { + Device.Address.Device = CurrentDevice; + if (LibNbIsDevicePresent (Device, This->pConfig)) { + Status = This->ScanDevice (This, Device); + if (Status == SCAN_STOP_BUS_ENUMERATION) { + return Status; + } + + } + } + return SCAN_FINISHED; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Scan Pci Device + * + * + * + * @param[in] This Pointer to PCI topology scan protocol + * @param[in] Device Pci address device to scan + */ +/*----------------------------------------------------------------------------------------*/ + +SCAN_STATUS +LibNbScanPciDevice ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Device + ) +{ + SCAN_STATUS Status; + UINT8 Header; + UINT32 CurrentFunction; + UINT32 MaxFunction; + CIMX_ASSERT (This != NULL); + if (This->ScanFunction == NULL) { + return SCAN_FINISHED; + } + LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Header, This->pConfig); + MaxFunction = (Header & 0x80)?7:0; + for (CurrentFunction = Device.Address.Function; CurrentFunction <= MaxFunction; CurrentFunction++) { + Device.Address.Function = CurrentFunction; + if (LibNbIsDevicePresent (Device, This->pConfig)) { + 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)); + Status = This->ScanFunction (This, Device); + if (Status == SCAN_STOP_DEVICE_ENUMERATION || Status == SCAN_STOP_BUS_ENUMERATION) { + return Status; + } + } + } + return SCAN_FINISHED; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set default Indexes + * + * + * @param[in] NbConfigPtr Northbridge configuration block pointer. + */ +/*----------------------------------------------------------------------------------------*/ + +VOID +LibNbSetDefaultIndexes ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR PciAddress; + PORT PortId; + LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr); + LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr); + LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, SB_CORE, NbConfigPtr); + PciAddress.AddressValue = NbConfigPtr->NbPciAddress.AddressValue; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + PciAddress.Address.Device = PortId; + LibNbPciRMW (PciAddress.AddressValue | NB_BIF_INDEX, AccessWidth32, 0x0, 0x0, NbConfigPtr); + } +} diff --git a/src/vendorcode/amd/cimx/rd890/nbLib.h b/src/vendorcode/amd/cimx/rd890/nbLib.h new file mode 100644 index 000000000000..af10946b9a93 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbLib.h @@ -0,0 +1,352 @@ +/** + * @file + * + * CNB Library function + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBLIB_H_ +#define _NBLIB_H_ + +#pragma pack(push, 1) + +/// NB_MCU_MODE +typedef enum { + AssertReset, ///< Assert reset + DeAssertReset ///< Deassert reset +} NB_MCU_MODE; + +/// SMU Firmware revision +typedef struct { + UINT16 MajorRev; ///< Major revision + UINT16 MinorRev; ///< Minor revision +} SMU_FIRMWARE_REV; + +/// Firmware block +typedef struct { + UINT16 Address; ///< Block Address + UINT16 Length; ///< Block length in DWORD + UINT32 *Data; ///< Pointer to data array +} SMU_FIRMWARE_BLOCK; + +/// Firmware header +typedef struct { + SMU_FIRMWARE_REV Revision; ///< Revision info + UINT16 NumberOfBlock; ///< Number of blocks + SMU_FIRMWARE_BLOCK *BlockArray; ///< Pointer to block definition array +} SMU_FIRMWARE_HEADER; + + +NB_INFO +LibNbGetRevisionInfo ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +AGESA_STATUS +LibNbCallBack ( + IN UINT32 CallBackId, + IN OUT UINTN Data, + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbPciWrite ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbPciRead ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbPciRMW ( + IN UINT32 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbPciIndexRead ( + IN UINT32 Address, + IN UINT32 Index, + IN ACCESS_WIDTH Width, + OUT UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbPciIndexWrite ( + IN UINT32 Address, + IN UINT32 Index, + IN ACCESS_WIDTH Width, + IN UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbPciIndexRMW ( + IN UINT32 Address, + IN UINT32 Index, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbIndirectTableInit ( + IN UINT32 Address, + IN UINT32 Index, + IN INDIRECT_REG_ENTRY *pTable, + IN UINTN Length, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +UINT8 +LibNbFindPciCapability ( + IN UINT32 Address, + IN UINT8 CapabilityId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbIoRMW ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbCpuHTLinkPhyRead ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT16 Register, + OUT UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbCpuHTLinkPhyWrite ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT16 Register, + IN UINT32 *Value, + IN AMD_NB_CONFIG *NbConfigPtr +); + +VOID +LibNbCpuHTLinkPhyRMW ( + IN UINT8 Node, + IN UINT8 Link, + IN UINT16 Register, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr +); + +VOID +LibNbEnableClkConfig ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +LibNbDisableClkConfig ( + IN AMD_NB_CONFIG *pConfig + ); + +BOOLEAN +LibNbIsDevicePresent ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +UINT32 +LibNbBitReverse ( + IN UINT32 Data, + IN UINT8 StartBit, + IN UINT8 StopBit + ); + +UINT32 +LibNbGetCpuFamily ( + VOID + ); + +VOID +LibNbIoWrite ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbIoRead ( + IN UINT16 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbLoadMcuFirmwareBlock ( + IN UINT16 Address, + IN UINT16 Size, + IN UINT32 *FirmwareBlockPtr, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +UINT32 +LibNbReadMcuRam ( + IN UINT16 Address, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbMcuControl ( + IN NB_MCU_MODE Operation, + IN AMD_NB_CONFIG *NbConfigPtr + ); + + +AGESA_STATUS +LibSystemApiCall ( + IN SYSTEM_API SystemApi, + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +LibNbApiCall ( + IN NB_API NbApi, + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +VOID +LibNbMemRMW ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN UINT32 Mask, + IN UINT32 Data, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbMemRead ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + IN VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +LibNbMemWrite ( + IN UINT64 Address, + IN ACCESS_WIDTH Width, + OUT VOID *Value, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +struct _PCI_SCAN_PROTOCOL; +typedef struct _PCI_SCAN_PROTOCOL PCI_SCAN_PROTOCOL; +typedef UINT32 SCAN_STATUS; + +typedef SCAN_STATUS (*SCAN_ENTRY) (PCI_SCAN_PROTOCOL *This, PCI_ADDR Device); + +#define SCAN_FINISHED 0x0 +#define SCAN_STOP_DEVICE_ENUMERATION 0x1 +#define SCAN_STOP_BUS_ENUMERATION 0x2 + + +/// PCI topology scan protocol +struct _PCI_SCAN_PROTOCOL { + SCAN_ENTRY ScanBus; ///< Pointer to function to scan device on PCI bus. + SCAN_ENTRY ScanDevice; ///< Pointer to function to scan function on PCI device. + SCAN_ENTRY ScanFunction; ///< Pointer to scan PCI function. + AMD_NB_CONFIG *pConfig; ///< NB configuration info. +}; + +SCAN_STATUS +LibNbScanPciBus ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Device + ); + +SCAN_STATUS +LibNbScanPciDevice ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Device + ); + +SCAN_STATUS +LibNbScanPciBridgeBuses ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Bridge + ); + +VOID +LibNbSetDefaultIndexes ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +UINT16 +LibNbFindPcieExtendedCapability ( + IN UINT32 Address, + IN UINT16 ExtendedCapabilityId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +BOOLEAN +LibNbIsIommuEnabled ( + IN AMD_NB_CONFIG *NbConfigPtr + ); + +#pragma pack(pop) + +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c new file mode 100644 index 000000000000..8394835d0680 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.c @@ -0,0 +1,121 @@ +/** + * @file + * + * NB RAS + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +extern UINT16 NbInitMaskedMemoryLength; + +typedef VOID (*MASKED_MEMORY_INIT_PROC) (IN UINT32 PciAddress, IN UINT16 AlinkAddress); + + +AGESA_STATUS +AmdMaskedMemoryInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (NbMaskedMemoryInit, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Mask Memory + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +NbMaskedMemoryInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT8 ExecutionBuffer[300]; + SCRATCH_1 Scratch; + UINT16 AlinkPort; + + Status = AGESA_SUCCESS; + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); + if (Scratch.MaskMemoryInit == OFF) { + return Status; + } + Scratch.MaskMemoryInit = OFF; + LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); + CIMX_ASSERT (NbInitMaskedMemoryLength < 300); + LibAmdMemCopy ((VOID*)ExecutionBuffer, (VOID*) (UINTN)NbInitMaskedMemory, NbInitMaskedMemoryLength, (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig); + (*((MASKED_MEMORY_INIT_PROC)(UINTN)ExecutionBuffer))(pConfig->NbPciAddress.AddressValue, AlinkPort); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG87, AccessS3SaveWidth32, 0x0, 0xffffffff, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG88, AccessS3SaveWidth32, 0x0, 0xffffffff, pConfig); + return Status; +} + diff --git a/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h new file mode 100644 index 000000000000..c364fe2d7529 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit.h @@ -0,0 +1,63 @@ +/** + * @file + * + * NB RAS + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBMASKEDMEMORYINIT_H_ +#define _NBMASKEDMEMORYINIT_H_ + +AGESA_STATUS +AmdMaskedMemoryInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +NbMaskedMemoryInit ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +NbInitMaskedMemory ( + IN UINT32 PciAddress, + IN UINT16 AlinkAddress + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S new file mode 100644 index 000000000000..3c148aa85e73 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbMaskedMemoryInit32.S @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/****************************************************************************** +* CIMX Northbridge +* +* Contains CIMX 32 bit library code +* +* Description: nbMaskedMemoryInit32.S - nb Masked Memory Init 32bit ASM code +* +******************************************************************************/ + +.altmacro + +#include <cpu/x86/post_code.h> + + .section ".text" + .code32 + .globl NbInitMaskedMemory, NbInitMaskedMemoryLength + +/* +* PciAddress = 8(%ebp) +* AlinkAddress = 12(%ebp) +*/ +.type NbInitMaskedMemory, @function + +NbInitMaskedMemory: + push %ebp + movl %esp, %ebp + pusha + cmp $0, 12(%ebp) + jz 0f + mov 12(%ebp), %dx + mov $0x80000004, %eax + out %eax, %dx + add $4, %dx + in %dx, %eax + btr $2, %eax + out %eax, %dx + 0: + mov 8(%ebp), %eax + shr $4, %eax + or $0x80000060, %eax + mov %eax, %ebx + mov $0x0cf8, %dx + out %eax, %dx + mov $0x0cfc, %dx + mov $(0x80 | 0x1B), %eax # NB_MISC_REG1B + out %eax, %dx + mov %ebx, %eax + mov $0x64, %al + mov $0x0cf8, %dx + out %eax, %dx + mov $0x0cfc, %dx + in %dx, %eax + and $(~(0x01ff << 21)), %eax + bts $15, %eax + xor %ecx, %ecx + out %eax, %dx +StartInit: + and $(~(0xff << 22)), %eax + shl $22, %ecx + or %ecx, %eax + shr $22, %ecx + out %eax, %dx + bts $21, %eax + out %eax, %dx + btr $21, %eax + out %eax, %dx + cmp $0x0ff, %cl + je DoneInit + inc %ecx + jmp StartInit +DoneInit: + btr $15, %eax + out %eax, %dx + cmp $0, 12(%ebp) + jz 1f + mov 12(%ebp), %dx + mov $0x80000004, %eax + out %eax, %dx + add $4, %dx + in %dx, %eax + bts $2, %eax + out %eax, %dx + 1: + popa + movl %ebp, %esp + pop %ebp + ret +NbInitMaskedMemoryLength = ( . - NbInitMaskedMemory) + diff --git a/src/vendorcode/amd/cimx/rd890/nbMiscInit.c b/src/vendorcode/amd/cimx/rd890/nbMiscInit.c new file mode 100644 index 000000000000..ded6934cec97 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbMiscInit.c @@ -0,0 +1,123 @@ +/** + * @file + * + * NB Initialization. + * + * Init IOAPIC/IOMMU/Misc NB features. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for all NB. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdMiscInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (MiscInitializer, ConfigPtr); + return Status; +} +/*----------------------------------------------------------------------------------------*/ +/** + * NB structure initializer. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +MiscInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AMD_NB_CONFIG_BLOCK *ConfigPtr; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMiscInitializer Enter\n")); + ConfigPtr = GET_BLOCK_CONFIG_PTR (NbConfigPtr); + if (ConfigPtr == NULL) { + return AGESA_FATAL; + } + if (ConfigPtr->PlatformType == DetectPlatform) { + NB_INFO NbInfo; + NbInfo = LibNbGetRevisionInfo (NbConfigPtr); + if (NbInfo.Type != NB_UNKNOWN && NbInfo.Type >= NB_SR5690 && NbInfo.Type <= NB_SR5650) { + ConfigPtr->PlatformType = ServerPlatform; + } else { + ConfigPtr->PlatformType = DesktopPlatform; + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NB_TRACE), "[NB]NbMiscInitializer Exit\n")); + return AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbMiscInit.h b/src/vendorcode/amd/cimx/rd890/nbMiscInit.h new file mode 100644 index 000000000000..2537e787f291 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbMiscInit.h @@ -0,0 +1,57 @@ +/** + * @file + * + * NB definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBMISCINIT_H_ +#define _NBMISCINIT_H_ + +AGESA_STATUS +AmdMiscInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +AGESA_STATUS +MiscInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbModuleInfo.c b/src/vendorcode/amd/cimx/rd890/nbModuleInfo.c new file mode 100644 index 000000000000..175e3b369e4c --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbModuleInfo.c @@ -0,0 +1,70 @@ +/** + * @file + * + * Function dispatcher. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +#define Int32FromChar(a,b,c,d) ((a) << 0 | (b) << 8 | (c) << 16 | (d) << 24) + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +VOLATILE AMD_MODULE_HEADER mNbModuleID = { +// 'DOM$', + Int32FromChar ('D', 'O', 'M', '$'), + CIMX_NB_ID, + CIMX_NB_REVISION, + AmdNbDispatcher, + NULL +}; diff --git a/src/vendorcode/amd/cimx/rd890/nbPcie.h b/src/vendorcode/amd/cimx/rd890/nbPcie.h new file mode 100644 index 000000000000..50120582d980 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcie.h @@ -0,0 +1,352 @@ +/** + * @file + * + * PCIE definitions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBPCIE_H_ +#define _NBPCIE_H_ + +#pragma pack(push, 1) + +/// PCIe Link Aspm mode +typedef enum { + PcieLinkAspmDisabled, ///< Disabled + PcieLinkAspmL0s, ///< L0s only + PcieLinkAspmL1, ///< L1 only + PcieLinkAspmL0sAndL1, ///< L0s and L1 + PcieLinkAspmL0sDownstreamOnly, ///< L0s Donnstream Port Only + PcieLinkAspmL0sDownstreamOnlyAndL1 ///< L0s Donnstream Port and L1 +} PCIE_LINK_ASPM; + +/// PCIe device type +typedef enum { + PcieDeviceEndPoint, ///< Endpoint + PcieDeviceLegacyEndPoint, ///< Legacy endpoint + PcieDeviceRootComplex = 4, ///< Root complex + PcieDeviceUpstreamPort, ///< Upstream port + PcieDeviceDownstreamPort, ///< Downstream Port + PcieDevicePcieToPcix, ///< PCIe to PCI/PCIx bridge + PcieDevicePcixToPcie, ///< PCI/PCIx to PCIe bridge + PcieNotPcieDevice = 0xff ///< unknown device +} PCIE_DEVICE_TYPE; + +/// PCIe Link Mode +typedef enum { + PcieLinkModeGen2, ///< Gen 2 + PcieLinkModeGen1, ///< Gen 1 + PcieLinkModeGen2SoftwareInitiated, ///< Gen 2 software + PcieLinkModeGen2AdvertizeOnly ///< Gen 2 advertise only +} PCIE_LINK_MODE; + +/// PCIE Link Status +typedef enum { + PcieLinkStatusNotConnected, ///< not connected + PcieLinkStatusConnected, ///< connected + PcieLinkStatusInCompliance, ///< compliant + PcieLinkStatusTrainingInProgress, ///< training in progress + PcieLinkStatusVcoNegotiationInProgress, ///< Vco negotiation in progress +} PCIE_LINK_STATUS; + +/// PCIE Link Width Information +typedef enum { + PcieLinkMaxWidth, ///< max width + PcieLinkCurrentWidth, ///< current width +} PCIE_LINK_WIDTH_INFO; + +/// PCIE Link Training +typedef enum { + PcieLinkTrainingRelease, ///< training release + PcieLinkTrainingHold ///< training hold +} PCIE_LINK_TRAINING; + +/// PCIE Strap Mode +typedef enum { + PcieCoreStrapConfigStart, ///< start + PcieCoreStrapConfigStop ///< stop +} PCIE_STRAP_MODE; + +/// PCIE Link Width +typedef enum { + PcieLinkWidth_x0 = 0, ///< x0 + PcieLinkWidth_x1 = 1, ///< x1 + PcieLinkWidth_x2, ///< x2 + PcieLinkWidth_x4, ///< x4 + PcieLinkWidth_x8, ///< x8 + PcieLinkWidth_x12, ///< x12 + PcieLinkWidth_x16 ///< x16 +} PCIE_LINK_WIDTH; + +/// PCIe Transmitter deemphasis advertise +typedef enum { + PcieTxDeemphasis6dB = 0, ///< -6dB + PcieTxDeemphasis3p5dB, ///< -3.5dB +} PCIE_LINK_DEEMPASIS; + +/// PCIe Transmitter deemphasis advertise +typedef enum { + PcieTxDriveStrangth26mA = 0, ///< 26mA + PcieTxDriveStrangth20mA, ///< 20mA + PcieTxDriveStrangth22mA, ///< 22mA + PcieTxDriveStrangth24mA, ///< 24mA +} PCIE_LINK_DRIVE_STRANGTH; + +/// PCIe Channel type +typedef enum { + PcieShortChannel = 1, ///< Short Channel + PcieMediumChannel, ///< Medium Channel + PcieLongChannel, ///< Long Channel +} NB_PCIE_CHANNEL_TYPE; + +/// PCI Core Reset +typedef enum { + PcieCoreResetAllDeassert = 1, ///< deassert + PcieCoreResetAllAssert, ///< assert + PcieCoreResetAllCheck, ///< check +} PCI_CORE_RESET; + +/// Misc PCIE Core Setting +typedef struct { + UINT32 CoreDisabled :1; ///< Core not present or disabled + UINT32 PowerOffPll :1; ///< Enable power off PLL if group of lanes controlled by PLL unused + UINT32 PowerOffPllInL1 :1; ///< Enable Power off PLL in L1 + UINT32 LclkClockGating :1; ///< Enable LCLK clock gating + UINT32 TxClockGating :1; ///< Enable TX clock gating + UINT32 PowerOffUnusedLanes :1; ///< Enable Power off pads for unused Lanes + UINT32 CplBufferAllocation :1; ///< Enable special/optimized CPL buffer allocation + UINT32 PerformanceMode :1; ///< Enable support PCIe Reference Clock overclocking. In addition to rump-up PCIe reference clock + UINT32 TxDriveStrength :2; /**< TX Drive strength (Only applicable if PCIE_CORE_SETTING::ChannelType == 0). + * @li @b 0 - 26mA + * @li @b 1 - 20mA + * @li @b 2 - 22mA + * @li @b 3 - 24mA + */ + UINT32 SkipConfiguration :1; ///< Special case to skip core configuration (configured outside of CIMx) + UINT32 TxHalfSwingMode :1; ///< Half Swing Mode for PCIe Transmitters (Only applicable if PCIE_CORE_SETTING::ChannelType == 0). + UINT32 ChannelType :3; /**< Group PCIe PHY setting for channel with specific trace length + * @li @b 0 - Use individual parameters to configure PCIe PHY (see PCIE_CORE_SETTING::TxHalfSwingMode, + PCIE_CORE_SETTING::TxDriveStrength, PCIE_EXT_PORT_CONFIG::PortDeemphasis). + * @li @b 1 - Short Channel. + * @li @b 2 - Midium Channel. + * @li @b 3 - Long Channel. + */ + UINT32 DetectPowerOffPllInL1 :1; ///< Enable detection if endpoint L1 acceptable latency allow Enable Power off PLL in L1. + UINT32 TxClockOff :1; ///< Disable TX clock if possible + UINT32 LclkClockOff :1; ///< Disable LCLK clock if possible + UINT32 RefClockInput :1; ///< Use dedicated ref. clock input (only applicable GPP1 and GPP2 cores). By default SB ref clock is used. + UINT32 Reserved :2; ///< + UINT32 CoreDisableStatus :1; /**< Output status of core disable/enable + * @li @b 0 = Core not disabled + * @li @b 1 = Core Disabled + */ +} PCIE_CORE_SETTING; + +/// Misc Configuration +typedef struct { + UINT32 DisableHideUnusedPorts :1; ///< Hide unused ports if no EP was detected and port non hotpluggable + UINT32 Peer2Peer :1; ///< Enable Peer to Peer. + UINT32 DisableGfxWorkaround :1; ///< disable RV370/RV380 workaround + UINT32 NbSbVc1 :1; ///< Enable VC1 for NB SB Audio traffic +} PCIE_MISC_CONFIG; + +/// Extended PCIE Port Configuration +typedef struct { + UINT32 PortL1ImmediateACK :1; ///< Validation feature + UINT32 PortLinkWidth :3; /**< Port Link width + * @li @b 0 - Auto. Default max link width. + * @li @b 1 - x1 + * @li @b 2 - x2 + * @li @b 3 - x4 + * @li @b 4 - x8 + * @li @b 6 - x16 + */ + UINT32 PortMapping :4; /**< Device number mapping info + * @li @b 0 - Default mapping + * @li @b n - PCI device number for port (Valid device numbers are 2/3/4/5/6/7/9/10/11/12/13). + */ + UINT32 PortHotplugDevMap :2; /**< PCA9539 device map. + *Only valid if PortHotplug = 1 + */ + UINT32 PortHotplugByteMap :1; /**< PCA9539 channel map. + *Only valid if PortHotplug = 1 + */ + UINT32 PortPowerLimit :8; ///< Slot power limit in W + UINT32 Reserved :2; ///< Reserved + UINT32 PortDeemphasis :2; /**< Port deempasis adverise (Only applicable if PCIE_CORE_SETTING::ChannelType == 0). + * @li @b 0 - 6dB + * @li @b 1 - 3.5dB + */ + +} PCIE_EXT_PORT_CONFIG; + +/// PCIE Port Configuration +typedef struct { + UINT32 PortPresent :1; /**< Port connection + * @li @b 0 - Port has no slot or EP connected. Link not needs to be trained. + * @li @b 1 - Has slot or EP connected. Link needs to be trained. + */ + UINT32 PortDetected :1; /**< Scratch bit to record status of training + * @li @b 0 - EP not detected + * @li @b 1 - EP detected + */ + UINT32 PortCompliance :1; /**< Link compliance mode + * @li @b 0 - Link in operational mode + * @li @b 1 - Force link into compliance mode + */ + UINT32 PortLinkMode :2; /**< Link speed mode configuration + * @li @b 0 - GEN2 Autonomous (GEN2 capability advertized and and immediate link speed change initiated). + * @li @b 1 - GEN1 + * @li @b 2 - GEN2 Software Initiated (Port trained to Gen1 thereafter if EP report GEN2 capability port reconfigured to GEN2) + * @li @b 3 - GEN2 advertize only (RC only advertize GEN2 capability and not initiate transition to GEN2 speed) + */ + UINT32 PortHotplug :2; /**< Port Hotplug configuration + * @li @b 0 - Hotplug Disabled + * @li @b 1 - Server Hotplug Enabled + * @li @b 2 - Reserved + * @li @b 3 - Reserved + */ + UINT32 PortAspm :3; /**< Port ASPM support + * @li @b 0 - Disabled + * @li @b 1 - L0s enable + * @li @b 2 - L1 enable + * @li @b 3 - L0s + L1 enable + * @li @b 4 - L0s Downstream Only + * @li @b 5 - L0s Downstream Only + L1 + * @li <b>4..7</b> - Reserved + */ + UINT32 PortReversed :1; /**< Port lanes reversed + * @li @b 0 - Lanes non reversed + * @li @b 1 - Lanes reversed + */ + UINT32 ForcePortDisable :1; /**< Port Disable after PCIE training + * @li @b 0 - Do not force port disable + * @li @b 1 - Force port disable + */ + UINT32 PortAlwaysVisible :1; /**< Port always visible + * @li @b 1 - Port always visible + */ +} PCIE_PORT_CONFIG; + +/// PCIE default configuration parameters structure +typedef struct { + PCIE_MISC_CONFIG PcieConfiguration; ///< PCIE configuration + PCIE_CORE_SETTING CoreSetting[5]; ///< Core Setting + UINT16 DeviceInitMaskS1; ///< Bit mask of ports id to be initialized at stage 1 + UINT16 DeviceInitMaskS2; ///< Bit mask of ports id to be initialized at stage 2 + UINT16 ResetToTrainingDelay; ///< Delay (in 1ms) after reset deassert before training started + UINT16 TrainingToLinkTestDelay; ///< Delay (in 1ms) after training started but before pooling link state + UINT16 ReceiverDetectionPooling; ///< Total amount time (in 1ms of pooling for passing receiver detection stage +} PCIE_DEFAULT_CONFIG; + +/// Link Info +typedef struct { + UINT8 LinkWidth; ///< width + UINT8 MaxLinkWidth; ///< max width + UINT8 Line0Offset; ///< line 0 offset +} LINK_INFO; + +/// Port Static Info +typedef struct { + UINT8 TrainingAddress; ///< training address + UINT8 ReversalAddress; ///< reversal address + UINT8 DeemphasisAddress; ///< de-emphasis address + UINT8 MappingAddress; ///< mapping address + UINT8 HotplugAddress; ///< Hotplug address +} PORT_STATIC_INFO; + +/// Core Info +typedef struct { + UINT32 CoreSelector; ///< core selector + UINT16 PortIdBitMap; ///< port Id + UINT8 TrainingRegister; ///< training + UINT8 DeemphasisRegister; ///< de-emphasis + UINT8 StrapRegister; ///< strap + UINT8 StrapAddress; ///< strap address + UINT8 HotplugRegister; ///< Hotplug descriptor register + UINT8 TxDriveStrengthRegister; ///< Tx drive strength register + UINT8 TxDriveStrengthOffset; ///< Tx drive strength bit offeset + UINT8 TxHalfSwingRegister; ///< Tx half swing register + UINT8 TxHalfSwingOffset; ///< Tx half swing bit offset + UINT8 TxHalfSwingDeepmhasisRegister; ///< Tx half swing deephasis register + UINT8 TxHalfSwingDeepmhasisOffset; ///< Tx half swing deephasis register + UINT8 TxOffOffset; ///< Tx shutdown enable offset + UINT8 LclkOffOffset; ///< Lclk shutdown enable offset + UINT8 LclkPermOffOffset; ///< Lclk Perm shutdown enable offset +} CORE_INFO; + +/// Port Information +typedef struct { + UINT8 MaxLinkWidth; ///< max link width + UINT8 Line0Offset; ///< offset + UINT8 SlaveCplBuffers; ///< Alternative to default CPL buffer count +} PORT_INFO; + +/// GPP Configuration Info +typedef struct { + PORT_INFO *PortInfoPtr; ///< port information + UINT32 PortIdMap; ///< port id map +} GPP_CFG_INFO; + + +#define GPP1_CORE 0x40000 +#define GPP2_CORE 0x60000 +#define GPP3a_CORE 0x70000 +#define GPP3b_CORE 0x30000 +#define SB_CORE 0x50000 + +#define GPP_CONFIG_GPP420000 0x01 +#define GPP_CONFIG_GPP411000 0x02 +#define GPP_CONFIG_GPP222000 0x03 +#define GPP_CONFIG_GPP221100 0x04 +#define GPP_CONFIG_GPP211110 0x05 +#define GPP_CONFIG_GPP111111 0x06 + +#define GFX_CONFIG_A 0x01 +#define GFX_CONFIG_B 0x02 + +#define GFX_CONFIG_AAAA (GFX_CONFIG_A | (GFX_CONFIG_A << 8) | (GFX_CONFIG_A << 16) | (GFX_CONFIG_A << 24)) +#define GFX_CONFIG_AABB (GFX_CONFIG_A | (GFX_CONFIG_A << 8) | (GFX_CONFIG_B << 16) | (GFX_CONFIG_B << 24)) + +#define PCIE_CAP_ID 0x10 + + +#pragma pack(pop) + +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieAspm.c b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.c new file mode 100644 index 000000000000..38bc41fb1a58 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.c @@ -0,0 +1,507 @@ +/** + * @file + * + * ASPM support. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" +#include "amdSbLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + + +VOID +PcieAspmSetOnRc ( + IN PCI_ADDR Device, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ); + +SCAN_STATUS +PcieSetDeviceAspm ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Function + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Port ASPM. + * Enable ASPM states on RC and EP. Only states supported by both RC and EP + * will be enabled. + * + * + * @param[in] PortId Pcie Port ID + * @param[in] AsmpState ASPM states to enable. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +PcieAsmpEnableOnPort ( + IN PORT PortId, + IN PCIE_LINK_ASPM AsmpState, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR Port; + UINT8 Lx; + PCI_ADDR NbPciAddress; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "PcieAsmpEnableOnPort Enter PortId [%d]\n", PortId)); + NbPciAddress.AddressValue = NB_SBDFO; + switch (AsmpState) { + case PcieLinkAspmDisabled: + return ; + case PcieLinkAspmL0s: + Lx = ASPM_UPSTREAM_L0s | ASPM_DOWNSTREAM_L0s; + break; + case PcieLinkAspmL1: + Lx = ASPM_L1; + break; + case PcieLinkAspmL0sAndL1: + Lx = ASPM_UPSTREAM_L0s | ASPM_DOWNSTREAM_L0s | ASPM_L1; + break; + case PcieLinkAspmL0sDownstreamOnly: + Lx = ASPM_DOWNSTREAM_L0s; + break; + case PcieLinkAspmL0sDownstreamOnlyAndL1: + Lx = ASPM_DOWNSTREAM_L0s | ASPM_L1; + break; + default: + CIMX_ASSERT (FALSE); + return ; + } + Port = PcieLibGetPortPciAddress (PortId, pConfig); +//NB-SB link + if (PortId == 8 && NbPciAddress.AddressValue == 0) { + if (PcieSbInitAspm ((Lx & ASPM_L1) | ((Lx & ASPM_UPSTREAM_L0s)?ASPM_L0s:0), pConfig) == AGESA_SUCCESS) { + PcieAspmEnableOnFunction (Port, (Lx & ASPM_L1) | ((Lx & ASPM_DOWNSTREAM_L0s)?ASPM_L0s:0), pConfig); + } + return ; + } + PcieAspmSetOnRc (Port, Lx, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "PcieAsmpEnableOnPort Exit. Lx[0x%x]\n", Lx)); + return ; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable Common Clock on PCIe Link + * + * + * + * @param[in] Downstream Downstream PCIe port PCI address + * @param[in] Upstream Upstream PCIe port PCI address + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ + +VOID +PcieAspmEnableCommonClock ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT16 DownstreamCommonClockCap; + UINT16 UpstreamCommonClockCap; + UINT16 Value; + UINT8 DownstreamPcieCapPtr; + UINT8 UpstreamPcieCapPtr; + DownstreamPcieCapPtr = LibNbFindPciCapability (Downstream.AddressValue, PCIE_CAP_ID, pConfig); + UpstreamPcieCapPtr = LibNbFindPciCapability (Upstream.AddressValue, PCIE_CAP_ID, pConfig); + if (DownstreamPcieCapPtr == 0 || UpstreamPcieCapPtr == 0) { + return ; + } + LibNbPciRead (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x10) , AccessWidth16, &DownstreamCommonClockCap, pConfig); + if ((DownstreamCommonClockCap & BIT6) != 0) { + //Aready enabled + return ; + } + LibNbPciRead (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x12) , AccessWidth16, &DownstreamCommonClockCap, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Downstream Common Clock Capability %d:%d:%d - %x\n", Downstream.Address.Bus, Downstream.Address.Device, Downstream.Address.Function, DownstreamCommonClockCap)); + LibNbPciRead (Upstream.AddressValue | (UpstreamPcieCapPtr + 0x12) , AccessWidth16, &UpstreamCommonClockCap, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Upstream Common Clock Capability %d:%d:%d - %x\n", Upstream.Address.Bus, Upstream.Address.Device, Upstream.Address.Function, UpstreamCommonClockCap)); + if ((DownstreamCommonClockCap & UpstreamCommonClockCap & BIT12) != 0) { + //Enable common clock + PcieAspmCommonClockOnFunction (Downstream, pConfig); + PcieAspmCommonClockOnDevice (Upstream, pConfig); +// LibNbPciRMW (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x10) , AccessS3SaveWidth8, 0xff, BIT6, pConfig); +// LibNbPciRMW (Upstream.AddressValue | (UpstreamPcieCapPtr + 0x10) , AccessS3SaveWidth8, 0xff, BIT6, pConfig); + //Reatrain link + LibNbPciRMW (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x10) , AccessS3SaveWidth8, 0xff, BIT5, pConfig); + do { + LibNbPciRead (Downstream.AddressValue | (DownstreamPcieCapPtr + 0x12) , AccessWidth16, (UINT16*)&Value, pConfig); + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, CIMX_S3_SAVE); + } while ((Value & BIT11) != 0); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set "Common Clock" enable on function + * + * + * + * @param[in] Device PCI address of function. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmCommonClockOnDevice ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 Value; + UINT8 MaxFunc; + UINT8 CurrentFunc; + LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Value, pConfig); + MaxFunc = (Value & BIT7)?7:0; + for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) { + Device.Address.Function = CurrentFunc; + if (LibNbIsDevicePresent (Device, pConfig)) { + PcieAspmCommonClockOnFunction (Device, pConfig); + } + } +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set "Common Clock" enable on function + * + * + * + * @param[in] Function PCI address of function. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmCommonClockOnFunction ( + IN PCI_ADDR Function, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 PcieCapPtr; + PcieCapPtr = LibNbFindPciCapability (Function.AddressValue, PCIE_CAP_ID, pConfig); + if (PcieCapPtr != 0) { + LibNbPciRMW (Function.AddressValue | (PcieCapPtr + 0x10) , AccessS3SaveWidth8, (UINT32)~(BIT6), BIT6, pConfig); + } +} +/*----------------------------------------------------------------------------------------*/ +/** + * Enable ASPM on PCIe Link + * + * + * + * @param[in] Downstream Downstream PCIe port PCI address + * @param[in] Upstream Upstream PCIe port PCI address + * @param[in] Lx Lx ASPM bitmap. + * Lx[0] - reserved + * Lx[1] - L1 enable + * Lx[2] - L0s enable for upstream ports + * Lx[3] - L0s enable for downstream ports + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ + +VOID +PcieAspmEnableOnLink ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ) +{ + ASPM_LINK_INFO AspmLinkInfo; + AspmLinkInfo.UpstreamLxCap = PcieAspmGetPmCapability (Upstream, pConfig); + AspmLinkInfo.DownstreamLxCap = PcieAspmGetPmCapability (Downstream, pConfig); + AspmLinkInfo.DownstreamPort = Downstream; + AspmLinkInfo.UpstreamPort = Upstream; + AspmLinkInfo.RequestedLx = Lx; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Downstream ASPM Capability %d:%d:%d - %x\n", Downstream.Address.Bus, Downstream.Address.Device, Downstream.Address.Function, AspmLinkInfo.DownstreamLxCap)); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Upstream ASPM Capability %d:%d:%d - %x\n", Upstream.Address.Bus, Upstream.Address.Device, Upstream.Address.Function, AspmLinkInfo.UpstreamLxCap)); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Requested ASPM State - %x\n", Lx)); + AspmLinkInfo.DownstreamLx = AspmLinkInfo.UpstreamLxCap & AspmLinkInfo.DownstreamLxCap & Lx & ASPM_L1; + AspmLinkInfo.UpstreamLx = AspmLinkInfo.DownstreamLx; + if ((AspmLinkInfo.UpstreamLxCap & ASPM_L0s) != 0 && (Lx & ASPM_UPSTREAM_L0s) != 0) { + AspmLinkInfo.UpstreamLx |= ASPM_L0s; + } + if ((AspmLinkInfo.DownstreamLxCap & ASPM_L0s) != 0 && (Lx & ASPM_DOWNSTREAM_L0s) != 0) { + AspmLinkInfo.DownstreamLx |= ASPM_L0s; + } +#ifndef ASPM_WORKAROUND_DISABLE + PcieAspmWorkarounds (&AspmLinkInfo, pConfig); +#endif + LibNbCallBack (PHCB_AmdPcieAsmpInfo, (UINTN)&AspmLinkInfo, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Upstream ASPM State - %x\n", AspmLinkInfo.UpstreamLx)); + PcieAspmEnableOnDevice (Upstream, AspmLinkInfo.UpstreamLx, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Downstream ASPM State - %x\n", AspmLinkInfo.DownstreamLx)); + PcieAspmEnableOnFunction (Downstream, AspmLinkInfo.DownstreamLx, pConfig); + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set ASMP State on all function of PCI device + * + * + * + * @param[in] Device PCI address of device. + * @param[in] Lx Lx ASPM bitmap. + * Lx[0] = L0s enable + * Lx[1] - L1 enable + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmEnableOnDevice ( + IN PCI_ADDR Device, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 Value; + UINT8 MaxFunc; + UINT8 CurrentFunc; + + LibNbPciRead (Device.AddressValue | 0x0E , AccessWidth8, &Value, pConfig); + MaxFunc = (Value & BIT7)?7:0; + for (CurrentFunc = 0; CurrentFunc <= MaxFunc; CurrentFunc++) { + Device.Address.Function = CurrentFunc; + if (LibNbIsDevicePresent (Device, pConfig)) { + PcieAspmEnableOnFunction (Device, Lx, pConfig); + } + } +} +/*----------------------------------------------------------------------------------------*/ +/** + * Set ASMP State on PCIe device function + * + * + * + * @param[in] Function PCI address of function. + * @param[in] Lx Lx ASPM bitmap. + * Lx[0] = L0s enable + * Lx[1] - L1 enable + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmEnableOnFunction ( + IN PCI_ADDR Function, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 PcieCapPtr; + PcieCapPtr = LibNbFindPciCapability (Function.AddressValue, PCIE_CAP_ID, pConfig); + if (PcieCapPtr != 0) { + LibNbPciRMW (Function.AddressValue | (PcieCapPtr + 0x10) , AccessS3SaveWidth8, (UINT32)~(BIT0 & BIT1), Lx, pConfig); + } +} + +/**----------------------------------------------------------------------------------------*/ +/** + * Port/Endpoint ASMP capability + * + * + * + * @param[in] Device PCI address of downstream port. + * @param[in] pConfig Northbridge configuration structure pointer. + * + * @retval Bitmap of actual supported Lx states + */ + /*----------------------------------------------------------------------------------------*/ +UINT8 +PcieAspmGetPmCapability ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 PcieCapPtr; + UINT8 Value; + PcieCapPtr = LibNbFindPciCapability (Device.AddressValue, PCIE_CAP_ID, pConfig); + if (PcieCapPtr == 0) { + return 0; + } + LibNbPciRead (Device.AddressValue | (PcieCapPtr + 0x0D) , AccessWidth8, &Value, pConfig); + return (Value >> 2) & 3; +} + + +/**----------------------------------------------------------------------------------------*/ +/** + * Scan PCIe topology + * + * + * + * @param[in] This Pointer to instance of scan protocol + * @param[in] Function PCI address of found device/function. + * + * @retval SCAN_FINISHED Scan for device finished. + */ + /*----------------------------------------------------------------------------------------*/ +SCAN_STATUS +PcieSetDeviceAspm ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Function + ) +{ + PCIE_DEVICE_TYPE DeviceType; + UINT8 SecondaryBus; + ASPM_WORKSPACE *WorkspacePtr; + WorkspacePtr = (ASPM_WORKSPACE*)This; + + DeviceType = PcieGetDeviceType (Function, This->pConfig); + if (DeviceType == PcieDeviceRootComplex || DeviceType == PcieDeviceDownstreamPort) { + PCI_ADDR UpstreamDevice; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached downstream port\n")); + //Lets enable Common clock + LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig); + LibNbPciRMW(Function.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffff, 0, This->pConfig); //This done to help UEFI bootscript restore bud topology. + if (SecondaryBus == 0) { + return SCAN_FINISHED; + } + //New Downstream Port + WorkspacePtr->LinkCount++; + if (WorkspacePtr->DownstreamPort.AddressValue == 0) { + WorkspacePtr->DownstreamPort.AddressValue = Function.AddressValue; + } + //Lets enable Common clock + UpstreamDevice.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0); + if (LibNbIsDevicePresent (UpstreamDevice, This->pConfig)) { + PcieAspmEnableCommonClock (Function, UpstreamDevice, This->pConfig); + } + This->ScanBus (This, UpstreamDevice); + if (WorkspacePtr->DownstreamPort.AddressValue == Function.AddressValue) { + WorkspacePtr->DownstreamPort.AddressValue = 0; + PcieAspmEnableOnLink (Function, UpstreamDevice, WorkspacePtr->Lx, This->pConfig); + } + } else if (DeviceType == PcieDeviceUpstreamPort ) { + PCI_ADDR DownstreamDevice; + + if (WorkspacePtr->DownstreamPort.AddressValue == 0) { + return SCAN_FINISHED; + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached upstream port\n")); + LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig); + LibNbPciRMW(Function.AddressValue | 0x18, AccessS3SaveWidth32, 0xffffffff, 0, This->pConfig); //This done to help UEFI bootscript restore bud topology. + if (SecondaryBus == 0) { + return SCAN_FINISHED; + } + DownstreamDevice.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0); + This->ScanBus (This, DownstreamDevice); + } else if (DeviceType < PcieDeviceLegacyEndPoint) { + // We reach end of link @toDo code to check exit latency. + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached endpoint \n")); + } + return SCAN_FINISHED; +} + +/**----------------------------------------------------------------------------------------*/ +/** + * Scan RC PCIe topology to setup ASPM + * + * + * + * @param[in] Device PCI address of downstream port. + * @param[in] Lx Lx ASPM bitmap. + * Lx[0] - reserved + * Lx[1] - L1 enable + * Lx[2] - L0s enable for upstream ports + * Lx[3] - L0s enable for downstream ports + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + /*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmSetOnRc ( + IN PCI_ADDR Device, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ) +{ + ASPM_WORKSPACE AspmWorkspace; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieSetPortAspm Enter\n")); + LibAmdMemFill (&AspmWorkspace, 0, sizeof (AspmWorkspace), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + AspmWorkspace.ScanPciePort.pConfig = pConfig; + AspmWorkspace.ScanPciePort.ScanBus = LibNbScanPciBus; + AspmWorkspace.ScanPciePort.ScanDevice = LibNbScanPciDevice; + AspmWorkspace.ScanPciePort.ScanFunction = PcieSetDeviceAspm; + AspmWorkspace.Lx = Lx; + AspmWorkspace.ScanPciePort.ScanFunction (&AspmWorkspace.ScanPciePort, Device); + if (AspmWorkspace.LinkCount > 1) { + LibNbScanPciBridgeBuses (&AspmWorkspace.ScanPciePort, Device); + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieSetPortAspm Exit\n")); +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieAspm.h b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.h new file mode 100644 index 000000000000..63a88a0c0e1e --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieAspm.h @@ -0,0 +1,131 @@ +/** + * @file + * + * ASPM support. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +#ifndef _NBPCIEASPM_H_ +#define _NBPCIEASPM_H_ + +VOID +PcieAsmpEnableOnPort ( + IN PORT PortId, + IN PCIE_LINK_ASPM AsmpState, + IN AMD_NB_CONFIG *pConfig + ); + +UINT8 +PcieAspmGetPmCapability ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieAspmEnableOnDevice ( + IN PCI_ADDR Device, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieAspmEnableOnFunction ( + IN PCI_ADDR Function, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieAspmEnableOnLink ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieAspmEnableCommonClock ( + IN PCI_ADDR Downstream, + IN PCI_ADDR Upstream, + IN AMD_NB_CONFIG *pConfig + ); + + +VOID +PcieAspmCommonClockOnDevice ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieAspmCommonClockOnFunction ( + IN PCI_ADDR Function, + IN AMD_NB_CONFIG *pConfig + ); + +#pragma pack (push, 1) + +/// Framework for ASPM enable +typedef struct { + PCI_SCAN_PROTOCOL ScanPciePort; ///< PCI scan protocol + PCI_ADDR DownstreamPort; ///< Downstream port to enable ASPM + UINT8 MaxL0sLatency; ///< TBD + UINT8 MaxL1Latency; ///< TBD + UINT8 LinkCount; ///< TBD + UINT8 Lx; ///< ASPM state to enable +} ASPM_WORKSPACE; + +#define ASPM_UPSTREAM_L0s BIT2 +#define ASPM_DOWNSTREAM_L0s BIT3 +#define ASPM_L1 BIT1 +#define ASPM_L0s BIT0 + +/// Framework for callback ASPM capability callback +typedef struct { + PCI_ADDR DownstreamPort; ///< Downstream port PCI address to enable ASPM + PCI_ADDR UpstreamPort; ///< Upstream port PCI address to enable ASPM + UINT8 DownstreamLxCap; ///< Downstream port ASPM capability + UINT8 UpstreamLxCap; ///< Upstream port ASPM capability + UINT8 DownstreamLx; ///< Downstream port ASPM setting + UINT8 UpstreamLx; ///< Upstream port ASPM setting + UINT8 RequestedLx; ///< Requested port ASPM setting +} ASPM_LINK_INFO; + +#pragma pack (pop) +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c new file mode 100644 index 000000000000..a77623e2c226 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.c @@ -0,0 +1,105 @@ +/** + * @file + * + * PCIe link width control. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate CPL buffers + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. * + */ +VOID +PcieLibCplBufferAllocation ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PORT PortId; + BOOLEAN IsAllocationEnabled; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCplBufferAllocation Enter [CoreId = %d]\n", CoreId)); + IsAllocationEnabled = FALSE; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig) && PcieLibGetCoreId (PortId, pConfig) == CoreId) { + PCI_ADDR Port; + PORT_INFO *pPortInfo; + pPortInfo = PcieLibGetPortInfo (PortId, pConfig); + if (pPortInfo->SlaveCplBuffers != 0) { + Port = PcieLibGetPortPciAddress (PortId, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d , Port Address 0x%x, CplBuffers, %d\n", PortId, Port.AddressValue, pPortInfo->SlaveCplBuffers)); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~(0x3f << 8), pPortInfo->SlaveCplBuffers << 8, pConfig); + IsAllocationEnabled = TRUE; + } + } + } + if (IsAllocationEnabled) { + CORE CoreAddress; + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG20 | CoreAddress, AccessWidth32, (UINT32)~(BIT11), BIT11, pConfig); + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCplBufferAllocation Exit\n")); +}
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h new file mode 100644 index 000000000000..87d3b3072250 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieCplBuffers.h @@ -0,0 +1,52 @@ +/** + * @file + * + * PCIe link width control. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBPCIECPLBUFFERS_H_ +#define _NBPCIECPLBUFFERS_H_ + +VOID +PcieLibCplBufferAllocation ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c new file mode 100644 index 000000000000..11115562700f --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieEarlyHwLib.c @@ -0,0 +1,475 @@ +/** + * @file + * + * PCIe silicon specific functions library. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "HotplugFirmware.h" +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +#define MCU_CLEAR_BLOCK_LENGTH 16 + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +INDIRECT_REG_ENTRY +STATIC +PcieMiscInitTable[] = { + { + NB_MISC_REG20, + (UINT32)~BIT1, + 0x0 + }, //enable static device remapping by default + { + NB_MISC_REG22, + 0xffffffff, + BIT27 | (0x8 << 12) | (0x8 << 16) | (0x8 << 20) + }, + { + NB_MISC_REG2B, + 0xffffffff, + (0x8 << 12) + }, + { + NB_MISC_REG6C, + 0xffffffff, + (0x8 << 16) + }, + { + NB_MISC_REG6B, + 0xffffffff, + (UINT32) (0x1f << 27) + }, //[13][12]Turn Off Offset Cancellation + { + NB_MISC_REG37, + (UINT32)~(BIT11 + BIT12 + BIT13), + 0x0 + }, //[14][13]Disables Rx Clock gating in CDR + { + NB_MISC_REG67, + (UINT32)~(BIT26 + BIT10 + BIT11), + BIT11 + }, //[13]Disables Rx Clock gating in CDR + //[16]Sets Electrical Idle Threshold + { + NB_MISC_REG2C, + (UINT32)~(BIT10), + 0x0 + }, //[13]Disables Rx Clock gating in CDR + { + NB_MISC_REG2A, + (UINT32)~(BIT17 + BIT16), + BIT17 + }, //[16]Sets Electrical l Idle Threshold + { + NB_MISC_REG32, + (UINT32)~(0x3F << 20), + (UINT32) (0x2A << 20) + } //[17][16]Sets Electrical Idle Threshold +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc Initialization prior port training. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +PcieLibPreTrainingInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + PCIE_CONFIG *pPcieConfig; + UINT32 ServerHotplugMask; + BOOLEAN SmuWa; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPreTrainingInit Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + ServerHotplugMask = 0; +//Init Misc registers + LibNbIndirectTableInit ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieMiscInitTable[0],NULL), + (sizeof (PcieMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); +//Setup peer-to-peer + if (pPcieConfig->PcieConfiguration.Peer2Peer == ON) { + if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (3, pConfig)] == GFX_CONFIG_AABB) { + Value = 0x08080404; + } else { + Value = 0x08080008; + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG49, AccessWidth32, 0, Value, pConfig); + if (pPcieConfig->CoreConfiguration[PcieLibGetCoreId (12, pConfig)] == GFX_CONFIG_AABB) { + Value = 0xFFFF0404; + } else { + Value = 0xFFFF0008; + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2F, AccessWidth32, 0, Value, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG48, AccessWidth32, (UINT32)~(BIT8), 0xffff0000, pConfig); + } + + //Remap device number +#ifndef DEVICE_REMAP_DISABLE + if (PciePortRemapInit (pConfig) != AGESA_SUCCESS ) { + REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_DEVICE_REMAP, 0, 0, 0, 0, pConfig); + } +#endif + +#ifndef HOTPLUG_SUPPORT_DISABLED + ServerHotplugMask = PcieInitHotplug (pConfig); +#endif + + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4A, AccessWidth32, &Value, pConfig); + SmuWa = ((Value & BIT21) != 0) ? TRUE : FALSE; + + if (SmuWa || ServerHotplugMask != 0) { + UINT32 BlockIndex; + UINT32 SmuWaData; + UINT16 Address; + UINT32 Data[MCU_CLEAR_BLOCK_LENGTH]; + + LibNbMcuControl (AssertReset, pConfig); + // clear SMU RAM + LibAmdMemFill (&Data[0], 0, sizeof (Data), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + for (Address = 0; Address < (16 * 1024); Address = Address + 4 * MCU_CLEAR_BLOCK_LENGTH) { + LibNbLoadMcuFirmwareBlock (Address, MCU_CLEAR_BLOCK_LENGTH, &Data[0], pConfig); + } + //Load SMU firmware + for (BlockIndex = 0; BlockIndex < Fm.NumberOfBlock; BlockIndex++) { + LibNbLoadMcuFirmwareBlock (Fm.BlockArray[BlockIndex].Address, Fm.BlockArray[BlockIndex].Length, Fm.BlockArray[BlockIndex].Data, pConfig); + } + if (SmuWa) { + SmuWaData = LibHtGetSmuWaData (pConfig); + LibNbLoadMcuFirmwareBlock (0xFE70, 0x1, &SmuWaData, pConfig); + } + SmuWaData = ((SmuWa == TRUE) ? 0x100 : 0x100) | ((ServerHotplugMask != 0) ? 0x1 : 0); + LibNbLoadMcuFirmwareBlock (0xFE74, 0x1, &SmuWaData, pConfig); + + LibNbMcuControl (DeAssertReset, pConfig); + } + +#ifndef HOTPLUG_SUPPORT_DISABLED + PcieCheckHotplug (ServerHotplugMask, pConfig); +#endif + +} + +INDIRECT_REG_ENTRY PcieCoreInitTable[] = { + { + NB_BIFNB_REG10, + (UINT32)~(BIT10 + BIT11 + BIT12), + BIT12 + }, + { + NB_BIFNB_REG20, + (UINT32)~(BIT8 + BIT9), + BIT9 + }, + { + NB_BIFNB_REG02, + (UINT32)~(BIT0), + BIT0 + }, + { + NB_BIFNB_REG40, + (UINT32)~(BIT14 + BIT15), + BIT15 + }, + { + NB_BIFNB_REGC2, + (UINT32)~(BIT25), + BIT25 + }, + { + NB_BIFNB_REGC1, + (UINT32)~(BIT0), + (BIT0 + BIT1 + BIT2) + }, + { + NB_BIFNB_REG1C, + 0x0, + (4 << 6) + (4 << 1) + 1 + } +}; + +INDIRECT_REG_ENTRY PcieRd790CoreInitTable[] = { + { + NB_BIFNB_REGC2, + (UINT32)~(BIT14), + (BIT14) + }, + { + NB_BIFNB_REGC1, + (UINT32)~(BIT2), + 0x0 + }, +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Core registers + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +PcieLibCommonCoreInit ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 CoreAddress; + NB_INFO NbInfo; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit (CoreId = %d) Enter\n", CoreId)); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + + LibNbIndirectTableInit ( + pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, + CoreAddress, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieCoreInitTable[0],NULL), + (sizeof (PcieCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + + if (CoreAddress == SB_CORE) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG10 | CoreAddress, AccessWidth32, (UINT32)~BIT9, BIT9, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG06, AccessWidth32, (UINT32)~BIT26, BIT26 + BIT1, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG1C | CoreAddress, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig); + } + if ( NbInfo.Type < NB_SR5690 ) { + LibNbIndirectTableInit ( + pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, + CoreAddress, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRd790CoreInitTable[0], NULL), + (sizeof (PcieRd790CoreInitTable) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonCoreInit Exit\n")); +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Core after training is completed + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. * + */ + + +VOID +PcieLibCoreAfterTrainingInit ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 CoreAddress; + PCIE_CONFIG *pPcieConfig; + PCI_ADDR ClkPciAddress; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Function = 1; + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG20 | CoreAddress, AccessWidth32, (UINT32)~(BIT9), 0, pConfig); +//Save core setting in scratch register + LibNbPciIndexWrite ( + pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, + NB_BIFNB_REG01 | CoreAddress, + AccessWidth32, + (UINT32*)&pPcieConfig->CoreSetting[CoreId], + pConfig + ); +//Save general setting in scratch + LibNbEnableClkConfig (pConfig); + LibNbPciWrite (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig); + LibNbDisableClkConfig (pConfig); + +} + + +INDIRECT_REG_ENTRY PciePortInitTable[] = { + { + NB_BIFNBP_REG02, + (UINT32)~(BIT15), + BIT15 + }, + { + NB_BIFNBP_REGA1, + (UINT32)~(BIT24 + BIT26), + BIT11 + }, + { + NB_BIFNBP_REGB1, + 0xffffffff, + BIT28 + BIT23 + BIT19 + BIT20 + }, + { + NB_BIFNBP_REGA4, + (UINT32)~(BIT0), + 0x0 + }, + { + NB_BIFNBP_REGA2, + (UINT32)~(BIT13), + BIT13 + }, + { + NB_BIFNBP_REGA3, + (UINT32)~(BIT9), + BIT9 + }, + { + NB_BIFNBP_REGA0, + 0xffff000f, + 0x6830 + }, + { + NB_BIFNBP_REGC1, + 0xfffffff0, + 0xC + }, + { + NB_BIFNBP_REG70, + (UINT32)~(BIT16 + BIT17 + BIT18), + BIT16 + BIT18 + } +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Init port registers + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieLibCommonPortInit ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR Port; + PCIE_CONFIG *pPcieConfig; + UINT32 PcieSlotCapability; + UINT32 CoreAddress; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit PortId %d Enter\n", PortId)); + Port = PcieLibGetPortPciAddress (PortId, pConfig); + CoreAddress = PcieLibGetCoreAddress (PcieLibGetCoreId (PortId, pConfig), pConfig); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + + LibNbIndirectTableInit ( + Port.AddressValue | NB_BIF_INDEX, + 0x0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PciePortInitTable[0],NULL), + (sizeof (PciePortInitTable) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + if (CoreAddress == GPP3a_CORE || CoreAddress == SB_CORE || CoreAddress == GPP3b_CORE) { + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~(BIT16 + BIT17 + BIT18), (BIT17 + BIT18), pConfig); + if (CoreAddress == GPP3a_CORE) { + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGB1, AccessWidth32, (UINT32)~(BIT22), BIT22, pConfig); + } + } +// Set completion timeout + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessS3SaveWidth8, 0xF0, 0x6, pConfig); + //if (CoreAddress != SB_CORE) { + // LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT0, 0x0, pConfig); + //} +//For hotplug ports + //if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF || + // pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON || + // LibNbGetRevisionInfo (pConfig).Revision == NB_REV_A11) { + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG20, AccessWidth32, (UINT32)~BIT19, 0x0, pConfig); + //} + +// Enable Immediate ACK + if (pPcieConfig->ExtPortConfiguration[PortId].PortL1ImmediateACK == ON) { + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA0, AccessWidth32, (UINT32)~BIT23, BIT23, pConfig); + } +//Set up slot capability + PcieSlotCapability = (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit << 7) | + ((Port.Address.Device | Port.Address.Bus << 5 ) << 19); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessS3SaveWidth32, (UINT32)~((0x3ff << 7) | (0x1fff << 19)), PcieSlotCapability, pConfig); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG5A, AccessS3SaveWidth16, (UINT32)~BIT8, BIT8, pConfig); +//Set interrupt pin info + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG3D, AccessS3SaveWidth8, 0x0, 0x1, pConfig); + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibCommonPortInit Exit\n")); +}; diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c new file mode 100644 index 000000000000..25ef38f587fd --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.c @@ -0,0 +1,343 @@ +/** + * @file + * + * Routines to support Hotplug. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdSbLib.h" + +#ifndef HOTPLUG_SUPPORT_DISABLED + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +#define ATTN_BUTTON_PRESENT BIT0 +#define PWR_CONTROLLER_PRESENT BIT1 +#define MRL_SENSOR_PRESENT BIT2 +#define ATTN_INDICATOR_PRESENT BIT3 +#define PWR_INDICATOR_PRESENT BIT4 +#define HOTPLUG_SURPRISE BIT5 +#define HOTPLUG_CAPABLE BIT6 + +#define ATTN_BUTTON_PRESSED BIT0 +#define PWR_FAULT_DETECTED BIT1 +#define MRL_SENSOR_CHANGED BIT2 +#define PRESENCE_DETECT_CHANGED BIT3 +#define COMMAND_COMPLETED BIT4 +#define MRL_SENSOR_STATE BIT5 +#define PRESENCE_DETECT_STATE BIT6 +#define DL_STATE_CHANGED BIT8 + +#define PWR_CONTROLLER_CNTL BIT10 +#define NO_COMMAND_COMPLETED_SUPPORTED BIT18 +#define SERVER_HOTPLUG_CAPABILITY \ + (ATTN_BUTTON_PRESENT | PWR_CONTROLLER_PRESENT | ATTN_INDICATOR_PRESENT | PWR_INDICATOR_PRESENT | HOTPLUG_CAPABLE) +#define NATIVE_HOTPLUG_CAPABILITY \ + (HOTPLUG_SURPRISE | HOTPLUG_CAPABLE) + +#define SERVER_HOTPLUG 1 +#define NATIVE_HOTPLUG 2 +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + /*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Ports Hotplug capability. + * Initialize hotplug controller init port hotplug capability + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + * @retval AGESA_SUCCESS Hotplug controller successfully initialized. + * @retval AGESA_FAIL Failure during initialization of hotplug controller. + */ +/*----------------------------------------------------------------------------------------*/ +UINT32 +PcieInitHotplug ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 ServerHotplugPortMask; + PORT PortId; + PCI_ADDR ClkPciAddress; + NB_INFO NbInfo; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + ServerHotplugPortMask = 0; + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Function = 1; + if (NbInfo.Type == NB_SR5690) { + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && + pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ) { + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + if (pPcieConfig->PortConfiguration[PortId].PortHotplug == SERVER_HOTPLUG) { + UINT8 HpDescriptorRegister; + UINT8 HpDescriptorOffset; + ServerHotplugPortMask |= 1 << PortId; + HpDescriptorOffset = (PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig))->HotplugAddress; + if (HpDescriptorOffset != 0xff) { + ServerHotplugPortMask |= 1 << PortId; + HpDescriptorRegister = (PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig))->HotplugRegister; + //Enable CLK config + LibNbEnableClkConfig (pConfig); + //Setup descriptor + LibNbPciRMW ( + ClkPciAddress.AddressValue | HpDescriptorRegister , + AccessWidth32, + 0xffffffff, + ((1 << 3) | (pPcieConfig->ExtPortConfiguration[PortId].PortHotplugDevMap << 2) | pPcieConfig->ExtPortConfiguration[PortId].PortHotplugByteMap) << HpDescriptorOffset, + pConfig + ); + //Hide CLK config + LibNbDisableClkConfig (pConfig); + // Enable power fault + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT4, BIT4, pConfig); + //Set up capability. Keep NO_COMMAND_COMPLETED_SUPPORTED (bit 18) to zero + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xfffbffff, SERVER_HOTPLUG_CAPABILITY, pConfig); + //Clear Status + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig); + } + } + if (pPcieConfig->PortConfiguration[PortId].PortHotplug == NATIVE_HOTPLUG) { + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xffffffff, NATIVE_HOTPLUG_CAPABILITY, pConfig); + } + } + } + } + return ServerHotplugPortMask; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Ports Hotplug capability. + * Initialize hotplug controller init port hotplug capability + * + * @param[in] ServerHotplugPortMask ServerHotplugPortMask + * @param[in] pConfig Northbridge configuration structure pointer. + * + * @retval AGESA_SUCCESS Hotplug controller successfully initialized. + * @retval AGESA_FAIL Failure during initialization of hotplug controller. + */ +/*----------------------------------------------------------------------------------------*/ +VOID +PcieCheckHotplug ( + IN UINT32 ServerHotplugPortMask, + IN AMD_NB_CONFIG *pConfig + ) +{ + PORT PortId; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckHotplug Enter\n")); + //Check if Firmware loaded successfully + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + //Check Firmware Loaded successfully + if ((ServerHotplugPortMask & (1 << PortId)) != 0) { + UINT32 Count; + PCI_ADDR Port; + UINT16 SlotStatus; + + Count = 30; //Setup counter for 30ms + Port = PcieLibGetPortPciAddress (PortId, pConfig); + do { + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0); + LibNbPciRead (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, &SlotStatus, pConfig); + } while ((SlotStatus & (ATTN_BUTTON_PRESSED | PWR_FAULT_DETECTED)) == 0 && --Count != 0); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Hotplug Firmware Init PortId = %d SlotStatus = 0x%x Retry = %d\n", PortId, SlotStatus, Count)); + if ((SlotStatus & PWR_FAULT_DETECTED) != 0 || (SlotStatus & (PWR_FAULT_DETECTED | ATTN_BUTTON_PRESSED)) == 0) { + REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_HOTPLUG_INIT, PortId, 0, 0, 0, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " ERROR!!!Hotplug Firmware Init FAIL\n")); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, (UINT32)~SERVER_HOTPLUG_CAPABILITY, 0x0, pConfig); + } else { + //Clear Status + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig); + if ((SlotStatus & PRESENCE_DETECT_CHANGED) != 0) { + //Power on slot + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG70, AccessWidth16, (UINT32)~PWR_CONTROLLER_CNTL, 0x0, pConfig); + } + } + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckHotplug Exit\n")); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Init Ports Hotplug capability. + * Initialize hotplug controller init port hotplug capability + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + * @retval AGESA_SUCCESS Hotplug controller successfully initialized. + * @retval AGESA_FAIL Failure during initialization of hotplug controller. + */ +/*----------------------------------------------------------------------------------------*/ +/* +AGESA_STATUS +PcieInitHotplug ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT32 ServerHotplugPortMask; + PORT PortId; + PCI_ADDR ClkPciAddress; + NB_INFO NbInfo; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + ServerHotplugPortMask = 0; + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Function = 1; + Status = AGESA_SUCCESS; + if (NbInfo.Type == NB_SR5690) { + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && + pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF ) { + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + if (pPcieConfig->PortConfiguration[PortId].PortHotplug == SERVER_HOTPLUG) { + UINT8 HpDescriptorRegister; + UINT8 HpDescriptorOffset; + ServerHotplugPortMask |= 1 << PortId; + HpDescriptorOffset = (PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig))->HotplugAddress; + if (HpDescriptorOffset != 0xff) { + ServerHotplugPortMask |= 1 << PortId; + HpDescriptorRegister = (PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig))->HotplugRegister; + //Enable CLK config + LibNbEnableClkConfig (pConfig); + //Setup descriptor + LibNbPciRMW ( + ClkPciAddress.AddressValue | HpDescriptorRegister , + AccessWidth32, + 0xffffffff, + ((1 << 3) | (pPcieConfig->ExtPortConfiguration[PortId].PortHotplugDevMap << 2) | pPcieConfig->ExtPortConfiguration[PortId].PortHotplugByteMap) << HpDescriptorOffset, + pConfig + ); + //Hide CLK config + LibNbDisableClkConfig (pConfig); + // Enable power fault + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG10, AccessWidth32, (UINT32)~BIT4, BIT4, pConfig); + //Set up capability. Keep NO_COMMAND_COMPLETED_SUPPORTED (bit 18) to zero + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xfffbffff, SERVER_HOTPLUG_CAPABILITY, pConfig); + //Clear Status + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig); + } + } + if (pPcieConfig->PortConfiguration[PortId].PortHotplug == NATIVE_HOTPLUG) { + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, 0xffffffff, NATIVE_HOTPLUG_CAPABILITY, pConfig); + } + } + } + if (ServerHotplugPortMask != 0) { + UINT32 FirmwareLength; + FirmwareLength = sizeof (Firmware); + if (FirmwareLength > 0) { + UINT32 *pFirmware; + pFirmware = (UINT32*)FIX_PTR_ADDR (&Firmware[0], NULL); + //Load firmware + LibNbMcuControl (AssertReset, pConfig); + LibNbLoadMcuFirmwareBlock (0x200, (sizeof (Firmware) - 64), pFirmware, pConfig); + LibNbLoadMcuFirmwareBlock (0xFFC0, 64, &pFirmware[(sizeof (Firmware) - 64) / 4], pConfig); + LibNbMcuControl (DeAssertReset, pConfig); + } + } + //Check if Firmware loaded successfully + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + //Check Firmware Loaded successfully + if ((ServerHotplugPortMask & (1 << PortId)) != 0) { + UINT32 Count; + PCI_ADDR Port; + UINT16 SlotStatus; + + Count = 30; //Setup counter for 30ms + Port = PcieLibGetPortPciAddress (PortId, pConfig); + do { + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0); + LibNbPciRead (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, &SlotStatus, pConfig); + } while ((SlotStatus & (ATTN_BUTTON_PRESSED | PWR_FAULT_DETECTED)) == 0 && --Count != 0); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Hotplug Firmware Init PortId = %d SlotStatus = 0x%x Retry = %d\n", PortId, SlotStatus, Count)); + if ((SlotStatus & PWR_FAULT_DETECTED) != 0 || (SlotStatus & (PWR_FAULT_DETECTED | ATTN_BUTTON_PRESSED)) == 0) { + Status = AGESA_ERROR; + REPORT_EVENT (AGESA_ERROR, PCIE_ERROR_HOTPLUG_INIT, PortId, 0, 0, 0, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " ERROR!!!Hotplug Firmware Init FAIL\n", PortId)); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG6C, AccessWidth32, ~SERVER_HOTPLUG_CAPABILITY, 0x0, pConfig); + } else { + //Clear Status + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG72, AccessWidth16, 0xffffffff, 0x11F, pConfig); + if ((SlotStatus & PRESENCE_DETECT_CHANGED) != 0) { + //Power on slot + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG70, AccessWidth16, ~PWR_CONTROLLER_CNTL, 0x0, pConfig); + } + } + } + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitHotplug Exit. Status[0x%x]\n", Status)); + return Status; +} +*/ +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h new file mode 100644 index 000000000000..1b7ba040b2ab --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieHotplug.h @@ -0,0 +1,62 @@ +/** + * @file + * + * PCIe hotplug support. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#ifndef _NBPCIEHOTPLUG_H_ +#define _NBPCIEHOTPLUG_H_ + + +UINT32 +PcieInitHotplug ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieCheckHotplug ( + IN UINT32 ServerHotplugPortMask, + IN AMD_NB_CONFIG *pConfig + ); +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c b/src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c new file mode 100644 index 000000000000..6fdf2b120c35 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieInitEarly.c @@ -0,0 +1,720 @@ +/** + * @file + * + * PCIe Early initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" +#include "amdSbLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + + /*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIE Init for all NB. + * Basic programming / EP training. After this call EP are fully operational. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +AmdPcieEarlyInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (PcieEarlyInit, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge PCIE Init. + * Basic programming / EP training. After this call EP are fully operational on particular NB. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieEarlyInit ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieEarlyInit Enter\n")); + Status = PcieLibInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0 , 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + Status = PciePreTrainingInit (NbConfigPtr); + Status = PcieInitPorts (NbConfigPtr); + Status = PcieAfterTrainingInit (NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieEarlyInit Exit [0x%x]\n", Status)); + return Status; +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc initialization prior port link training started + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PciePreTrainingInit ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + CORE CoreId ; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePreTrainingInit Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + //Unhide all ports + PcieLibUnHidePorts (pConfig); + if (pPcieConfig->PcieMmioBaseAddress != 0 && pPcieConfig->PcieMmioSize != 0) { + PcieLibSetPcieMmioBase (pPcieConfig->PcieMmioBaseAddress, pPcieConfig->PcieMmioSize, pConfig); + } + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreId %d CoreSetting = 0x%x\n", CoreId, *((UINT32*)&pConfig->pPcieConfig->CoreSetting[CoreId]))); + //if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) { + //Configure cores + if (pPcieConfig->CoreSetting[CoreId].SkipConfiguration == OFF) { + PcieLibSetCoreConfiguration (CoreId, pConfig); + } + //Init core registers + PcieLibCommonCoreInit (CoreId, pConfig); + //} + } + PcieLibPreTrainingInit (pConfig); + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreId %d CoreSetting = 0x%x\n", CoreId, *((UINT32*)&pConfig->pPcieConfig->CoreSetting[CoreId]))); + //Init CPL buffer allocation + //if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF && pPcieConfig->CoreSetting[CoreId].CplBufferAllocation == ON) { + if (pPcieConfig->CoreSetting[CoreId].CplBufferAllocation == ON) { + PcieLibCplBufferAllocation (CoreId, pConfig); + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePreTrainingInit Exit\n")); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc initialization after port training complete + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieAfterTrainingInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + CORE CoreId; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { +// if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) { + //Configure cores + PcieLibCoreAfterTrainingInit (CoreId, pConfig); +// } + } + //Hide all Ports + PcieLibHidePorts (pConfig); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Train PCIE Ports + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieInitPorts ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + + Status = AGESA_SUCCESS; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + if (pPcieConfig->DeviceInitMaskS1 != 0) { + Status = PcieInitSelectedPorts (pPcieConfig->DeviceInitMaskS1, pConfig); + } + if (pPcieConfig->DeviceInitMaskS2 != 0) { + Status = PcieInitSelectedPorts (pPcieConfig->DeviceInitMaskS2, pConfig); + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Train PCIE Ports selected for this stage + * + * + * @param[in] SelectedPortMask Bitmap of port ID selected for training. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieInitSelectedPorts ( + IN UINT16 SelectedPortMask, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + PORT PortId; + BOOLEAN RequestResetDelay; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitSelectedPorts (Ports = 0x%x) Enter\n", SelectedPortMask)); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + Status = AGESA_SUCCESS; + RequestResetDelay = FALSE; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d PortConfiguration = 0x%x ExtPortConfiguration = 0x%x\n", PortId, *((UINT32*)&pPcieConfig->PortConfiguration[PortId]), *((UINT32*)&pPcieConfig->ExtPortConfiguration[PortId]))); + if ((SelectedPortMask & (1 << PortId)) != 0) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) { + PCIE_LINK_MODE LinkMode; + //Deassert slot reset. Bring EP out of reset + Status = LibNbCallBack (PHCB_AmdPortResetDeassert, 1 << PortId, pConfig); + if (Status == AGESA_SUCCESS) { + //STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ResetToTrainingDelay * 1000, 0); + RequestResetDelay = TRUE; + } + //Init common registers + PcieLibCommonPortInit (PortId, pConfig); + //Check if we already have device failure to go to Gen2 before + if (PcieLibCheckGen2Disabled (PortId, pConfig)) { + pPcieConfig->PortConfiguration[PortId].PortLinkMode = PcieLinkModeGen1; + pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB; // this is to workaround Gen2 + } + //@todo Add handling for scratch register for PCIE Gen + switch (pPcieConfig->PortConfiguration[PortId].PortLinkMode) { + case PcieLinkModeGen2: + case PcieLinkModeGen2AdvertizeOnly: + case PcieLinkModeGen1: + LinkMode = pPcieConfig->PortConfiguration[PortId].PortLinkMode; + break; + default: + LinkMode = PcieLinkModeGen1; + } + PcieLibSetLinkMode (PortId, LinkMode, pConfig); + //Enable Compliance Mode + if (pPcieConfig->PortConfiguration[PortId].PortCompliance == ON) { + PcieLibSetLinkCompliance (PortId, pConfig); + } + } else { + //Port disabled + SelectedPortMask &= (~(1 << PortId)); + } + } + } + if (RequestResetDelay) { + STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ResetToTrainingDelay * 1000, 0); + } + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if ((SelectedPortMask & (1 << PortId)) != 0) { + //Release Port Training + PcieLibPortTrainingControl (PortId, PcieLinkTrainingRelease, pConfig); + } + } + STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->TrainingToLinkTestDelay * 1000, 0); + Status = PcieCheckSelectedPorts (SelectedPortMask, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitSelectedPorts Exit\n")); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check link state on selected ports. + * + * + * + * @param[in] SelectedPortMask Bitmap of port ID selected for training. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieCheckSelectedPorts ( + IN UINT16 SelectedPortMask, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + PORT PortId; + UINT16 PortMask; + UINT16 CurrentPortMask; + PCIE_LINK_STATUS PortsLinkStatus[MAX_PORT_ID + 1]; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckSelectedPorts (Ports = 0x%x) Enter\n", SelectedPortMask)); + Status = AGESA_SUCCESS; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + PortMask = SelectedPortMask; + // Clear up link state storage + LibAmdMemFill (PortsLinkStatus, 0, sizeof (PortsLinkStatus), (AMD_CONFIG_PARAMS *)&(pPcieConfig->sHeader)); + // Initial check for link status on all ports + if (PortMask != 0) { + PcieGetPortsLinkStatus (PortMask, &PortsLinkStatus[0], pPcieConfig->ReceiverDetectionPooling, pConfig); + } + // Check if training on any ports in progress + PortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusTrainingInProgress); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #1 PortMask = 0x%x\n", PortMask)); + if (PortMask != 0) { + // Try to recover ports in case of broken lane + if (PcieBrokenLaneWorkaround (PortMask, pConfig) != AGESA_UNSUPPORTED) { + // Update port status array + PortMask |= PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected); + PcieGetPortsLinkStatus (PortMask, &PortsLinkStatus[0], pPcieConfig->ReceiverDetectionPooling, pConfig); + } + } + // Check if training on any ports still in progress + CurrentPortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusTrainingInProgress); + if (PortMask != CurrentPortMask) { + REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_BROKEN_LINE, (PortMask^CurrentPortMask)&PortMask, 0, 0, 0, pConfig); + } + PortMask = CurrentPortMask; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #2 PortMask = 0x%x\n", PortMask)); + if (PortMask != 0) { + // Try to recover port training by downgrading link speed to Gen1 + if (PcieGen2Workaround (PortMask, pConfig) != AGESA_UNSUPPORTED) { + PortMask |= PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected); + PcieGetPortsLinkStatus (PortMask, &PortsLinkStatus[0], pPcieConfig->ReceiverDetectionPooling, pConfig); + } + } + // Check if training on any ports still in progress + CurrentPortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusTrainingInProgress); + if (PortMask != CurrentPortMask) { + REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_GEN2_FAIL, (PortMask^CurrentPortMask)&PortMask, 0, 0, 0, pConfig); + } + PortMask = CurrentPortMask; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #3 PortMask = 0x%x\n", PortMask)); + if (PortMask != 0) { + REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_TRAINING_FAIL, PortMask, 0, 0, 0, pConfig); + PcieMiscWorkaround (&PortsLinkStatus[0], pConfig); + } + //Get bitmap of successfully trained ports + PortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " #4 PortMask = 0x%x\n", PortMask)); + if (PortMask != 0) { + // Check if VCO negotiation is completed + PcieCheckVco (PortMask, &PortsLinkStatus[0], pConfig); + } + CurrentPortMask = PcieFindPortsWithLinkStatus (&PortsLinkStatus[0], PcieLinkStatusConnected); + if (PortMask != CurrentPortMask) { + REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_VCO_NEGOTIATON, (PortMask^CurrentPortMask)&PortMask, 0, 0, 0, pConfig); + } + PortMask = CurrentPortMask; + //Update status port status info + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if ((SelectedPortMask & (1 << PortId)) != 0) { + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + if (PortsLinkStatus[PortId] == PcieLinkStatusInCompliance) { + pPcieConfig->PortConfiguration[PortId].PortCompliance = ON; + } else { + if (PortsLinkStatus[PortId] == PcieLinkStatusConnected) { + if (LibNbCallBack (PHCB_AmdPortTrainingCompleted, Port.AddressValue, pConfig) == AGESA_ERROR) { + PortsLinkStatus[PortId] = 0; + } + if (PortsLinkStatus[PortId] == PcieLinkStatusConnected && + pPcieConfig->PcieConfiguration.DisableGfxWorkaround == OFF && + PcieLibGetPortLinkInfo (PortId, pConfig).MaxLinkWidth >= PcieLinkWidth_x8 && + PcieGfxWorkarounds (PortId, pConfig) != AGESA_SUCCESS) { + //CIMX_ASSERT (FALSE); + PortsLinkStatus[PortId] = 0; + } + if (PortsLinkStatus[PortId] == PcieLinkStatusConnected) { + pPcieConfig->PortConfiguration[PortId].PortDetected = ON; + PcieLibSetLinkWidth (PortId, pPcieConfig->ExtPortConfiguration[PortId].PortLinkWidth, pConfig); + } + } + if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF && + pPcieConfig->PortConfiguration[PortId].PortHotplug == OFF) { + //Port training on Hold if Link in not connected and not in compliance + PcieLibPortTrainingControl (PortId, PcieLinkTrainingHold, pConfig); + } + } + if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF || + pPcieConfig->PortConfiguration[PortId].PortHotplug == ON) { + // For all port without devices and hotplug ports + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~BIT19, BIT19, pConfig); + } + LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG01, AccessWidth32, (UINT32*)&pPcieConfig->PortConfiguration[PortId], pConfig); + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG108, AccessWidth32, (UINT32*)&pPcieConfig->ExtPortConfiguration[PortId], pConfig); + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieCheckSelectedPorts Exit\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Workaround for broken TX line. + * + * + * + * @param[in] SelectedPortMask Bitmap of port ID selected for training. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieBrokenLaneWorkaround ( + IN UINT16 SelectedPortMask, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PORT PortId; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieBrokenLaneWorkaround Enter\n")); + Status = AGESA_UNSUPPORTED; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if ((SelectedPortMask & (1 << PortId)) != 0) { + LINK_INFO LinkInfo = PcieLibGetPortLinkInfo (PortId, pConfig); + if (LinkInfo.MaxLinkWidth > PcieLinkWidth_x1 && LinkInfo.LinkWidth < LinkInfo.MaxLinkWidth) { + PcieLibPowerOffPortLanes (PortId, LinkInfo.LinkWidth, pConfig); + if (PcieLibResetSlot (PortId, pConfig) == AGESA_SUCCESS) { + Status = AGESA_SUCCESS; + } + } + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieBrokenLaneWorkaround Exit\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Workaround for device violating Gen2 spec. + * Downgrade link speed to Gen1. + * + * + * + * @param[in] SelectedPortMask Bitmap of port ID selected for training. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieGen2Workaround ( + IN UINT16 SelectedPortMask, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + PORT PortId; + BOOLEAN RequestPciReset; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGen2Workaround Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + RequestPciReset = FALSE; + Status = AGESA_UNSUPPORTED; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if ((SelectedPortMask & (1 << PortId)) != 0) { + if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen2 || + pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen2AdvertizeOnly || + pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis == PcieTxDeemphasis3p5dB) { + //Degrade link speed to Gen1 + pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB; + PcieLibSetLinkMode (PortId, PcieLinkModeGen1, pConfig); + PcieLibSetGen2Disabled (PortId, pConfig); + if (PcieLibResetSlot (PortId, pConfig) != AGESA_SUCCESS) { + //Slot reset logic not supported request PCI reset. + RequestPciReset = TRUE; + } + //Report back to caller that potential downgrade case is detected. + Status = AGESA_SUCCESS; + } + } + if (RequestPciReset) { + PcieLibRequestPciReset (pConfig); + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGen2Workaround Enter\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Try to recover system by issuing system wide PCI reset. + * + * + * + * @param[in] PortsLinkStatus Array of link status for every Port + * @param[in] pConfig Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieMiscWorkaround ( + IN PCIE_LINK_STATUS *PortsLinkStatus, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PORT PortId; + UINT16 PortMask; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieMiscWorkaround Enter\n")); + Status = AGESA_UNSUPPORTED; + PortMask = PcieFindPortsWithLinkStatus (PortsLinkStatus, PcieLinkStatusTrainingInProgress); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if ((PortMask & (1 << PortId)) != 0) { + if (PcieLibRequestPciReset (pConfig)!= AGESA_SUCCESS) { + break; + } + PortMask = PcieFindPortsWithLinkStatus (PortsLinkStatus, PcieLinkStatusTrainingInProgress); + if (PortMask == 0) { + break; + } + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieMiscWorkaround Exit\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check VCO negotiation complete. + * Routine will retry retrain device infinitely if VCO negotiation is failing. + * + * + * @param[in] SelectedPortMask Bitmap of port ID selected for training. + * @param[in] PortsLinkStatus Array of link status for every Port + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieCheckVco ( + IN UINT16 SelectedPortMask, + IN PCIE_LINK_STATUS *PortsLinkStatus, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT16 VcoNegotiationInProgressPortMask; + PORT PortId; + UINT16 VcoStatus; + UINT32 LinkRetrainCount; + UINT32 VcoPoll; + UINT32 Value; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]VcoNegotiationInProgress Enter\n")); + Status = AGESA_SUCCESS; + VcoNegotiationInProgressPortMask = SelectedPortMask; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (VcoNegotiationInProgressPortMask & (1 << PortId)) { + // For each port where VCO needs to be checked + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + PortsLinkStatus[PortId] = PcieLinkStatusVcoNegotiationInProgress; + for (LinkRetrainCount = 0; LinkRetrainCount < 10; LinkRetrainCount++) { + // Poll for 200 ms for VC0 negotioation completion + for (VcoPoll = 0; VcoPoll < 200; VcoPoll++) { + LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &VcoStatus, pConfig); + if ((VcoStatus & BIT1) != 0) { + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0); + } else { + PortsLinkStatus[PortId] = PcieLinkStatusConnected; + break; + } + } //For each VcoPoll + if (PortsLinkStatus[PortId] == PcieLinkStatusVcoNegotiationInProgress) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_MISC), " Vco Not Completed. Retrain link on PortId %d\n", PortId)); + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig); + Value = (Value & 0xfffffe80) | ((Value & 0x70) >> 4) | BIT8; + LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig); + } else { + break; //Vco negotiations complete + } + } //For each LinkRetrainCount + if (PortsLinkStatus[PortId] == PcieLinkStatusVcoNegotiationInProgress) { + PortsLinkStatus[PortId] = PcieLinkStatusNotConnected; + } + } // Vco negotiations required + } //For each port + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]VcoNegotiationInProgress Exit\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bit map of ports with particular link status + * + * + * + * @param[in] PortLinkStatus Pointer to array of link status for every Port + * @param[in] LinkStatus LinkStatus to search for. + * + */ +/*----------------------------------------------------------------------------------------*/ +UINT16 +PcieFindPortsWithLinkStatus ( + IN PCIE_LINK_STATUS *PortLinkStatus, + IN PCIE_LINK_STATUS LinkStatus + ) +{ + UINT16 PortMask; + PORT PortId; + + PortMask = 0; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PortLinkStatus[PortId] == LinkStatus) PortMask |= (1 << PortId); + } + return PortMask; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Gather link state for selected ports. + * + * + * @param[in] SelectedPortMask Bitmap of port ID selected for training. + * @param[in] PortLinkStatus Pointer to array of link status for every Port + * @param[in] Pooling Time in MS to pool for link status change. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +PCIE_LINK_STATUS +PcieGetPortsLinkStatus ( + IN UINT16 SelectedPortMask, + IN OUT PCIE_LINK_STATUS *PortLinkStatus, + IN UINT32 Pooling, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_LINK_STATUS Status; + PORT PortId; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGetPortsLinkStatus Enter\n")); + Status = PcieLinkStatusNotConnected; + Pooling *= 10; + while (Pooling-- != 0 && Status != PcieLinkStatusConnected) { + Status = PcieLinkStatusConnected; //Set up initial overall state as connected + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + //Work only on selected ports + if ((SelectedPortMask & (1 << PortId)) != 0) { + PCI_ADDR Port; + UINT32 LinkState; + Port = PcieLibGetPortPciAddress (PortId, pConfig); //Get PCI address of this port + //Get link state + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, pConfig); + LinkState &= 0x3F; + //CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_MISC), " PortId %d LinkState = 0x%x \n", PortId, LinkState)); + printk(BIOS_INFO, "[NBPCIE] PortId %02d LinkState = 0x%x \n", PortId, LinkState); + //Check if link in L0 state + + if (LinkState == 0x10) { + PortLinkStatus[PortId] = PcieLinkStatusConnected; + } else { + Status = PcieLinkStatusNotConnected; + //Check if link in compliance mode + if (LinkState == 0x7) { + PortLinkStatus[PortId] = PcieLinkStatusInCompliance; + } else { + //Check if we passed receiver detection. It will indicate that device present. + if (LinkState > 0x4) { + PortLinkStatus[PortId] = PcieLinkStatusTrainingInProgress; + } + } + } + } + } + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 100, 0); + } + return Status; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c b/src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c new file mode 100644 index 000000000000..17ae4f746bef --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieInitLate.c @@ -0,0 +1,505 @@ +/** + * @file + * + * PCIE Late Initialization + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" +#include "amdSbLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd PCIE Late Init for all NB. + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +AGESA_STATUS +AmdPcieLateInit ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (PcieLateInit, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd PCIE Late Init for all NB. + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +AGESA_STATUS +AmdPcieLateInitWa ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (PcieLateInitWa, ConfigPtr); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd PCIE Special Init for all NB. + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +AGESA_STATUS +AmdPcieValidatePortState ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (PcieValidatePortState, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd PCIE S3 Init fro all NB. + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +AGESA_STATUS +AmdPcieS3Init ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (PcieLateInit, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB PCIE Late Init. + * Extended programming. Enable power management and misc capability. + * Prepare PCIE subsystem to boot to OS. + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLateInit ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + PcieLibUnHidePorts (NbConfigPtr); + Status = PcieLateValidateConfiguration (NbConfigPtr); + if (Status == AGESA_FATAL) { + PcieLibHidePorts (NbConfigPtr); + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + PcieLibLateInit (NbConfigPtr); + Status = PcieLateInitPorts (NbConfigPtr); + Status = PcieLateInitCores (NbConfigPtr); + PcieLibHidePorts (NbConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NB PCIE Late Init. + * Extended programming. Enable power management and misc capability. + * Prepare PCIE subsystem to boot to OS. + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLateInitWa ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 Value; + BOOLEAN SmuWa; + LibNbPciIndexRead (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG4A, AccessWidth32, &Value, NbConfigPtr); + SmuWa = ((Value & BIT21) != 0) ? TRUE : FALSE; + if (SmuWa) { + UINT32 SmuWaData; + LibNbMcuControl (AssertReset, NbConfigPtr); + SmuWaData = LibNbReadMcuRam (0xFE74, NbConfigPtr); + SmuWaData &= 0x00ff; + LibNbLoadMcuFirmwareBlock (0xFE74, 0x1, &SmuWaData, NbConfigPtr); + LibNbMcuControl (DeAssertReset, NbConfigPtr); + } + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Late init PCIE Ports + * + * + * +* @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLateInitPorts ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + PORT PortId; + BOOLEAN IsIommuEnabled; + NB_INFO NbInfo; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitPorts Enter\n")); + IsIommuEnabled = LibNbIsIommuEnabled (NbConfigPtr); + NbInfo = LibNbGetRevisionInfo (NbConfigPtr); + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); + Status = AGESA_SUCCESS; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + CORE CoreId; + CoreId = PcieLibGetCoreId (PortId, NbConfigPtr); + if (!PcieLibIsValidCoreId (CoreId, NbConfigPtr)) { + PcieLibPowerOffPortLanes (PortId, PcieLinkWidth_x0, NbConfigPtr); + } else if (PcieLibIsValidPortId (PortId, NbConfigPtr)) { + PCIE_LINK_WIDTH LinkWidth; + PCI_ADDR Port; + LinkWidth = PcieLibGetLinkWidth (PortId, NbConfigPtr); + CoreId = PcieLibGetCoreId (PortId, NbConfigPtr); + Port = PcieLibGetPortPciAddress (PortId, NbConfigPtr); + PcieLateCommonPortInit (PortId, NbConfigPtr); + if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON) { + if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen2SoftwareInitiated) { + PcieInitiateSoftwareGen2 (PortId, NbConfigPtr); + } + PcieAsmpEnableOnPort (PortId, (UINT8)pPcieConfig->PortConfiguration[PortId].PortAspm, NbConfigPtr); + } + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70 , AccessS3SaveWidth32, (UINT32)~BIT12, 0, NbConfigPtr); //PCIE should not ignore malformed packet error or ATS request + if (pPcieConfig->PortConfiguration[PortId].PortCompliance == OFF && + pPcieConfig->PortConfiguration[PortId].PortHotplug == OFF && + pPcieConfig->CoreSetting[CoreId].PowerOffUnusedLanes == ON) { + PcieLibPowerOffPortLanes (PortId, LinkWidth, NbConfigPtr); + } + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitPorts Exit\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Late init PCIE Cores. Core level feature/power management etc. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLateInitCores ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + CORE CoreId; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitCores Enter\n")); + Status = AGESA_SUCCESS; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Init CoreId [%d]\n", CoreId)); + if (pPcieConfig->CoreSetting[CoreId].PowerOffPllInL1 == ON) { + PcieLibEnablePllPowerOffInL1 (CoreId, pConfig); + } + if (pPcieConfig->CoreSetting[CoreId].PowerOffPll == ON) { + PcieLibPowerOffPll (CoreId, pConfig); + } + PcieLibMiscLateCoreSetting (CoreId, pConfig); + PcieLibManageTxClock (CoreId, pConfig); + PcieLibManageLclkClock (CoreId, pConfig); + } +#ifndef VC1_SUPPORT_DISABLE + if (NB_SBDFO == 0 && pPcieConfig->PcieConfiguration.NbSbVc1 == ON) { + PcieNbSbSetupVc (pConfig); + } +#endif + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateInitCores Exit\n")); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Set up NB-SB virtual channel for audio traffic + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieNbSbSetupVc ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 VCStatus; + PCI_ADDR Port; + + Port = PcieLibGetPortPciAddress (8, pConfig); + if (PcieSbSetupVc (pConfig) == AGESA_SUCCESS) { + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG124, AccessS3SaveWidth8, 0x01, 0, pConfig); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG130, AccessS3SaveWidth32, (UINT32)~(BIT24 + BIT25 + BIT26), 0xFE + BIT24, pConfig); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG130, AccessS3SaveWidth32, 0xffffffff, BIT31, pConfig); + do { + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, CIMX_S3_SAVE); + LibNbPciRead (Port.AddressValue | NB_PCIP_REG134, AccessWidth32, &VCStatus, pConfig); + } while (VCStatus & BIT17); + PcieSbEnableVc (pConfig); + } +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Late common Port Init + * + * + * @param[in] PortId Port Id + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLateCommonPortInit ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + Status = AGESA_SUCCESS; + + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Initiate SW Gen2 switch + * + * + * + * @param[in] PortId Port Id. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieInitiateSoftwareGen2 ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 LinkSpeedCap; + UINT8 PcieCapPtr; + UINT8 SecondaryBus; + UINT32 Value; + UINT32 Counter; + PCI_ADDR Ep; + PCI_ADDR Port; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitiateSoftwareGen2 PortId[%d] Enter\n", PortId)); + Counter = 5000; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + LibNbPciRead (Port.AddressValue | NB_PCIP_REG19, AccessWidth8, &SecondaryBus, pConfig); + Ep.AddressValue = 0; + Ep.Address.Bus = SecondaryBus; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE] SecondaryBus = 0x%x \n", SecondaryBus)); + PcieCapPtr = LibNbFindPciCapability (Ep.AddressValue, PCIE_CAP_ID, pConfig); + LibNbPciRead (Ep.AddressValue | (PcieCapPtr + 0xC), AccessWidth8, &LinkSpeedCap, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE] PcieCapPtr = 0x%x \n", PcieCapPtr)); + if ((LinkSpeedCap & 0xf) < 2) { + return; + } + PcieLibSetLinkMode (PortId, PcieLinkModeGen2, pConfig); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA4 , AccessS3SaveWidth32, (UINT32)~(BIT18), BIT18 , pConfig); + do { + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, CIMX_S3_SAVE); + LibNbPciIndexRead (Port.AddressValue | NB_PCIP_REGE0, NB_BIFNBP_REGA5, AccessWidth32, &Value, pConfig); + } while ((UINT8)Value != 0x10 && Counter-- != 0); + LibNbPciIndexRead (Port.AddressValue | NB_PCIP_REGE0, NB_BIFNBP_REGA4, AccessWidth32, &Value, pConfig); + if ((Value & BIT24) != 0) { + //Initiate link speed change + LibNbPciIndexRMW (Port.AddressValue | NB_PCIP_REGE0, NB_BIFNBP_REGA4, AccessS3SaveWidth32, ((UINT32)~BIT7), BIT7, pConfig); + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieInitiateSoftwareGen2 Exit\n")); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Validate input parameters configuration for PCie Late Init call. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLateValidateConfiguration ( + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + NB_INFO NbInfo; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateValidateConfiguration Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + if (pPcieConfig == NULL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, pConfig); + CIMX_ASSERT (FALSE); + return AGESA_FATAL; + } + if (pPcieConfig->sHeader.InitializerID != INITIALIZED_BY_INITIALIZER) { + PcieLibInitializer (pConfig); + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLateValidateConfiguration Exit\n")); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * PcieValidatePortState + * Port disable or port visibility control + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieValidatePortState ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = AGESA_SUCCESS; + PcieLibUnHidePorts (NbConfigPtr); + PcieLibValidatePortStateInit (NbConfigPtr); + PcieForcePortsVisibleOrDisable (NbConfigPtr); + PcieLibHidePorts (NbConfigPtr); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * PciePortsVisibleOrDisable + * Set ports always visible or disable based on input parameter + * + * + * +* @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ +VOID +PcieForcePortsVisibleOrDisable ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCIE_CONFIG *pPcieConfig; + PORT PortId; + PCI_ADDR Port; + + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, NbConfigPtr)) { + Port = PcieLibGetPortPciAddress (PortId, NbConfigPtr); + if (pPcieConfig->PortConfiguration[PortId].ForcePortDisable == ON ) { + pPcieConfig->PortConfiguration[PortId].PortPresent = OFF; + pPcieConfig->PortConfiguration[PortId].PortDetected = OFF; + } + if (pPcieConfig->PortConfiguration[PortId].PortAlwaysVisible == ON) { + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG70, AccessWidth32, (UINT32)~BIT19, BIT19, NbConfigPtr); + pPcieConfig->PortConfiguration[PortId].PortPresent = ON; + pPcieConfig->PortConfiguration[PortId].PortDetected = ON; + } + LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG01, AccessWidth32, (UINT32*)&pPcieConfig->PortConfiguration[PortId], NbConfigPtr); + } + } +} + diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c new file mode 100644 index 000000000000..8b1782e7bb62 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieLateHwLib.c @@ -0,0 +1,486 @@ +/** + * @file + * + * PCIe silicon specific functions library. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc Initialization in late init + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +PcieLibLateInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + PORT PortId; + PCIE_CONFIG *pPcieConfig; + PCI_ADDR ClkPciAddress; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Function = 1; + //Restore general setting in scratch + LibNbEnableClkConfig (pConfig); + LibNbPciRead (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig); + LibNbDisableClkConfig (pConfig); + // Restore Core setting from scratch + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { +// if (PcieLibIsCoreAccessible (CoreId, pConfig) && pPcieConfig->CoreSetting[CoreId].CoreDisabled != ON ) { + UINT32 CoreAddress; + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + LibNbPciIndexRead ( + pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, + NB_BIFNB_REG01 | CoreAddress, + AccessWidth32, + (UINT32*)&pPcieConfig->CoreSetting[CoreId], + pConfig + ); +// } else { +// pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON; +// } +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Core Setting CoreId %d Setting %x Enter\n", CoreId, (UINT32)(pPcieConfig->CoreSetting[CoreId]))); + } + // Restore port Setting from scratch + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig)) { + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + //Reload port configuration from scratch register + LibNbPciIndexRead ( + Port.AddressValue | NB_BIF_INDEX, + NB_BIFNBP_REG01, + AccessWidth32, + (UINT32*)&pPcieConfig->PortConfiguration[PortId], + pConfig + ); + LibNbPciRead (Port.AddressValue | NB_PCIP_REG108, AccessWidth32, (UINT32*)&pPcieConfig->ExtPortConfiguration[PortId], pConfig); +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Port setting PortId %d Setting %x Enter\n", PortId, (UINT32)(pPcieConfig->PortConfiguration[PortId]))); + } else { + *((UINT32*)&pPcieConfig->ExtPortConfiguration[PortId]) = 0; + *((UINT32*)&pPcieConfig->PortConfiguration[PortId]) = 0; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc Initialization in validate port state + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +VOID +PcieLibValidatePortStateInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + PORT PortId; + UINT32 PortAlwaysVisible; + UINT32 ForcePortDisable; + PCIE_CONFIG *pPcieConfig; + PCI_ADDR ClkPciAddress; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Function = 1; + //Restore general setting in scratch + LibNbEnableClkConfig (pConfig); + LibNbPciRead (ClkPciAddress.AddressValue | NB_CLK_REG78, AccessWidth32, &pPcieConfig->PcieConfiguration, pConfig); + LibNbDisableClkConfig (pConfig); + // Restore Core setting from scratch + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { +// if (PcieLibIsCoreAccessible (CoreId, pConfig) && pPcieConfig->CoreSetting[CoreId].CoreDisabled != ON ) { + UINT32 CoreAddress; + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + LibNbPciIndexRead ( + pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, + NB_BIFNB_REG01 | CoreAddress, + AccessWidth32, + (UINT32*)&pPcieConfig->CoreSetting[CoreId], + pConfig + ); +// } else { +// pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON; +// } +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Core Setting CoreId %d Setting %x Enter\n", CoreId, (UINT32)(pPcieConfig->CoreSetting[CoreId]))); + } + // Restore port Setting from scratch + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig)) { + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + PortAlwaysVisible = pPcieConfig->PortConfiguration[PortId].PortAlwaysVisible; + ForcePortDisable = pPcieConfig->PortConfiguration[PortId].ForcePortDisable; + //Reload port configuration from scratch register + LibNbPciIndexRead ( + Port.AddressValue | NB_BIF_INDEX, + NB_BIFNBP_REG01, + AccessWidth32, + (UINT32*)&pPcieConfig->PortConfiguration[PortId], + pConfig + ); + pPcieConfig->PortConfiguration[PortId].PortAlwaysVisible = PortAlwaysVisible; + pPcieConfig->PortConfiguration[PortId].ForcePortDisable = ForcePortDisable; + LibNbPciRead (Port.AddressValue | NB_PCIP_REG108, AccessWidth32, (UINT32*)&pPcieConfig->ExtPortConfiguration[PortId], pConfig); +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Recover Port setting PortId %d Setting %x Enter\n", PortId, (UINT32)(pPcieConfig->PortConfiguration[PortId]))); + } else { + *((UINT32*)&pPcieConfig->ExtPortConfiguration[PortId]) = 0; + *((UINT32*)&pPcieConfig->PortConfiguration[PortId]) = 0; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable LCLK clock gating or shutdown LCLK clock banch if possible + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieLibManageLclkClock ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + UINT32 Mask; + PCI_ADDR ClkPciAddress; + UINT32 CoreAddress; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibManageLclkClock [CoreId %d] Enter \n", CoreId)); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + ClkPciAddress = pConfig->NbPciAddress; + ClkPciAddress.Address.Function = 1; + LibNbEnableClkConfig (pConfig); + + if (pPcieConfig->CoreSetting[CoreId].LclkClockGating == ON) { + ClkPciAddress.Address.Register = NB_CLK_REGE8; + Value = 0; + Mask = 0; + switch (CoreAddress) { + case GPP1_CORE: + ClkPciAddress.Address.Register = NB_CLK_REG94; + Mask = BIT16; + break; + case GPP2_CORE: + Value = BIT28; + break; + case GPP3a_CORE: + Value = BIT31; + break; + case GPP3b_CORE: + Value = BIT25; + break; + case SB_CORE: + ClkPciAddress.Address.Register = NB_CLK_REG94; + Mask = BIT24; + break; + default: + CIMX_ASSERT (FALSE); + } + LibNbPciRMW (ClkPciAddress.AddressValue, AccessS3SaveWidth32, ~Mask, Value, pConfig); + } + if (pPcieConfig->CoreSetting[CoreId].LclkClockOff == ON) { + UINT8 ActiveCoreMap; + ActiveCoreMap = PcieLibGetActiveCoreMap (pConfig); + if ((ActiveCoreMap & (1 << CoreId)) == 0) { + //Core not active we can shutdown LCLK permanantly + CORE_INFO *pCoreInfo; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Shutdown LCKL clock\n")); + pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); + ClkPciAddress.Address.Register = NB_CLK_REGE0; + pPcieConfig->CoreSetting[CoreId].CoreDisableStatus = ON; + // We have to setup Index for BIFNB to point out to SB core. After this point core registers no longer accesasable + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, 0x00 | SB_CORE, AccessS3SaveWidth32, 0xffffffff, 0x00, pConfig); + LibNbPciRMW (ClkPciAddress.AddressValue, AccessS3SaveWidth32, 0xffffffff, 1 << pCoreInfo->LclkOffOffset, pConfig); + + Value = 0; + if (CoreAddress == GPP1_CORE) { + if ((ActiveCoreMap & 0xb) == 0 && !LibNbIsIommuEnabled (pConfig)) { + // Can shutdown master core + Value = 1 << pCoreInfo->LclkPermOffOffset; + } + } else { + Value = 1 << pCoreInfo->LclkPermOffOffset; + } + if (Value != 0) { + NbIommuDisconnectPcieCore (CoreId, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG27, AccessS3SaveWidth32, 0xffffffff, Value, pConfig); + + } + } + } + LibNbDisableClkConfig (pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Power Off Pll for unused lanes. + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +PcieLibPowerOffPll ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + UINT32 CoreAddress; + UINT32 PowerOfPllValue; + UINT32 PadsMap; + //UINT32 TxClockOffValue; + UINT32 PowerOfPllRegister; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + PowerOfPllValue = 0; + PadsMap = 0; + //TxClockOffValue = 0; + PowerOfPllRegister = NB_MISC_REG23; + + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG65 | CoreAddress, AccessS3SaveWidth32, &PadsMap, pConfig); + if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { + if ((PadsMap & 0xf0) == 0xf0) { + //Power Off PLL1 + PowerOfPllValue |= (BIT1 | BIT3); + if ((PadsMap & 0x0f) == 0x0f && pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AABB) { + //Power Off PLL0 + PowerOfPllValue |= (BIT0 | BIT2); + } + } + if (CoreAddress == GPP2_CORE) { + PowerOfPllValue <<= 8; + //TxClockOffValue = BIT1; + } else { + //TxClockOffValue = BIT0; + } + if ((UINT16)PadsMap != 0xffff) { + //TxClockOffValue = 0; //Do not disable TX clock in case any line is ON + } + } + if (CoreAddress == GPP3a_CORE ) { + if ((UINT16)PadsMap == 0x3F3F) { + PowerOfPllValue = BIT18 | BIT16; + //TxClockOffValue = BIT2; + } + } + if (CoreAddress == GPP3b_CORE ) { + PowerOfPllRegister = NB_MISC_REG2E; + if ((UINT16)PadsMap == 0x0F0F) { + PowerOfPllValue = BIT8 | BIT6; + //TxClockOffValue = BIT3; + } + } + //Power Off Pll + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, PowerOfPllRegister , AccessS3SaveWidth32, 0xffffffff, PowerOfPllValue, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Power off PLL CoreId %d, Value 0x%x\n", CoreId, PowerOfPllValue)); + //Turn off TXCLK + //LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG07, AccessS3SaveWidth32, 0xffffffff, TxClockOffValue, pConfig); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable TX clock gating or shutdown TX clock if possible + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. * + */ +VOID +PcieLibManageTxClock ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + UINT32 CoreAddress; + UINT32 Value; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + if (pPcieConfig->CoreSetting[CoreId].TxClockGating == ON) { + switch (CoreAddress) { + case GPP1_CORE: + Value = BIT4; + break; + case GPP2_CORE: + Value = BIT5; + break; + case GPP3a_CORE: + Value = BIT6; + break; + case GPP3b_CORE: + Value = BIT24; + break; + case SB_CORE: + Value = BIT7; + break; + default: + Value = 0; + CIMX_ASSERT (FALSE); + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG07, AccessS3SaveWidth32, 0xffffffff, Value, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessS3SaveWidth32, (UINT32)~BIT6, BIT6, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG11 | CoreAddress, AccessS3SaveWidth32, 0xfffffff0, 0x0C, pConfig); + } + if (pPcieConfig->CoreSetting[CoreId].TxClockOff == ON) { + UINT8 ActiveCoreMap; + ActiveCoreMap = PcieLibGetActiveCoreMap (pConfig); + if ((ActiveCoreMap & (1 << CoreId)) == 0) { + //Core not active we can shutdown TX clk permanantly + CORE_INFO *pCoreInfo; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Shutdown TX clock\n")); + pPcieConfig->CoreSetting[CoreId].CoreDisableStatus = ON; + pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG07, AccessS3SaveWidth32, 0xffffffff, 1 << pCoreInfo->TxOffOffset, pConfig); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable Pll Power Down in L1. + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. * + */ +VOID +PcieLibEnablePllPowerOffInL1 ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + UINT32 Value; + UINT32 CoreAddress; + PORT PortId; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + if (pPcieConfig->CoreSetting[CoreId].DetectPowerOffPllInL1 == ON && !PciePllOffComatibilityTest (CoreId, pConfig)) { + return; + } + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig) && PcieLibGetCoreId (PortId, pConfig) == CoreId) { + if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) { + // set up max exit latency requirment for hotplug ports + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC1 , AccessS3SaveWidth32, 0xffffffff, 0xf, pConfig); + } + } + } + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + Value = BIT8; + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessS3SaveWidth32, (UINT32)~(BIT9 + BIT4), BIT3 + BIT0 + BIT12, pConfig); + if (CoreAddress == GPP3b_CORE || CoreAddress == GPP3a_CORE || CoreAddress == SB_CORE) { + Value |= BIT3; + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG02 | CoreAddress, AccessS3SaveWidth32, 0xffffffff, Value, pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc. core setting. + * + * + * + * @param[in] CoreId PCI Express- Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +PcieLibMiscLateCoreSetting ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ +//Lock + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, + NB_BIFNB_REG10 | PcieLibGetCoreAddress (CoreId, pConfig), + AccessS3SaveWidth32, + 0xffffffff, + BIT0, + pConfig + ); +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLib.c b/src/vendorcode/amd/cimx/rd890/nbPcieLib.c new file mode 100644 index 000000000000..2e91cb6c1a26 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieLib.c @@ -0,0 +1,1604 @@ +/** + * @file + * + * PCIe silicon specific functions library. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" +#include "amdSbLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +UINT32 +PcieLibGetCoreConfiguration ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieLibValidateGfxConfig ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + + + +CORE_INFO CoreInfoTable[] = { + { // GPP1_CORE_ID = 0 It is GFX Core (GPP1 Core) + GPP1_CORE, // Core Selector + (BIT2 | BIT3), // Port ID Mask. Defines what ports belongs + NB_MISC_REG08, + NB_MISC_REG28, // De-emphasis register + NB_MISC_REG26, // Strap control register + 28, // Strap bit offset + NB_CLK_REGF0, + NB_MISC_REG35, 26, // TX drive strength and offset + NB_MISC_REG35, 18, // TX half swing + NB_MISC_REG36, 24, // TX zero deemphasis + 0, + 28, + 23 + }, + { // GPP2_CORE_ID = 1 It is GFX2 Core (GPP2 Core) + GPP2_CORE, // Core Selector + (BIT11 | BIT12), // Port ID Mask. Defines what ports belongs + NB_MISC_REG08, + NB_MISC_REG27, // De-emphasis register + NB_MISC_REG26, // Strap control register + 29, // Strap bit offset + NB_CLK_REGF0, + NB_MISC_REG35, 28, // TX drive strength and offset + NB_MISC_REG35, 19, // TX half swing + NB_MISC_REG36, 26, // TX zero deemphasis + 1, + 29, + 24 + }, + { // GPP3a_CORE_ID = 2 It is GPP Core (GPP3a Core) + GPP3a_CORE, // Core Selector + (BIT4 | BIT5 | BIT6 | BIT7 | BIT9 | BIT10), // Port ID Mask. Defines what ports belongs + NB_MISC_REG08, + NB_MISC_REG28, // De-emphasis register + NB_MISC_REG26, // Strap control register + 30, // Strap bit offset + NB_CLK_REGF4, + NB_MISC_REG35, 30, // TX drive strength and offset + NB_MISC_REG35, 20, // TX half swing + NB_MISC_REG36, 28, // TX zero deemphasis + 2, + 30, + 25 + }, + { // GPP3b_CORE_ID = 3 It is GPP2 Core (GPP3b Core) + GPP3b_CORE, // Core Selector + (BIT13), // Port ID Mask. Defines what ports belongs + NB_MISC_REG2A, + NB_MISC_REG2D, // De-emphasis register + NB_MISC_REG2D, // Strap control register + 21, // Strap bit offset + NB_CLK_REGF4, + NB_MISC_REG2C, 4, // TX drive strength and offset + NB_MISC_REG2C, 2, // TX half swing + NB_MISC_REG2B, 10, // TX zero deemphasis + 3, + 31, + 26 + }, + { // SB_CORE_ID = 4 It is SB Core + SB_CORE, // Core Selector + (BIT8), // Port ID Mask. Defines what ports belongs + NB_MISC_REG08, + NB_MISC_REG6F, // De-emphasis register + 0x0, + 0x0, + 0x0, + NB_MISC_REG68, 8, // TX drive strength and offset + NB_MISC_REG67, 27, // TX half swing + NB_MISC_REG68, 20, // TX zero deemphasis + 0xff, + 0xff, + 0xff + } +}; + + +PORT_INFO pGfxPortFullA = { + PcieLinkWidth_x16, 0, 0 +}; + +PORT_INFO pGfxPortA = { + PcieLinkWidth_x8, 0, 96 +}; + +PORT_INFO pGfxPortB = { + PcieLinkWidth_x8, 8, 96 +}; + +PORT_INFO pGpp420000[] = { + {PcieLinkWidth_x4, 0, 56}, + {PcieLinkWidth_x2, 4, 28} +}; + +PORT_INFO pGpp411000[] = { + {PcieLinkWidth_x4, 0, 56}, + {PcieLinkWidth_x1, 4, 14}, + {PcieLinkWidth_x1, 5, 14} +}; + +PORT_INFO pGpp222000[] = { + {PcieLinkWidth_x2, 0, 28}, + {PcieLinkWidth_x2, 2, 28}, + {PcieLinkWidth_x2, 4, 28} +}; + +PORT_INFO pGpp221100[] = { + {PcieLinkWidth_x2, 0, 28}, + {PcieLinkWidth_x2, 2, 28}, + {PcieLinkWidth_x1, 4, 14}, + {PcieLinkWidth_x1, 5, 14} +}; + +PORT_INFO pGpp211110[] = { + {PcieLinkWidth_x2, 0, 28}, + {PcieLinkWidth_x1, 2, 14}, + {PcieLinkWidth_x1, 3, 14}, + {PcieLinkWidth_x1, 4, 14}, + {PcieLinkWidth_x4, 0, 0 }, //Dummy entry + {PcieLinkWidth_x1, 5, 14} +}; + +PORT_INFO pGpp111111[] = { + {PcieLinkWidth_x1, 0, 14}, + {PcieLinkWidth_x1, 1, 14}, + {PcieLinkWidth_x1, 2, 14}, + {PcieLinkWidth_x1, 3, 14}, + {PcieLinkWidth_x4, 0, 0 }, //Dummy entry + {PcieLinkWidth_x1, 4, 14}, + {PcieLinkWidth_x1, 5, 14} +}; + +GPP_CFG_INFO GppCfgInfoTable[] = { + {pGpp420000, 0xff50fff4}, + {pGpp411000, 0xf650fff4}, + {pGpp222000, 0xff60f5f4}, + {pGpp221100, 0xf760f5f4}, + {pGpp211110, 0xf97065f4}, + {pGpp111111, 0xfA907654} +}; + +CONST PORT_STATIC_INFO PortInfoTable[] = { +//Training Reversal Deemp Mapping Hotplug Offset + {4 , 3, 0 , 4 , 0 }, //2 + {5 , 4, 1 , 8 , 8 }, //3 + {21, 7, 2 , 12 , 0 }, //4 + {22, 8, 3 , 16 , 8 }, //5 + {23, 9, 4 , 20 , 16 }, //6 + {24, 10, 5 , 24 , 0xFF }, //7 + {20, 0, 1 , 0xFF , 0xFF }, //8 + {25, 11, 6 , 28 , 0xFF }, //9 + {26, 12, 7 , 0 , 0xFF }, //10 + {6 , 5, 30, 4 , 16 }, //11 + {7 , 6, 31, 8 , 24 }, //12 + {4 , 25, 5 , 12 , 24 } //13 +}; + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Port Training Control + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] Operation Release or Hold training + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +VOID +PcieLibPortTrainingControl ( + IN PORT PortId, + IN PCIE_LINK_TRAINING Operation, + IN AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + CORE_INFO *pCoreInfo; + PORT_STATIC_INFO *pStaticPortInfo; + CoreId = PcieLibGetCoreId (PortId, pConfig); + pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); + pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + pCoreInfo->TrainingRegister, + AccessWidth32, + ~(1 << pStaticPortInfo->TrainingAddress), + (Operation == PcieLinkTrainingHold)?(1 << pStaticPortInfo->TrainingAddress):0, + pConfig + ); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCI address of Port. + * Function return pcie Address based on port mapping and core configuration. + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +PCI_ADDR +PcieLibGetPortPciAddress ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR Port; + UINT32 RemapEnable; + UINT32 RemapValue; + PORT_STATIC_INFO *pPortStaticInfo; + + RemapEnable = 0; + RemapValue = 0; + pPortStaticInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); + Port.AddressValue = pConfig->NbPciAddress.AddressValue; + + LibNbPciIndexRead ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + NB_MISC_REG20, + AccessWidth32, + &RemapEnable, + pConfig + ); + if (pPortStaticInfo->MappingAddress != 0xff && RemapEnable & BIT0) { + LibNbPciIndexRead ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + (PortId > 9)? NB_MISC_REG21:NB_MISC_REG20, + AccessWidth32, + &RemapValue, + pConfig + ); + RemapValue = (RemapValue >> pPortStaticInfo->MappingAddress) & 0xf; + } + if (RemapValue == 0) { + RemapValue = PortId; + } + Port.Address.Device = RemapValue; + return Port; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Core register selector. + * Function return selector to access BIFNB register space for selected core + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +UINT32 +PcieLibGetCoreAddress ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + return PcieLibGetCoreInfo (CoreId, pConfig)->CoreSelector; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Core Id + * Function return PCIE core ID base on Port ID + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + * @retval Core ID. + */ +CORE +PcieLibGetCoreId ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + CORE_INFO *pCoreInfoTable = (CORE_INFO*)FIX_PTR_ADDR (&CoreInfoTable[0], NULL); + CORE CoreId; + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + if (pCoreInfoTable[CoreId].PortIdBitMap & (1 << PortId)) { + break; + } + } + return CoreId; +} + +/* +INDIRECT_REG_ENTRY +STATIC +PcieMiscInitTable[] = { + { + NB_MISC_REG20, + (UINT32)~BIT1, + 0x0 + }, //enable static device remapping by default + { + NB_MISC_REG22, + 0xffffffff, + BIT27 + }, //[10]CMGOOD_OVERRIDE for all 5 pcie cores. + { + NB_MISC_REG6B, + 0xffffffff, + (UINT32) (0x1f << 27) + }, //[13][12]Turn Off Offset Cancellation + { + NB_MISC_REG37, + (UINT32)~(BIT11 + BIT12 + BIT13), + 0x0 + }, //[14][13]Disables Rx Clock gating in CDR + { + NB_MISC_REG67, + (UINT32)~(BIT26 + BIT10 + BIT11), + BIT11 + }, //[13]Disables Rx Clock gating in CDR + //[16]Sets Electrical Idle Threshold + { + NB_MISC_REG2C, + (UINT32)~(BIT10), + 0x0 + }, //[13]Disables Rx Clock gating in CDR + { + NB_MISC_REG2A, + (UINT32)~(BIT17 + BIT16), + BIT17 + }, //[16]Sets Electrical l Idle Threshold + { + NB_MISC_REG32, + (UINT32)~(0x3F << 20), + (UINT32) (0x2A << 20) + } //[17][16]Sets Electrical Idle Threshold +}; +*/ + + + +UINT8 GppConfigTable[] = { + 0x0, 0x1, 0x2, 0xC, 0xA, 0x4, 0xB +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Set Core Configuration. + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +PcieLibSetCoreConfiguration ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 LaneReversalValue; + PORT PortId; + PCIE_CONFIG *pPcieConfig; + CORE_INFO *pCoreInfo; + CORE CoreAddress; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetCoreConfiguration CoreId = %d Configuration = 0x%x Enter\n", CoreId, pPcieConfig->CoreConfiguration[CoreId])); + pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + LaneReversalValue = 0; + PcieLibCoreReset (CoreId, PcieCoreResetAllAssert, pConfig); + PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStart, pConfig); + //Setup GFX/GFX2 core configuration + if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { + if (pPcieConfig->CoreConfiguration[CoreId] == GFX_CONFIG_AABB) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, (CoreAddress == GPP1_CORE)?BIT8:BIT9, pConfig); + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 2000, 0); + } + if (pPcieConfig->CoreSetting[CoreId].RefClockInput == ON) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG6C, AccessWidth32, 0xffffffff, (CoreAddress == GPP1_CORE)?BIT9:BIT31, pConfig); + } + } + //Setup GPP core configuration + if (CoreAddress == GPP3a_CORE) { + UINT32 Mux; + UINT8 *pGppConfigTable; + + Mux = 0; + pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL); + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + NB_MISC_REG67, AccessWidth32, + 0xfffffff0, + (UINT32)pGppConfigTable[pPcieConfig->CoreConfiguration[CoreId]], + pConfig + ); + switch (pPcieConfig->CoreConfiguration[CoreId]) { + case GPP_CONFIG_GPP420000: + Mux = (pPcieConfig->PortConfiguration[6].PortReversed == ON)?0xF05BA00:0x055B000; + break; + case GPP_CONFIG_GPP411000: + Mux = 0x215B400; + break; + case GPP_CONFIG_GPP222000: + case GPP_CONFIG_GPP211110: + Mux = (pPcieConfig->PortConfiguration[4].PortReversed == ON)?0xFFF0AAA:0xFF0BAA0; + break; + case GPP_CONFIG_GPP221100: + Mux = 0x215B400; + break; + case GPP_CONFIG_GPP111111: + Mux = 0x2AA3554; + break; + default: + CIMX_ASSERT (FALSE); + } + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, 0xf0000000, Mux, pConfig); + } + PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStop, pConfig); + PcieLibCoreReset (CoreId, PcieCoreResetAllDeassert, pConfig); + //Setup lane reversal + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig)) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && + pPcieConfig->PortConfiguration[PortId].PortReversed == ON && + (pCoreInfo->PortIdBitMap & (1 << PortId)) != 0) { + PORT_STATIC_INFO *pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); + LaneReversalValue |= (1 << (pStaticPortInfo->ReversalAddress)); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Port reversed Port Id %d Native Id %d, Reversal Address %d \n", PortId, PcieLibNativePortId (PortId, pConfig), pStaticPortInfo->ReversalAddress)); + } + } + } + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + (CoreAddress == GPP3b_CORE) ? NB_MISC_REG2D : NB_MISC_REG27, + AccessWidth32, 0xffffffff, + LaneReversalValue, + pConfig + ); + //Setup performance mode + if (pPcieConfig->CoreSetting[CoreId].PerformanceMode == ON) { + UINT32 RegisterAddress; + switch (CoreAddress) { + case GPP1_CORE: + RegisterAddress = NB_MISC_REG33; + break; + case GPP2_CORE: + RegisterAddress = NB_MISC_REG22; + break; + default: + RegisterAddress = 0; + break; + } + if (RegisterAddress != 0) { + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress , AccessWidth32, 0xfffffC00, 0xB5, pConfig); + } + } + //Setup Tx Drive Strength + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + pCoreInfo->TxDriveStrengthRegister , + AccessWidth32, + ~(0x3 << pCoreInfo->TxDriveStrengthOffset), + pPcieConfig->CoreSetting[CoreId].TxDriveStrength << pCoreInfo->TxDriveStrengthOffset, + pConfig + ); + //Setup Tx half swing + if (pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode == ON) { + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + pCoreInfo->TxHalfSwingRegister, + AccessWidth32, + ~(0x1 << pCoreInfo->TxHalfSwingOffset), + 0x0, + pConfig + ); + // Setup half swing deemphasis + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + pCoreInfo->TxHalfSwingDeepmhasisRegister , + AccessWidth32, + ~(0x3 << pCoreInfo->TxHalfSwingDeepmhasisOffset), + 0x0, + pConfig + ); + } + //Finalize straps for this core + PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStart, pConfig); + PcieLibStrapModeControl (CoreId, PcieCoreStrapConfigStop, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetCoreConfiguration Exit\n")); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Core Configuration + * Function return GPPSB/GFX/GFX2 core configuration. + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +UINT32 +PcieLibGetCoreConfiguration ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 CoreConfiguration; + UINT32 Value; + CORE CoreAddress; + + CoreConfiguration = 0, + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibGetCoreConfiguration (Core = 0x%x) Enter\n", CoreAddress)); + if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, &Value, pConfig); + CoreConfiguration = (Value & ((CoreAddress == GPP1_CORE) ? BIT8:BIT9))? GFX_CONFIG_AABB:GFX_CONFIG_AAAA; + } else { + if (CoreAddress == GPP3a_CORE) { + UINT8 *pGppConfigTable; + pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL); + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG67, AccessWidth32, &Value, pConfig); + while (pGppConfigTable[CoreConfiguration] != (Value & 0xf)) { + CoreConfiguration++; + } + } + } +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibGetCoreConfiguration (CoreConfiguration = 0x%x) Exit\n", CoreConfiguration)); + return CoreConfiguration; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return link misc information (max link width, current link width, lane 0 map) + * + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +LINK_INFO +PcieLibGetPortLinkInfo ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + PCI_ADDR Port; + PORT_INFO *pPortInfo; + LINK_INFO LinkInfo = {0, 0, 0}; + + Port = PcieLibGetPortPciAddress (PortId, pConfig); + pPortInfo = PcieLibGetPortInfo (PortId, pConfig); +//Read current link width + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig); + Value = (Value >> 4) & 0xf; + LinkInfo.LinkWidth = (UINT8)Value; + LinkInfo.MaxLinkWidth = pPortInfo->MaxLinkWidth; + LinkInfo.Line0Offset = pPortInfo->Line0Offset; +// CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " PortId %d LinkWidth 0x%x MaxLinkWidth 0x%x Line0Offset %d\n", PortId, LinkInfo.LinkWidth, LinkInfo.MaxLinkWidth,LinkInfo.Line0Offset)); + return LinkInfo; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if port in lane reversed configuration. + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +BOOLEAN +PcieLibIsPortReversed ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + BOOLEAN Result; + UINT32 Value; + PCIE_CONFIG *pPcieConfig; + PCI_ADDR Port; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + Port = PcieLibGetPortPciAddress (PortId, pConfig); + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REG50, AccessWidth32, &Value, pConfig); + if (pPcieConfig->PortConfiguration[PortId].PortReversed == ON || (Value & BIT0) != 0) { + Result = TRUE; + } else { + Result = FALSE; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if core id valid for current silicon + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +BOOLEAN +PcieLibIsValidCoreId ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 CoreAddress; + NB_INFO NbInfo; + + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + if (CoreAddress == GPP3b_CORE) { + if (NbInfo.Type == NB_RD890 || NbInfo.Type == NB_SR5690) { + return TRUE; + } else { + return FALSE; + } + } + if (CoreAddress == GPP2_CORE && (NbInfo.Type == NB_RD780 || NbInfo.Type == NB_RX780 || NbInfo.Type == NB_SR5650 || NbInfo.Type == NB_990X || NbInfo.Type == NB_970)) { + return FALSE; + } + return TRUE; +} + + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if port Id valid for current core configuration + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +BOOLEAN +PcieLibIsValidPortId ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + NB_INFO NbInfo; + + CoreId = PcieLibGetCoreId (PortId, pConfig); + NbInfo = LibNbGetRevisionInfo (pConfig); + if (!PcieLibIsValidCoreId (CoreId, pConfig)) { + return FALSE; + } + if ((PortId == 3 || PortId == 12) && PcieLibGetCoreConfiguration (CoreId, pConfig) != GFX_CONFIG_AABB) { + return FALSE; + } + if (PortId == 3 && NbInfo.Type == NB_970) { + return FALSE; + } + if (PortId == 12 && NbInfo.Type == NB_SR5670) { + return FALSE; + } + if (PortId == 13 || PortId == 8) { + return TRUE; + } else { + return (PcieLibNativePortId (PortId, pConfig) == 0xf)?FALSE:TRUE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Link mode. Gen1/Gen2/Gen2-Advertize + * + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] Operation Link Mode + * @param[in] pConfig Northbridge configuration structure pointer. + */ + + +VOID +PcieLibSetLinkMode ( + IN PORT PortId, + IN PCIE_LINK_MODE Operation, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR Port; + UINT8 LinkSpeed; + UINT32 LinkDeemphasisMask; + UINT32 LinkDeemphasisValue; + UINT32 RegA4Value; + UINT32 RegA2Value; + UINT32 RegC0Value; + CORE_INFO *pCoreInfo; + PORT_STATIC_INFO *pStaticPortInfo; + PCIE_CONFIG *pPcieConfig; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibSetLinkMode PortId %d Operation %d Enter\n", PortId, Operation)); + LinkSpeed = 2; + RegA4Value = BIT29 + BIT0; + RegA2Value = 0; + RegC0Value = 0; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + pStaticPortInfo = PcieLibGetStaticPortInfo (PcieLibNativePortId (PortId, pConfig), pConfig); + pCoreInfo = PcieLibGetCoreInfo (PcieLibGetCoreId (PortId, pConfig), pConfig); + + LinkDeemphasisValue = pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis << pStaticPortInfo->DeemphasisAddress; + LinkDeemphasisMask = ~(1 << pStaticPortInfo->DeemphasisAddress); + + if (Operation == PcieLinkModeGen1 || Operation == PcieLinkModeGen2AdvertizeOnly) { + RegC0Value = BIT15; + RegA2Value = BIT13; + if (Operation == PcieLinkModeGen1) { + RegA4Value = 0; + LinkSpeed = 1; + LinkDeemphasisValue = 0; + } + } + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " pCoreInfo->DeemphasisRegister %x pStaticPortInfo->DeemphasisAddress %x LinkDeemphasisMask %x, LinkDeemphasisValue %x\n", pCoreInfo->DeemphasisRegister, pStaticPortInfo->DeemphasisAddress, LinkDeemphasisMask, LinkDeemphasisValue)); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA4 , AccessWidth32, (UINT32)~(BIT0 + BIT29), RegA4Value , pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, pCoreInfo->DeemphasisRegister, AccessWidth32, LinkDeemphasisMask, LinkDeemphasisValue , pConfig); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, 0xF0, LinkSpeed, pConfig); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC0 , AccessWidth32, (UINT32)~(BIT15), RegC0Value , pConfig); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2 , AccessWidth32, (UINT32)~(BIT13), RegA2Value , pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Request PCIE reset to be executed + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLibRequestPciReset ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + SCRATCH_1 Scratch; + + Status = AGESA_UNSUPPORTED; + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); + if (Scratch.ResetCount == 0xf) { + Scratch.ResetCount = 0; + } + if (Scratch.ResetCount < 5) { + ++Scratch.ResetCount; + LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); + if (LibNbCallBack (PHCB_AmdGeneratePciReset, WARM_RESET , pConfig) != AGESA_SUCCESS) { + LibNbIoRMW (0xCF9, AccessWidth8, 0, 0x6, pConfig); + } + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Control Core Reset + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] Operation Assert/Deassert/Check core reset + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +PCI_CORE_RESET +PcieLibCoreReset ( + IN CORE CoreId, + IN PCI_CORE_RESET Operation, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + UINT32 CalibrationReset; + UINT32 GlobalReset; + UINT32 RegisterAddress; + UINT32 CoreAddress; + + RegisterAddress = NB_MISC_REG08; + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + switch (CoreAddress) { + case GPP3b_CORE: + RegisterAddress = NB_MISC_REG2A; // break missing and it is not an error. + case GPP1_CORE: + CalibrationReset = BIT14; + GlobalReset = BIT15; + break; + case GPP2_CORE: + CalibrationReset = BIT12; + GlobalReset = BIT13; + break; + case GPP3a_CORE: + CalibrationReset = BIT30; + GlobalReset = BIT31; + break; + default: + return PcieCoreResetAllDeassert; + } + switch (Operation) { + case PcieCoreResetAllDeassert: + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, ~CalibrationReset, 0x0, pConfig); + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 200, 0); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, ~GlobalReset, 0x0, pConfig); + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 2000, 0); + break; + case PcieCoreResetAllAssert: + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, 0xffffffff, CalibrationReset | GlobalReset, pConfig); + break; + case PcieCoreResetAllCheck: + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, RegisterAddress, AccessS3SaveWidth32, &Value, pConfig); + Operation = (Value & (CalibrationReset | GlobalReset))?PcieCoreResetAllAssert:PcieCoreResetAllDeassert; + break; + default: + CIMX_ASSERT (FALSE); + } + return Operation; +} + +UINT8 GfxLineMapTable[] = { + 0x00, 0x01, 0x01, 0x03, 0x0f, 0x00, 0xFF +}; +UINT8 GppLineMapTable[] = { + 0x00, 0x01, 0x03, 0x0F +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Power off port lanes. + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] Width Port Link Width. + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +VOID +PcieLibPowerOffPortLanes ( + IN PORT PortId, + IN PCIE_LINK_WIDTH Width, + IN AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + LINK_INFO LinkInfo; + UINT32 PowerOffPads; + UINT32 CoreAddress; + UINT8* pLineMapTable; + UINT16 MaxLaneBitMap; + UINT16 LaneBitMap; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPowerOffPortLanes (PortId = %d, Width = %d) Enter\n", PortId, Width)); + CoreId = PcieLibGetCoreId (PortId, pConfig); + LinkInfo = PcieLibGetPortLinkInfo (PortId, pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + if (CoreAddress == GPP1_CORE || CoreAddress == GPP2_CORE) { + pLineMapTable = &GfxLineMapTable[0]; + LinkInfo.Line0Offset /= 2; + } else { + pLineMapTable = &GppLineMapTable[0]; + } + pLineMapTable = (UINT8*)FIX_PTR_ADDR (pLineMapTable, NULL); + LaneBitMap = pLineMapTable[Width]; + MaxLaneBitMap = pLineMapTable[LinkInfo.MaxLinkWidth]; + if (PcieLibIsPortReversed (PortId, pConfig)) { + LaneBitMap = (UINT16)LibNbBitReverse ((UINT32)LaneBitMap, LibAmdBitScanForward (MaxLaneBitMap), LibAmdBitScanReverse (MaxLaneBitMap)); + } + PowerOffPads = (MaxLaneBitMap ^ LaneBitMap) << LinkInfo.Line0Offset; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Pads %x Exit\n", PowerOffPads)); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_BIF_INDEX, NB_BIFNB_REG65 | CoreAddress, AccessWidth32, 0xffffffff, PowerOffPads | (PowerOffPads << 8), pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibPowerOffPortLanes Exit\n")); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Hide Unused Ports + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieLibHidePorts ( + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 PresentPortMask; + UINT32 DetectedPortMask; + UINT32 HotplugPortMask; + UINT32 Value; + PORT PortId; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibHidePorts Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + PresentPortMask = 0; + DetectedPortMask = 0; + HotplugPortMask = 0; + // Hide SB Port + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, (UINT32)~BIT6, 0, pConfig); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) { + PCI_ADDR Port; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON ) { + DetectedPortMask |= 1 << Port.Address.Device; + } + if (pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) { + HotplugPortMask |= 1 << Port.Address.Device; + } + PresentPortMask |= 1 << Port.Address.Device; + } + } + + if (pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON) { + Value = PresentPortMask; + } else { + Value = DetectedPortMask | HotplugPortMask; + } + //CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Present Port 0x%x Visible Ports 0x%xExit\n",PresentPortMask,VisiblePortMask)); + Value = (~((Value & (0xFC)) + ((Value & 0x3E00) << 7))) & 0x1F00FC; + // Hide GFX/GFX2/GPP/GPP2 Ports + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessS3SaveWidth32, 0xffffffff, Value, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibHidePorts Exit\n")); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * UnHide all PCIE Ports + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +VOID +PcieLibUnHidePorts ( + IN AMD_NB_CONFIG *pConfig + ) +{ + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessS3SaveWidth32, (UINT32)~0x1F00FCul, 0, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessS3SaveWidth32, (UINT32)~BIT6, BIT6, pConfig); +} + + + +PCIE_DEFAULT_CONFIG PcieDefaultConfig = { + {0, 1, 0, 0}, + { + {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP1 + {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP2 + {0, 1, 1, 1, 1, 1, 1, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP3a + {0, 1, 1, 1, 1, 1, 0, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 1, 1, 1}, //GPP3b + {0, 1, 0, 1, 1, 1, 0, 0, PcieTxDriveStrangth22mA, 0, 0, PcieMediumChannel, 0, 0, 0} //SB + }, + (BIT2 + BIT4 + BIT5 + BIT6 + BIT7 + BIT8 + BIT9 + BIT10 + BIT11 + BIT13) | (BIT3 + BIT12), + 0, + 2, + 0, + 60, +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for all NB. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdPcieInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + Status = LibNbApiCall (PcieLibInitializer, ConfigPtr); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize default PCIE_CONFIG setting + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLibInitializer ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + PCIE_CONFIG *pPcieConfig; + PCIE_DEFAULT_CONFIG *pPcieDefaultConfig; + AMD_NB_CONFIG_BLOCK *ConfigPtr; + PORT PortId; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibInitializer Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + if (pPcieConfig == NULL) { + return AGESA_WARNING; + } + if (pPcieConfig->sHeader.InitializerID == INITIALIZED_BY_INITIALIZER) { + return AGESA_SUCCESS; + } + ConfigPtr = GET_BLOCK_CONFIG_PTR (pConfig); + LibAmdMemFill (pPcieConfig, 0, sizeof (PCIE_CONFIG), (AMD_CONFIG_PARAMS *)&(pPcieConfig->sHeader)); + pPcieConfig->sHeader.InitializerID = INITIALIZED_BY_INITIALIZER; + pPcieDefaultConfig = (PCIE_DEFAULT_CONFIG*)FIX_PTR_ADDR (&PcieDefaultConfig, NULL); + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + pPcieConfig->CoreSetting[CoreId] = pPcieDefaultConfig->CoreSetting[CoreId]; + } + pPcieConfig->PcieConfiguration = pPcieDefaultConfig->PcieConfiguration; + if (ConfigPtr->PlatformType == DesktopPlatform) { + pPcieConfig->PcieConfiguration.NbSbVc1 = ON; + } + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis3p5dB; + } + pPcieConfig->CoreConfiguration[2] = PcieLibGetCoreConfiguration (2, pConfig); + pPcieConfig->ReceiverDetectionPooling = pPcieDefaultConfig->ReceiverDetectionPooling; + pPcieConfig->ResetToTrainingDelay = pPcieDefaultConfig->ResetToTrainingDelay; + pPcieConfig->ExtPortConfiguration[8].PortL1ImmediateACK = ON; + pPcieConfig->TrainingToLinkTestDelay = pPcieDefaultConfig->TrainingToLinkTestDelay; + pPcieConfig->DeviceInitMaskS1 = pPcieDefaultConfig->DeviceInitMaskS1; + pPcieConfig->DeviceInitMaskS2 = pPcieDefaultConfig->DeviceInitMaskS2; + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibInitializer Exit\n")); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/* + * Validate Gfx Core Configuration + * + * + * + * + * + */ +AGESA_STATUS +PcieLibValidateGfxConfig ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieLibValidateGfxConfig Enter\n")); + CoreId = PcieLibGetCoreId (PortId, pConfig); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreConfiguration[%d] = \n", CoreId)); + if (pPcieConfig->CoreConfiguration[CoreId] == 0x0) { + pPcieConfig->CoreConfiguration[CoreId] = (pPcieConfig->PortConfiguration[PortId].PortPresent == ON)?GFX_CONFIG_AABB:GFX_CONFIG_AAAA; + } else { + if (pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AABB && + pPcieConfig->CoreConfiguration[CoreId] != GFX_CONFIG_AAAA) { + //We have received request for unknown configuration. + //pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON; + pPcieConfig->PortConfiguration[PortId].PortPresent = 0; + pPcieConfig->PortConfiguration[PortId - 1].PortPresent = 0; + return AGESA_WARNING; + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " CoreConfiguration[%d] = %x\n", CoreId, pPcieConfig->CoreConfiguration[CoreId])); + return AGESA_SUCCESS; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Validate input parameters for early PCIE init. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieLibInitValidateInput ( + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_CONFIG *pPcieConfig; + NB_INFO NbInfo; + CORE CoreId; + PORT PortId; + + NbInfo = LibNbGetRevisionInfo (pConfig); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + if (NbInfo.Type == NB_UNKNOWN || pPcieConfig == NULL) { + return AGESA_FATAL; + } + Status = AGESA_SUCCESS; + //Validate GFX configuration + if (PcieLibValidateGfxConfig (3, pConfig) != AGESA_SUCCESS) { + REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_CORE_CONFIGURATION, GPP1_CORE , 0, 0, 0, pConfig); + Status = AGESA_WARNING; + } + if (PcieLibValidateGfxConfig (12, pConfig) != AGESA_SUCCESS) { + REPORT_EVENT (AGESA_WARNING, PCIE_ERROR_CORE_CONFIGURATION, GPP2_CORE , 0, 0, 0, pConfig); + Status = AGESA_WARNING; + } + //Enable SB port on NB - SB chain and disable otherwise + pPcieConfig->PortConfiguration[8].PortPresent = (pConfig->NbPciAddress.AddressValue == 0)?ON:OFF; + + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + if (pPcieConfig->PcieConfiguration.DisableHideUnusedPorts == ON) { + //pPcieConfig->CoreSetting[CoreId].PowerOffUnusedLanes = OFF; + pPcieConfig->CoreSetting[CoreId].TxClockOff = OFF; + pPcieConfig->CoreSetting[CoreId].LclkClockOff = OFF; + pPcieConfig->CoreSetting[CoreId].PowerOffPll = OFF; + } + if (pPcieConfig->CoreSetting[CoreId].ChannelType != 0) { + //Set Trasmitter drive strength based on cahnnel type + if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieLongChannel) { + pPcieConfig->CoreSetting[CoreId].TxDriveStrength = (NbInfo.Revision == NB_REV_A11)? PcieTxDriveStrangth24mA : PcieTxDriveStrangth26mA; + } else { + pPcieConfig->CoreSetting[CoreId].TxDriveStrength = PcieTxDriveStrangth22mA; + } + // Enable half swing mode + if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieShortChannel) { + pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode = ON; + } else { + pPcieConfig->CoreSetting[CoreId].TxHalfSwingMode = OFF; + } + } + } + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + CoreId = PcieLibGetCoreId (PortId, pConfig); + if (pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit == 0) { + pPcieConfig->ExtPortConfiguration[PortId].PortPowerLimit = 75; //Set 75W by default + } + if (pPcieConfig->CoreSetting[CoreId].ChannelType != 0) { + if (pPcieConfig->CoreSetting[CoreId].ChannelType == PcieLongChannel) { + pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis6dB; + } else { + pPcieConfig->ExtPortConfiguration[PortId].PortDeemphasis = PcieTxDeemphasis3p5dB; + } + } + } + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable PCIE Extended configuration MMIO. + * + * + * + * @param[in] PcieMmioBase MMIO Base Address in 1MB unit. + * @param[in] PcieMmioSize MMIO Size in 1MB unit + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieLibSetPcieMmioBase ( + IN UINT16 PcieMmioBase, + IN UINT16 PcieMmioSize, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 BAR3BusRange; + + BAR3BusRange = LibAmdBitScanReverse ((UINT32)PcieMmioSize); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessWidth32, (UINT32)~BIT3, 0x0, pConfig); + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG7F, AccessWidth8, (UINT32)~BIT6, BIT6, pConfig); + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | (NB_PCI_REG84 + 2), AccessWidth8, (UINT32)~(0x7), (BAR3BusRange > 8)?0:BAR3BusRange, pConfig); + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG1C, AccessWidth32, 0, (UINT32) (PcieMmioBase << 20), pConfig); + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG7F, AccessWidth8, (UINT32)~BIT6, 0, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG32, AccessWidth32, 0xffffffff, BIT28, pConfig); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG00, AccessWidth32, 0xffffffff, BIT3, pConfig); + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | NB_PCI_REG04, AccessWidth8, (UINT32)~BIT1, BIT1, pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Assert/Deassert Strap valid enables programming for misc strap features. + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] Operation Assert or deassert strap valid. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieLibStrapModeControl ( + IN CORE CoreId, + IN PCIE_STRAP_MODE Operation, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + CORE_INFO *pCoreInfo; + + pCoreInfo = PcieLibGetCoreInfo (CoreId, pConfig); + LibNbPciIndexRMW ( + pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, + pCoreInfo->StrapRegister, + AccessS3SaveWidth32, + ~(1 << pCoreInfo->StrapAddress), + (Operation == PcieCoreStrapConfigStart)?(1 << pCoreInfo->StrapAddress):0, + pConfig + ); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Pcie Port Info. + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +PORT_INFO* +PcieLibGetPortInfo ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + UINT32 CoreConfig; + PORT_INFO *pPortInfo; + PORT NativePortId; + GPP_CFG_INFO *pGppCfgInfoTable; + + CoreId = PcieLibGetCoreId (PortId, pConfig); + CoreConfig = PcieLibGetCoreConfiguration (CoreId, pConfig); + switch (PcieLibGetCoreAddress (CoreId, pConfig)) { + case GPP1_CORE: + case GPP2_CORE: + pPortInfo = &pGfxPortFullA; + if (CoreConfig == GFX_CONFIG_AABB) { + if (PortId == 3 || PortId == 12) { + pPortInfo = &pGfxPortB; + } else { + pPortInfo = &pGfxPortA; + } + } + break; + case SB_CORE: + case GPP3b_CORE: + pPortInfo = &pGpp420000[0]; + break; + case GPP3a_CORE: + pGppCfgInfoTable = (GPP_CFG_INFO*)FIX_PTR_ADDR (&GppCfgInfoTable[CoreConfig - 1], NULL); + NativePortId = PcieLibNativePortId (PortId, pConfig); + if (NativePortId == 0xf) { + return NULL; + } + pPortInfo = &pGppCfgInfoTable->PortInfoPtr[NativePortId - 4]; + break; + default: + return NULL; + } + return (PORT_INFO*)FIX_PTR_ADDR (pPortInfo, NULL); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Pointer to static port info + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +PORT_STATIC_INFO* +PcieLibGetStaticPortInfo ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + PORT_STATIC_INFO *pPortStaticInfo; + + pPortStaticInfo = (PORT_STATIC_INFO*)FIX_PTR_ADDR (&PortInfoTable[PortId - MIN_PORT_ID], NULL); + return pPortStaticInfo ; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Native Port Id. + * Native Port Id can be different from Port ID only on GPPSB core ports. + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +PORT +PcieLibNativePortId ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + CORE CoreId; + GPP_CFG_INFO *pGppCfgInfoTable; + + CoreId = PcieLibGetCoreId (PortId, pConfig); + if (PcieLibGetCoreAddress (CoreId, pConfig) == GPP3a_CORE) { + UINT32 CoreConfig; + CoreConfig = PcieLibGetCoreConfiguration (CoreId, pConfig); + pGppCfgInfoTable = (GPP_CFG_INFO*)FIX_PTR_ADDR (&GppCfgInfoTable[CoreConfig - 1], NULL); + return (pGppCfgInfoTable->PortIdMap >> ((PortId - 4) * 4)) & 0xF; + } else { + return PortId; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get pointer to Core info structure. + * + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +CORE_INFO* +PcieLibGetCoreInfo ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + return (CORE_INFO*)FIX_PTR_ADDR (&CoreInfoTable[CoreId], NULL); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Reset Device in slot. + * Check if slot has controlled by GPI reset. If support toggle reset for 10us. + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +AGESA_STATUS +PcieLibResetSlot ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + + Status = LibNbCallBack (PHCB_AmdPortResetSupported, (UINTN) (1 << PortId), pConfig); + if (Status == AGESA_SUCCESS) { + LibNbCallBack (PHCB_AmdPortResetAssert, (UINTN) (1 << PortId), pConfig); + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 10, 0); + LibNbCallBack (PHCB_AmdPortResetDeassert, (UINTN) (1 << PortId), pConfig); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Secondary level interface to check if Gen2 disabled. + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +BOOLEAN +PcieLibCheckGen2Disabled ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + SCRATCH_1 Scratch; + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); + if ((Scratch.PortGen2Disable & (1 << (PortId - 2))) != 0) { + return FALSE; + } else { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Force Gen2 Disable\n")); + return TRUE; + } +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Request Gen 2 disabled on next boot. + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +VOID +PcieLibSetGen2Disabled ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *pConfig + ) +{ + SCRATCH_1 Scratch; + + LibNbPciIndexRead (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); + Scratch.PortGen2Disable &= (~(1 << (PortId - 2))); + LibNbPciIndexWrite (pConfig->NbPciAddress.AddressValue | NB_HTIU_INDEX, NB_HTIU_REG15, AccessS3SaveWidth32, (UINT32*)&Scratch, pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Force link to compliance mode + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +PcieLibSetLinkCompliance ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCI_ADDR Port; + PCIE_CONFIG *pPcieConfig; + + Port = PcieLibGetPortPciAddress (PortId, pConfig); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + if (pPcieConfig->PortConfiguration[PortId].PortLinkMode == PcieLinkModeGen1) { + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGC0, AccessWidth32, (UINT32)~BIT13, BIT13, pConfig); + } else { + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, (UINT32)~BIT4, BIT4, pConfig); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCIe device type + * + * + * + * @param[in] Device PCI address of device. + * @param[in] pConfig Northbridge configuration structure pointer. + * + * @retval PCIe device type (see PCIE_DEVICE_TYPE) + */ + /*----------------------------------------------------------------------------------------*/ + +PCIE_DEVICE_TYPE +PcieGetDeviceType ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT8 PcieCapPtr; + UINT8 Value; + + PcieCapPtr = LibNbFindPciCapability (Device.AddressValue, PCIE_CAP_ID, pConfig); + if (PcieCapPtr != 0) { + LibNbPciRead (Device.AddressValue | (PcieCapPtr + 0x2) , AccessWidth8, &Value, pConfig); + return Value >> 4; + } + return PcieNotPcieDevice; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get bitmap of cores that have active or potentially active ports + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + * @retval Bitmap of cores + */ + /*----------------------------------------------------------------------------------------*/ + +UINT8 +PcieLibGetActiveCoreMap ( + IN AMD_NB_CONFIG *pConfig + ) +{ + PORT PortId; + CORE CoreId; + UINT8 ActiveCoreMap; + PCIE_CONFIG *pPcieConfig; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + ActiveCoreMap = 0; + //Check through Ports + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PcieLibIsValidPortId (PortId, pConfig)) { + if (pPcieConfig->PortConfiguration[PortId].PortCompliance == ON || + pPcieConfig->PortConfiguration[PortId].PortDetected == ON || + pPcieConfig->PortConfiguration[PortId].PortHotplug != OFF) { + CoreId = PcieLibGetCoreId (PortId, pConfig); + ActiveCoreMap |= (1 << CoreId); + } + } + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Active Core Map = %x\n", ActiveCoreMap)); + return ActiveCoreMap; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c new file mode 100644 index 000000000000..ec3ec80f7e48 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.c @@ -0,0 +1,160 @@ +/** + * @file + * + * PCIe link width control. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * Set Pcie Link Width + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] LinkWidth New Link Width + * @param[in] pConfig Northbridge configuration structure pointer. + */ +AGESA_STATUS +PcieLibSetLinkWidth ( + IN PORT PortId, + IN PCIE_LINK_WIDTH LinkWidth, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PCIE_LINK_WIDTH NewLinkWidth; + PCIE_LINK_WIDTH CurrentLinkWidth; + + Status = AGESA_SUCCESS; + NewLinkWidth = LinkWidth; + CurrentLinkWidth = PcieLibGetLinkWidth (PortId, pConfig); + if (NewLinkWidth == 0 || NewLinkWidth > CurrentLinkWidth) { + NewLinkWidth = CurrentLinkWidth; + } + if (NewLinkWidth == PcieLinkWidth_x12) { + NewLinkWidth = PcieLinkWidth_x8; + } + if (NewLinkWidth < CurrentLinkWidth) { + CORE CoreId; + UINT32 Value; + UINT32 CoreAddress; + BOOLEAN PoolPortStatus; + PCI_ADDR Port; + + CoreId = PcieLibGetCoreId (PortId, pConfig); + CoreAddress = PcieLibGetCoreAddress (CoreId, pConfig); + PoolPortStatus = TRUE; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + LibNbPciIndexRMW (NB_SBDFO | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessWidth32, (UINT32)~BIT0, BIT0, pConfig); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, 0xfffffff8, (NewLinkWidth) | BIT8 | BIT7, pConfig); + while (PoolPortStatus) { + LibNbPciRead (Port.AddressValue | NB_PCIP_REG6A, AccessWidth16, &Value, pConfig); + if ((Value & BIT11) == 0) { + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig); + if ((Value & BIT8) == 0) { + LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &Value, pConfig); + if ((Value & BIT1) == 0) { + PoolPortStatus = FALSE; + } + } + } + } + LibNbPciIndexRMW (NB_SBDFO | NB_BIF_INDEX, NB_BIFNB_REG40 | CoreAddress, AccessWidth32, (UINT32)~BIT0, 0 , pConfig); + LibNbPciIndexRMW (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, (UINT32)~BIT7, 0, pConfig); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Return link with + * + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +PCIE_LINK_WIDTH +PcieLibGetLinkWidth ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_LINK_WIDTH LinkWidth; + UINT32 Value; + PCI_ADDR Port; + + Port = PcieLibGetPortPciAddress (PortId, pConfig); +// Read current link State + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &Value, pConfig); + if ((Value & 0x3f) == 0x10) { + //Read current link width + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, pConfig); + LinkWidth = (Value >> 4) & 0xf; + } else { + //Link not in L0 + LinkWidth = PcieLinkWidth_x0; + } + return LinkWidth; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h new file mode 100644 index 000000000000..8eab54172cd5 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieLinkWidth.h @@ -0,0 +1,60 @@ +/** + * @file + * + * PCIe link width control. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBPCIELINKWIDTH_H_ +#define _NBPCIELINKWIDTH_H_ + +AGESA_STATUS +PcieLibSetLinkWidth ( + IN PORT PortId, + IN PCIE_LINK_WIDTH LinkWidth, + IN AMD_NB_CONFIG *pConfig + ); + +PCIE_LINK_WIDTH +PcieLibGetLinkWidth ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePllControl.c b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.c new file mode 100644 index 000000000000..ec2206bfca62 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.c @@ -0,0 +1,193 @@ +/** + * @file + * + * PCIe Port device number remapping. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +SCAN_STATUS +PciePllOffCheckFunction ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Function + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if EP allowed exit latency allowed PLL in L1 to be disabled on non hotplug ports. + * + * + * @param[in] CoreId CoreId + * @param[in] pConfig Northbridge configuration structure pointer. + */ +BOOLEAN +PciePllOffComatibilityTest ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ) +{ + PLLOFF_WORKSPACE PllOffWorkspace; + PORT PortId; + BOOLEAN Result; + PCIE_CONFIG *pPcieConfig; + BOOLEAN IsHotplugPorst; + BOOLEAN IsNonHotplugPorts; + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePllOffInL1ComatibilityTest Enter Core [%d]\n", CoreId)); + LibAmdMemFill (&PllOffWorkspace, 0, sizeof (PllOffWorkspace), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + PllOffWorkspace.ScanPciePort.pConfig = pConfig; + PllOffWorkspace.ScanPciePort.ScanBus = LibNbScanPciBus; + PllOffWorkspace.ScanPciePort.ScanDevice = LibNbScanPciDevice; + PllOffWorkspace.ScanPciePort.ScanFunction = PciePllOffCheckFunction; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig) && PcieLibGetCoreId (PortId, pConfig) == CoreId) { + if (pPcieConfig->PortConfiguration[PortId].PortHotplug == ON) { + IsHotplugPorst = TRUE; + continue; // Skip hotplug ports . Will make decision later. + } + if (pPcieConfig->PortConfiguration[PortId].PortDetected == ON) { + PCI_ADDR Port; + IsNonHotplugPorts = TRUE; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + PllOffWorkspace.ScanPciePort.ScanFunction (&PllOffWorkspace.ScanPciePort, Port); + } + } + } + if (PllOffWorkspace.MaxL1Latency != 0 && PllOffWorkspace.MaxL1Latency < 34) { + Result = FALSE; + } else { + Result = TRUE; + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePllOffInL1ComatibilityTest Exit [%d]\n", Result)); + return Result; +} + +/**----------------------------------------------------------------------------------------*/ +/** + * Scan PCIe topology + * + * + * + * @param[in] This Pointer to instance of scan protocol + * @param[in] Function PCI address of found device/function. + * + * @retval SCAN_FINISHED Scan for device finished. + */ + /*----------------------------------------------------------------------------------------*/ +SCAN_STATUS +PciePllOffCheckFunction ( + IN PCI_SCAN_PROTOCOL *This, + IN PCI_ADDR Function + ) +{ + PLLOFF_WORKSPACE *WorkspacePtr; + PCIE_DEVICE_TYPE DeviceType; + UINT8 SecondaryBus; + PCI_ADDR Port; + + WorkspacePtr = (PLLOFF_WORKSPACE*) This; + DeviceType = PcieGetDeviceType (Function, This->pConfig); + if (DeviceType == PcieDeviceRootComplex || DeviceType == PcieDeviceDownstreamPort) { + WorkspacePtr->LinkCount++; + //Lets enable Common clock + LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig); + if (SecondaryBus == 0) { + return SCAN_FINISHED; + } + Port.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0); + This->ScanBus (This, Port); + WorkspacePtr->LinkCount--; + } else if (DeviceType == PcieDeviceUpstreamPort ) { + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached upstream port\n")); + LibNbPciRead (Function.AddressValue | 0x19, AccessWidth8, &SecondaryBus, This->pConfig); + if (SecondaryBus == 0) { + return SCAN_FINISHED; + } + Port.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0); + This->ScanBus (This, Port); + } else if (DeviceType <= PcieDeviceLegacyEndPoint) { + // We reach end of the link + UINT8 PcieCapPtr; + UINT32 Value; + UINT8 L1AcceptableLatency; + PcieCapPtr = LibNbFindPciCapability (Function.AddressValue, PCIE_CAP_ID, This->pConfig); + if (PcieCapPtr != 0) { + LibNbPciRead (Function.AddressValue | (PcieCapPtr + 0x0D) , AccessWidth8, &Value, This->pConfig); + if (((Value >> 2) & ASPM_L1) != 0) { + LibNbPciRead ((Function.AddressValue | (PcieCapPtr + 4)), AccessWidth32, &Value, This->pConfig); + L1AcceptableLatency = ((UINT8) (1 << ((Value >> 9) & 0x7)) & 0x7F); + if (WorkspacePtr->LinkCount > 1) { + L1AcceptableLatency = L1AcceptableLatency + WorkspacePtr->LinkCount; + } + if (WorkspacePtr->MaxL1Latency < L1AcceptableLatency) { + WorkspacePtr->MaxL1Latency = L1AcceptableLatency; + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (This->pConfig), CIMX_NBPCIE_TRACE), " Reached end of link at 0x%x with Acceptable Exit Latency %dus \n", Function.AddressValue, L1AcceptableLatency)); + } + } + } + return SCAN_FINISHED; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePllControl.h b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.h new file mode 100644 index 000000000000..44193a528cb4 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPciePllControl.h @@ -0,0 +1,63 @@ +/** + * @file + * + * PLL off in L1 support. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +#ifndef _NBPLLCONTROL_H_ +#define _NBPLLCONTROL_H_ + +BOOLEAN +PciePllOffComatibilityTest ( + IN CORE CoreId, + IN AMD_NB_CONFIG *pConfig + ); + + +#pragma pack (push, 1) +/// Framework for testing for ability to diable PLL in L1 +typedef struct { + PCI_SCAN_PROTOCOL ScanPciePort; ///< PCI scan protocol + PCI_ADDR DownstreamPort; ///< Downstream port to enable ASPM + UINT8 MaxL1Latency; ///< TBD + UINT8 LinkCount; ///< TBD +} PLLOFF_WORKSPACE; + +#pragma pack (pop) +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c new file mode 100644 index 000000000000..639f1495655e --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.c @@ -0,0 +1,182 @@ +/** + * @file + * + * PCIe Port device number remapping. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +PORT +STATIC +PciePortRemapAllocateDeviceId ( + IN UINT8 *UnusedPortMap +); +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Remap PCIe ports device number. + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +AGESA_STATUS +PciePortRemapInit ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + PORT FinalDeviceIdList[MAX_PORT_ID + 1]; + UINT8 UsedDeviceIdMap[MAX_PORT_ID + 1]; + BOOLEAN IsDeviceRemapEnabled; + PORT PortId; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePortDeviceNumberRemap Enter \n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + Status = AGESA_SUCCESS; + IsDeviceRemapEnabled = FALSE; + // Remap Device + LibAmdMemFill (&UsedDeviceIdMap, 0, sizeof (UsedDeviceIdMap), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + LibAmdMemFill (&FinalDeviceIdList, 0, sizeof (FinalDeviceIdList), (AMD_CONFIG_PARAMS *)&(pConfig->sHeader)); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (PcieLibIsValidPortId (PortId, pConfig)) { + PORT NativePortId = PcieLibNativePortId (PortId, pConfig); + if (pPcieConfig->PortConfiguration[PortId].PortPresent) { + //FinalDeviceIdList[PortId] = PortId; + if (pPcieConfig->ExtPortConfiguration[PortId].PortMapping != 0) { + if (pPcieConfig->ExtPortConfiguration[PortId].PortMapping < MIN_PORT_ID || + pPcieConfig->ExtPortConfiguration[PortId].PortMapping > MAX_PORT_ID || + pPcieConfig->ExtPortConfiguration[PortId].PortMapping == 8) { + return AGESA_ERROR; + } + FinalDeviceIdList[NativePortId] = pPcieConfig->ExtPortConfiguration[PortId].PortMapping; + IsDeviceRemapEnabled = TRUE; + } else { + FinalDeviceIdList[NativePortId] = PortId; + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Requested Port Mapping %d -> %d\n", PortId, FinalDeviceIdList[PortId])); + if (UsedDeviceIdMap[FinalDeviceIdList[NativePortId]] == 0 ) { + UsedDeviceIdMap[FinalDeviceIdList[NativePortId]] = 1; + } else { + return AGESA_ERROR; + } + } + } + } + if (!IsDeviceRemapEnabled) { + return Status; + } + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + PORT_STATIC_INFO *pStaticPortInfo; + pStaticPortInfo = PcieLibGetStaticPortInfo (PortId, pConfig); + if (pStaticPortInfo->MappingAddress == 0xFF) { + continue; + } + if (FinalDeviceIdList[PortId] == 0) { + FinalDeviceIdList[PortId] = PciePortRemapAllocateDeviceId (&UsedDeviceIdMap[0]); + } + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Port Mapping %d -> %d\n", PortId, FinalDeviceIdList[PortId])); + LibNbPciIndexRMW ( + NB_SBDFO | NB_MISC_INDEX, + (PortId > 9)?NB_MISC_REG21:NB_MISC_REG20, + AccessWidth32, + 0xffffffff, + FinalDeviceIdList [PortId] << pStaticPortInfo->MappingAddress, + pConfig + ); + + } + LibNbPciIndexRMW (NB_SBDFO | NB_MISC_INDEX, NB_MISC_REG20, AccessWidth32, 0xffffffff, 0x3, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PciePortDeviceNumberRemap Exit [0x%x] \n", Status)); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate Device number from unused port array. + * + * + * + * @param[in] UnusedPortMap Unused port array. + */ + +PORT +STATIC +PciePortRemapAllocateDeviceId ( + IN UINT8 *UnusedPortMap + ) +{ + PORT PortId; + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (UnusedPortMap[PortId] == 0) { + UnusedPortMap[PortId] = 1; + break; + } + } + return PortId; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h new file mode 100644 index 000000000000..32236f07a07b --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPciePortRemap.h @@ -0,0 +1,52 @@ +/** + * @file + * +* PCIe Port device number remapping. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBPCIEPORTREMAP_H_ +#define _NBPCIEPORTREMAP_H_ + +AGESA_STATUS +PciePortRemapInit ( + IN AMD_NB_CONFIG *pConfig + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c b/src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c new file mode 100644 index 000000000000..918fbd43f140 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieRecovery.c @@ -0,0 +1,753 @@ +/** + * @file + * + * PCIe in recovery support + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +VOID +PcieRecoveryCoreInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +VOID +PcieRecoveryPortTraining ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ); + +VOID +PcieRecoveryCommonPortInit ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +PcieRecoveryCommonCoreInit ( + IN CORE CoreId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +UINT32 +PcieRecoveryGetCoreAddress ( + IN CORE CoreId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +PCI_ADDR +PcieRecoveryGetPortPciAddress ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +PcieRecoveryPcieCheckPorts ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +VOID +PcieRecoveryReleaseTraining ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ); + +PORT +PcieRecoveryNativePortId ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +/*----------------------------------------------------------------------------------------*/ +/** + * PCIE Recovery Init. Basic programming / EP training. + * After this call EP are fully operational. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ +AGESA_STATUS +AmdPcieEarlyInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ +#ifdef PCIE_RECOVERY_SUPPORT + PcieRecoveryCoreInit (ConfigPtr); + PcieRecoveryPortTraining (ConfigPtr); +#endif + return AGESA_SUCCESS; +} + + +#ifdef PCIE_RECOVERY_SUPPORT + +INDIRECT_REG_ENTRY +STATIC +PcieRecoveryMiscInitTable[] = { + { + NB_MISC_REG0C, + (UINT32)~0x001f00FC, + 0x00000000 + }, + { + NB_MISC_REG20, + (UINT32)~BIT1, + 0x0 + }, //enable static device remapping by default + { + NB_MISC_REG22, + 0xffffffff, + BIT27 + }, //[10]CMGOOD_OVERRIDE for all 5 pcie cores. + { + NB_MISC_REG6B, + 0xffffffff, + (UINT32) (0x1f << 27) + }, //[13][12]Turn Off Offset Cancellation + { + NB_MISC_REG37, + (UINT32)~(BIT11 + BIT12 + BIT13), + 0x0 + }, //[14][13]Disables Rx Clock gating in CDR + { + NB_MISC_REG67, + (UINT32)~(BIT26 + BIT10 + BIT11), + BIT11 + }, //[13]Disables Rx Clock gating in CDR + { + NB_MISC_REG2C, + (UINT32)~(BIT10), + 0x0 + }, //[13]Disables Rx Clock gating in CDR + { + NB_MISC_REG2A, + (UINT32)~(BIT17 + BIT16), + BIT17 + }, //[16]Sets Electrical l Idle Threshold + { + NB_MISC_REG32, + (UINT32)~(0x3F << 20), + (UINT32) (0x2A << 20) + }, //[17][16]Sets Electrical Idle Threshold + { + NB_MISC_REG28, + 0xffffff00, + 0x0 + }, + { + NB_MISC_REG27, + 0x3fffffff, + 0x0 + }, + { + NB_MISC_REG2D, + (UINT32)~(BIT5), + 0x0 + } +}; + +// 2 3 4 5 6 7 8 9 A B C D +UINT8 PortToCoreMappingTable[] = { 0xff, 0xff, 0, 0, 3, 3, 3, 3, 4, 3, 3, 1, 1, 3 }; + +/*----------------------------------------------------------------------------------------*/ +/** + * Minimum core initialization + * + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +VOID +PcieRecoveryCoreInit ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + CORE CoreId; + PORT PortId; + AMD_NB_CONFIG *NbConfigPtr; + PCIE_CONFIG *pPcieConfig; + + NbConfigPtr = &ConfigPtr->Northbridges[0]; + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); +//Init Misc registers + LibNbIndirectTableInit ( + NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryMiscInitTable[0],NULL), + (sizeof (PcieRecoveryMiscInitTable) / sizeof (INDIRECT_REG_ENTRY)), + NbConfigPtr + ); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON) { + pPcieConfig->CoreSetting[PortToCoreMappingTable[PortId]].CoreDisabled = OFF; + } + } + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + if (pPcieConfig->CoreSetting[CoreId].CoreDisabled == OFF) { + //Init core registers and configuration + PcieRecoveryCommonCoreInit (CoreId, NbConfigPtr); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Port link training initialization + * + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +VOID +PcieRecoveryPortTraining ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + PORT PortId; + UINT32 PortToHideMap; + AMD_NB_CONFIG *NbConfigPtr; + PCIE_CONFIG *pPcieConfig; + + PortToHideMap = 0; + NbConfigPtr = &ConfigPtr->Northbridges[0]; + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON) { + PcieRecoveryCommonPortInit (PortId, NbConfigPtr); + if (LibNbCallBack (PHCB_AmdPortResetDeassert, 1 << PortId, NbConfigPtr) == AGESA_SUCCESS) { + STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), pPcieConfig->ResetToTrainingDelay, 0); + } + if (PortId != 8) { + PcieRecoveryReleaseTraining (PortId, NbConfigPtr); + } + } + } + STALL (GET_BLOCK_CONFIG_PTR (pConfig), pPcieConfig->ReceiverDetectionPooling, 0); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + PCI_ADDR Port; + Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr); + if (pPcieConfig->PortConfiguration[PortId].PortPresent == ON && PortId != 8) { + PcieRecoveryPcieCheckPorts (PortId, NbConfigPtr); + + pPcieConfig->PortConfiguration[PortId].PortLinkMode = PcieLinkModeGen1; + + LibNbPciIndexWrite ( + Port.AddressValue | NB_BIF_INDEX, + NB_BIFNBP_REG01, + AccessWidth32, + (UINT32*)&pPcieConfig->PortConfiguration[PortId], + NbConfigPtr + ); + } + if (pPcieConfig->PortConfiguration[PortId].PortDetected == OFF) { + PortToHideMap |= (1 << PortId); + } + } + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0C, AccessWidth32, 0xffffffff, (PortToHideMap & 0xFC) | ((PortToHideMap & 0x3E00) << 7), NbConfigPtr); +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check link training Status + * + * + * + * + * @param[in] Config Northbridges configuration structure pointer. + * + */ +VOID +PcieRecoveryPcieCheckPorts ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCIE_CONFIG *pPcieConfig; + PCI_ADDR Port; + UINT32 LinkState; + UINT32 LinkStatePooling; + UINT32 Value; + + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); + Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr); + LinkStatePooling = pPcieConfig->ReceiverDetectionPooling; + do { + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCoreInit PortId = %d LinkState 0x%x\n", PortId, LinkState)); + LinkState &= 0x3F; + if (LinkState == 0x10) { + UINT16 VcoStatus; + BOOLEAN VcoNotCompleted; + UINT32 VcoPooling; + VcoNotCompleted = TRUE; + VcoPooling = 6000; + do { + LibNbPciRead (Port.AddressValue | NB_PCIP_REG12A, AccessWidth16, &VcoStatus, NbConfigPtr); + if (VcoStatus & BIT1) { + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, NbConfigPtr); + Value = (Value & 0xfffffe80) | ((Value & 0x70) >> 4) | BIT8; + LibNbPciIndexWrite (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA2, AccessWidth32, &Value, NbConfigPtr); + STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 5000, 0); + } else { + VcoNotCompleted = FALSE; + } + } while (VcoNotCompleted || --VcoPooling != 0); + if (!VcoNotCompleted) { + pPcieConfig->PortConfiguration[PortId].PortDetected = ON; + } + } else { + STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 1000, 0); + } + } while (LinkState != 0x10 && --LinkStatePooling != 0); +} + + +UINT8 PortTrainingOffset[] = { + 4, 5, 21, 22, 23, 24, 20, 25, 26, 6, 7 , 4 +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Check link training Status + * + * + * + * + * @param[in] Config Northbridges configuration structure pointer. + * + */ +VOID +PcieRecoveryReleaseTraining ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PORT NativePortId; + + NativePortId = PcieRecoveryNativePortId (PortId, NbConfigPtr); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryReleaseTraining PortId = %d NativeId %d BitOfset %d\n", + PortId, NativePortId, ((UINT8*)FIX_PTR_ADDR (&PortTrainingOffset[0], NULL))[NativePortId - MIN_PORT_ID])); + LibNbPciIndexRMW ( + NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, + (PortId == 13)? NB_MISC_REG2A:NB_MISC_REG08, + AccessWidth32, + ~(1 << ((UINT8*)FIX_PTR_ADDR (&PortTrainingOffset[0], NULL))[NativePortId - MIN_PORT_ID]), + 0, + NbConfigPtr + ); +} + +INDIRECT_REG_ENTRY PcieRecoveryPortInitTable[] = { + { + NB_BIFNBP_REG02, + (UINT32)~(BIT15), + BIT15 + }, + { + NB_BIFNBP_REGA1, + (UINT32)~(BIT24), + BIT11 + }, + { + NB_BIFNBP_REGB1, + 0xffffffff, + BIT28 + BIT23 + BIT19 + BIT20 + }, + { + NB_BIFNBP_REGA4, + (UINT32)~(BIT0), + 0x0 + }, + { + NB_BIFNBP_REGA2, + (UINT32)~(BIT13), + BIT13 + }, + { + NB_BIFNBP_REGA3, + (UINT32)~(BIT9), + BIT9 + }, + { + NB_BIFNBP_REGA0, + 0xffff00ff, + 0x6130 + }, + { + NB_BIFNBP_REG70, + (UINT32)~(BIT16 + BIT17 + BIT18), + BIT16 + BIT18 + }, + // Set Link for Gen1 + { + NB_BIFNBP_REGC0, + (UINT32)~(BIT15), + BIT15 + }, + { + NB_BIFNBP_REGA2, + (UINT32)~(BIT13), + BIT13 + }, + { + NB_BIFNBP_REGA4, + (UINT32)~(BIT0 + BIT29), + 0x0 + } +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Port basic register init + * + * + * + * + * @param[in] Config Northbridges configuration structure pointer. + * + */ + +VOID +PcieRecoveryCommonPortInit ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR Port; + + Port = PcieRecoveryGetPortPciAddress (PortId, NbConfigPtr); + LibNbIndirectTableInit ( + Port.AddressValue | NB_BIF_INDEX, + 0x0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryPortInitTable[0],NULL), + (sizeof (PcieRecoveryPortInitTable) / sizeof (INDIRECT_REG_ENTRY)), + NbConfigPtr + ); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG80, AccessWidth8, 0xF0, 0x6, NbConfigPtr); + LibNbPciRMW (Port.AddressValue | NB_PCIP_REG88, AccessWidth8, 0xF0, 0x0, NbConfigPtr); +} + + +UINT8 GppConfigTable[] = { + 0x0, 0x1, 0x2, 0xC, 0xA, 0x4, 0xB +}; + +INDIRECT_REG_ENTRY PcieRecoveryCoreInitTable[] = { + { + NB_BIFNB_REG10, + (UINT32)~(BIT10 + BIT11 + BIT12), + BIT12 + }, + { + NB_BIFNB_REG20, + (UINT32)~(BIT8 + BIT9), + BIT9 + }, + { + NB_BIFNB_REG02, + (UINT32)~(BIT0), + BIT0 + }, + { + NB_BIFNB_REG40, + (UINT32)~(BIT14 + BIT15), + BIT15 + }, + { + NB_BIFNB_REGC1, + (UINT32)~(BIT0), + (BIT0 + BIT1 + BIT2) + }, + { + NB_BIFNB_REG1C, + 0x0, + (4 << 6) + (4 << 1) + 1 + } +}; +/*----------------------------------------------------------------------------------------*/ +/** + * Core basic register init + * + * + * + * + * @param[in] Config Northbridges configuration structure pointer. + * + */ + +VOID +PcieRecoveryCommonCoreInit ( + IN CORE CoreId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 CoreAddress; + PCIE_CONFIG *pPcieConfig; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCommonCoreInit CoreID = %d Enter\n", CoreId)); + CoreAddress = PcieRecoveryGetCoreAddress (CoreId, NbConfigPtr); + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); + //Setup GPP1 core configuration + if (CoreAddress == GPP1_CORE && (pPcieConfig->CoreConfiguration[0] == GFX_CONFIG_AABB || NbConfigPtr->pPcieConfig->PortConfiguration[3].PortPresent == ON)) { + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, 0xffffffff, BIT15, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, BIT28, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT8, NbConfigPtr); + STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 2000, 0); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, 0x0, NbConfigPtr); + } + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, (UINT32)~BIT15, 0x0, NbConfigPtr); + //Setup GPP2 core configuration + if (CoreAddress == GPP2_CORE && (pPcieConfig->CoreConfiguration[1] == GFX_CONFIG_AABB || NbConfigPtr->pPcieConfig->PortConfiguration[12].PortPresent == ON)) { + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, 0xffffffff, BIT13, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT28, BIT29, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT9, NbConfigPtr); + STALL (GET_BLOCK_CONFIG_PTR (NbConfigPtr), 2000, 0); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT29, 0x0, NbConfigPtr); + } + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08 , AccessWidth32, (UINT32)~BIT13, 0x0, NbConfigPtr); + //Setup GPP core configuration + if (CoreAddress == GPP3a_CORE) { + UINT32 Mux; + UINT8 *pGppConfigTable; + Mux = 0; + pGppConfigTable = (UINT8*)FIX_PTR_ADDR (&GppConfigTable[0], NULL); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, 0xffffffff, BIT31, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT30, BIT30, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG67, AccessWidth32, 0xfffffff0, (UINT32)pGppConfigTable[pPcieConfig->CoreConfiguration[CoreId]], NbConfigPtr); + switch (pPcieConfig->CoreConfiguration[CoreId]) { + case GPP_CONFIG_GPP420000: + Mux = (pPcieConfig->PortConfiguration[6].PortReversed == ON)?0xF05BA00:0x055B000; + break; + case GPP_CONFIG_GPP411000: + Mux = 0x215B400; + break; + case GPP_CONFIG_GPP222000: + case GPP_CONFIG_GPP211110: + Mux = (pPcieConfig->PortConfiguration[4].PortReversed == ON)?0xFFF0AAA:0xFF0BAA0; + break; + case GPP_CONFIG_GPP221100: + Mux = 0x215B400; + break; + case GPP_CONFIG_GPP111111: + Mux = 0x2AA3554; + break; + } + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, 0xf0000000, Mux, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG26, AccessWidth32, (UINT32)~BIT30, 0x0, NbConfigPtr); + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG08, AccessWidth32, (UINT32)~BIT31, 0x0, NbConfigPtr); + } + if (CoreAddress == GPP3b_CORE) { + LibNbPciIndexRMW (NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG2A, AccessWidth32, (UINT32)~BIT15, 0, NbConfigPtr); + } + LibNbIndirectTableInit ( + NbConfigPtr->NbPciAddress.AddressValue | NB_BIF_INDEX, + CoreAddress, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&PcieRecoveryCoreInitTable[0],NULL), + (sizeof (PcieRecoveryCoreInitTable) / sizeof (INDIRECT_REG_ENTRY)), + NbConfigPtr + ); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieRecoveryCommonCoreInit Exitr\n")); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Core register selector. + * Function return selector to access BIFNB register space for selected core + * + * + * @param[in] CoreId PCI Express Core ID + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +UINT32 +PcieRecoveryGetCoreAddress ( + IN CORE CoreId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 CoreAddress; + CoreAddress = GPP1_CORE; + switch (CoreId) { + case 0x0: + CoreAddress = GPP1_CORE; + break; + case 0x1: + CoreAddress = GPP2_CORE; + break; + case 0x2: + CoreAddress = GPP3a_CORE; + break; + case 0x3: + CoreAddress = GPP3b_CORE; + break; + case 0x4: + CoreAddress = SB_CORE; + break; + default: + CIMX_ASSERT (FALSE); + } + return CoreAddress; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get PCI address of Port. + * Function return pcie Address based on port mapping and core configuration. + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +PCI_ADDR +PcieRecoveryGetPortPciAddress ( + IN PORT PortId, + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCI_ADDR Port; + Port = NbConfigPtr->NbPciAddress; + Port.Address.Device = PortId; + return Port; +} + +UINT32 GppNativeIdTable[] = { + 0xff50fff4, + 0xf650fff4, + 0xff60f5f4, + 0xf760f5f4, + 0xf87065f4, + 0xf9807654 +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Native Port Id. + * Native Port Id can be different from Port ID only on GPPSB core ports. + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ + +PORT +PcieRecoveryNativePortId ( + IN PORT PortId, + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + UINT32 GppNativeIdMap; + if (PortId > 3 && PortId < 11) { + GppNativeIdMap = ((UINT32*)FIX_PTR_ADDR (&GppNativeIdTable[0], NULL))[NbConfigPtr->pPcieConfig->CoreConfiguration[0x2] - 1]; + return (GppNativeIdMap >> ((PortId - 4)*4)) & 0xF; + } else { + return PortId; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize default PCIE_CONFIG setting + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +PcieRecoveryInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + PCIE_CONFIG *pPcieConfig; + CORE CoreId; + pPcieConfig = GET_PCIE_CONFIG_PTR (NbConfigPtr); + if (pPcieConfig == NULL) { + return AGESA_FATAL; + } + LibAmdMemFill (pPcieConfig, 0, sizeof (PCIE_CONFIG), (AMD_CONFIG_PARAMS *)NbConfigPtr); + pPcieConfig->ReceiverDetectionPooling = 120; + pPcieConfig->ResetToTrainingDelay = 4; + for (CoreId = 0; CoreId <= MAX_CORE_ID; CoreId++) { + pPcieConfig->CoreSetting[CoreId].CoreDisabled = ON; + } + return AGESA_SUCCESS; +} + +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieSb.c b/src/vendorcode/amd/cimx/rd890/nbPcieSb.c new file mode 100644 index 000000000000..3ef609443284 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieSb.c @@ -0,0 +1,195 @@ +/** + * @file + * + * PCIe support for misc Southbridges. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdSbLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/* + * Set up NB-SB virtual channel for audio traffic + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ + +/*----------------------------------------------------------------------------------------*/ +/* + * Set up NB-SB virtual channel for audio traffic + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +AGESA_STATUS +PcieSbSetupVc ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT16 AlinkPort; + + Status = PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig); + if (Status != AGESA_SUCCESS) { + return Status; + } + + LibNbIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x80000124, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffff01, 0, pConfig); + LibNbIoRMW (AlinkPort, AccessS3SaveWidth32 , 0x0, 0x80000130, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, (UINT32)~(BIT24 + BIT25 + BIT26), 0xFE + BIT24, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffffff, BIT31, pConfig); + return AGESA_SUCCESS; +} +/*----------------------------------------------------------------------------------------*/ +/* + * Set up NB-SB virtual channel for audio traffic + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +VOID +PcieSbEnableVc ( + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT16 AlinkPort; + Status = PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig); + if (Status != AGESA_SUCCESS) { + return; + } + LibNbIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0xC0000050, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffffff, BIT3, pConfig); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Init SB ASPM. + * Enable ASPM states on SB + * + * + * @param[in] Lx Lx ASPM bitmap. Lx[0] - L0s enable. Lx[1] - L1 enable. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieSbInitAspm ( + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT16 AlinkPort; + + Status = PcieSbAgetAlinkIoAddress (&AlinkPort, pConfig); + if (Status != AGESA_SUCCESS) { + return Status; + } + LibNbIoRMW (AlinkPort, AccessS3SaveWidth32, 0x0, 0x40000038, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0x0, 0xA0, pConfig); + LibNbIoRMW (AlinkPort , AccessS3SaveWidth32, 0x0, 0x4000003c, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffff00ff, 0x6900, pConfig ); + LibNbIoRMW (AlinkPort , AccessS3SaveWidth32, 0x0, 0x80000068, pConfig); + LibNbIoRMW (AlinkPort + 4, AccessS3SaveWidth32, 0xffffffff, Lx, pConfig); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get Alink config address + * + * + */ +/*----------------------------------------------------------------------------------------*/ +AGESA_STATUS +PcieSbAgetAlinkIoAddress ( + OUT UINT16 *AlinkPort, + IN AMD_NB_CONFIG *pConfig + ) +{ + SB_INFO SbInfo; + SbInfo = LibAmdSbGetRevisionInfo ((pConfig == NULL)?NULL:GET_BLOCK_CONFIG_PTR (pConfig)); + if (SbInfo.Type == SB_UNKNOWN) { + return AGESA_UNSUPPORTED; + } + if (SbInfo.Type == SB_SB700) { + LibNbPciRead (MAKE_SBDFO (0, 0, 0x14, 0, 0xf0), AccessWidth16, AlinkPort, pConfig); + } else { + LibAmdSbPmioRead (0xE0, AccessWidth16, AlinkPort, NULL); + } + if (*AlinkPort == 0) { + return AGESA_UNSUPPORTED; + } + return AGESA_SUCCESS; +}
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieSb.h b/src/vendorcode/amd/cimx/rd890/nbPcieSb.h new file mode 100644 index 000000000000..2b0914c4a1d6 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieSb.h @@ -0,0 +1,71 @@ +/** + * @file + * + * PCIe support for misc Southbridges. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBPCIESB_H_ +#define _NBPCIESB_H_ + + +AGESA_STATUS +PcieSbInitAspm ( + IN UINT8 Lx, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieSbSetupVc ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieSbEnableVc ( + IN AMD_NB_CONFIG *pConfig + ); + + +AGESA_STATUS +PcieSbAgetAlinkIoAddress ( + OUT UINT16 *AlinkPort, + IN AMD_NB_CONFIG *pConfig + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c new file mode 100644 index 000000000000..771c489ea065 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.c @@ -0,0 +1,436 @@ +/** + * @file + * + * Routines to support misc PCIe workarounds. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdSbLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +PcieConfigureBridgeResources ( + IN PCI_ADDR Port, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieFreeBridgeResources ( + IN PCI_ADDR Port, + IN AMD_NB_CONFIG *pConfig + ); + + AGESA_STATUS +PcieDeskewWorkaround ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ); + +AGESA_STATUS +PcieNvWorkaround ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ); + +BOOLEAN +PcieIsDeskewCardDetected ( + IN UINT16 DeviceId + ); + + /*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc GFX Card Workaround + * RV3780/RV380 desk workaround. NV43 lost SSID workaround. + * + * + * + * @param[in] PortId PCI Express Port ID + * @param[in] pConfig Northbridge configuration structure pointer. + */ +AGESA_STATUS +PcieGfxWorkarounds ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ) +{ + AGESA_STATUS Status; + UINT32 Count; + UINT16 DeviceId; + UINT16 VendorId; + UINT8 DevClassCode; + PCI_ADDR Port; + PCI_ADDR Ep; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGfxWorkarounds PortId %d Enter\n", PortId)); + Status = AGESA_SUCCESS; + Port = PcieLibGetPortPciAddress (PortId, pConfig); + Ep.AddressValue = MAKE_SBDFO (0, Port.Address.Bus + 5, 0, 0, 0); + if (PcieConfigureBridgeResources (Port, pConfig) != AGESA_SUCCESS) { + return AGESA_SUCCESS; + } + for (Count = 0; Count <= 5000; Count++) { + LibNbPciRead (Ep.AddressValue | 0x02, AccessWidth16, &DeviceId, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), " Endpoint Device ID %x\n", DeviceId)); + if (DeviceId != 0xffff) { + break; + }; + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, 0); + } + if (Count >= 5000) { + PcieLibRequestPciReset (pConfig); + return AGESA_WARNING; + } + LibNbPciRead (Ep.AddressValue | 0x02, AccessWidth16, &DeviceId, pConfig); + LibNbPciRead (Ep.AddressValue, AccessWidth16, &VendorId, pConfig); + if (VendorId == 0xffff) { + PcieLibRequestPciReset (pConfig); + return AGESA_WARNING; + } + LibNbPciRead (Ep.AddressValue | 0x0B , AccessWidth8, &DevClassCode, pConfig); + if (DevClassCode == 3) { + if (VendorId == 0x1002 && PcieIsDeskewCardDetected (DeviceId)) { + Status = PcieDeskewWorkaround (Ep, pConfig); + } else { + if (VendorId == 0x10DE) { + Status = PcieNvWorkaround (Ep, pConfig); + } + } + } + PcieFreeBridgeResources (Port, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieGfxWorkarounds Exit [Status = 0x%x]\n", Status)); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * RV370/RV380 Deskew workaround + * + * + * + * @param[in] Device Pcie Address of ATI RV370/RV380 card. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +AGESA_STATUS +PcieDeskewWorkaround ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + UINTN MmioBase; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieDeskewWorkaround Enter\n")); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + MmioBase = pPcieConfig->TempMmioBaseAddress << 20; + if (MmioBase == 0) { + return AGESA_SUCCESS; + } + LibNbPciWrite (Device.AddressValue | 0x18, AccessWidth32, &MmioBase, pConfig); + LibNbPciRMW (Device.AddressValue | 0x04, AccessWidth8 , (UINT32)~BIT1, BIT1, pConfig); + *(UINT16*)(MmioBase + 0x120) = 0xb700; + if (*(UINT16*) (MmioBase + 0x120) == 0xb700) { + *(UINT32*)(MmioBase + 0x124) = 0x13; + if (*(UINT32*) (MmioBase + 0x124) == 0x13) { + if (*(UINT32*) (MmioBase + 0x12C) & BIT8) { +// TRACE((DMSG_PCIE_MISC,"Deskew ERROR Generate Reset\n")); + PcieLibRequestPciReset (pConfig); + return AGESA_WARNING; + } + } + } + LibNbPciRMW (Device.AddressValue | 0x04, AccessWidth8, (UINT32)~BIT1, 0x0, pConfig); + LibNbPciRMW (Device.AddressValue | 0x18, AccessWidth32, 0x0, 0x0, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieDeskewWorkaround Exit\n")); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * NV43 card workaround (lost SSID) + * + * + * + * @param[in] Device Pcie Address of NV43 card. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +AGESA_STATUS +PcieNvWorkaround ( + IN PCI_ADDR Device, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 DeviceSSID; + PCIE_CONFIG *pPcieConfig; + UINTN MmioBase; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieNvWorkaround Enter\n")); + LibNbPciIndexRMW (pConfig->NbPciAddress.AddressValue | NB_MISC_INDEX, NB_MISC_REG0B, AccessS3SaveWidth32, 0xffffffff, BIT2 + BIT1, pConfig); + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + MmioBase = pPcieConfig->TempMmioBaseAddress << 20; + if (MmioBase == 0) { + return AGESA_SUCCESS; + } + LibNbPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, ((UINT32)MmioBase) | 1, pConfig); + LibNbPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x2, pConfig); + LibNbPciRead (Device.AddressValue | 0x2c, AccessWidth32, &DeviceSSID, pConfig); + if (DeviceSSID != *(UINT32*) (MmioBase + 0x54)) { + LibNbPciRMW (Device.AddressValue | 0x40, AccessWidth32, 0x0, *(UINT32*) (MmioBase + 0x54), pConfig); + } + LibNbPciRMW (Device.AddressValue | 0x30, AccessWidth32, 0x0, 0x0, pConfig); + LibNbPciRMW (Device.AddressValue | 0x4, AccessWidth8, 0x0, 0x0, pConfig); + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (pConfig), CIMX_NBPCIE_TRACE), "[NBPCIE]PcieNvWorkaround Exit\n")); + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Allocate temporary resources for Pcie P2P bridge + * + * + * + * @param[in] Port Pci Address of Port to initialize. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +AGESA_STATUS +PcieConfigureBridgeResources ( + IN PCI_ADDR Port, + IN AMD_NB_CONFIG *pConfig + ) +{ + PCIE_CONFIG *pPcieConfig; + UINT32 Value; + UINT32 MmioBase; + + pPcieConfig = GET_PCIE_CONFIG_PTR (pConfig); + MmioBase = pPcieConfig->TempMmioBaseAddress << 20; + if (MmioBase == 0) { + return AGESA_WARNING; + } + Value = Port.Address.Bus + ((Port.Address.Bus + 5) << 8) + ((Port.Address.Bus + 5) << 16); + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG18, AccessWidth32, &Value, pConfig); + Value = MmioBase + (MmioBase >> 16); + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG20, AccessWidth32, &Value, pConfig); + Value = 0x000fff0; + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG24, AccessWidth32, &Value, pConfig); + Value = 0x2; + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG04, AccessWidth8, &Value, pConfig); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Free temporary resources for Pcie P2P bridge + * + * + * + * @param[in] Port Pci Address of Port to clear resource allocation. + * @param[in] pConfig Northbridge configuration structure pointer. + */ +VOID +PcieFreeBridgeResources ( + IN PCI_ADDR Port, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 Value; + + Value = 0; + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG04, AccessWidth8, &Value, pConfig); + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG18, AccessWidth32, &Value, pConfig); + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG20, AccessWidth32, &Value, pConfig); + LibNbPciWrite (Port.AddressValue | NB_PCIP_REG24, AccessWidth32, &Value, pConfig); + +} + +/*----------------------------------------------------------------------------------------*/ +/* + * Check if card required test for deskew workaround + * + * + * + * + * + */ + +BOOLEAN +PcieIsDeskewCardDetected ( + IN UINT16 DeviceId + ) +{ + if ((DeviceId >= 0x3150 && DeviceId <= 0x3152) || (DeviceId == 0x3154) || + (DeviceId == 0x3E50) || (DeviceId == 0x3E54) || + ((DeviceId & 0xfff8) == 0x5460) || ((DeviceId & 0xfff8) == 0x5B60)) { + return TRUE; + } + return FALSE; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if we can accsee to EP. Wait for up to 1 sec if EP requred extra time to initialize. + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +PcieEpReadyWorkaround ( + IN AMD_NB_CONFIG *pConfig + ) +{ + PORT PortId; + UINT8 TempBus; + PCI_ADDR Device; + TempBus = (UINT8) (pConfig->NbPciAddress.Address.Bus + 5); + Device.AddressValue = MAKE_SBDFO (0, TempBus, 0, 0, 0); + for (PortId = MIN_PORT_ID; PortId <= MAX_PORT_ID; PortId++) { + PCI_ADDR Port; + Port.AddressValue = MAKE_SBDFO (0, pConfig->NbPciAddress.Address.Bus , PortId, 0, 0); + if (LibNbIsDevicePresent (Port, pConfig)) { + UINT32 LinkState; + LibNbPciIndexRead (Port.AddressValue | NB_BIF_INDEX, NB_BIFNBP_REGA5, AccessWidth32, &LinkState, pConfig); + LinkState &= 0x3F; + if (LinkState == 0x10) { + BOOLEAN IsDevicePresent; + UINT32 PortBusConfiguration; + UINT32 Count; + Count = 1000; + LibNbPciRead (Port.AddressValue | 0x18, AccessWidth32, &PortBusConfiguration, pConfig); + LibNbPciRMW (Port.AddressValue | 0x18, AccessWidth32, 0x0, (TempBus << 8) | (TempBus << 16), pConfig); + do { + IsDevicePresent = LibNbIsDevicePresent (Device, pConfig); + STALL (GET_BLOCK_CONFIG_PTR (pConfig), 1000, CIMX_S3_SAVE); + } while (IsDevicePresent == FALSE && Count-- != 0 ); + LibNbPciWrite (Port.AddressValue | 0x18, AccessWidth32, &PortBusConfiguration, pConfig); + } + } + } +} + +UINT16 AspmBrDeviceTable[] = { + 0x1002, 0x9441, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10B5, 0xFFFF, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0402, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0193, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0422, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0292, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x00F9, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0141, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0092, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D0, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D1, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D2, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D3, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D5, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D7, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01D8, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01DC, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01DE, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x01DF, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x016A, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x10DE, 0x0392, (UINT16)~(ASPM_L1 | ASPM_L0s), + 0x168C, 0xFFFF, (UINT16)~(ASPM_L0s) +}; + + +/*----------------------------------------------------------------------------------------*/ +/** + * Misc PCIe ASPM workarounds + * + * @param[in] AspmLinkInfoPtr Pointer to link ASPM info. + * @param[in] pConfig Northbridge configuration structure pointer. + * + */ +/*----------------------------------------------------------------------------------------*/ +VOID +PcieAspmWorkarounds ( + IN OUT ASPM_LINK_INFO *AspmLinkInfoPtr, + IN AMD_NB_CONFIG *pConfig + ) +{ + UINT32 UpstreamDeviceId; + UINT32 DownstreamDeviceId; + UINTN i; + LibNbPciRead (AspmLinkInfoPtr->UpstreamPort.AddressValue, AccessWidth32, &UpstreamDeviceId, pConfig); + LibNbPciRead (AspmLinkInfoPtr->UpstreamPort.AddressValue, AccessWidth32, &DownstreamDeviceId, pConfig); + for (i = 0; i < (sizeof (AspmBrDeviceTable) / sizeof (UINT16)); i = i + 3) { + UINT32 DeviceId; + UINT32 VendorId; + VendorId = AspmBrDeviceTable[i]; + DeviceId = AspmBrDeviceTable[i + 1]; + if (VendorId == (UINT16)UpstreamDeviceId || VendorId == (UINT16)DownstreamDeviceId ) { + if (DeviceId == 0xFFFF || DeviceId == (UpstreamDeviceId >> 16) || DeviceId == (DownstreamDeviceId >> 16)) { + AspmLinkInfoPtr->UpstreamLx &= AspmBrDeviceTable[i + 2]; + AspmLinkInfoPtr->DownstreamLx &= AspmBrDeviceTable[i + 2]; + } + } + } + if ((UINT16)UpstreamDeviceId == 0x168c) { + // Atheros (Ignore dev capability enable L1 if requested) + AspmLinkInfoPtr->UpstreamLx = AspmLinkInfoPtr->RequestedLx & ASPM_L1; + AspmLinkInfoPtr->DownstreamLx = AspmLinkInfoPtr->UpstreamLx; + LibNbPciRMW (AspmLinkInfoPtr->UpstreamPort.AddressValue | 0x70C, AccessS3SaveWidth32, 0x0, 0x0F003F01, pConfig); + } +} diff --git a/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h new file mode 100644 index 000000000000..4d72386ea294 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPcieWorkarounds.h @@ -0,0 +1,65 @@ +/** + * @file + * + * PCIe support for misc Southbridges. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBPCIEWORKAROUNDS_H_ +#define _NBPCIEWORKAROUNDS_H_ + + +AGESA_STATUS +PcieGfxWorkarounds ( + IN PORT PortId, + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieEpReadyWorkaround ( + IN AMD_NB_CONFIG *pConfig + ); + +VOID +PcieAspmWorkarounds ( + IN OUT ASPM_LINK_INFO *AspmLinkInfoPtr, + IN AMD_NB_CONFIG *pConfig + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c b/src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c new file mode 100644 index 000000000000..cde7d06b1822 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbPowerOnReset.c @@ -0,0 +1,383 @@ +/** + * @file + * + * Power on Reset register initialization. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" +#include "amdDebugOutLib.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +AGESA_STATUS +NbPorInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ); + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ +/// PCI registers init table +CONST REGISTER_ENTRY NbPorPciTable[] = { + {NB_PCI_REG04, 0xFD, 0x02}, +//Reg84h[4]=1 (EV6MODE) to allow decode of 640k-1MB + {NB_PCI_REG84, 0xEF, 0x10}, +//Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge +//Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation + {NB_PCI_REG4C, 0x00, 0x42}, +//Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation. +//Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge + {NB_PCI_REG4E, 0xFF, 0x05}, +//Set temporary NB TOM to 0xE0000000 + {NB_PCI_REG90 + 3, 0x00, 0xE0} +}; + +/// MISCIND registers init table +CONST INDIRECT_REG_ENTRY NbPorMiscTable[] = { +// NB_MISC_IND_WR_EN + IOC_PCIE_CNTL +// Block non-snoop DMA request if PMArbDis is set. +// Set BMSetDis + { + NB_MISC_REG0B, + 0xFFFF0000, + 0x00000180 + }, +// NBCFG (NBMISCIND 0x0): NB_CNTL - +// HIDE_NB_AGP_CAP ([0], default=1)HIDE +// HIDE_P2P_AGP_CAP ([1], default=1)HIDE +// HIDE_NB_GART_BAR ([2], default=1)HIDE +// HIDE_MMCFG_BAR ([3], default=1)HIDE +// AGPMODE30 ([4], default=0)DISABLE +// AGP30ENCHANCED ([5], default=0)DISABLE +// HIDE_AGP_CAP ([8], default=1)ENABLE + { + NB_MISC_REG00, + 0xFFFF0000, + 0x0000010e + }, +//NBMISIND:0x01 Bit[8]=1 IOC will forward the byte-enable (BE), which is 16'b0 for zero-byte reads, of the PCIE DMA request upstream to HTIU. +//NBMISIND:0x01 Bit[9]=1 zero-byte reads. + { + NB_MISC_REG01, + 0xFFFFFFFF, + 0x00000310 + }, +//NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow PWM features to work. + { + NB_MISC_REG40, + 0xffffffff, + 0x00000500 + }, +//Enable slot power message + { + NB_MISC_REG51, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG53, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG55, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG57, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG59, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG5B, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG5D, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG5F, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG61, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG63, + 0x00000000, + 0x00100106 + }, + { + NB_MISC_REG1F, + 0x00000000, + 0x00100106 + }, +//NBMISCIND:0x0C[13]= 1 Enables GSM Mode. + { + NB_MISC_REG0C, + 0xffffffff, + BIT13 + BIT20 + }, +//NBMISCIND:0x12[16]= 1 ReqID for GPP1 and GPP2 +//NBMISCIND:0x12[17]= 1 ReqID for GPP3a, GPP3b, SB +//NBMISCIND:0x12[18]= 0 ReqID override for SB +//NBMISCIND:0x12[19]= 1 Enable INT accumulators +//NBMISCIND:0x12[20, 21, 23]= 1 4103, 4125, 4155 4186 (A21). +//NBMISCIND:0x12[22]=0 Prevent spurious DR of UMA request (RPR 5.9.3) + { + NB_MISC_REG12, + (UINT32)~(BIT18 + BIT22), + 0xBB0000 + }, +//NBMISCIND:0x75[15.13,16..18,21..19,24..22,25..25] = 0x4 Enable AER +//NBMISCIND:0x75[29]= 1 Device ID for hotplug and PME message. + { + NB_MISC_REG75, + (UINT32)~BIT28, + (4 << 13) | (4 << 16) | (4 << 19) | (4 << 22) | (4 << 25) | BIT29 + }, +//PCIe CDR setting + { + NB_MISC_REG38, + 0xffffffff, + BIT6 + BIT7 + BIT14 + BIT15 + BIT22 + BIT23 + }, + { + NB_MISC_REG67, + 0xffffffff, + BIT21 + BIT22 + }, + { + NB_MISC_REG2C, + (UINT32)~(BIT0 + BIT1 + BIT19), + BIT0 + BIT1 + }, + { + NB_MISC_REG6C, + (UINT32)~(BIT10), + 0x0 + }, + { + NB_MISC_REG34, + (UINT32)~(BIT7 + BIT15 + BIT23), + 0x0 + }, + { + NB_MISC_REG37, + (UINT32)~(0xffful << 20), + (0xdddul << 20) + }, + { + NB_MISC_REG68, + (UINT32)~(0xful << 16), + (0xd << 16) + }, + { + NB_MISC_REG2B, + (UINT32)~(0xful << 24 ), + (0xd << 24) + }, + // Enable ACS capability + { + NB_MISC_REG6A, + 0xffffffff, + BIT2 + } +}; + +/// HTIUIND registers init table +CONST INDIRECT_REG_ENTRY NbPorHtiuTable[] = { +//HTIU x 05 [8] = 0x0 Enables PC checking for FCB release. +//HTIU x 05 [13,13,3,14,10,12,17,18,15,4,6,19] = 0x1 Misc (A21) + {NB_HTIU_REG05, 0xFFFFFEFF, BIT8 + BIT16 + BIT13 + BIT3 + BIT14 + BIT10 + BIT12 + BIT17 + BIT18 + BIT15 + + BIT4 + BIT6 + BIT19 }, + //HTIU x 06 [0] = 0x0 Enables writes to pass in-progress reads +//HTIU x 06 [1] = 0x1 Enables streaming of CPU writes +//HTIU x 06 [9] = 0x1 Enables extended write buffer for CPU writes +//HTIU x 06 [13] = 0x1 Enables additional response buffers +//HTIU x 06 [17] = 0x1 Enables special reads to pass writes +//HTIU x 06 [16:15] = 0x3 Enables decoding of C1e/C3 and FID cycles +//HTIU x 06 [25] = 0x1 Enables HTIU-display handshake bypass. +//HTIU x 06 [30] = 0x1 Enables tagging fix + {NB_HTIU_REG06, 0xFFFFFFFE, 0x04203A202}, +//HTIU x 07 [0] = 0x1 Enables byte-write optimization for IOC requests +//HTIU x 07 [1] = 0x0 Disables delaying STPCLK de-assert during FID sequence. Needed when enhanced UMA arbitration is used. +//HTIU x 07 [2] = 0x0 Disables upstream system-management delay + {NB_HTIU_REG07, 0xFFFFFFF9, 0x0001 }, +//HTIU x 1C [31:17]=0xfff i.e. 0001 1111 1111 111 or 1FFE Enables all traffic to be detected as GSM traffic. + {NB_HTIU_REG1C, 0xFFFFFFFF, 0x1ffe0000 }, +//HTIU x 15 [27]=0x1 Powers down the chipset DLLs in the LS2 state. + {NB_HTIU_REG15, 0xFFFFFFFF, BIT27 }, +//Enable transmit PHY to reinitialize in HT1 mode when tristate is enabled +//HTIU x 16 [10]=0x1 enable proper DLL reset sequence. + {NB_HTIU_REG16, 0xFFFFFFFF, BIT11 + BIT10}, +//HTIU x 2A [1:0]=0x1 Optimize chipset HT transmitter drive strength + {NB_HTIU_REG2A, 0xfffffffc, 0x00000001 } +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Amd Power on Reset Initialization for all NB. + * + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + + +AGESA_STATUS +AmdPowerOnResetInit ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + + Status = LibNbApiCall (NbPowerOnResetInit, ConfigPtr); + return Status; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * NB Power on Reset Initialization. + * Basic registers initialization. + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + + +AGESA_STATUS +NbPowerOnResetInit ( + IN AMD_NB_CONFIG *NbConfigPtr + ) +{ + AGESA_STATUS Status; + REGISTER_ENTRY *pTable; + UINTN i; + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPOR_TRACE), "[NBPOR]NbPowerOnResetInit Enter\n")); + Status = NbPorInitValidateInput (NbConfigPtr); + if (Status == AGESA_FATAL) { + REPORT_EVENT (AGESA_FATAL, GENERAL_ERROR_BAD_CONFIGURATION, 0, 0, 0, 0, NbConfigPtr); + CIMX_ASSERT (FALSE); + return Status; + } + //Init Pci Registers + pTable = (REGISTER_ENTRY*)FIX_PTR_ADDR (&NbPorPciTable[0], NULL); + for (i = 0; i < (sizeof (NbPorPciTable) / sizeof (REGISTER_ENTRY)); i++) { + LibNbPciRMW (NbConfigPtr->NbPciAddress.AddressValue | pTable->Register, AccessWidth8, pTable->Mask, pTable->Data, NbConfigPtr); + ++pTable; + } + //Init Misc registers + LibNbIndirectTableInit ( + NbConfigPtr->NbPciAddress.AddressValue | NB_MISC_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbPorMiscTable[0], NULL), + (sizeof (NbPorMiscTable) / sizeof (INDIRECT_REG_ENTRY)), + NbConfigPtr + ); + + //Init Htiu registers + LibNbIndirectTableInit ( + NbConfigPtr->NbPciAddress.AddressValue | NB_HTIU_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbPorHtiuTable[0],NULL), + (sizeof (NbPorHtiuTable) / sizeof (INDIRECT_REG_ENTRY)), + NbConfigPtr + ); + + CIMX_TRACE ((TRACE_DATA (GET_BLOCK_CONFIG_PTR (NbConfigPtr), CIMX_NBPOR_TRACE), "[NBPOR]NbPowerOnResetInit Exit\n")); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Validate input parameters + * + * + * + * + * @param[in] pConfig Northbridge configuration structure pointer. + */ + + +AGESA_STATUS +NbPorInitValidateInput ( + IN AMD_NB_CONFIG *pConfig + ) +{ + return (LibNbGetRevisionInfo (pConfig).Type == NB_UNKNOWN)?AGESA_FATAL:AGESA_SUCCESS; +} diff --git a/src/vendorcode/amd/cimx/rd890/nbRecovery.c b/src/vendorcode/amd/cimx/rd890/nbRecovery.c new file mode 100644 index 000000000000..71c6959a25a1 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbRecovery.c @@ -0,0 +1,192 @@ +/** + * @file + * + * Recovery support + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ +/// PCI registers init table +CONST REGISTER_ENTRY NbRecoveryPorPciTable[] = { + {NB_PCI_REG04,0xFD,0x02}, +//Reg84h[4]=1 (EV6MODE) to allow decode of 640k-1MB + {NB_PCI_REG84,0xEF,0x10}, +//Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge +//Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation + {NB_PCI_REG4C,0x00,0x42}, +//Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation. +//Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge + {NB_PCI_REG4E,0xFF,0x05}, +//Set temporary NB TOM to 0xE0000000 + {NB_PCI_REG90 + 3, 0x00, 0xE0} +}; + +/// MISCIND registers init table +CONST INDIRECT_REG_ENTRY NbRecoveryPorMiscTable[] = { +// NB_MISC_IND_WR_EN + IOC_PCIE_CNTL +// Block non-snoop DMA request if PMArbDis is set. +// Set BMSetDis + {NB_MISC_REG0B, 0xFFFF0000, 0x00000180}, +// NBCFG (NBMISCIND 0x0): NB_CNTL - +// HIDE_NB_AGP_CAP ([0], default=1)HIDE +// HIDE_P2P_AGP_CAP ([1], default=1)HIDE +// HIDE_NB_GART_BAR ([2], default=1)HIDE +// HIDE_MMCFG_BAR ([3], default=1)HIDE +// AGPMODE30 ([4], default=0)DISABLE +// AGP30ENCHANCED ([5], default=0)DISABLE +// HIDE_AGP_CAP ([8], default=1)ENABLE + {NB_MISC_REG00, 0xFFFF0000, 0x0000010e}, + {NB_MISC_REG01, 0xFFFFFFFF, 0x00000010}, + {NB_MISC_REG0C, 0xFFFFFFFF, 0x001f00FC}, +//NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow PWM features to work. + {NB_MISC_REG40, 0xffffffff, 0x00000500}, +}; + +/// HTIUIND registers init table +INDIRECT_REG_ENTRY NbRecoveryPorHtiuTable[] = { +//HTIU x 06 [0] = 0x0 Enables writes to pass in-progress reads +//HTIU x 06 [1] = 0x1 Enables streaming of CPU writes +//HTIU x 06 [9] = 0x1 Enables extended write buffer for CPU writes +//HTIU x 06 [13] = 0x1 Enables additional response buffers +//HTIU x 06 [17] = 0x1 Enables special reads to pass writes +//HTIU x 06 [16:15] = 0x3 Enables decoding of C1e/C3 and FID cycles +//HTIU x 06 [25] = 0x1 Enables HTIU-display handshake bypass. +//HTIU x 06 [30] = 0x1 Enables tagging fix + {NB_HTIU_REG06, 0xFFFFFFFE, 0x04203A202}, +//HTIU x 07 [0] = 0x1 Enables byte-write optimization for IOC requests +//HTIU x 07 [1] = 0x0 Disables delaying STPCLK de-assert during FID sequence. Needed when enhanced UMA arbitration is used. +//HTIU x 07 [2] = 0x0 Disables upstream system-management delay + {NB_HTIU_REG07, 0xFFFFFFF9, 0x0001 }, +//HTIU x 1C [31:17]=0xfff i.e. 0001 1111 1111 111 or 1FFE Enables all traffic to be detected as GSM traffic. + {NB_HTIU_REG1C, 0xFFFFFFFF, 0x1ffe0000 }, //vsj-2007-09-04 +//Enable transmit PHY to reinitialize in HT1 mode when tristate is enabled + {NB_HTIU_REG16, 0xFFFFFFFF, BIT11 }, +//HTIU x 2A [1:0]=0x1 Optimize chipset HT transmitter drive strength + {NB_HTIU_REG2A, 0xfffffffc, 0x00000001 } +}; + +/*----------------------------------------------------------------------------------------*/ +/** + * Northbridge Power on Reset Initialization for all NB in system. + * + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + + +AGESA_STATUS +AmdPowerOnResetInit ( + IN AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + REGISTER_ENTRY *pTable; + AMD_NB_CONFIG *pConfig; + UINTN i; + + pConfig = &ConfigPtr->Northbridges[0]; + pTable = (REGISTER_ENTRY*)FIX_PTR_ADDR (&NbRecoveryPorPciTable[0], NULL); + for (i = 0; i < (sizeof (NbRecoveryPorPciTable) / sizeof (REGISTER_ENTRY)); i++) { + LibNbPciRMW (pConfig->NbPciAddress.AddressValue | pTable->Register, AccessWidth8, pTable->Mask, pTable->Data, pConfig); + ++pTable; + } + //Init Misc registers + LibNbIndirectTableInit ( + ConfigPtr->Northbridges[0].NbPciAddress.AddressValue | NB_MISC_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbRecoveryPorMiscTable[0],NULL), + (sizeof (NbRecoveryPorMiscTable) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + + //Init Htiu registers + LibNbIndirectTableInit ( + ConfigPtr->Northbridges[0].NbPciAddress.AddressValue | NB_HTIU_INDEX, + 0, + (INDIRECT_REG_ENTRY*)FIX_PTR_ADDR (&NbRecoveryPorHtiuTable[0], NULL), + (sizeof (NbRecoveryPorHtiuTable) / sizeof (INDIRECT_REG_ENTRY)), + pConfig + ); + + return AGESA_SUCCESS; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Initialize misc setting + * + * + * + * @param[in] NbConfigPtr Northbridge configuration structure pointer. + * + */ + +AGESA_STATUS +MiscRecoveryInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ) +{ + return AGESA_SUCCESS; +} + + diff --git a/src/vendorcode/amd/cimx/rd890/nbRecovery.h b/src/vendorcode/amd/cimx/rd890/nbRecovery.h new file mode 100644 index 000000000000..e6b04c0be452 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbRecovery.h @@ -0,0 +1,53 @@ +/** + * @file + * + * NB definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBRECOVERY_H_ +#define _NBRECOVERY_H_ + + +AGESA_STATUS +MiscRecoveryInitializer ( + IN OUT AMD_NB_CONFIG *NbConfigPtr + ); + +#endif
\ No newline at end of file diff --git a/src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c b/src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c new file mode 100644 index 000000000000..f9b6132a145e --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbRecoveryInitializer.c @@ -0,0 +1,98 @@ +/** + * @file + * + * Recovery support + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ + +#include "NbPlatform.h" + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------------------------*/ +/** + * AMD structures initializer for recovery. + * + * + * + * @param[in] ConfigPtr Northbridges configuration block pointer. + * + */ + +AGESA_STATUS +AmdInitializer ( + IN OUT AMD_NB_CONFIG_BLOCK *ConfigPtr + ) +{ + AGESA_STATUS Status; + AMD_NB_CONFIG *NbConfigPtr; + NbConfigPtr = &ConfigPtr->Northbridges[0]; + Status = MiscRecoveryInitializer (NbConfigPtr); + if (Status == AGESA_FATAL) { + return Status; + } +#ifdef PCIE_RECOVERY_SUPPORT + Status = PcieRecoveryInitializer (NbConfigPtr); + if (Status == AGESA_FATAL) { + return Status; + } +#endif + return Status; + +} diff --git a/src/vendorcode/amd/cimx/rd890/nbRegisters.h b/src/vendorcode/amd/cimx/rd890/nbRegisters.h new file mode 100644 index 000000000000..621f1e96027b --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbRegisters.h @@ -0,0 +1,420 @@ +/** + * @file + * + * Registers definition. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBREGISTERS_H_ +#define _NBREGISTERS_H_ + +#define NB_PCI_REG04 0x04 +#define NB_PCI_REG1C 0x1C +#define NB_PCI_REG44 0x44 +#define NB_PCI_REG4C 0x4C +#define NB_PCI_REG4E 0x4E +#define NB_PCI_REG50 0x50 +#define NB_PCI_REG54 0x54 +#define NB_PCI_REG58 0x58 +#define NB_PCI_REG5C 0x5c +#define NB_PCI_REG60 0x60 +#define NB_PCI_REG78 0x78 +#define NB_PCI_REG7C 0x7C +#define NB_PCI_REG7F 0x7f +#define NB_PCI_REG95 0x95 +#define NB_PCI_REG97 0x97 +#define NB_PCI_REG80 0x80 +#define NB_PCI_REG84 0x84 +#define NB_PCI_REG8C 0x8C +#define NB_PCI_REG8D 0x8D +#define NB_PCI_REG90 0x90 +#define NB_PCI_REG94 0x94 +#define NB_PCI_REG98 0x98 +#define NB_PCI_REG9C 0x9C +#define NB_PCI_REGA0 0xA0 +#define NB_PCI_REGA4 0xA4 +#define NB_PCI_REGA6 0xA6 +#define NB_PCI_REGA7 0xA7 +#define NB_PCI_REGA8 0xA8 +#define NB_PCI_REGAC 0xAC +#define NB_PCI_REGC8 0xC8 +#define NB_PCI_REGCB 0xCB +#define NB_PCI_REGD1 0xD1 +#define NB_PCI_REGD2 0xD2 +#define NB_PCI_REGE0 0xE0 +#define NB_PCI_REGE8 0xE8 +#define NB_PCI_REGF8 0xF8 +#define NB_PCI_REGFC 0xFC + +#define NB_APC_REG04 0x04 +#define NB_APC_REG18 0x18 + +/****************************************************************************************** +; PCIE Port PCI config registers +;******************************************************************************************/ + +#define NB_PCIP_REG04 0x04 +#define NB_PCIP_REG18 0x18 +#define NB_PCIP_REG19 0x19 +#define NB_PCIP_REG20 0x20 +#define NB_PCIP_REG24 0x24 +#define NB_PCIP_REG3D 0x3D +#define NB_PCIP_REG5A 0x5A +#define NB_PCIP_REG64 0x64 +#define NB_PCIP_REG68 0x68 +#define NB_PCIP_REG6A 0x6A +#define NB_PCIP_REG6B 0x6b +#define NB_PCIP_REG6C 0x6c +#define NB_PCIP_REG70 0x70 +#define NB_PCIP_REG72 0x72 +#define NB_PCIP_REG80 0x80 +#define NB_PCIP_REG88 0x88 +#define NB_PCIP_REGE0 0xE0 +#define NB_PCIP_REG108 0x108 +#define NB_PCIP_REG124 0x124 +#define NB_PCIP_REG12A 0x12A +#define NB_PCIP_REG130 0x130 +#define NB_PCIP_REG134 0x134 + + +/****************************************************************************************** +; HTIUNBIND register definition +;******************************************************************************************/ + +#define NB_HTIU_INDEX NB_PCI_REG94 +#define HTIU_WRITE 0x100 + +#define NB_HTIU_REG05 (0x05 | HTIU_WRITE) +#define NB_HTIU_REG06 (0x06 | HTIU_WRITE) +#define NB_HTIU_REG07 (0x07 | HTIU_WRITE) +#define NB_HTIU_REG0C (0x0C | HTIU_WRITE) +#define NB_HTIU_REG12 (0x12 | HTIU_WRITE) +#define NB_HTIU_REG15 (0x15 | HTIU_WRITE) +#define NB_HTIU_REG16 (0x16 | HTIU_WRITE) +#define NB_HTIU_REG17 (0x17 | HTIU_WRITE) +#define NB_HTIU_REG19 (0x19 | HTIU_WRITE) +#define NB_HTIU_REG1A (0x1A | HTIU_WRITE) +#define NB_HTIU_REG1C (0x1C | HTIU_WRITE) +#define NB_HTIU_REG1D (0x1D | HTIU_WRITE) +#define NB_HTIU_REG1E (0x1E | HTIU_WRITE) +#define NB_HTIU_REG2A (0x2A | HTIU_WRITE) +#define NB_HTIU_REG2D (0x2D | HTIU_WRITE) +#define NB_HTIU_REG30 (0x30 | HTIU_WRITE) +#define NB_HTIU_REG31 (0x31 | HTIU_WRITE) +#define NB_HTIU_REG32 (0x32 | HTIU_WRITE) +#define NB_HTIU_REG34 (0x34 | HTIU_WRITE) +#define NB_HTIU_REG37 (0x37 | HTIU_WRITE) +#define NB_HTIU_REG3A (0x3A | HTIU_WRITE) +#define NB_HTIU_REG3B (0x3B | HTIU_WRITE) +#define NB_HTIU_REG3C (0x3C | HTIU_WRITE) +#define NB_HTIU_REG46 (0x46 | HTIU_WRITE) +#define NB_HTIU_REG4B (0x4B | HTIU_WRITE) +#define NB_HTIU_REG50 (0x50 | HTIU_WRITE) +#define NB_HTIU_REG55 (0x55 | HTIU_WRITE) +#define NB_HTIU_REG56 (0x56 | HTIU_WRITE) +#define NB_HTIU_REG57 (0x57 | HTIU_WRITE) +#define NB_HTIU_REG58 (0x58 | HTIU_WRITE) +#define NB_HTIU_REG59 (0x59 | HTIU_WRITE) +#define NB_HTIU_REG5A (0x5A | HTIU_WRITE) +#define NB_HTIU_REG5C (0x5C | HTIU_WRITE) +#define NB_HTIU_REG5D (0x5D | HTIU_WRITE) +#define NB_HTIU_REG5E (0x5E | HTIU_WRITE) +#define NB_HTIU_REG5F (0x5F | HTIU_WRITE) +#define NB_HTIU_REG60 (0x60 | HTIU_WRITE) +#define NB_HTIU_REG61 (0x61 | HTIU_WRITE) +#define NB_HTIU_REG62 (0x62 | HTIU_WRITE) +#define NB_HTIU_REG63 (0x63 | HTIU_WRITE) +#define NB_HTIU_REG64 (0x64 | HTIU_WRITE) +#define NB_HTIU_REG65 (0x65 | HTIU_WRITE) +#define NB_HTIU_REG66 (0x66 | HTIU_WRITE) +#define NB_HTIU_REG68 (0x68 | HTIU_WRITE) +#define NB_HTIU_REG6B (0x6B | HTIU_WRITE) +#define NB_HTIU_REG6D (0x6D | HTIU_WRITE) +#define NB_HTIU_REG70 (0x70 | HTIU_WRITE) +#define NB_HTIU_REG71 (0x71 | HTIU_WRITE) +#define NB_HTIU_REG72 (0x72 | HTIU_WRITE) +#define NB_HTIU_REG73 (0x73 | HTIU_WRITE) +#define NB_HTIU_REG74 (0x74 | HTIU_WRITE) +#define NB_HTIU_REG75 (0x75 | HTIU_WRITE) +#define NB_HTIU_REG87 (0x87 | HTIU_WRITE) +#define NB_HTIU_REG88 (0x88 | HTIU_WRITE) +#define NB_HTIU_REGA8 (0xA8 | HTIU_WRITE) +#define NB_HTIU_REGA9 (0xA9 | HTIU_WRITE) + +/****************************************************************************************** +; Clock Configuration register +;******************************************************************************************/ +#define NB_CLK_REG48 0x48 +#define NB_CLK_REG4C 0x4C +#define NB_CLK_REG5C 0x5C +#define NB_CLK_REG60 0x60 +#define NB_CLK_REG78 0x78 +#define NB_CLK_REG84 0x84 +#define NB_CLK_REG8C 0x8C +#define NB_CLK_REG90 0x90 +#define NB_CLK_REG94 0x94 +#define NB_CLK_REGB0 0xB0 +#define NB_CLK_REGB4 0xB4 +#define NB_CLK_REGCC 0xCC +#define NB_CLK_REGD4 0xD4 +#define NB_CLK_REGD5 0xD5 +#define NB_CLK_REGD6 0xD6 +#define NB_CLK_REGD8 0xD8 +#define NB_CLK_REGE0 0xE0 +#define NB_CLK_REGE4 0xE4 +#define NB_CLK_REGE8 0xE8 +#define NB_CLK_REGF0 0xF0 +#define NB_CLK_REGF4 0xF4 +#define NB_CLK_REGF8 0xF8 +#define NB_CLK_REGF9 0xF9 +#define NB_CLK_REGFA 0xFA +#define NB_CLK_REGFB 0xFB + +/****************************************************************************************** +; MISCIND/NBCFG register definition +;******************************************************************************************/ +#define NB_MISC_INDEX NB_PCI_REG60 +#define MISC_WRITE 0x80 + +#define NB_MISC_REG00 (0x00 | MISC_WRITE) +#define NB_MISC_REG01 (0x01 | MISC_WRITE) +#define NB_MISC_REG07 (0x07 | MISC_WRITE) +#define NB_MISC_REG08 (0x08 | MISC_WRITE) +#define NB_MISC_REG0B (0x0B | MISC_WRITE) +#define NB_MISC_REG0C (0x0C | MISC_WRITE) +#define NB_MISC_REG12 (0x12 | MISC_WRITE) +#define NB_MISC_REG1E (0x1E | MISC_WRITE) +#define NB_MISC_REG1F (0x1F | MISC_WRITE) +#define NB_MISC_REG20 (0x20 | MISC_WRITE) +#define NB_MISC_REG21 (0x21 | MISC_WRITE) +#define NB_MISC_REG22 (0x22 | MISC_WRITE) +#define NB_MISC_REG23 (0x23 | MISC_WRITE) +#define NB_MISC_REG24 (0x24 | MISC_WRITE) +#define NB_MISC_REG26 (0x26 | MISC_WRITE) +#define NB_MISC_REG27 (0x27 | MISC_WRITE) +#define NB_MISC_REG28 (0x28 | MISC_WRITE) +#define NB_MISC_REG29 (0x29 | MISC_WRITE) +#define NB_MISC_REG2A (0x2A | MISC_WRITE) +#define NB_MISC_REG2B (0x2B | MISC_WRITE) +#define NB_MISC_REG2C (0x2C | MISC_WRITE) +#define NB_MISC_REG2D (0x2D | MISC_WRITE) +#define NB_MISC_REG2E (0x2E | MISC_WRITE) +#define NB_MISC_REG2F (0x2F | MISC_WRITE) +#define NB_MISC_REG32 (0x32 | MISC_WRITE) +#define NB_MISC_REG33 (0x33 | MISC_WRITE) +#define NB_MISC_REG34 (0x34 | MISC_WRITE) +#define NB_MISC_REG35 (0x35 | MISC_WRITE) +#define NB_MISC_REG36 (0x36 | MISC_WRITE) +#define NB_MISC_REG37 (0x37 | MISC_WRITE) +#define NB_MISC_REG38 (0x38 | MISC_WRITE) +#define NB_MISC_REG39 (0x39 | MISC_WRITE) +#define NB_MISC_REG3A (0x3A | MISC_WRITE) +#define NB_MISC_REG3B (0x3B | MISC_WRITE) +#define NB_MISC_REG3C (0x3C | MISC_WRITE) +#define NB_MISC_REG40 (0x40 | MISC_WRITE) +#define NB_MISC_REG48 (0x48 | MISC_WRITE) +#define NB_MISC_REG49 (0x49 | MISC_WRITE) +#define NB_MISC_REG4A (0x4A | MISC_WRITE) +#define NB_MISC_REG4B (0x4B | MISC_WRITE) +#define NB_MISC_REG4E (0x4E | MISC_WRITE) +#define NB_MISC_REG4F (0x4F | MISC_WRITE) +#define NB_MISC_REG51 (0x51 | MISC_WRITE) +#define NB_MISC_REG53 (0x53 | MISC_WRITE) +#define NB_MISC_REG55 (0x55 | MISC_WRITE) +#define NB_MISC_REG57 (0x57 | MISC_WRITE) +#define NB_MISC_REG59 (0x59 | MISC_WRITE) +#define NB_MISC_REG5B (0x5B | MISC_WRITE) +#define NB_MISC_REG5D (0x5D | MISC_WRITE) +#define NB_MISC_REG5F (0x5F | MISC_WRITE) +#define NB_MISC_REG61 (0x61 | MISC_WRITE) +#define NB_MISC_REG63 (0x63 | MISC_WRITE) +#define NB_MISC_REG66 (0x66 | MISC_WRITE) +#define NB_MISC_REG67 (0x67 | MISC_WRITE) +#define NB_MISC_REG68 (0x68 | MISC_WRITE) +#define NB_MISC_REG69 (0x69 | MISC_WRITE) +#define NB_MISC_REG6A (0x6A | MISC_WRITE) +#define NB_MISC_REG6B (0x6B | MISC_WRITE) +#define NB_MISC_REG6C (0x6C | MISC_WRITE) +#define NB_MISC_REG6F (0x6f | MISC_WRITE) +#define NB_MISC_REG74 (0x74 | MISC_WRITE) +#define NB_MISC_REG75 (0x75 | MISC_WRITE) +#define NB_MISC_REG76 (0x76 | MISC_WRITE) +#define NB_MISC_REG7D (0x7D | MISC_WRITE) + +/****************************************************************************************** +; MISCIND/NBCFG register definition +;******************************************************************************************/ +#define NB_MC_INDEX NB_PCI_REGE8 +#define MC_WRITE 0x200 + +#define NB_MC_REG01 (0x01 | MC_WRITE) +#define NB_MC_REG02 (0x02 | MC_WRITE) +#define NB_MC_REG04 (0x04 | MC_WRITE) +#define NB_MC_REG05 (0x05 | MC_WRITE) +#define NB_MC_REG06 (0x06 | MC_WRITE) +#define NB_MC_REG07 (0x07 | MC_WRITE) +#define NB_MC_REG08 (0x08 | MC_WRITE) +#define NB_MC_REG09 (0x09 | MC_WRITE) +#define NB_MC_REG0B (0x0B | MC_WRITE) +#define NB_MC_REG0C (0x0C | MC_WRITE) +#define NB_MC_REG0D (0x0D | MC_WRITE) +#define NB_MC_REG0E (0x0E | MC_WRITE) +#define NB_MC_REG0F (0x0F | MC_WRITE) +#define NB_MC_REG10 (0x10 | MC_WRITE) +#define NB_MC_REG11 (0x11 | MC_WRITE) +#define NB_MC_REG12 (0x12 | MC_WRITE) +#define NB_MC_REG13 (0x13 | MC_WRITE) +#define NB_MC_REG14 (0x14 | MC_WRITE) +#define NB_MC_REG16 (0x16 | MC_WRITE) +#define NB_MC_REG23 (0x23 | MC_WRITE) +#define NB_MC_REG25 (0x25 | MC_WRITE) +#define NB_MC_REG29 (0x29 | MC_WRITE) +#define NB_MC_REG2A (0x2A | MC_WRITE) +#define NB_MC_REG2C (0x2C | MC_WRITE) +#define NB_MC_REG30 (0x30 | MC_WRITE) +#define NB_MC_REG3C (0x3C | MC_WRITE) +#define NB_MC_REG3D (0x3D | MC_WRITE) +#define NB_MC_REG49 (0x49 | MC_WRITE) +#define NB_MC_REG4A (0x4A | MC_WRITE) +#define NB_MC_REG4B (0x4B | MC_WRITE) +#define NB_MC_REG4C (0x4C | MC_WRITE) +#define NB_MC_REG4D (0x4D | MC_WRITE) +#define NB_MC_REGA0 (0xA0 | MC_WRITE) +#define NB_MC_REGA1 (0xA1 | MC_WRITE) +#define NB_MC_REGA2 (0xA2 | MC_WRITE) +#define NB_MC_REGA3 (0xA3 | MC_WRITE) +#define NB_MC_REGA4 (0xA4 | MC_WRITE) +#define NB_MC_REGA5 (0xA5 | MC_WRITE) +#define NB_MC_REGA6 (0xA6 | MC_WRITE) +#define NB_MC_REGA7 (0xA7 | MC_WRITE) +#define NB_MC_REGA8 (0xA8 | MC_WRITE) +#define NB_MC_REGAA (0xAA | MC_WRITE) +#define NB_MC_REGAF (0xAF | MC_WRITE) +#define NB_MC_REGB0 (0xB0 | MC_WRITE) +#define NB_MC_REGB2 (0xB2 | MC_WRITE) +#define NB_MC_REGB1 (0xB1 | MC_WRITE) +#define NB_MC_REGB4 (0xB4 | MC_WRITE) +#define NB_MC_REGB5 (0xB5 | MC_WRITE) +#define NB_MC_REGB6 (0xB6 | MC_WRITE) +#define NB_MC_REGB7 (0xB7 | MC_WRITE) +#define NB_MC_REGB8 (0xB8 | MC_WRITE) +#define NB_MC_REGB9 (0xB9 | MC_WRITE) +#define NB_MC_REGBA (0xBA | MC_WRITE) +#define NB_MC_REGC1 (0xC1 | MC_WRITE) +#define NB_MC_REGC2 (0xC2 | MC_WRITE) +#define NB_MC_REGC3 (0xC3 | MC_WRITE) +#define NB_MC_REGC4 (0xC4 | MC_WRITE) +#define NB_MC_REGC5 (0xC5 | MC_WRITE) +#define NB_MC_REGC8 (0xC8 | MC_WRITE) +#define NB_MC_REGC9 (0xC9 | MC_WRITE) +#define NB_MC_REGCA (0xCA | MC_WRITE) +#define NB_MC_REGCB (0xCB | MC_WRITE) +#define NB_MC_REGCC (0xCC | MC_WRITE) +#define NB_MC_REGCE (0xCE | MC_WRITE) +#define NB_MC_REGD0 (0xD0 | MC_WRITE) +#define NB_MC_REGD2 (0xD2 | MC_WRITE) +#define NB_MC_REGD3 (0xD3 | MC_WRITE) +#define NB_MC_REGD6 (0xD6 | MC_WRITE) +#define NB_MC_REGD7 (0xD7 | MC_WRITE) +#define NB_MC_REGD8 (0xD8 | MC_WRITE) +#define NB_MC_REGD9 (0xD9 | MC_WRITE) +#define NB_MC_REGE0 (0xE0 | MC_WRITE) +#define NB_MC_REGE1 (0xE1 | MC_WRITE) +#define NB_MC_REGE8 (0xE8 | MC_WRITE) +#define NB_MC_REGE9 (0xE9 | MC_WRITE) +#define NB_MC_REGF0 (0xF0 | MC_WRITE) + +/****************************************************************************************** +; PCIEIND_P(BIFNBP) register definition +;******************************************************************************************/ +#define NB_BIF_INDEX NB_PCI_REGE0 + +#define NB_BIFNBP_REG01 0x01 +#define NB_BIFNBP_REG02 0x02 +#define NB_BIFNBP_REG10 0x10 +#define NB_BIFNBP_REG20 0x20 +#define NB_BIFNBP_REG40 0x40 +#define NB_BIFNBP_REG50 0x50 +#define NB_BIFNBP_REG70 0x70 +#define NB_BIFNBP_REGA0 0xA0 +#define NB_BIFNBP_REGA1 0xA1 +#define NB_BIFNBP_REGA2 0xA2 +#define NB_BIFNBP_REGA3 0xA3 +#define NB_BIFNBP_REGA4 0xA4 +#define NB_BIFNBP_REGA5 0xA5 +#define NB_BIFNBP_REGB1 0xB1 +#define NB_BIFNBP_REGC0 0xC0 +#define NB_BIFNBP_REGC1 0xC1 + +/****************************************************************************************** +; PCIEIND(BIFNB) register definition +;******************************************************************************************/ +#define NB_BIFNB_REG01 0x01 +#define NB_BIFNB_REG02 0x02 +#define NB_BIFNB_REG10 0x10 +#define NB_BIFNB_REG11 0x11 +#define NB_BIFNB_REG1C 0x1C +#define NB_BIFNB_REG20 0x20 +#define NB_BIFNB_REG40 0x40 +#define NB_BIFNB_REG65 0x65 +#define NB_BIFNB_REGC1 0xC1 +#define NB_BIFNB_REGC2 0xC2 +#define NB_BIFNB_REGF9 0xF9 + + +#define MC_CLK_INDEX 0x60 + +/****************************************************************************************** +; IOAPICCFG register definition +;******************************************************************************************/ +#define NB_IOAPICCFG_INDEX NB_PCI_REGF8 + +#define NB_IOAPICCFG_REG00 0x00 +#define NB_IOAPICCFG_REG01 0x01 +#define NB_IOAPICCFG_REG02 0x02 +#define NB_IOAPICCFG_REG03 0x03 +#define NB_IOAPICCFG_REG04 0x04 +#define NB_IOAPICCFG_REG05 0x05 +#define NB_IOAPICCFG_REG06 0x06 +#define NB_IOAPICCFG_REG07 0x07 +#define NB_IOAPICCFG_REG08 0x08 +#define NB_IOAPICCFG_REG09 0x09 +#define NB_IOAPICCFG_REG0A 0x0A + +#endif diff --git a/src/vendorcode/amd/cimx/rd890/nbType.h b/src/vendorcode/amd/cimx/rd890/nbType.h new file mode 100644 index 000000000000..ef224c3cb2e5 --- /dev/null +++ b/src/vendorcode/amd/cimx/rd890/nbType.h @@ -0,0 +1,1075 @@ +/* + * @file + * + * Misc definitions. + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: CIMx-NB + * @e sub-project: + * @e \$Revision:$ @e \$Date:$ + * + */ +/***************************************************************************** + * + * Copyright (C) 2012 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +#ifndef _NBTYPE_H_ +#define _NBTYPE_H_ + +//#pragma pack(push, 1) //GCC ERROR + +#define CIMX_NB_REVISION "1.0.1.7" +#define CIMX_NB_ID "SR5690" + +#ifndef MAX_NB_COUNT + //#define MAX_NB_COUNT 4 + #error hi, MAX_NB_COUNT not define +#endif + +#define MAX_PORT_ID 13 +#define MIN_PORT_ID 2 + +#define MAX_CORE_ID 4 + + +typedef UINT32 PORT; +typedef UINT32 CORE; + + + +/// The HT Path to Northbridge +typedef struct { + UINT8 NodeID; ///< Node ID + UINT8 LinkID; /**< HT Link ID + * @par + * LinkID[3:0]- Link Id + * @li <b>0</b> - Link 0 + * @li <b>1</b> - Link 1 + * @li <b>2</b> - Link 2 + * @li <b>3</b> - Link 3 + * @par + * LinkID[7:4]- Sublink Id + * @li <b>1</b> - Sublink 0 + * @li <b>2</b> - Sublink 1 + * + * @PlatformDependant + */ +} HT_PATH; + +/// The configuration structure common header. +typedef struct { + UINT16 Version; ///< Version of this structure + UINT16 Reserved; ///< Reserved for future use + UINT32 InitializerID; ///< Signature of initializer +} AMD_COMMON_STRUCT_HEADER; + +/// The PCIE configuration parameters +typedef struct { + AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header + PCIE_MISC_CONFIG PcieConfiguration; ///< General configuration option + UINT32 ExtPcieConfiguration; ///< Extended General configuration option (Reserved for future use) + UINT32 CoreConfiguration[5]; /**< Core configuration + * @li <b>CoreConfiguration[0]</b> - GPP1 Core Configuration + * <TABLE border="0"> + * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">if CoreConfiguration[0] == 0 && PortConfiguration[3].PortPresent == 1 </TD></TR> + * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">CoreConfiguration[0] == 0x02020101</TD></TR> + * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">if CoreConfiguration[0] == 0 && PortConfiguration[3].PortPresent == 0</TD></TR> + * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">CoreConfiguration[0] == 0x01010101</TD></TR> + * </TABLE> + * @li <b>CoreConfiguration[1]</b> - GPP2 Core Configuration + * <TABLE border="0"> + * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">if CoreConfiguration[1] == 0 && PortConfiguration[12].PortPresent == 1 </TD></TR> + * <TR><TD class="indexkey" width=120> Dual Port 2x8 </TD><TD class="indexvalue">CoreConfiguration[1] == 0x02020101</TD></TR> + * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">if CoreConfiguration[1] == 0 && PortConfiguration[12].PortPresent == 0</TD></TR> + * <TR><TD class="indexkey" width=120> Single Port 1x16 </TD><TD class="indexvalue">CoreConfiguration[1] == 0x01010101</TD></TR> + * </TABLE> + * @li <b>CoreConfiguration[2]</b> - GPP3a Core Configuration + * <TABLE border="0"> + * <TR><TD class="indexkey" width=120> 4:2:0:0:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x1 </TD></TR> + * <TR><TD class="indexkey" width=120> 4:1:1:0:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x2</TD></TR> + * <TR><TD class="indexkey" width=120> 2:2:2:0:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x3</TD></TR> + * <TR><TD class="indexkey" width=120> 2:2:1:1:0:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x4</TD></TR> + * <TR><TD class="indexkey" width=120> 2:1:1:1:1:0 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x5</TD></TR> + * <TR><TD class="indexkey" width=120> 1:1:1:1:1:1 </TD><TD class="indexvalue">CoreConfiguration[2] == 0x6</TD></TR> + * </TABLE> + * @li <b>CoreConfiguration[3]</b> - Reserved + * @li <b>CoreConfiguration[4]</b> - Reserved + + * @PlatformDependant + */ + PCIE_CORE_SETTING CoreSetting[5]; /**< Core setting + * see PCIE_CORE_SETTING for details + * @li <b>CoreSetting[0]</b> - GPP1 Core Settings + * @li <b>CoreSetting[1]</b> - GPP2 Core Settings + * @li <b>CoreSetting[2]</b> - GPP3a Core Settings + * @li <b>CoreSetting[3]</b> - GPP3b Core Settings + * @li <b>CoreSetting[4]</b> - SB Core setting + */ + PCIE_PORT_CONFIG PortConfiguration[15]; /**< Port configuration + * see PCIE_PORT_CONFIG for details + * @li <b>PortConfiguration[0]</b> - Reserved + * @li <b>PortConfiguration[1]</b> - Reserved + * @li <b>PortConfiguration[2]</b> - PCIE Port Device 2 configuration + * @li <b>PortConfiguration[3]</b> - PCIE Port Device 3 configuration + * @li ... + * @li <b>PortConfiguration[13]</b> - PCIE Port Device 13 configuration + * + * @PlatformDependant + */ + PCIE_EXT_PORT_CONFIG ExtPortConfiguration[15]; /**< Extended Port configuration + * see PCIE_EXT_PORT_CONFIG for details. + * @li <b>ExtPortConfiguration[0]</b> - Reserved + * @li <b>ExtPortConfiguration[1]</b> - Reserved + * @li <b>ExtPortConfiguration[2]</b> - PCIE Port Device 2 configuration + * @li <b>ExtPortConfiguration[3]</b> - PCIE Port Device 3 configuration + * @li ... + * @li <b>ExtPortConfiguration[13]</b> - PCIE Port Device 13 configuration + * + * @PlatformDependant + */ + + UINT16 PcieMmioBaseAddress; /**< PCIE Extended MMIO base address in 1MB Unit. + * If PcieMmioBaseAddress == 0 assume MMIO setup already done. + * PCIE MMIO range should be programmed in CPU F1x[BC:80] Memory Mapped IO Base/Limit Registers as Non Posted if enabled in NB. + * <b>IMPORTANT!!! </b>Platform which use Rev10 and later CPU family should use PCIE MMIO functionality provided by CPU See "Configuration Space" in "BIOS and Kernel Developer's Guide For AMD Family 10h" + * + * @PlatformDependant + */ + + UINT16 PcieMmioSize; /**< PCIE Extended MMIO size in 1MB Unit. + * if PcieMmioBaseAddress != 0 and PcieMmioSize == 0 ignore both parameters and assume MMIO setup already done + * if PcieMmioBaseAddress == 0 and PcieMmioSize != 0 ignore both parameters and assume MMIO setup already done + * PCIE MMIO range should be programmed in CPU F1x[BC:80] Memory Mapped IO Base/Limit Registers as Non Posted if enabled in NB. + * <b>IMPORTANT!!!</b>Platform which use Rev10 and later CPU family should use PCIE MMIO functionality provided by CPU See "Configuration Space" in "BIOS and Kernel Developer's Guide For AMD Family 10h" + * + * @PlatformDependant + */ + UINT16 TempMmioBaseAddress; /**< Temporary MMIO base in 1MB Unit + * MMIO base address for temporary 256MB MMIO range. + * Range should be programmed in CPU F1x[BC:80] Memory Mapped IO Base/Limit Registers as Posted + * + * @PlatformDependant + */ + UINT16 DeviceInitMaskS1; ///< Bit mask of ports to be initialized at stage 1 + UINT16 DeviceInitMaskS2; ///< Bit mask of ports to be initialized at stage 2 + UINT16 ResetToTrainingDelay; ///< Delay (in 1ms) after reset deassert before training started + UINT16 TrainingToLinkTestDelay; ///< Delay (in 1ms) after training started but before pooling link state + UINT16 ReceiverDetectionPooling; ///< Total amount time (in 1ms of pooling for passing receiver detection stage + UINT32 Reserved12[16]; ///< Reserved for internal use. +} PCIE_CONFIG; + + + +/// The NB/IOMMU configuration +typedef struct { + AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header + UINT8 UnitIdClumping; /**< Unit ID clamping. + * UnitId clamping configuration base on PCIE port 3/12 presence. + * @li <b>0</b> - Disable + * @li <b>1</b> - Dev3 + * @li <b>2</b> - Dev12 + * @li <b>3</b> - Dev3 & Dev12 + + * @FilledByInitializer + */ + UINT8 P2PMode; /**< Peer-To-Peer (p2p) Modes + * Peep-To-Peer mode selection + * @li <b>0</b> - Default + * @li <b>1</b> - Mode 1 + * @li <b>2</b> - Mode 2 + * @li <b>0x8x</b> - Skip Initialization + + * @FilledByInitializer + */ + UINT8 Reserved2[2]; ///< Reserved for internal use. + UINT16 SysMemoryTomBelow4G; /**< Top of System memory below 4G in 1MB unit + * Top of physical memory including all reserved system memory etc. + * @PlatformDependant + */ + UINT32 SysMemoryTomAbove4G; /**< Top of System memory above 4G in 1MB unit + * Top of physical memory including all reserved system memory etc. + * @PlatformDependant + */ + UINT16 Reserved; ///< Used for internally to save APIC ID of Core 0. + UINT64 IommuBaseAddress; /**< IOMMU base address. + * 16kb aligned base address for IOMMU control registers + * @PlatformDependant + */ + UINT64 BroadcastBaseAddress; /**< PCIE Broadcast MMIO base address. + * This feature can be utilized broadcast address aware driver (AMD GFX driver) + * If BroadcastBaseAddress == 0 MMIO will not be enabled + * @PlatformDependant + */ + UINT16 BroadcastSize; /**< PCIE Broadcast MMIO size in MB. + * If BroadcastSize == 0 MMIO will not be enabled + * @PlatformDependant + */ + UINT16 Reserved3; ///< Reserved for internal use. + UINT64 IoApicBaseAddress; /**< NB IO APIC Base address. + * If IoApicBaseAddress == 0 IOAPIC will not be enabled + * @PlatformDependant + */ + UINT32 SSID; ///< NB Subsystem/Subvendor ID + UINT32 IommuTpologyInfo; ///< For intrernal use only + UINT32 Reserved4[8]; ///< Reserved for internal use. +} NB_CONFIG; + + +/// The NB Buffer Allocation/request parameters +typedef struct { + IN UINTN BufferLength; ///< Buffer length + IN UINT32 BufferHandle; ///< Buffer handle + OUT VOID* BufferPtr; ///< Pointer to the buffer +} NB_BUFFER_PARAMS; + + +/// The IOMMU exclusion range +typedef struct { + UINT64 Start; ///< Range Start address + UINT64 Length; ///< Range length +} IOMMU_EXCLUSIONRANGE; + +//#pragma warning (push) +//#pragma warning (disable: 4200) + +/// The IOMMU exclusion table +typedef struct { + UINTN TableLength; ///< Exclusion table length + IOMMU_EXCLUSIONRANGE ExclusionRange[]; ///< Array of exclusion range entries. +} IOMMU_EXCLUSIONTABLE; +//#pragma warning (pop) + +/// The HT configuration structure +typedef struct { + AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header + UINT8 LSx; /**< HT link LS state enable + * @li <b>0</b> - LS0 + * @li <b>1</b> - LS1 + * @li <b>2</b> - LS2 + * @li <b>3</b> - LS3 + * @li <b>4</b> - Same as CPU (use CPU setting setup by AGESA) + * @li <b>0x8x</b> - Skip Setting + + * @FilledByInitializer + */ + UINT8 Reserved; ///< Reserved for internal use. + UINT8 LinkBufferOptimization; /**< CPU - NB HT link optimization. + * @li <b>0</b> - Disabled + * @li <b>1</b> - Enable + * @li <b>2..7</b> - Reserved + */ + UINT8 HtExtendedAddressSupport; /**<Extended HT Address Support + * @li <b>0</b> - Disable + * @li <b>1</b> - Enable + * @li <b>0x8x</b> - Skip setting + + * @FilledByInitializer + */ + UINT8 HtLinkTriState; /**< HT Link tristate control + * @li <b>1</b> - Disable + * @li <b>2</b> - CAD/CTL + * @li <b>3</b> - CAD/CTL/CLK + * @li <b>0x8x</b> - Skip setting + + * @FilledByInitializer + */ + UINT8 NbTransmitterDeemphasis; /**< NB deemphasis level + * @li <b>0</b> - Disabled + * @li <b>1</b> - 1.32dB (0 to 4.5" trace length) + * @li <b>2</b> - 2.08dB (4.5" to 8" trace length) + * @li <b>3</b> - 3.10dB (8" to 11" trace length) + * @li <b>4</b> - 4.22dB (11" to 14" trace length) + * @li <b>5</b> - 5.50dB (14" to 18" trace length) + * @li <b>6</b> - 7.05dB (18+" trace length) + + * @PlatformDependant + */ + UINT16 HtReferenceClock; /**< HT Reference clock. + * + * @FilledByInitializer + */ + UINT32 Reserved1[10]; ///< Reserved +} HT_CONFIG; + + +/// The NB configuration structure +struct _AMD_NB_CONFIG_BLOCK; +typedef struct _AMD_NB_CONFIG_BLOCK AMD_NB_CONFIG_BLOCK; + +/// The NB configuration structure +typedef struct { + AMD_COMMON_STRUCT_HEADER sHeader; ///< Standard structure header + PCI_ADDR NbPciAddress; /**<PCI address of NB + * PCI Address to Access NB. Depends on HT topology and configuration for multi NB platform. + * Always 0:0:0 on single NB platform. + * @PlatformDependant + */ + HT_PATH NbHtPath; /**< HT path to NB. + * Path to NB CPU->Ht Link Number->NB + * @PlatformDependant + */ + UINT16 Reserved21; ///< Reserved for internal use. + NB_CONFIG *pNbConfig; ///< Pointer to NB configuration structure + HT_CONFIG *pHtConfig; ///< Pointer to HT configuration structure + PCIE_CONFIG *pPcieConfig; ///< Pointer to PCIE configuration structure + AMD_NB_CONFIG_BLOCK **ConfigPtr; ///< Pointer to main config block structure + VOID *ReservedPtr; ///< Reserved for internal use. +} AMD_NB_CONFIG; + + +/// The configuration block for all NB in system. +struct _AMD_NB_CONFIG_BLOCK { + AMD_CONFIG_PARAMS StandardHeader; ///< Standard structure header + UINT8 NumberOfNorthbridges; /**< Number of AMD_NB_CONFIG configuration structures + * @li <b>0</b> - One NB. + * @li <b>1</b> - Two NB. + * @li <b>2</b> - Three NB. + * @li <b>3</b> - Four NB. + + * @PlatformDependant + */ + UINT8 Scratch; /**< Variable for internal use + * @li <b>Bit[0]</b> = 0 Enable DebugOut, = 1 Disable DebugOut(only applicable for DebugOut enabled binaries). + */ + UINT8 PlatformType; /**< Platform Type (Server/Desktop). + * @li<b>0</b> - Unknown + * @li<b>1</b> - Desktop + * @li<b>2</b> - Server + + * @PlatformDependant + */ + UINT8 CurrentNorthbridge; /**< Northbridge ID which currently being initialized. + * Variable filled by CIMx and can be used during callback + * to identify to which NB callback belongs. + */ + AMD_NB_CONFIG Northbridges[MAX_NB_COUNT]; ///< Array of configuration structures for one or more NB in system +}; + +/// The IO APIC Interrupt Mapping Info +typedef struct { + UINT8 Group; /**< Group mapping for slot or endpoint device (connected to PCIE port) interrupts . + @li <b>0</b> - mapped to Grp 0 (pin 0..3 of IO APIC) + @li <b>1</b> - mapped to Grp 1 (pin 4..7 of IO APIC) + @li ... + @li <b>7</b> - mapped to Grp 7 (pin 28..31 of IO APIC) + */ + UINT8 Swizzle; /**< Swizzle interrupt in the Group. + @li <b>0</b> - ABCD + @li <b>1</b> - BCDA + @li <b>2</b> - CDAB + @li <b>3</b> - DABC + */ + UINT8 Pin; /**<Interrupt pin for PCIE bridge + @li <b>0</b> - Pin 0 of IO APIC + @li <b>1</b> - Pin 1 of IO APIC + @li ... + @li <b>31</b> - Pin 31 of IO APIC + */ +} APIC_DEVICE_INFO; + +typedef AGESA_STATUS (*SYSTEM_API) (AMD_NB_CONFIG_BLOCK *ConfigPtr); +typedef AGESA_STATUS (*NB_API) (AMD_NB_CONFIG *NbConfigPtr); + +/// Northbridge info +typedef struct { + UINT8 Type; ///< NB Model (RS780/RD790/RD890...) + UINT8 Revision; ///< NB Revision ID +} NB_INFO; + +/// API workspace +typedef struct { + AMD_NB_CONFIG_BLOCK *ConfigPtr; ///< NB congiguration + AGESA_STATUS Status; ///< return status +} API_WORKSPACE; + +/// Indirect register entry +typedef struct { + UINT32 Register; ///< register + UINT32 Mask; ///< AND mask + UINT32 Data; ///< data +} INDIRECT_REG_ENTRY; + +/// Register entry +typedef struct { + UINT8 Register; ///< register + UINT8 Mask; ///< AND mask + UINT8 Data; ///< data +} REGISTER_ENTRY; + +/// Scratchpad +typedef struct { + UINT32 ResetCount :4; ///< PCIe reset count + UINT32 PortGen2Disable :12; ///< PCIe Gen 2 disable + UINT32 MaskMemoryInit :1; ///< Mask memory init complete +} SCRATCH_1; + +/// Scratchpad +typedef struct { + UINT32 GlobalInterruptBase :8; ///< TBD +} SCRATCH_4; + + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page LegacyInterfaceCalls Legacy Interface Calls + * <TD>@subpage PH_Initializer_Page "PH_Initializer"</TD><TD></TD> + * <TD>@subpage PH_AmdPowerOnResetInit_Page "PH_AmdPowerOnResetInit"</TD><TD></TD> + * <TD>@subpage PH_AmdNbHtInit_Page "PH_AmdNbHtInit"</TD><TD></TD> + * <TD>@subpage PH_AmdPcieEarlyInit_Page "PH_AmdPcieEarlyInit"</TD><TD></TD> + * <TD>@subpage PH_AmdEarlyPostInit_Page "PH_AmdEarlyPostInit"</TD><TD></TD> + * <TD>@subpage PH_AmdMidPostInit_Page "PH_AmdMidPostInit"</TD><TD></TD> + * <TD>@subpage PH_AmdLatePostInit_Page "PH_AmdLatePostInit"</TD><TD></TD> + * <TD>@subpage PH_AmdS3Init_Page "PH_AmdS3Init"</TD><TD></TD> + * +*/ + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page PH_Initializer_Page PH_AmdNbInitializer + * @section PH_Initializer PH_AmdNbInitializer Interface Call + * Initialize structure referenced by AMD_NB_CONFIG::pHtConfig, AMD_NB_CONFIG::pPcieConfig and AMD_NB_CONFIG::pNbConfig to default recommended value.(Except platform dependant parameters See @ref PlatformDependParam "Platform Dependant Parameters" ) + * @subsection PH_Initializer_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_Initializer_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * </TABLE> + * @subsection PH_Initializer_Page_Initializer Initializer + * @par + * Not Applicable + * @subsection PH_Initializer_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdInitializer 0x100 + +/*--------------------------- Documentation Pages ---------------------------*/ +/** + * @page PH_AmdPowerOnResetInit_Page PH_AmdPowerOnResetInit + * @section PH_AmdPowerOnResetInit PH_AmdPowerOnResetInit Interface Call + * Initialize Northbridge registers on power-on reset. + * @subsection PH_AmdPowerOnResetInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdPowerOnResetInit_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * </TABLE> + * @subsection PH_AmdPowerOnResetInit_Initializer Initializer + * @par + * Not Required + * @subsection PH_AmdPowerOnResetInit_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdPowerOnResetInit 0x00 +/** + * @page PH_AmdNbHtInit_Page PH_AmdNbHtInit + * @section PH_AmdNbHtInit PH_AmdNbHtInit Interface Call + * Initialize NB HT subsystem. + * @subsection PH_AmdNbHtInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdNbHtInit_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * </TABLE> + * @subsection PH_AmdNbHtInit_Initializer Initializer + * @par + * Required (see @ref PH_Initializer_Page "PH_Initializer") + * @subsection PH_AmdNbHtInit_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbHtPath </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pHtConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdNbHtInit 0x10 +/** + * @page PH_AmdEarlyPostInit_Page PH_AmdEarlyPostInit + * @section PH_AmdEarlyPostInit PH_AmdEarlyPostInit Interface Call + * Initialize misc Northbridge feature at Early Post. + * @subsection PH_AmdEarlyPostInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdEarlyPostInit_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * </TABLE> + * @subsection PH_AmdEarlyPostInit_Initializer Initializer + * @par + * Required. (see @ref PH_Initializer_Page) + * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init + * must use same copy of AMD_NB_CONFIG_BLOCK + * @subsection PH_AmdEarlyPostInit_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbHtPath </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pNbConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pPcieConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> NB_CONFIG::SysMemoryTomBelow4G </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> NB_CONFIG::SysMemoryTomAbove4G </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdEarlyPostInit 0x30 +/** + * @page PH_AmdMidPostInit_Page PH_AmdMidPostInit + * @section PH_AmdMidPostInit PH_AmdMidPostInit Interface Call + * Initialize misc Northbridge feature at Mid Post. + * @subsection PH_AmdMidPostInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdMidPostInit_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdUpdateApicInterruptMapping_Page "PHCB_AmdUpdateApicInterruptMapping"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdAllocateBuffer_Page "PHCB_AmdAllocateBuffer "</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdGetExclusionTable_Page "PHCB_AmdGetExclusionTable "</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * </TABLE> + * @subsection PH_AmdMidPostInit_Initializer Initializer + * @par + * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init must use same copy of AMD_NB_CONFIG_BLOCK structure. + * @subsection PH_AmdMidPostInit_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> NB_CONFIG::IommuBaseAddress </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> NB_CONFIG::IoApicBaseAddress </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdMidPostInit 0x40 +/** + * @page PH_AmdLatePostInit_Page PH_AmdLatePostInit + * @section PH_AmdLatePostInit PH_AmdLatePostInit Interface Call + * Initialize misc Northbridge feature at Late Post. + * @subsection PH_AmdLatePostInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdLatePostInit_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPcieAsmpInfo "PHCB_AmdPcieAsmpInfo"</TD></TR> + * </TABLE> + * @subsection PH_AmdLatePostInit_Initializer Initializer + * @par + * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init must use same copy of AMD_NB_CONFIG_BLOCK structure. + * @subsection PH_AmdLatePostInit_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader</TD><TD class="indexvalue"><B>Required </B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdLatePostInit 0x50 + + /** + * @page PH_AmdPcieEarlyInit_Page PH_AmdPcieEarlyInit + * @section PH_AmdPcieEarlyInit PH_AmdPcieEarlyInit Interface Call + * Init PCI Express Subsystem. Train link on all enabled Ports. Initialize hotplug. + * @subsection PH_AmdPcieEarlyInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdPcieEarlyInit_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortTrainingCompleted_Page "PHCB_AmdPortTrainingCompleted"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortResetSupported_Page "PHCB_AmdPortResetSupported"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortResetAssert_Page "PHCB_AmdPortResetAssert"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPortResetDeassert_Page "PHCB_AmdPortResetDeassert"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * </TABLE> + * @subsection PH_AmdPcieEarlyInit_Initializer Initializer + * @par + * Required. + * @subsection PH_AmdPcieEarlyInit_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::NumberOfNorthbridges </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::NbPciAddress </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG::pPcieConfig </TD><TD class="indexvalue"><B>Required</B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdPcieEarlyInit 0x20 +/** + * @page PH_AmdS3Init_Page PH_AmdS3Init + * @section PH_AmdS3Init PH_AmdS3Init Interface Call + * Init misc. feature PCI Express Subsystem. Enable power management feature. Power off unused lanes/PLL etc. + * @subsection PH_AmdPcieLateInit_CallIn Call Prototype + * @par + * AGESA_STATUS *(ImageEntryPtr)(AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdS3Init_Callback Callback`s + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdUpdateApicInterruptMapping_Page "PHCB_AmdUpdateApicInterruptMapping"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdReportEvent_Page "PHCB_AmdReportEvent"</TD></TR> + * <TR><TD class="indexkey" width=380> @ref PHCB_AmdPcieAsmpInfo "PHCB_AmdPcieAsmpInfo"</TD></TR> + * </TABLE> + * @subsection PH_AmdS3Init_Initializer Initializer + * @par + * PH_AmdEarlyPostInit/PH_AmdMidPostInit/PH_AmdLatePostInit/PH_AmdS3Init must use same copy of AMD_NB_CONFIG_BLOCK structure. + * @subsection PH_AmdS3Init_Data Configuration Data. + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=380> AMD_NB_CONFIG_BLOCK::StandardHeader </TD><TD class="indexvalue"><B>Required </B></TD></TR> + * </TABLE> + * + */ +#define PH_AmdS3Init 0x60 + +/* + Secondary level interface function +*/ +#define PH_AmdPcieS3Init 0x61 +#define PH_AmdNbS3Init 0x62 +#define PH_AmdPcieLateInit 0x51 +#define PH_AmdNbLateInit 0x52 + +/** + *This function PH_AmdPcieValidatePortState must be called + * after the PH_AmdPcieEarlyInit and before PH_AmdLatePostInit + */ +#define PH_AmdPcieValidatePortState 0x70 + + +/** + * @page PHCB_AmdPortTrainingCompleted_Page PHCB_AmdPortTrainingCompleted + * @section PHCB_AmdPortTrainingCompleted PHCB_AmdPortTrainingCompleted Callback + * PCIE Port Initialization Completed endpoint detected. + * @subsection PHCB_AmdPortTrainingCompleted_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortId, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PH_AmdS3Init_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8000</TD></TR> + * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500>PCI Express Port Id</TD></TR> + * </TABLE> + * @subsection PHCB_AmdPortTrainingCompleted_Retrun Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_ERROR</TD><TD class="indexvalue" width=500>Disable Port</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdPortTrainingCompleted 0x8000 +/** + * @page PHCB_AmdPortResetDeassert_Page PHCB_AmdPortResetDeassert + * @section PHCB_AmdPortResetDeassert PHCB_AmdPortResetDeassert Callback + * Deassert reset for device or slot connected to PCIE Port. + * @subsection PHCB_AmdPortResetDeassert_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortIdBitMap, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdPortTrainingCompleted_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500> 0x8001</TD></TR> + * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500>bitmap of port id to deassert reset (0x4 - PortId 2, 0x8 PortId 3, ...)</TD></TR> + * </TABLE> + * @subsection PHCB_AmdPortTrainingCompleted_Retrun Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Reset successfully deasserted</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdPortResetDeassert 0x8001 +/** + * @page PHCB_AmdPortResetAssert_Page PHCB_AmdPortResetAssert + * @section PHCB_AmdPortResetAssert PHCB_AmdPortResetAssert Callback + * Assert reset for device connected to PCIE Port. + * @subsection PHCB_AmdPortResetDeassert_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortIdBitMap, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdPortResetAssert_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8002</TD></TR> + * <TR><TD class="indexkey" width=160>PortIdBitMap</TD><TD class="indexvalue" width=500>Bitmap of port id to assert reset (0x4 - PortId 2, 0x8 PortId 3, ...)</TD></TR> + * </TABLE> + * @subsection PHCB_AmdPortResetAssert_Retrun Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Reset successfully asserted</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdPortResetAssert 0x8002 +/** + * @page PHCB_AmdPortResetSupported_Page PHCB_AmdPortResetSupported + * @section PHCB_AmdPortResetSupported PHCB_AmdPortResetSupported Callback + * Test if controllable reset logic present for PCIE Port. + * @subsection PHCB_AmdPortResetSupported_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN PortId, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdPortResetSupported_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8003</TD></TR> + * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500> Port ID to check GPIO controlled reset logic present for slot or endpoint connected to this port</TD></TR> + * </TABLE> + * @subsection PHCB_AmdPortResetSupported_Retrun Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Slot/Device connected to port has GPIO controlled reset logic</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdPortResetSupported 0x8003 + + +/** + * @page PHCB_AmdGeneratePciReset_Page PHCB_AmdGeneratePciReset + * @section PHCB_AmdPortResetSupported PHCB_AmdGeneratePciReset Callback + * Request PCI reset generation. + * @subsection PHCB_AmdGeneratePciReset_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, UINTN ResetType, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdGeneratePciReset_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8004</TD></TR> + * <TR><TD class="indexkey" width=160>PortId</TD><TD class="indexvalue" width=500> Reset type. 0x01 - Warm Reset, 0x02 - Cold Reset</TD></TR> + * </TABLE> + * @subsection PHCB_AmdGeneratePciReset_Retrun Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>"Any"</TD><TD class="indexvalue" width=500>CIMx will generate reset by writing port 0xCF9</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Debug feature to completely avoid reset generation</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdGeneratePciReset 0x8004 + +/** + * @page PHCB_AmdGetExclusionTable_Page PHCB_AmdGetExclusionTable + * @section PHCB_AmdGetExclusionTable PHCB_AmdGetExclusionTable Callback + * Return the IOMMU exclusion table related to the current configuration block + * @subsection PHCB_AmdGetExclusionTable_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, IOMMU_EXCLUSIONTABLE *ExclusionTable, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdGetExclusionTable_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8005</TD></TR> + * <TR><TD class="indexkey" width=160>ExclusionTable</TD><TD class="indexvalue" width=500>Pointer to IOMMU exclusion table</TD></TR> + * </TABLE> + * @subsection PHCB_AmdGetExclusionTable_Return Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Valid table returned</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdGetExclusionTable 0x8005 + +/** + * @page PHCB_AmdAllocateBuffer_Page PHCB_AmdAllocateBuffer + * @section PHCB_AmdAllocateBuffer PHCB_AmdAllocateBuffer Callback + * Return the address of a memory buffer (size in bytes). + * + * ACPI handles used: + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>'SRVI'</TD><TD class="indexvalue" width=500>IO virtualization table</TD></TR> + * </TABLE> + * @par + * Usage: Buffer can be be allocated via PMM function 0 with handle and size specified in BufferParamsPtr, and + * the address must be returned in BufferParamsPtr. + * @par + * <b>Important Note:</b> Allocation for ACPI table will be requested during AmdEarlyPostInit or AmdMidPostInit and must be linked to + * ACPI table structure prior AmdLatePostInit interface call. + * @subsection PHCB_AmdAllocateBuffer_Callin Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, NB_BUFFER_PARAMS *BufferParamPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdAllocateBuffer_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8006</TD></TR> + * <TR><TD class="indexkey" width=160>BufferParamPtr</TD><TD class="indexvalue" width=500>Pointer to buffer parameters</TD></TR> + * </TABLE> + * @subsection PHCB_AmdAllocateBuffer_Return Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Buffer returned</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdAllocateBuffer 0x8006 + +/** + * @page PHCB_AmdUpdateApicInterruptMapping_Page PHCB_AmdUpdateApicInterruptMapping + * @section PHCB_AmdUpdateApicInterruptMapping PHCB_AmdUpdateApicInterruptMapping Callback + * Provide pointer to default IOAPIC interrupt mapping table + * @subsection PHCB_AmdUpdateApicInterruptMapping_Callin Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, APIC_DEVICE_INFO *pApicPortInfo, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdUpdateApicInterruptMapping_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8007</TD></TR> + * <TR><TD class="indexkey" width=160>pApicPortInfo</TD><TD class="indexvalue" width=500>Pointer to array of structures containing default IO APIC interrupt mapping info. For default interrupt mapping info see \ref gDefaultApicDeviceInfoTable</TD></TR> + * </TABLE> + * @subsection PHCB_AmdUpdateApicInterruptMapping_Return Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Interrupt mapping configuration completed</TD></TR> + * </TABLE> + * + */ + +#define PHCB_AmdUpdateApicInterruptMapping 0x8007 + +/** + * @page PHCB_AmdFreeBuffer_Page PHCB_AmdFreeBuffer + * @section PHCB_AmdFreeBuffer PHCB_AmdFreeBuffer Callback + * Free a specific memory buffer by handle. + * + * ACPI handles used: + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>'SRVI'</TD><TD class="indexvalue" width=500>IO virtualization table</TD></TR> + * </TABLE> + * @par + * <b>Important Note:</b> ACPI tables as listed above will not be explicitly freed and must be linked into the system ACPI table structure. + * + * @subsection PHCB_AmdFreeBuffer_Callin Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, NB_BUFFER_PARAMS *BufferParamPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdFreeBuffer_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8008</TD></TR> + * <TR><TD class="indexkey" width=160>BufferParamPtr</TD><TD class="indexvalue" width=500>Pointer to buffer parameters</TD></TR> + * </TABLE> + * @subsection PHCB_AmdFreeBuffer_Return Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Buffer freed</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdFreeBuffer 0x8008 + +/** + * @page PHCB_AmdLocateBuffer_Page PHCB_AmdLocateBuffer + * @section PHCB_AmdLocateBuffer PHCB_AmdLocateBuffer Callback + * Locate a specific memory buffer by handle (See also @ref PHCB_AmdAllocateBuffer_Page "PHCB_AmdAllocateBuffer"). + * + * @subsection PHCB_AmdLocateBuffer_Callin Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, NB_BUFFER_PARAMS *BufferParamPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdLocateBuffer_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8009</TD></TR> + * <TR><TD class="indexkey" width=160>BufferParamPtr</TD><TD class="indexvalue" width=500>Pointer to buffer parameters</TD></TR> + * </TABLE> + * @subsection PHCB_AmdLocateBuffer_Return Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Buffer Located</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdLocateBuffer 0x8009 + +/** + * @page PHCB_AmdReportEvent_Page PHCB_AmdReportEvent + * @section PHCB_AmdReportEvent PHCB_AmdReportEvent Callback + * Report event to platform firmware + * To exclude an entry, set the value of DeviceId to 0xFFFF + * + * @subsection PHCB_AmdReportEvent_Callin Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, AGESA_EVENT *Event, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdReportEvent_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160> CallBackId</TD><TD class="indexvalue" width=500>0x8010</TD></TR> + * <TR><TD class="indexkey" width=160> Event</TD><TD class="indexvalue" width=500>pointer to event structure</TD></TR> + * </TABLE> + * @subsection PHCB_AmdReportEvent_Events Events + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160> Event Class</TD><TD class="indexkey">Event Info </TD><TD class="indexkey">Description</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20010100</TD><TD class="indexvalue" >Hotplug controller firmware initialization fail</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20010200</TD><TD class="indexvalue">Link training fail</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20010300</TD><TD class="indexvalue">Incorrect PCIE Core COnfiguration requested</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010400</TD><TD class="indexvalue">Link width downgraded </TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010500</TD><TD class="indexvalue">Link speed forced to Gen1.</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010600</TD><TD class="indexvalue">VCO negotiation fail.</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_WARNING</TD><TD class="indexvalue">0x20010700</TD><TD class="indexvalue">Incorrect port device number remapping configuration</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_FATAL</TD><TD class="indexvalue">0x20000100</TD><TD class="indexvalue" >Invalid configuration structure</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_WARRNING</TD><TD class="indexvalue">0x20000200</TD><TD class="indexvalue">NB not present</TD></TR> + * <TR><TD class="indexvalue" width=160> AGESA_ERROR</TD><TD class="indexvalue">0x20000300</TD><TD class="indexvalue">Can not locate ACPI table</TD></TR> + * </TABLE> + * @subsection PHCB_AmdReportEvent_Return Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>AGESA_UNSUPPORTED</TD><TD class="indexvalue" width=500>Callback not supported</TD></TR> + * <TR><TD class="indexkey" width=160>AGESA_SUCCESS</TD><TD class="indexvalue" width=500>Event successfully logged</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdReportEvent 0x8010 +/** + * @page PHCB_AmdPcieAsmpInfo_Page PHCB_AmdPcieAsmpInfo + * @section PHCB_AmdPcieAsmpInfo PHCB_AmdPcieAsmpInfo Callback + * Give platform chance to update PCIe link ASPM setting. + * @subsection PHCB_AmdPcieAsmpInfo_CallIn Call Prototype + * @par + * AGESA_STATUS *(CallBackPtr)(UINT32 CallBackId, ASPM_LINK_INFO *AspmLinkInfoPtr, AMD_NB_CONFIG_BLOCK *ConfigPtr) + * @subsection PHCB_AmdPcieAsmpInfo_Parameters Parameters + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>CallBackId</TD><TD class="indexvalue" width=500>0x8011</TD></TR> + * <TR><TD class="indexkey" width=160>AspmLinkInfoPtr</TD><TD class="indexvalue" width=500> ASPM link info see ASPM_LINK_INFO for details.</TD></TR> + * </TABLE> + * @subsection PHCB_AmdPcieAsmpInfo_Retrun Return Value + * @par + * <TABLE border="0"> + * <TR><TD class="indexkey" width=160>"Any"</TD><TD class="indexvalue" width=500>CIMx will use content on ASPM_LINK_INFO to enable ASPM</TD></TR> + * </TABLE> + * + */ +#define PHCB_AmdPcieAsmpInfo 0x8011 + + +#define CB_AmdSetNbPorConfig 0x9000 +#define CB_AmdSetHtConfig 0x9001 +#define CB_AmdSetPcieEarlyConfig 0x9002 +#define CB_AmdSetEarlyPostConfig 0x9003 +#define CB_AmdSetMidPostConfig 0x9004 +#define CB_AmdSetLatePostConfig 0x9005 +#define CB_AmdSetRecoveryConfig 0x9006 + +#define ON 0x1 +#define OFF 0x0 + +#define NB_RD890TV 0x00 +#define NB_RD780 0x01 +#define NB_RX780 0x02 +#define NB_SR5690 0x10 +#define NB_SR5670 0x15 +#define NB_SR5650 0x20 +#define NB_RD890 0x25 +#define NB_990FX 0x25 //990FX= RD890 +#define NB_990X 0x30 //990X= SR5650 +#define NB_970 0x35 + +#define NB_UNKNOWN 0xff + +#define NB_REV_A11 0x00 +#define NB_REV_A12 0x02 + +#define DEV3_CLUMPING 1 +#define DEV12_CLUMPING 2 + +#define INITIALIZED_BY_INITIALIZER 0xAA + +#define CPU_FAMILY_NPT 0x00000000 +#define CPU_FAMILY_GH 0x00100000 + +#define GET_NB_CONFIG_PTR(x) x->pNbConfig +#define GET_HT_CONFIG_PTR(x) x->pHtConfig +#define GET_PCIE_CONFIG_PTR(x) x->pPcieConfig +#define GET_BLOCK_CONFIG_PTR(x) (*(x->ConfigPtr)) +#define NB_SBDFO pConfig->NbPciAddress.AddressValue + +#define ABCD 0 +#define BCDA 1 +#define CDAB 2 +#define DABC 3 + +/// Platform Type +typedef enum { + DetectPlatform, ///< Autodetect platform type based on NB skew + DesktopPlatform, ///< Desktop platform + ServerPlatform ///< Server platform +} PLATFORM_TYPE; + +/// APIC register info +typedef struct { + UINT8 EpRoutingOffset; ///< Ep routing offset + UINT8 EpRoutingRegister; ///< Ep routing reg + UINT8 RcRoutingOffset; ///< Rc routing offset + UINT8 RcRoutingRegister; ///< Rc routing reg +} APIC_REGISTER_INFO; + + +#define PortInterruptPinMap(Pin, Port) (Pin << Port) + +#define HtPinMapOffset 0 +#define IommuPinMapOffset 8 + + +#define CIMX_MIN(x, y) (((x) > (y)) ? (y) : (x)) +#define CIMX_MAX(x, y) (((x) > (y)) ? (x) : (y)) +//#pragma pack(pop) + +#endif |