blob: 69bb2c2e50cb142573e99ee81c7f24d7e1bc3983 [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"
Kyösti Mälkki26f297e2014-05-26 11:27:54 +030022#include <northbridge/amd/agesa/BiosCallOuts.h>
Frank Vibrans69da1b62011-02-14 19:04:45 +000023#include "heapManager.h"
24#include "SB800.h"
Kyösti Mälkki50c96372014-10-18 07:51:03 +030025#include <southbridge/amd/cimx/sb800/gpio_oem.h>
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030026#include <stdlib.h>
Frank Vibrans69da1b62011-02-14 19:04:45 +000027
Kyösti Mälkkic0096012014-05-05 18:56:33 +030028static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
29static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
30
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030031const BIOS_CALLOUT_STRUCT BiosCallouts[] =
Frank Vibrans69da1b62011-02-14 19:04:45 +000032{
Kyösti Mälkkief9343c2014-05-04 11:42:55 +030033 {AGESA_ALLOCATE_BUFFER, agesa_AllocateBuffer },
34 {AGESA_DEALLOCATE_BUFFER, agesa_DeallocateBuffer },
35 {AGESA_LOCATE_BUFFER, agesa_LocateBuffer },
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030036 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkkia1ebbc42014-10-17 22:33:22 +030037 {AGESA_READ_SPD, agesa_ReadSpd },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030038 {AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +030039 {AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
Kyösti Mälkkic0096012014-05-05 18:56:33 +030040 {AGESA_GNB_PCIE_SLOT_RESET, board_GnbPcieSlotReset },
41 {AGESA_HOOKBEFORE_DRAM_INIT, board_BeforeDramInit },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030042 {AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopSuccess },
43 {AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopSuccess },
44 {AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopSuccess },
Frank Vibrans69da1b62011-02-14 19:04:45 +000045};
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030046const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
Frank Vibrans69da1b62011-02-14 19:04:45 +000047
Frank Vibrans69da1b62011-02-14 19:04:45 +000048/* Call the host environment interface to provide a user hook opportunity. */
Kyösti Mälkkic0096012014-05-05 18:56:33 +030049static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +000050{
Kerry Shehf03360f2012-01-19 13:25:55 +080051 AGESA_STATUS Status;
52 UINTN FcnData;
53 MEM_DATA_STRUCT *MemData;
54 UINT32 AcpiMmioAddr;
55 UINT32 GpioMmioAddr;
56 UINT8 Data8;
57 UINT16 Data16;
58 UINT8 TempData8;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070059
Kerry Shehf03360f2012-01-19 13:25:55 +080060 FcnData = Data;
61 MemData = ConfigPtr;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070062
Kerry Shehf03360f2012-01-19 13:25:55 +080063 Status = AGESA_SUCCESS;
Kerry Sheh01f7ab92012-01-19 13:18:36 +080064 /* Get SB MMIO Base (AcpiMmioAddr) */
Kerry Shehf03360f2012-01-19 13:25:55 +080065 WriteIo8 (0xCD6, 0x27);
66 Data8 = ReadIo8(0xCD7);
67 Data16 = Data8<<8;
68 WriteIo8 (0xCD6, 0x26);
69 Data8 = ReadIo8(0xCD7);
70 Data16 |= Data8;
71 AcpiMmioAddr = (UINT32)Data16 << 16;
72 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070073
Kerry Shehf03360f2012-01-19 13:25:55 +080074 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
75 Data8 &= ~BIT5;
76 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
77 TempData8 &= 0x03;
78 TempData8 |= Data8;
79 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070080
Kerry Shehf03360f2012-01-19 13:25:55 +080081 Data8 |= BIT2+BIT3;
82 Data8 &= ~BIT4;
83 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
84 TempData8 &= 0x23;
85 TempData8 |= Data8;
86 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080087
Kerry Shehf03360f2012-01-19 13:25:55 +080088 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
89 Data8 &= ~BIT5;
90 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
91 TempData8 &= 0x03;
92 TempData8 |= Data8;
93 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080094
Kerry Shehf03360f2012-01-19 13:25:55 +080095 Data8 |= BIT2+BIT3;
96 Data8 &= ~BIT4;
97 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
98 TempData8 &= 0x23;
99 TempData8 |= Data8;
100 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700101
Kerry Shehf03360f2012-01-19 13:25:55 +0800102 switch(MemData->ParameterListPtr->DDR3Voltage){
103 case VOLT1_35:
104 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
105 Data8 &= ~(UINT8)BIT6;
106 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
107 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
108 Data8 |= (UINT8)BIT6;
109 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
110 break;
111 case VOLT1_25:
112 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
113 Data8 &= ~(UINT8)BIT6;
114 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
115 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
116 Data8 &= ~(UINT8)BIT6;
117 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
118 break;
119 case VOLT1_5:
120 default:
121 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
122 Data8 |= (UINT8)BIT6;
123 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
124 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
125 Data8 &= ~(UINT8)BIT6;
126 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
127 }
128 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000129}
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800130
Frank Vibrans69da1b62011-02-14 19:04:45 +0000131/* PCIE slot reset control */
Kyösti Mälkkic0096012014-05-05 18:56:33 +0300132static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +0000133{
Kerry Shehf03360f2012-01-19 13:25:55 +0800134 AGESA_STATUS Status;
135 UINTN FcnData;
136 PCIe_SLOT_RESET_INFO *ResetInfo;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700137
Kerry Shehf03360f2012-01-19 13:25:55 +0800138 UINT32 GpioMmioAddr;
139 UINT32 AcpiMmioAddr;
140 UINT8 Data8;
141 UINT16 Data16;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700142
Kerry Shehf03360f2012-01-19 13:25:55 +0800143 FcnData = Data;
144 ResetInfo = ConfigPtr;
145 // Get SB800 MMIO Base (AcpiMmioAddr)
146 WriteIo8(0xCD6, 0x27);
147 Data8 = ReadIo8(0xCD7);
148 Data16=Data8<<8;
149 WriteIo8(0xCD6, 0x26);
150 Data8 = ReadIo8(0xCD7);
151 Data16|=Data8;
152 AcpiMmioAddr = (UINT32)Data16 << 16;
153 Status = AGESA_UNSUPPORTED;
154 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
155 switch (ResetInfo->ResetId)
156 {
157 case 4:
158 switch (ResetInfo->ResetControl) {
159 case AssertSlotReset:
160 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
161 Data8 &= ~(UINT8)BIT6 ;
162 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
163 Status = AGESA_SUCCESS;
164 break;
165 case DeassertSlotReset:
166 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
167 Data8 |= BIT6 ;
168 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
169 Status = AGESA_SUCCESS;
170 break;
171 }
172 break;
173 case 6:
174 switch (ResetInfo->ResetControl) {
175 case AssertSlotReset:
176 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
177 Data8 &= ~(UINT8)BIT6 ;
178 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
179 Status = AGESA_SUCCESS;
180 break;
181 case DeassertSlotReset:
182 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
183 Data8 |= BIT6 ;
184 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
185 Status = AGESA_SUCCESS;
186 break;
187 }
188 break;
189 case 7:
190 switch (ResetInfo->ResetControl) {
191 case AssertSlotReset:
192 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
193 Data8 &= ~(UINT8)BIT6 ;
194 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
195 Status = AGESA_SUCCESS;
196 break;
197 case DeassertSlotReset:
Jens Rottmannf87855c2013-02-18 18:56:48 +0100198 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Kerry Shehf03360f2012-01-19 13:25:55 +0800199 Data8 |= BIT6 ;
200 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
201 Status = AGESA_SUCCESS;
202 break;
203 }
204 break;
205 }
206 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000207}