blob: 672231420357fe31909dfc52ac25a34a90ed07be [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
Patrick Georgib890a122015-03-26 15:17:45 +010017 * Foundation, Inc.
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
Stefan Reinauerdd132a52015-07-30 11:16:37 -070028static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr);
29static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr);
Kyösti Mälkkic0096012014-05-05 18:56:33 +030030
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älkki5e19fa42014-05-04 23:13:54 +030033 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkkia1ebbc42014-10-17 22:33:22 +030034 {AGESA_READ_SPD, agesa_ReadSpd },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030035 {AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +030036 {AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
Kyösti Mälkkic0096012014-05-05 18:56:33 +030037 {AGESA_GNB_PCIE_SLOT_RESET, board_GnbPcieSlotReset },
38 {AGESA_HOOKBEFORE_DRAM_INIT, board_BeforeDramInit },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030039 {AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopSuccess },
40 {AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopSuccess },
41 {AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopSuccess },
Frank Vibrans69da1b62011-02-14 19:04:45 +000042};
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030043const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
Frank Vibrans69da1b62011-02-14 19:04:45 +000044
Frank Vibrans69da1b62011-02-14 19:04:45 +000045/* Call the host environment interface to provide a user hook opportunity. */
Stefan Reinauerdd132a52015-07-30 11:16:37 -070046static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +000047{
Kerry Shehf03360f2012-01-19 13:25:55 +080048 AGESA_STATUS Status;
49 UINTN FcnData;
50 MEM_DATA_STRUCT *MemData;
51 UINT32 AcpiMmioAddr;
52 UINT32 GpioMmioAddr;
53 UINT8 Data8;
54 UINT16 Data16;
55 UINT8 TempData8;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070056
Kerry Shehf03360f2012-01-19 13:25:55 +080057 FcnData = Data;
58 MemData = ConfigPtr;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070059
Kerry Shehf03360f2012-01-19 13:25:55 +080060 Status = AGESA_SUCCESS;
Kerry Sheh01f7ab92012-01-19 13:18:36 +080061 /* Get SB MMIO Base (AcpiMmioAddr) */
Kerry Shehf03360f2012-01-19 13:25:55 +080062 WriteIo8 (0xCD6, 0x27);
63 Data8 = ReadIo8(0xCD7);
64 Data16 = Data8<<8;
65 WriteIo8 (0xCD6, 0x26);
66 Data8 = ReadIo8(0xCD7);
67 Data16 |= Data8;
68 AcpiMmioAddr = (UINT32)Data16 << 16;
69 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070070
Kerry Shehf03360f2012-01-19 13:25:55 +080071 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
72 Data8 &= ~BIT5;
73 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
74 TempData8 &= 0x03;
75 TempData8 |= Data8;
76 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070077
Kerry Shehf03360f2012-01-19 13:25:55 +080078 Data8 |= BIT2+BIT3;
79 Data8 &= ~BIT4;
80 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
81 TempData8 &= 0x23;
82 TempData8 |= Data8;
83 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080084
Kerry Shehf03360f2012-01-19 13:25:55 +080085 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
86 Data8 &= ~BIT5;
87 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
88 TempData8 &= 0x03;
89 TempData8 |= Data8;
90 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080091
Kerry Shehf03360f2012-01-19 13:25:55 +080092 Data8 |= BIT2+BIT3;
93 Data8 &= ~BIT4;
94 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
95 TempData8 &= 0x23;
96 TempData8 |= Data8;
97 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070098
Kerry Shehf03360f2012-01-19 13:25:55 +080099 switch(MemData->ParameterListPtr->DDR3Voltage){
100 case VOLT1_35:
101 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
102 Data8 &= ~(UINT8)BIT6;
103 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
104 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
105 Data8 |= (UINT8)BIT6;
106 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
107 break;
108 case VOLT1_25:
109 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
110 Data8 &= ~(UINT8)BIT6;
111 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
112 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
113 Data8 &= ~(UINT8)BIT6;
114 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
115 break;
116 case VOLT1_5:
117 default:
118 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
119 Data8 |= (UINT8)BIT6;
120 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
121 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
122 Data8 &= ~(UINT8)BIT6;
123 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
124 }
125 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000126}
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800127
Frank Vibrans69da1b62011-02-14 19:04:45 +0000128/* PCIE slot reset control */
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700129static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +0000130{
Kerry Shehf03360f2012-01-19 13:25:55 +0800131 AGESA_STATUS Status;
132 UINTN FcnData;
133 PCIe_SLOT_RESET_INFO *ResetInfo;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700134
Kerry Shehf03360f2012-01-19 13:25:55 +0800135 UINT32 GpioMmioAddr;
136 UINT32 AcpiMmioAddr;
137 UINT8 Data8;
138 UINT16 Data16;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700139
Kerry Shehf03360f2012-01-19 13:25:55 +0800140 FcnData = Data;
141 ResetInfo = ConfigPtr;
142 // Get SB800 MMIO Base (AcpiMmioAddr)
143 WriteIo8(0xCD6, 0x27);
144 Data8 = ReadIo8(0xCD7);
145 Data16=Data8<<8;
146 WriteIo8(0xCD6, 0x26);
147 Data8 = ReadIo8(0xCD7);
148 Data16|=Data8;
149 AcpiMmioAddr = (UINT32)Data16 << 16;
150 Status = AGESA_UNSUPPORTED;
151 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
152 switch (ResetInfo->ResetId)
153 {
154 case 4:
155 switch (ResetInfo->ResetControl) {
156 case AssertSlotReset:
157 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
158 Data8 &= ~(UINT8)BIT6 ;
159 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
160 Status = AGESA_SUCCESS;
161 break;
162 case DeassertSlotReset:
163 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
164 Data8 |= BIT6 ;
165 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
166 Status = AGESA_SUCCESS;
167 break;
168 }
169 break;
170 case 6:
171 switch (ResetInfo->ResetControl) {
172 case AssertSlotReset:
173 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
174 Data8 &= ~(UINT8)BIT6 ;
175 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
176 Status = AGESA_SUCCESS;
177 break;
178 case DeassertSlotReset:
179 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
180 Data8 |= BIT6 ;
181 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
182 Status = AGESA_SUCCESS;
183 break;
184 }
185 break;
186 case 7:
187 switch (ResetInfo->ResetControl) {
188 case AssertSlotReset:
189 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
190 Data8 &= ~(UINT8)BIT6 ;
191 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
192 Status = AGESA_SUCCESS;
193 break;
194 case DeassertSlotReset:
Jens Rottmannf87855c2013-02-18 18:56:48 +0100195 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Kerry Shehf03360f2012-01-19 13:25:55 +0800196 Data8 |= BIT6 ;
197 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
198 Status = AGESA_SUCCESS;
199 break;
200 }
201 break;
202 }
203 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000204}