blob: 56130125ed4d3516ed815203fbb42650be02f9bc [file] [log] [blame]
Frank Vibrans69da1b62011-02-14 19:04:45 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Paul Menzela46a7122013-02-23 18:37:27 +010017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Frank Vibrans69da1b62011-02-14 19:04:45 +000018 */
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070019
Kyösti Mälkki526c2fb2014-07-10 22:16:58 +030020#include "AGESA.h"
Frank Vibrans69da1b62011-02-14 19:04:45 +000021#include "amdlib.h"
22#include "BiosCallOuts.h"
Frank Vibrans69da1b62011-02-14 19:04:45 +000023#include "heapManager.h"
24#include "SB800.h"
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030025#include <stdlib.h>
Frank Vibrans69da1b62011-02-14 19:04:45 +000026
Kyösti Mälkkic0096012014-05-05 18:56:33 +030027static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
28static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
29
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030030const BIOS_CALLOUT_STRUCT BiosCallouts[] =
Frank Vibrans69da1b62011-02-14 19:04:45 +000031{
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030032 {AGESA_ALLOCATE_BUFFER, agesa_AllocateBuffer },
33 {AGESA_DEALLOCATE_BUFFER, agesa_DeallocateBuffer },
34 {AGESA_LOCATE_BUFFER, agesa_LocateBuffer },
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030035 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkkia1ebbc42014-10-17 22:33:22 +030036 {AGESA_READ_SPD, agesa_ReadSpd },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030037 {AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +030038 {AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
Kyösti Mälkkic0096012014-05-05 18:56:33 +030039 {AGESA_GNB_PCIE_SLOT_RESET, board_GnbPcieSlotReset },
40 {AGESA_HOOKBEFORE_DRAM_INIT, board_BeforeDramInit },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030041 {AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopSuccess },
42 {AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopSuccess },
43 {AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopSuccess },
Frank Vibrans69da1b62011-02-14 19:04:45 +000044};
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030045const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
Frank Vibrans69da1b62011-02-14 19:04:45 +000046
Frank Vibrans69da1b62011-02-14 19:04:45 +000047/* Call the host environment interface to provide a user hook opportunity. */
Kyösti Mälkkic0096012014-05-05 18:56:33 +030048static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +000049{
Kerry Shehf03360f2012-01-19 13:25:55 +080050 AGESA_STATUS Status;
51 UINTN FcnData;
52 MEM_DATA_STRUCT *MemData;
53 UINT32 AcpiMmioAddr;
54 UINT32 GpioMmioAddr;
55 UINT8 Data8;
56 UINT16 Data16;
57 UINT8 TempData8;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070058
Kerry Shehf03360f2012-01-19 13:25:55 +080059 FcnData = Data;
60 MemData = ConfigPtr;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070061
Kerry Shehf03360f2012-01-19 13:25:55 +080062 Status = AGESA_SUCCESS;
Kerry Sheh01f7ab92012-01-19 13:18:36 +080063 /* Get SB MMIO Base (AcpiMmioAddr) */
Kerry Shehf03360f2012-01-19 13:25:55 +080064 WriteIo8 (0xCD6, 0x27);
65 Data8 = ReadIo8(0xCD7);
66 Data16 = Data8<<8;
67 WriteIo8 (0xCD6, 0x26);
68 Data8 = ReadIo8(0xCD7);
69 Data16 |= Data8;
70 AcpiMmioAddr = (UINT32)Data16 << 16;
71 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070072
Kerry Shehf03360f2012-01-19 13:25:55 +080073 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
74 Data8 &= ~BIT5;
75 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
76 TempData8 &= 0x03;
77 TempData8 |= Data8;
78 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070079
Kerry Shehf03360f2012-01-19 13:25:55 +080080 Data8 |= BIT2+BIT3;
81 Data8 &= ~BIT4;
82 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
83 TempData8 &= 0x23;
84 TempData8 |= Data8;
85 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080086
Kerry Shehf03360f2012-01-19 13:25:55 +080087 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
88 Data8 &= ~BIT5;
89 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
90 TempData8 &= 0x03;
91 TempData8 |= Data8;
92 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080093
Kerry Shehf03360f2012-01-19 13:25:55 +080094 Data8 |= BIT2+BIT3;
95 Data8 &= ~BIT4;
96 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
97 TempData8 &= 0x23;
98 TempData8 |= Data8;
99 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700100
Kerry Shehf03360f2012-01-19 13:25:55 +0800101 switch(MemData->ParameterListPtr->DDR3Voltage){
102 case VOLT1_35:
103 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
104 Data8 &= ~(UINT8)BIT6;
105 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
106 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
107 Data8 |= (UINT8)BIT6;
108 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
109 break;
110 case VOLT1_25:
111 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
112 Data8 &= ~(UINT8)BIT6;
113 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
114 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
115 Data8 &= ~(UINT8)BIT6;
116 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
117 break;
118 case VOLT1_5:
119 default:
120 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
121 Data8 |= (UINT8)BIT6;
122 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
123 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
124 Data8 &= ~(UINT8)BIT6;
125 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
126 }
127 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000128}
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800129
Frank Vibrans69da1b62011-02-14 19:04:45 +0000130/* PCIE slot reset control */
Kyösti Mälkkic0096012014-05-05 18:56:33 +0300131static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +0000132{
Kerry Shehf03360f2012-01-19 13:25:55 +0800133 AGESA_STATUS Status;
134 UINTN FcnData;
135 PCIe_SLOT_RESET_INFO *ResetInfo;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700136
Kerry Shehf03360f2012-01-19 13:25:55 +0800137 UINT32 GpioMmioAddr;
138 UINT32 AcpiMmioAddr;
139 UINT8 Data8;
140 UINT16 Data16;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700141
Kerry Shehf03360f2012-01-19 13:25:55 +0800142 FcnData = Data;
143 ResetInfo = ConfigPtr;
144 // Get SB800 MMIO Base (AcpiMmioAddr)
145 WriteIo8(0xCD6, 0x27);
146 Data8 = ReadIo8(0xCD7);
147 Data16=Data8<<8;
148 WriteIo8(0xCD6, 0x26);
149 Data8 = ReadIo8(0xCD7);
150 Data16|=Data8;
151 AcpiMmioAddr = (UINT32)Data16 << 16;
152 Status = AGESA_UNSUPPORTED;
153 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
154 switch (ResetInfo->ResetId)
155 {
156 case 4:
157 switch (ResetInfo->ResetControl) {
158 case AssertSlotReset:
159 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
160 Data8 &= ~(UINT8)BIT6 ;
161 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
162 Status = AGESA_SUCCESS;
163 break;
164 case DeassertSlotReset:
165 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
166 Data8 |= BIT6 ;
167 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
168 Status = AGESA_SUCCESS;
169 break;
170 }
171 break;
172 case 6:
173 switch (ResetInfo->ResetControl) {
174 case AssertSlotReset:
175 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
176 Data8 &= ~(UINT8)BIT6 ;
177 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
178 Status = AGESA_SUCCESS;
179 break;
180 case DeassertSlotReset:
181 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
182 Data8 |= BIT6 ;
183 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
184 Status = AGESA_SUCCESS;
185 break;
186 }
187 break;
188 case 7:
189 switch (ResetInfo->ResetControl) {
190 case AssertSlotReset:
191 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
192 Data8 &= ~(UINT8)BIT6 ;
193 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
194 Status = AGESA_SUCCESS;
195 break;
196 case DeassertSlotReset:
Jens Rottmannf87855c2013-02-18 18:56:48 +0100197 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Kerry Shehf03360f2012-01-19 13:25:55 +0800198 Data8 |= BIT6 ;
199 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
200 Status = AGESA_SUCCESS;
201 break;
202 }
203 break;
204 }
205 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000206}