2015-05-13 03:19:47 +02:00
|
|
|
/*
|
|
|
|
* This file is part of the coreboot project.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2008-2009 coresystems GmbH
|
|
|
|
* Copyright (C) 2014 Google Inc.
|
2015-05-13 03:23:27 +02:00
|
|
|
* Copyright (C) 2015 Intel Corporation.
|
2015-05-13 03:19:47 +02:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; version 2 of the License.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <console/console.h>
|
|
|
|
#include <delay.h>
|
|
|
|
#include <arch/io.h>
|
|
|
|
#include <device/device.h>
|
|
|
|
#include <device/pci.h>
|
|
|
|
#include <device/pci_def.h>
|
|
|
|
#include <soc/pch.h>
|
|
|
|
#include <soc/pci_devs.h>
|
|
|
|
#include <soc/ramstage.h>
|
|
|
|
#include <soc/spi.h>
|
|
|
|
|
|
|
|
u8 pch_revision(void)
|
|
|
|
{
|
|
|
|
return pci_read_config8(PCH_DEV_LPC, PCI_REVISION_ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 pch_type(void)
|
|
|
|
{
|
|
|
|
return pci_read_config16(PCH_DEV_LPC, PCI_DEVICE_ID);
|
|
|
|
}
|
|
|
|
|
2015-05-13 03:23:27 +02:00
|
|
|
void *get_spi_bar(void)
|
2015-05-13 03:19:47 +02:00
|
|
|
{
|
2015-05-13 03:23:27 +02:00
|
|
|
device_t dev = PCH_DEV_SPI;
|
|
|
|
uint32_t bar;
|
|
|
|
|
2015-09-17 20:50:39 +02:00
|
|
|
bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
|
2015-05-13 03:23:27 +02:00
|
|
|
/* Bits 31-12 are the base address as per EDS for SPI 1F/5,
|
|
|
|
* Don't care about 0-11 bit
|
|
|
|
*/
|
2015-09-17 20:50:39 +02:00
|
|
|
return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
|
2015-05-13 03:19:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 pch_read_soft_strap(int id)
|
|
|
|
{
|
2015-05-13 03:23:27 +02:00
|
|
|
uint32_t fdoc;
|
|
|
|
void *spibar = get_spi_bar();
|
2015-05-13 03:19:47 +02:00
|
|
|
|
2015-05-13 03:23:27 +02:00
|
|
|
fdoc = read32(spibar + SPIBAR_FDOC);
|
2015-05-13 03:19:47 +02:00
|
|
|
fdoc &= ~0x00007ffc;
|
2015-05-13 03:23:27 +02:00
|
|
|
write32(spibar + SPIBAR_FDOC, fdoc);
|
2015-05-13 03:19:47 +02:00
|
|
|
|
|
|
|
fdoc |= 0x00004000;
|
|
|
|
fdoc |= id * 4;
|
2015-05-13 03:23:27 +02:00
|
|
|
write32(spibar + SPIBAR_FDOC, fdoc);
|
2015-05-13 03:19:47 +02:00
|
|
|
|
2015-05-13 03:23:27 +02:00
|
|
|
return read32(spibar + SPIBAR_FDOD);
|
2015-05-13 03:19:47 +02:00
|
|
|
}
|
|
|
|
|
2015-05-13 03:23:27 +02:00
|
|
|
#if ENV_RAMSTAGE
|
|
|
|
void pch_enable_dev(device_t dev)
|
2015-05-13 03:19:47 +02:00
|
|
|
{
|
2015-05-13 03:23:27 +02:00
|
|
|
/* FSP should implement routines to disable PCH IPs */
|
2015-05-13 03:19:47 +02:00
|
|
|
u32 reg32;
|
|
|
|
|
|
|
|
/* These devices need special enable/disable handling */
|
|
|
|
switch (PCI_SLOT(dev->path.pci.devfn)) {
|
|
|
|
case PCH_DEV_SLOT_PCIE:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dev->enabled) {
|
|
|
|
printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
|
|
|
|
|
|
|
|
/* Ensure memory, io, and bus master are all disabled */
|
|
|
|
reg32 = pci_read_config32(dev, PCI_COMMAND);
|
|
|
|
reg32 &= ~(PCI_COMMAND_MASTER |
|
|
|
|
PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
|
|
|
|
pci_write_config32(dev, PCI_COMMAND, reg32);
|
|
|
|
} else {
|
|
|
|
/* Enable SERR */
|
|
|
|
reg32 = pci_read_config32(dev, PCI_COMMAND);
|
|
|
|
reg32 |= PCI_COMMAND_SERR;
|
|
|
|
pci_write_config32(dev, PCI_COMMAND, reg32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|