blob: 84ad3553720fe4599de34a6efadae605786d8300 [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
Paul Menzela8ae1c62013-02-20 13:21:20 +010012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Frank Vibrans69da1b62011-02-14 19:04:45 +000013 * GNU General Public License for more details.
Frank Vibrans69da1b62011-02-14 19:04:45 +000014 */
efdesign98d7a696d2011-09-15 15:24:26 -060015
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älkki6025efa2014-05-05 13:20:56 +030021#include <stdlib.h>
Frank Vibrans69da1b62011-02-14 19:04:45 +000022
Stefan Reinauerdd132a52015-07-30 11:16:37 -070023static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr);
24static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr);
Kyösti Mälkkic0096012014-05-05 18:56:33 +030025
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030026const BIOS_CALLOUT_STRUCT BiosCallouts[] =
Frank Vibrans69da1b62011-02-14 19:04:45 +000027{
Kyösti Mälkki5e19fa42014-05-04 23:13:54 +030028 {AGESA_DO_RESET, agesa_Reset },
Kyösti Mälkkia1ebbc42014-10-17 22:33:22 +030029 {AGESA_READ_SPD, agesa_ReadSpd },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030030 {AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
Kyösti Mälkki6b4b1512014-05-05 12:05:53 +030031 {AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
Kyösti Mälkkic0096012014-05-05 18:56:33 +030032 {AGESA_GNB_PCIE_SLOT_RESET, board_GnbPcieSlotReset },
33 {AGESA_HOOKBEFORE_DRAM_INIT, board_BeforeDramInit },
Kyösti Mälkkic459f962014-05-04 17:07:45 +030034 {AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopSuccess },
35 {AGESA_HOOKBEFORE_DQS_TRAINING, agesa_NoopSuccess },
36 {AGESA_HOOKBEFORE_EXIT_SELF_REF, agesa_NoopSuccess },
Frank Vibrans69da1b62011-02-14 19:04:45 +000037};
Kyösti Mälkki6025efa2014-05-05 13:20:56 +030038const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
Frank Vibrans69da1b62011-02-14 19:04:45 +000039
Marc Jones36abff12011-11-07 23:26:14 -070040/* Call the host environment interface to provide a user hook opportunity. */
Stefan Reinauerdd132a52015-07-30 11:16:37 -070041static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +000042{
Jens Rottmann384ee9f2013-02-18 20:26:50 +010043 // Unlike e.g. AMD Inagua, Persimmon is unable to vary the RAM voltage.
44 // Make sure the right speed settings are selected.
45 ((MEM_DATA_STRUCT*)ConfigPtr)->ParameterListPtr->DDR3Voltage = VOLT1_5;
46 return AGESA_SUCCESS;
Frank Vibrans69da1b62011-02-14 19:04:45 +000047}
efdesign98d7a696d2011-09-15 15:24:26 -060048
Frank Vibrans69da1b62011-02-14 19:04:45 +000049/* PCIE slot reset control */
Stefan Reinauerdd132a52015-07-30 11:16:37 -070050static AGESA_STATUS board_GnbPcieSlotReset (UINT32 Func, UINTN Data, VOID *ConfigPtr)
Frank Vibrans69da1b62011-02-14 19:04:45 +000051{
Marc Jones36abff12011-11-07 23:26:14 -070052 AGESA_STATUS Status;
53 UINTN FcnData;
54 PCIe_SLOT_RESET_INFO *ResetInfo;
efdesign98d7a696d2011-09-15 15:24:26 -060055
Marc Jones36abff12011-11-07 23:26:14 -070056 UINT32 GpioMmioAddr;
57 UINT32 AcpiMmioAddr;
58 UINT8 Data8;
59 UINT16 Data16;
efdesign98d7a696d2011-09-15 15:24:26 -060060
Marc Jones36abff12011-11-07 23:26:14 -070061 FcnData = Data;
62 ResetInfo = ConfigPtr;
63 // Get SB800 MMIO Base (AcpiMmioAddr)
64 WriteIo8(0xCD6, 0x27);
65 Data8 = ReadIo8(0xCD7);
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +020066 Data16 = Data8 << 8;
Marc Jones36abff12011-11-07 23:26:14 -070067 WriteIo8(0xCD6, 0x26);
68 Data8 = ReadIo8(0xCD7);
Elyes HAOUAS6350a2e2016-09-16 20:49:38 +020069 Data16 |= Data8;
Marc Jones36abff12011-11-07 23:26:14 -070070 AcpiMmioAddr = (UINT32)Data16 << 16;
71 Status = AGESA_UNSUPPORTED;
72 GpioMmioAddr = AcpiMmioAddr + GPIO_BASE;
73 switch (ResetInfo->ResetId)
74 {
Jens Rottmannfa8702c2013-02-18 19:40:33 +010075 case 46: // GPIO50 = SBGPIO_PCIE_RST# affects LAN0, LAN1, PCIe slot
Marc Jones36abff12011-11-07 23:26:14 -070076 switch (ResetInfo->ResetControl) {
zbaoafd141d2012-03-30 15:32:07 +080077 case AssertSlotReset:
Jens Rottmannfa8702c2013-02-18 19:40:33 +010078 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG50);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +020079 Data8 &= ~(UINT8)BIT6;
Jens Rottmannfa8702c2013-02-18 19:40:33 +010080 Write64Mem8(GpioMmioAddr+SB_GPIO_REG50, Data8);
Marc Jones36abff12011-11-07 23:26:14 -070081 Status = AGESA_SUCCESS;
82 break;
zbaoafd141d2012-03-30 15:32:07 +080083 case DeassertSlotReset:
Jens Rottmannfa8702c2013-02-18 19:40:33 +010084 Data8 = Read64Mem8(GpioMmioAddr+SB_GPIO_REG50);
Elyes HAOUASf2fcf222016-10-02 10:09:11 +020085 Data8 |= BIT6;
Jens Rottmannfa8702c2013-02-18 19:40:33 +010086 Write64Mem8 (GpioMmioAddr+SB_GPIO_REG50, Data8);
Marc Jones36abff12011-11-07 23:26:14 -070087 Status = AGESA_SUCCESS;
88 break;
89 }
90 break;
91 }
92 return Status;
Frank Vibrans69da1b62011-02-14 19:04:45 +000093}