blob: a76431364a34ab4c1356613a098a8212e7040536 [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
Frank Vibrans69da1b62011-02-14 19:04:45 +000020#include "agesawrapper.h"
21#include "amdlib.h"
22#include "BiosCallOuts.h"
Frank Vibrans69da1b62011-02-14 19:04:45 +000023#include "heapManager.h"
24#include "SB800.h"
Kimarie Hoot31c5e072013-03-06 16:18:09 -070025#include <northbridge/amd/agesa/family14/dimmSpd.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
Kerry Sheh01f7ab92012-01-19 13:18:36 +080030STATIC BIOS_CALLOUT_STRUCT BiosCallouts[] =
Frank Vibrans69da1b62011-02-14 19:04:45 +000031{
Kyösti Mälkki08df7322014-05-04 14:53:36 +030032 {AGESA_ALLOCATE_BUFFER, BiosAllocateBuffer },
33 {AGESA_DEALLOCATE_BUFFER, BiosDeallocateBuffer },
Kyösti Mälkki08df7322014-05-04 14:53:36 +030034 {AGESA_LOCATE_BUFFER, BiosLocateBuffer },
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030035 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkki08df7322014-05-04 14:53:36 +030036 {AGESA_READ_SPD, BiosReadSpd },
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};
45
46AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
47{
Kerry Shehf03360f2012-01-19 13:25:55 +080048 UINTN i;
49 AGESA_STATUS CalloutStatus;
Kerry Sheh01f7ab92012-01-19 13:18:36 +080050 UINTN CallOutCount = sizeof (BiosCallouts) / sizeof (BiosCallouts [0]);
Frank Vibrans69da1b62011-02-14 19:04:45 +000051
Kerry Sheh01f7ab92012-01-19 13:18:36 +080052 CalloutStatus = AGESA_UNSUPPORTED;
Frank Vibrans69da1b62011-02-14 19:04:45 +000053
Kerry Sheh01f7ab92012-01-19 13:18:36 +080054 for (i = 0; i < CallOutCount; i++) {
55 if (BiosCallouts[i].CalloutName == Func) {
Kerry Shehf03360f2012-01-19 13:25:55 +080056 CalloutStatus = BiosCallouts[i].CalloutPtr (Func, Data, ConfigPtr);
57 return CalloutStatus;
58 }
59 }
Frank Vibrans69da1b62011-02-14 19:04:45 +000060
Kerry Sheh01f7ab92012-01-19 13:18:36 +080061 return CalloutStatus;
62}
Frank Vibrans69da1b62011-02-14 19:04:45 +000063
Frank Vibrans69da1b62011-02-14 19:04:45 +000064/* Call the host environment interface to provide a user hook opportunity. */
Kyösti Mälkkic0096012014-05-05 18:56:33 +030065static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +000066{
Kerry Shehf03360f2012-01-19 13:25:55 +080067 AGESA_STATUS Status;
68 UINTN FcnData;
69 MEM_DATA_STRUCT *MemData;
70 UINT32 AcpiMmioAddr;
71 UINT32 GpioMmioAddr;
72 UINT8 Data8;
73 UINT16 Data16;
74 UINT8 TempData8;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070075
Kerry Shehf03360f2012-01-19 13:25:55 +080076 FcnData = Data;
77 MemData = ConfigPtr;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070078
Kerry Shehf03360f2012-01-19 13:25:55 +080079 Status = AGESA_SUCCESS;
Kerry Sheh01f7ab92012-01-19 13:18:36 +080080 /* Get SB MMIO Base (AcpiMmioAddr) */
Kerry Shehf03360f2012-01-19 13:25:55 +080081 WriteIo8 (0xCD6, 0x27);
82 Data8 = ReadIo8(0xCD7);
83 Data16 = Data8<<8;
84 WriteIo8 (0xCD6, 0x26);
85 Data8 = ReadIo8(0xCD7);
86 Data16 |= Data8;
87 AcpiMmioAddr = (UINT32)Data16 << 16;
88 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070089
Kerry Shehf03360f2012-01-19 13:25:55 +080090 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
91 Data8 &= ~BIT5;
92 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
93 TempData8 &= 0x03;
94 TempData8 |= Data8;
95 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070096
Kerry Shehf03360f2012-01-19 13:25:55 +080097 Data8 |= BIT2+BIT3;
98 Data8 &= ~BIT4;
99 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
100 TempData8 &= 0x23;
101 TempData8 |= Data8;
102 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800103
Kerry Shehf03360f2012-01-19 13:25:55 +0800104 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
105 Data8 &= ~BIT5;
106 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
107 TempData8 &= 0x03;
108 TempData8 |= Data8;
109 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800110
Kerry Shehf03360f2012-01-19 13:25:55 +0800111 Data8 |= BIT2+BIT3;
112 Data8 &= ~BIT4;
113 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
114 TempData8 &= 0x23;
115 TempData8 |= Data8;
116 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700117
Kerry Shehf03360f2012-01-19 13:25:55 +0800118 switch(MemData->ParameterListPtr->DDR3Voltage){
119 case VOLT1_35:
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 break;
127 case VOLT1_25:
128 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
129 Data8 &= ~(UINT8)BIT6;
130 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
131 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
132 Data8 &= ~(UINT8)BIT6;
133 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
134 break;
135 case VOLT1_5:
136 default:
137 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
138 Data8 |= (UINT8)BIT6;
139 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
140 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
141 Data8 &= ~(UINT8)BIT6;
142 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
143 }
144 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000145}
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800146
Frank Vibrans69da1b62011-02-14 19:04:45 +0000147/* PCIE slot reset control */
Kyösti Mälkkic0096012014-05-05 18:56:33 +0300148static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +0000149{
Kerry Shehf03360f2012-01-19 13:25:55 +0800150 AGESA_STATUS Status;
151 UINTN FcnData;
152 PCIe_SLOT_RESET_INFO *ResetInfo;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700153
Kerry Shehf03360f2012-01-19 13:25:55 +0800154 UINT32 GpioMmioAddr;
155 UINT32 AcpiMmioAddr;
156 UINT8 Data8;
157 UINT16 Data16;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700158
Kerry Shehf03360f2012-01-19 13:25:55 +0800159 FcnData = Data;
160 ResetInfo = ConfigPtr;
161 // Get SB800 MMIO Base (AcpiMmioAddr)
162 WriteIo8(0xCD6, 0x27);
163 Data8 = ReadIo8(0xCD7);
164 Data16=Data8<<8;
165 WriteIo8(0xCD6, 0x26);
166 Data8 = ReadIo8(0xCD7);
167 Data16|=Data8;
168 AcpiMmioAddr = (UINT32)Data16 << 16;
169 Status = AGESA_UNSUPPORTED;
170 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
171 switch (ResetInfo->ResetId)
172 {
173 case 4:
174 switch (ResetInfo->ResetControl) {
175 case AssertSlotReset:
176 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
177 Data8 &= ~(UINT8)BIT6 ;
178 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
179 Status = AGESA_SUCCESS;
180 break;
181 case DeassertSlotReset:
182 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
183 Data8 |= BIT6 ;
184 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
185 Status = AGESA_SUCCESS;
186 break;
187 }
188 break;
189 case 6:
190 switch (ResetInfo->ResetControl) {
191 case AssertSlotReset:
192 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
193 Data8 &= ~(UINT8)BIT6 ;
194 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
195 Status = AGESA_SUCCESS;
196 break;
197 case DeassertSlotReset:
198 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
199 Data8 |= BIT6 ;
200 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
201 Status = AGESA_SUCCESS;
202 break;
203 }
204 break;
205 case 7:
206 switch (ResetInfo->ResetControl) {
207 case AssertSlotReset:
208 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
209 Data8 &= ~(UINT8)BIT6 ;
210 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
211 Status = AGESA_SUCCESS;
212 break;
213 case DeassertSlotReset:
Jens Rottmannf87855c2013-02-18 18:56:48 +0100214 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Kerry Shehf03360f2012-01-19 13:25:55 +0800215 Data8 |= BIT6 ;
216 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
217 Status = AGESA_SUCCESS;
218 break;
219 }
220 break;
221 }
222 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000223}