blob: e68db1362f5aac796262f9fd3f2bd5acda29d6cd [file] [log] [blame]
Kerry Shehb7993512011-11-15 21:27:07 +08001/*
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.
Kerry Shehb7993512011-11-15 21:27:07 +080014 */
15
Kyösti Mälkki526c2fb2014-07-10 22:16:58 +030016#include "AGESA.h"
Kerry Shehb7993512011-11-15 21:27:07 +080017#include "amdlib.h"
Kyösti Mälkki26f297e2014-05-26 11:27:54 +030018#include <northbridge/amd/agesa/BiosCallOuts.h>
Kerry Shehb7993512011-11-15 21:27:07 +080019#include "heapManager.h"
20#include "SB800.h"
Kyösti Mälkki50c96372014-10-18 07:51:03 +030021#include <southbridge/amd/cimx/sb800/gpio_oem.h>
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030022#include <stdlib.h>
Kerry Shehb7993512011-11-15 21:27:07 +080023
Stefan Reinauerdd132a52015-07-30 11:16:37 -070024static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr);
25static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr);
Kyösti Mälkkic0096012014-05-05 18:56:33 +030026
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030027const BIOS_CALLOUT_STRUCT BiosCallouts[] =
Kerry Shehb7993512011-11-15 21:27:07 +080028{
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030029 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkkia1ebbc42014-10-17 22:33:22 +030030 {AGESA_READ_SPD, agesa_ReadSpd },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030031 {AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +030032 {AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
Kyösti Mälkkic0096012014-05-05 18:56:33 +030033 {AGESA_GNB_PCIE_SLOT_RESET, board_GnbPcieSlotReset },
34 {AGESA_HOOKBEFORE_DRAM_INIT, board_BeforeDramInit },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030035 {AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopSuccess },
36 {AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopSuccess },
37 {AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopSuccess },
Kerry Shehb7993512011-11-15 21:27:07 +080038};
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030039const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
Kerry Shehb7993512011-11-15 21:27:07 +080040
Kerry Shehb7993512011-11-15 21:27:07 +080041/* Call the host environment interface to provide a user hook opportunity. */
Stefan Reinauerdd132a52015-07-30 11:16:37 -070042static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kerry Shehb7993512011-11-15 21:27:07 +080043{
44 AGESA_STATUS Status;
45 UINTN FcnData;
46 MEM_DATA_STRUCT *MemData;
47 UINT32 AcpiMmioAddr;
48 UINT32 GpioMmioAddr;
49 UINT8 Data8;
50 UINT16 Data16;
51 UINT8 TempData8;
52
53 FcnData = Data;
54 MemData = ConfigPtr;
55
56 Status = AGESA_SUCCESS;
57 /* Get SB MMIO Base (AcpiMmioAddr) */
58 WriteIo8 (0xCD6, 0x27);
59 Data8 = ReadIo8(0xCD7);
60 Data16 = Data8<<8;
61 WriteIo8 (0xCD6, 0x26);
62 Data8 = ReadIo8(0xCD7);
63 Data16 |= Data8;
64 AcpiMmioAddr = (UINT32)Data16 << 16;
65 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
66
67 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
68 Data8 &= ~BIT5;
69 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
70 TempData8 &= 0x03;
71 TempData8 |= Data8;
72 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Patrick Georgi472efa62012-02-16 20:44:20 +010073
Kerry Shehb7993512011-11-15 21:27:07 +080074 Data8 |= BIT2+BIT3;
75 Data8 &= ~BIT4;
76 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
77 TempData8 &= 0x23;
78 TempData8 |= Data8;
79 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
80
81 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
82 Data8 &= ~BIT5;
83 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
84 TempData8 &= 0x03;
85 TempData8 |= Data8;
86 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
87
88 Data8 |= BIT2+BIT3;
89 Data8 &= ~BIT4;
90 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
91 TempData8 &= 0x23;
92 TempData8 |= Data8;
93 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
94
95 switch(MemData->ParameterListPtr->DDR3Voltage){
96 case VOLT1_35:
97 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
98 Data8 &= ~(UINT8)BIT6;
99 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
100 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
101 Data8 |= (UINT8)BIT6;
102 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
103 break;
104 case VOLT1_25:
105 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
106 Data8 &= ~(UINT8)BIT6;
107 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
108 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
109 Data8 &= ~(UINT8)BIT6;
110 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
111 break;
112 case VOLT1_5:
113 default:
114 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
115 Data8 |= (UINT8)BIT6;
116 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
117 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
118 Data8 &= ~(UINT8)BIT6;
119 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
120 }
121 return Status;
122}
123
Kerry Shehb7993512011-11-15 21:27:07 +0800124/* PCIE slot reset control */
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700125static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Kerry Shehb7993512011-11-15 21:27:07 +0800126{
127 AGESA_STATUS Status;
128 UINTN FcnData;
129 PCIe_SLOT_RESET_INFO *ResetInfo;
130
131 UINT32 GpioMmioAddr;
132 UINT32 AcpiMmioAddr;
133 UINT8 Data8;
134 UINT16 Data16;
135
136 FcnData = Data;
137 ResetInfo = ConfigPtr;
138 // Get SB800 MMIO Base (AcpiMmioAddr)
139 WriteIo8(0xCD6, 0x27);
140 Data8 = ReadIo8(0xCD7);
141 Data16=Data8<<8;
142 WriteIo8(0xCD6, 0x26);
143 Data8 = ReadIo8(0xCD7);
144 Data16|=Data8;
145 AcpiMmioAddr = (UINT32)Data16 << 16;
146 Status = AGESA_UNSUPPORTED;
147 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
148 switch (ResetInfo->ResetId)
149 {
150 case 4:
151 switch (ResetInfo->ResetControl)
152 {
153 case AssertSlotReset:
154 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
Patrick Georgi472efa62012-02-16 20:44:20 +0100155 Data8 &= ~(UINT8)BIT6 ;
Kerry Shehb7993512011-11-15 21:27:07 +0800156 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
157 Status = AGESA_SUCCESS;
158 break;
159 case DeassertSlotReset:
160 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
Patrick Georgi472efa62012-02-16 20:44:20 +0100161 Data8 |= BIT6 ;
Kerry Shehb7993512011-11-15 21:27:07 +0800162 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
163 Status = AGESA_SUCCESS;
164 break;
165 }
166 break;
167 case 6:
168 switch (ResetInfo->ResetControl)
169 {
170 case AssertSlotReset:
171 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
172 Data8 &= ~(UINT8)BIT6 ;
173 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
174 Status = AGESA_SUCCESS;
175 break;
176 case DeassertSlotReset:
177 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
Patrick Georgi472efa62012-02-16 20:44:20 +0100178 Data8 |= BIT6 ;
Kerry Shehb7993512011-11-15 21:27:07 +0800179 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
180 Status = AGESA_SUCCESS;
181 break;
182 }
183 break;
184 case 7:
185 switch (ResetInfo->ResetControl)
186 {
187 case AssertSlotReset:
188 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
189 Data8 &= ~(UINT8)BIT6 ;
190 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
191 Status = AGESA_SUCCESS;
192 break;
193 case DeassertSlotReset:
Jens Rottmannf87855c2013-02-18 18:56:48 +0100194 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Kerry Shehb7993512011-11-15 21:27:07 +0800195 Data8 |= BIT6 ;
196 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
197 Status = AGESA_SUCCESS;
198 break;
199 }
200 break;
201 }
202 return Status;
203}