blob: 7525cbc34e734b5ee66e8cc80cbcb63138fc50b0 [file] [log] [blame]
Scott Duplichana649a962011-02-24 05:00:33 +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
Scott Duplichana649a962011-02-24 05:00:33 +000018 */
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070019
Scott Duplichana649a962011-02-24 05:00:33 +000020#include "agesawrapper.h"
21#include "amdlib.h"
22#include "BiosCallOuts.h"
23#include "heapManager.h"
24#include "SB800.h"
Jens Rottmanndb6c5bf2013-03-21 22:21:28 +010025#include <northbridge/amd/agesa/family14/dimmSpd.h>
Scott Duplichana649a962011-02-24 05:00:33 +000026
Kyösti Mälkkif1bb19a2014-05-04 17:23:49 +030027/* Should AGESA_GNB_PCIE_SLOT_RESET use agesa_NoopSuccess?
28 *
29 * Board is known to have some issues with integrated NIC and
30 * might need implementation to drive some GPIOs.
31 */
32
Kyösti Mälkkic0096012014-05-05 18:56:33 +030033static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr);
34
Aladyshev Konstantin3d63b0a2012-12-19 00:58:35 +040035CONST BIOS_CALLOUT_STRUCT BiosCallouts[] =
Scott Duplichana649a962011-02-24 05:00:33 +000036{
Kyösti Mälkki08df7322014-05-04 14:53:36 +030037 {AGESA_ALLOCATE_BUFFER, BiosAllocateBuffer },
38 {AGESA_DEALLOCATE_BUFFER, BiosDeallocateBuffer },
Kyösti Mälkki08df7322014-05-04 14:53:36 +030039 {AGESA_LOCATE_BUFFER, BiosLocateBuffer },
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030040 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkki08df7322014-05-04 14:53:36 +030041 {AGESA_READ_SPD, BiosReadSpd },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030042 {AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +030043 {AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030044 {AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopSuccess },
Kyösti Mälkkic0096012014-05-05 18:56:33 +030045 {AGESA_HOOKBEFORE_DRAM_INIT, board_BeforeDramInit },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030046 {AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopSuccess },
Kyösti Mälkkif1bb19a2014-05-04 17:23:49 +030047 {AGESA_GNB_PCIE_SLOT_RESET, agesa_NoopUnsupported },
Scott Duplichana649a962011-02-24 05:00:33 +000048};
49
Aladyshev Konstantin3d63b0a2012-12-19 00:58:35 +040050AGESA_STATUS GetBiosCallout (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
51{
52 UINTN i;
53 AGESA_STATUS CalloutStatus;
54 UINTN CallOutCount = sizeof (BiosCallouts) / sizeof (BiosCallouts [0]);
55
56 for (i = 0; i < CallOutCount; i++)
Scott Duplichana649a962011-02-24 05:00:33 +000057 {
58 if (BiosCallouts[i].CalloutName == Func)
59 {
60 break;
61 }
62 }
63
Aladyshev Konstantin3d63b0a2012-12-19 00:58:35 +040064 if(i >= CallOutCount)
Scott Duplichana649a962011-02-24 05:00:33 +000065 {
66 return AGESA_UNSUPPORTED;
67 }
68
69 CalloutStatus = BiosCallouts[i].CalloutPtr (Func, Data, ConfigPtr);
70
71 return CalloutStatus;
72}
73
Scott Duplichana649a962011-02-24 05:00:33 +000074/* Call the host environment interface to provide a user hook opportunity. */
Kyösti Mälkkic0096012014-05-05 18:56:33 +030075static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINT32 Data, VOID *ConfigPtr)
Scott Duplichana649a962011-02-24 05:00:33 +000076{
77 AGESA_STATUS Status;
78 UINTN FcnData;
79 MEM_DATA_STRUCT *MemData;
80 UINT32 AcpiMmioAddr;
81 UINT32 GpioMmioAddr;
82 UINT8 Data8;
83 UINT16 Data16;
84 UINT8 TempData8;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070085
Scott Duplichana649a962011-02-24 05:00:33 +000086 FcnData = Data;
87 MemData = ConfigPtr;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070088
Scott Duplichana649a962011-02-24 05:00:33 +000089 Status = AGESA_SUCCESS;
90 /* Get SB800 MMIO Base (AcpiMmioAddr) */
91 WriteIo8 (0xCD6, 0x27);
92 Data8 = ReadIo8(0xCD7);
93 Data16 = Data8<<8;
94 WriteIo8 (0xCD6, 0x26);
95 Data8 = ReadIo8(0xCD7);
96 Data16 |= Data8;
97 AcpiMmioAddr = (UINT32)Data16 << 16;
98 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
Stefan Reinauer5ff7c132011-10-31 12:56:45 -070099
Scott Duplichana649a962011-02-24 05:00:33 +0000100 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG178);
101 Data8 &= ~BIT5;
102 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
103 TempData8 &= 0x03;
104 TempData8 |= Data8;
105 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700106
Scott Duplichana649a962011-02-24 05:00:33 +0000107 Data8 |= BIT2+BIT3;
108 Data8 &= ~BIT4;
109 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
110 TempData8 &= 0x23;
111 TempData8 |= Data8;
112 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, TempData8);
113 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG179);
114 Data8 &= ~BIT5;
115 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
116 TempData8 &= 0x03;
117 TempData8 |= Data8;
118 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
119 Data8 |= BIT2+BIT3;
120 Data8 &= ~BIT4;
121 TempData8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
122 TempData8 &= 0x23;
123 TempData8 |= Data8;
124 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, TempData8);
Stefan Reinauer5ff7c132011-10-31 12:56:45 -0700125
Scott Duplichana649a962011-02-24 05:00:33 +0000126 switch(MemData->ParameterListPtr->DDR3Voltage){
127 case VOLT1_35:
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_25:
136 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
137 Data8 &= ~(UINT8)BIT6;
138 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
139 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
140 Data8 &= ~(UINT8)BIT6;
141 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
142 break;
143 case VOLT1_5:
144 default:
145 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG178);
146 Data8 |= (UINT8)BIT6;
147 Write64Mem8(GpioMmioAddr+SB_GPIO_REG178, Data8);
148 Data8 = Read64Mem8 (GpioMmioAddr+SB_GPIO_REG179);
149 Data8 &= ~(UINT8)BIT6;
150 Write64Mem8(GpioMmioAddr+SB_GPIO_REG179, Data8);
151 }
Marshall Buschmaneab1db12011-06-10 21:16:41 -0500152 // disable memory clear for boot time reduction
153 MemData->ParameterListPtr->EnableMemClr = FALSE;
Scott Duplichana649a962011-02-24 05:00:33 +0000154 return Status;
155}