blob: 5d11c06dabeb1b21783dd7fcf1431f4156a33165 [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.
Frank Vibrans69da1b62011-02-14 19:04:45 +000014 */
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070015
Kyösti Mälkki526c2fb2014-07-10 22:16:58 +030016#include "AGESA.h"
Frank Vibrans69da1b62011-02-14 19:04:45 +000017#include "amdlib.h"
Kyösti Mälkki26f297e2014-05-26 11:27:54 +030018#include <northbridge/amd/agesa/BiosCallOuts.h>
Frank Vibrans69da1b62011-02-14 19:04:45 +000019#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>
Frank Vibrans69da1b62011-02-14 19:04:45 +000023
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[] =
Frank Vibrans69da1b62011-02-14 19:04:45 +000028{
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 },
Frank Vibrans69da1b62011-02-14 19:04:45 +000038};
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030039const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
Frank Vibrans69da1b62011-02-14 19:04:45 +000040
Frank Vibrans69da1b62011-02-14 19:04:45 +000041/* 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)
Frank Vibrans69da1b62011-02-14 19:04:45 +000043{
Kerry Shehf03360f2012-01-19 13:25:55 +080044 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;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070052
Kerry Shehf03360f2012-01-19 13:25:55 +080053 FcnData = Data;
54 MemData = ConfigPtr;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070055
Kerry Shehf03360f2012-01-19 13:25:55 +080056 Status = AGESA_SUCCESS;
Kerry Sheh01f7ab92012-01-19 13:18:36 +080057 /* Get SB MMIO Base (AcpiMmioAddr) */
Kerry Shehf03360f2012-01-19 13:25:55 +080058 WriteIo8 (0xCD6, 0x27);
59 Data8 = ReadIo8(0xCD7);
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +020060 Data16 = Data8 << 8;
Kerry Shehf03360f2012-01-19 13:25:55 +080061 WriteIo8 (0xCD6, 0x26);
62 Data8 = ReadIo8(0xCD7);
63 Data16 |= Data8;
64 AcpiMmioAddr = (UINT32)Data16 << 16;
65 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070066
Kerry Shehf03360f2012-01-19 13:25:55 +080067 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);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070073
Kerry Shehf03360f2012-01-19 13:25:55 +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);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080080
Kerry Shehf03360f2012-01-19 13:25:55 +080081 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);
Kerry Sheh01f7ab92012-01-19 13:18:36 +080087
Kerry Shehf03360f2012-01-19 13:25:55 +080088 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);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070094
Kerry Shehf03360f2012-01-19 13:25:55 +080095 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;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000122}
Kerry Sheh01f7ab92012-01-19 13:18:36 +0800123
Frank Vibrans69da1b62011-02-14 19:04:45 +0000124/* PCIE slot reset control */
Stefan Reinauerdd132a52015-07-30 11:16:37 -0700125static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +0000126{
Kerry Shehf03360f2012-01-19 13:25:55 +0800127 AGESA_STATUS Status;
128 UINTN FcnData;
129 PCIe_SLOT_RESET_INFO *ResetInfo;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700130
Kerry Shehf03360f2012-01-19 13:25:55 +0800131 UINT32 GpioMmioAddr;
132 UINT32 AcpiMmioAddr;
133 UINT8 Data8;
134 UINT16 Data16;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700135
Kerry Shehf03360f2012-01-19 13:25:55 +0800136 FcnData = Data;
137 ResetInfo = ConfigPtr;
138 // Get SB800 MMIO Base (AcpiMmioAddr)
139 WriteIo8(0xCD6, 0x27);
140 Data8 = ReadIo8(0xCD7);
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200141 Data16 = Data8 << 8;
Kerry Shehf03360f2012-01-19 13:25:55 +0800142 WriteIo8(0xCD6, 0x26);
143 Data8 = ReadIo8(0xCD7);
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +0200144 Data16 |= Data8;
Kerry Shehf03360f2012-01-19 13:25:55 +0800145 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 case AssertSlotReset:
153 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +0200154 Data8 &= ~(UINT8)BIT6;
Kerry Shehf03360f2012-01-19 13:25:55 +0800155 Write64Mem8(GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
156 Status = AGESA_SUCCESS;
157 break;
158 case DeassertSlotReset:
159 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG21);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +0200160 Data8 |= BIT6;
Kerry Shehf03360f2012-01-19 13:25:55 +0800161 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG21, Data8); // MXM_GPIO0. GPIO21
162 Status = AGESA_SUCCESS;
163 break;
164 }
165 break;
166 case 6:
167 switch (ResetInfo->ResetControl) {
168 case AssertSlotReset:
169 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +0200170 Data8 &= ~(UINT8)BIT6;
Kerry Shehf03360f2012-01-19 13:25:55 +0800171 Write64Mem8(GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
172 Status = AGESA_SUCCESS;
173 break;
174 case DeassertSlotReset:
175 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG25);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +0200176 Data8 |= BIT6;
Kerry Shehf03360f2012-01-19 13:25:55 +0800177 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG25, Data8); // PCIE_RST#_LAN, GPIO25
178 Status = AGESA_SUCCESS;
179 break;
180 }
181 break;
182 case 7:
183 switch (ResetInfo->ResetControl) {
184 case AssertSlotReset:
185 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +0200186 Data8 &= ~(UINT8)BIT6;
Kerry Shehf03360f2012-01-19 13:25:55 +0800187 Write64Mem8(GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
188 Status = AGESA_SUCCESS;
189 break;
190 case DeassertSlotReset:
Jens Rottmannf87855c2013-02-18 18:56:48 +0100191 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG02);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +0200192 Data8 |= BIT6;
Kerry Shehf03360f2012-01-19 13:25:55 +0800193 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG02, Data8); // MPCIE_RST0, GPIO02
194 Status = AGESA_SUCCESS;
195 break;
196 }
197 break;
198 }
199 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +0000200}