southbridge/amd/sr5650: Add MCFG ACPI table support
As the southbridge largely controls the PCI[e] configuration space this patch moves the resource allocation from the northbridge to the southbridge when the extended configuration space region is enabled. Change-Id: I0c4ba74ddcc727cd92b848d5d3240e6f9f392101 Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: https://review.coreboot.org/12050 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com> Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
This commit is contained in:
parent
5f2bf6d02d
commit
1eaaa0e446
|
@ -740,7 +740,10 @@ static void amdfam10_domain_read_resources(device_t dev)
|
||||||
if (IS_ENABLED(CONFIG_MMCONF_SUPPORT)) {
|
if (IS_ENABLED(CONFIG_MMCONF_SUPPORT)) {
|
||||||
struct resource *res = new_resource(dev, 0xc0010058);
|
struct resource *res = new_resource(dev, 0xc0010058);
|
||||||
res->base = CONFIG_MMCONF_BASE_ADDRESS;
|
res->base = CONFIG_MMCONF_BASE_ADDRESS;
|
||||||
res->size = CONFIG_MMCONF_BUS_NUMBER * 4096*256;
|
res->size = CONFIG_MMCONF_BUS_NUMBER * 1024 * 1024; /* Each bus needs 1M */
|
||||||
|
res->align = log2(res->size);
|
||||||
|
res->gran = log2(res->size);
|
||||||
|
res->limit = 0xffffffffffffffffULL; /* 64-bit location allowed */
|
||||||
res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
|
res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE |
|
||||||
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
|
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
|
#include <arch/acpi.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/pci.h>
|
#include <device/pci.h>
|
||||||
#include <device/pci_ids.h>
|
#include <device/pci_ids.h>
|
||||||
|
@ -349,6 +350,17 @@ void rs780_enable(device_t dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !IS_ENABLED(CONFIG_AMD_SB_CIMX)
|
||||||
|
unsigned long acpi_fill_mcfg(unsigned long current)
|
||||||
|
{
|
||||||
|
/* FIXME
|
||||||
|
* Leave table blank until proper contents
|
||||||
|
* are determined.
|
||||||
|
*/
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct chip_operations southbridge_amd_rs780_ops = {
|
struct chip_operations southbridge_amd_rs780_ops = {
|
||||||
CHIP_NAME("ATI RS780")
|
CHIP_NAME("ATI RS780")
|
||||||
.enable_dev = rs780_enable,
|
.enable_dev = rs780_enable,
|
||||||
|
|
|
@ -30,12 +30,6 @@
|
||||||
#include <cpu/amd/powernow.h>
|
#include <cpu/amd/powernow.h>
|
||||||
#include "sb700.h"
|
#include "sb700.h"
|
||||||
|
|
||||||
unsigned long acpi_fill_mcfg(unsigned long current)
|
|
||||||
{
|
|
||||||
/* Just a dummy */
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lpc_init(device_t dev)
|
static void lpc_init(device_t dev)
|
||||||
{
|
{
|
||||||
u8 byte;
|
u8 byte;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* This file is part of the coreboot project.
|
* This file is part of the coreboot project.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
* Copyright (C) 2010 Advanced Micro Devices, Inc.
|
||||||
|
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -25,12 +26,6 @@
|
||||||
#include <arch/acpi.h>
|
#include <arch/acpi.h>
|
||||||
#include "sb800.h"
|
#include "sb800.h"
|
||||||
|
|
||||||
unsigned long acpi_fill_mcfg(unsigned long current)
|
|
||||||
{
|
|
||||||
/* Just a dummy */
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lpc_init(device_t dev)
|
static void lpc_init(device_t dev)
|
||||||
{
|
{
|
||||||
u8 byte;
|
u8 byte;
|
||||||
|
|
|
@ -15,3 +15,12 @@
|
||||||
|
|
||||||
config SOUTHBRIDGE_AMD_SR5650
|
config SOUTHBRIDGE_AMD_SR5650
|
||||||
bool
|
bool
|
||||||
|
|
||||||
|
if SOUTHBRIDGE_AMD_SR5650
|
||||||
|
config EXT_CONF_SUPPORT
|
||||||
|
bool "Enable PCI-E MMCONFIG support"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Select to enable PCI-E MMCONFIG support on the SR5650.
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#include <device/pci_ids.h>
|
#include <device/pci_ids.h>
|
||||||
#include <device/pci_ops.h>
|
#include <device/pci_ops.h>
|
||||||
#include <arch/ioapic.h>
|
#include <arch/ioapic.h>
|
||||||
|
#include <lib.h>
|
||||||
#include "sr5650.h"
|
#include "sr5650.h"
|
||||||
|
#include "cmn.h"
|
||||||
|
|
||||||
/* Table 6-6 Recommended Interrupt Routing Configuration */
|
/* Table 6-6 Recommended Interrupt Routing Configuration */
|
||||||
typedef struct _apic_device_info {
|
typedef struct _apic_device_info {
|
||||||
|
@ -154,6 +156,11 @@ static void pcie_init(struct device *dev)
|
||||||
|
|
||||||
static void sr5690_read_resource(struct device *dev)
|
static void sr5690_read_resource(struct device *dev)
|
||||||
{
|
{
|
||||||
|
if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
|
||||||
|
printk(BIOS_DEBUG,"%s: %s\n", __func__, dev_path(dev));
|
||||||
|
set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 1 << 3); /* Hide BAR3 */
|
||||||
|
}
|
||||||
|
|
||||||
pci_dev_read_resources(dev);
|
pci_dev_read_resources(dev);
|
||||||
|
|
||||||
/* rpr6.2.(1). Write the Base Address Register (BAR) */
|
/* rpr6.2.(1). Write the Base Address Register (BAR) */
|
||||||
|
@ -167,6 +174,88 @@ static void sr5690_read_resource(struct device *dev)
|
||||||
static void sr5690_set_resources(struct device *dev)
|
static void sr5690_set_resources(struct device *dev)
|
||||||
{
|
{
|
||||||
pci_write_config32(dev, 0xf8, 0x1); /* Set IOAPIC's index to 1 and make sure no one changes it */
|
pci_write_config32(dev, 0xf8, 0x1); /* Set IOAPIC's index to 1 and make sure no one changes it */
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
|
||||||
|
uint32_t reg;
|
||||||
|
device_t amd_ht_cfg_dev;
|
||||||
|
device_t amd_addr_map_dev;
|
||||||
|
resource_t res_base;
|
||||||
|
resource_t res_end;
|
||||||
|
uint32_t base;
|
||||||
|
uint32_t limit;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG,"%s %s\n", dev_path(dev), __func__);
|
||||||
|
|
||||||
|
/* Find requisite AMD CPU devices */
|
||||||
|
amd_ht_cfg_dev = dev_find_slot(0, PCI_DEVFN(0x18, 0));
|
||||||
|
amd_addr_map_dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
|
||||||
|
|
||||||
|
if (!amd_ht_cfg_dev || !amd_addr_map_dev) {
|
||||||
|
printk(BIOS_WARNING, "%s: %s Unable to locate CPU control devices\n", __func__, dev_path(dev));
|
||||||
|
} else {
|
||||||
|
res = sr5650_retrieve_cpu_mmio_resource();
|
||||||
|
if (res) {
|
||||||
|
/* Set up MMCONFIG bus range */
|
||||||
|
set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 0 << 3); /* Make BAR3 visible */
|
||||||
|
set_nbcfg_enable_bits(dev, 0x7c, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register */
|
||||||
|
set_nbcfg_enable_bits(dev, 0x84, 7 << 16, 0 << 16); /* Program bus range = 255 busses */
|
||||||
|
pci_write_config32(dev, 0x1c, res->base);
|
||||||
|
|
||||||
|
/* Enable MMCONFIG decoding. */
|
||||||
|
set_htiu_enable_bits(dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */
|
||||||
|
set_nbcfg_enable_bits(dev, 0x7c, 1 << 30, 0 << 30); /* Disable writes to the BAR3 register */
|
||||||
|
set_nbmisc_enable_bits(dev, 0x0, 1 << 3, 1 << 3); /* Hide BAR3 */
|
||||||
|
|
||||||
|
/* Set up nonposted resource in MMIO space */
|
||||||
|
res_base = res->base; /* Get the base address */
|
||||||
|
res_end = resource_end(res); /* Get the limit (rounded up) */
|
||||||
|
printk(BIOS_DEBUG, "%s: %s[0x1c] base = %0llx limit = %0llx\n", __func__, dev_path(dev), res_base, res_end);
|
||||||
|
|
||||||
|
/* Locate an unused MMIO resource */
|
||||||
|
for (reg = 0xb8; reg >= 0x80; reg -= 8) {
|
||||||
|
base = pci_read_config32(amd_addr_map_dev, reg);
|
||||||
|
limit = pci_read_config32(amd_addr_map_dev, reg + 4);
|
||||||
|
if (!(base & 0x3))
|
||||||
|
break; /* Unused resource found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If an unused MMIO resource was available, set up the mapping */
|
||||||
|
if (!(base & 0x3)) {
|
||||||
|
uint32_t sblk;
|
||||||
|
|
||||||
|
/* Remember this resource has been stored. */
|
||||||
|
res->flags |= IORESOURCE_STORED;
|
||||||
|
report_resource_stored(dev, res, " <mmconfig>");
|
||||||
|
|
||||||
|
/* Get SBLink value (HyperTransport I/O Hub Link ID). */
|
||||||
|
sblk = (pci_read_config32(amd_ht_cfg_dev, 0x64) >> 8) & 0x3;
|
||||||
|
|
||||||
|
/* Calculate the MMIO mapping base */
|
||||||
|
base &= 0x000000f0;
|
||||||
|
base |= ((res_base >> 8) & 0xffffff00);
|
||||||
|
base |= 3;
|
||||||
|
|
||||||
|
/* Calculate the MMIO mapping limit */
|
||||||
|
limit &= 0x00000048;
|
||||||
|
limit |= ((res_end >> 8) & 0xffffff00);
|
||||||
|
limit |= (sblk << 4);
|
||||||
|
limit |= (1 << 7);
|
||||||
|
|
||||||
|
/* Configure and enable MMIO mapping */
|
||||||
|
printk(BIOS_INFO, "%s: %s <- index %x base %04x limit %04x\n", __func__, dev_path(amd_addr_map_dev), reg, base, limit);
|
||||||
|
pci_write_config32(amd_addr_map_dev, reg + 4, limit);
|
||||||
|
pci_write_config32(amd_addr_map_dev, reg, base);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printk(BIOS_WARNING, "%s: %s No free MMIO resources available\n", __func__, dev_path(dev));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printk(BIOS_WARNING, "%s: %s Unable to locate CPU MMCONF resource\n", __func__, dev_path(dev));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pci_dev_set_resources(dev);
|
pci_dev_set_resources(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,21 @@
|
||||||
extern void set_pcie_dereset(void);
|
extern void set_pcie_dereset(void);
|
||||||
extern void set_pcie_reset(void);
|
extern void set_pcie_reset(void);
|
||||||
|
|
||||||
|
struct resource * sr5650_retrieve_cpu_mmio_resource() {
|
||||||
|
device_t cpu;
|
||||||
|
struct resource *res;
|
||||||
|
|
||||||
|
for (cpu = all_devices; cpu; cpu = cpu->next) {
|
||||||
|
if (cpu->bus->dev->path.type != DEVICE_PATH_CPU_CLUSTER)
|
||||||
|
continue;
|
||||||
|
res = probe_resource(cpu->bus->dev, 0xc0010058);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* extension registers */
|
/* extension registers */
|
||||||
u32 pci_ext_read_config32(device_t nb_dev, device_t dev, u32 reg)
|
u32 pci_ext_read_config32(device_t nb_dev, device_t dev, u32 reg)
|
||||||
{
|
{
|
||||||
|
@ -796,6 +811,22 @@ static void add_ivrs_device_entries(struct device *parent, struct device *dev, i
|
||||||
free(root_level);
|
free(root_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long acpi_fill_mcfg(unsigned long current)
|
||||||
|
{
|
||||||
|
struct resource *res;
|
||||||
|
resource_t mmconf_base = EXT_CONF_BASE_ADDRESS;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_EXT_CONF_SUPPORT)) {
|
||||||
|
res = sr5650_retrieve_cpu_mmio_resource();
|
||||||
|
if (res)
|
||||||
|
mmconf_base = res->base;
|
||||||
|
|
||||||
|
current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, mmconf_base, 0x0, 0x0, 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long acpi_fill_ivrs(acpi_ivrs_t* ivrs, unsigned long current)
|
static unsigned long acpi_fill_ivrs(acpi_ivrs_t* ivrs, unsigned long current)
|
||||||
{
|
{
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
|
|
@ -131,4 +131,5 @@ void sr5650_iommu_enable_resources(device_t dev);
|
||||||
void sr5650_nb_pci_table(device_t nb_dev);
|
void sr5650_nb_pci_table(device_t nb_dev);
|
||||||
void init_gen2(device_t nb_dev, device_t dev, u8 port);
|
void init_gen2(device_t nb_dev, device_t dev, u8 port);
|
||||||
void sr56x0_lock_hwinitreg(void);
|
void sr56x0_lock_hwinitreg(void);
|
||||||
|
struct resource * sr5650_retrieve_cpu_mmio_resource(void);
|
||||||
#endif /* SR5650_H */
|
#endif /* SR5650_H */
|
||||||
|
|
Loading…
Reference in New Issue