diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc index f802388724..1969a3526c 100644 --- a/src/soc/intel/baytrail/Makefile.inc +++ b/src/soc/intel/baytrail/Makefile.inc @@ -30,6 +30,7 @@ ramstage-y += pmutil.c smm-y += pmutil.c smm-y += smihandler.c ramstage-y += smm.c +ramstage-y += southcluster.c # Remove as ramstage gets fleshed out ramstage-y += placeholders.c diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c new file mode 100644 index 0000000000..32b8799e58 --- /dev/null +++ b/src/soc/intel/baytrail/southcluster.c @@ -0,0 +1,130 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2013 Google Inc. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static inline void +add_mmio_resource(device_t dev, int i, unsigned long addr, unsigned long size) +{ + mmio_resource(dev, i, addr >> 10, size >> 10); +} + +static void sc_add_mmio_resources(device_t dev) +{ + add_mmio_resource(dev, PBASE, PMC_BASE_ADDRESS, 1024); + add_mmio_resource(dev, IOBASE, IO_BASE_ADDRESS, 16 * 1024); + add_mmio_resource(dev, IBASE, ILB_BASE_ADDRESS, 1024); + add_mmio_resource(dev, SBASE, SPI_BASE_ADDRESS, 1024); + add_mmio_resource(dev, MPBASE, MPHY_BASE_ADDRESS, 1024 * 1024); + add_mmio_resource(dev, PUBASE, PUNIT_BASE_ADDRESS, 2048); + add_mmio_resource(dev, RCBA, RCBA_BASE_ADDRESS, 1024); +} + +/* Default IO range claimed by the LPC device. The upper bound is exclusive. */ +#define LPC_DEFAULT_IO_RANGE_LOWER 0 +#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000 + +static inline int io_range_in_default(int base, int size) +{ + /* Does it start above the range? */ + if (base >= LPC_DEFAULT_IO_RANGE_UPPER) + return 0; + + /* Is it entirely contained? */ + if (base >= LPC_DEFAULT_IO_RANGE_LOWER && + (base + size) < LPC_DEFAULT_IO_RANGE_UPPER) + return 1; + + /* This will return not in range for partial overlaps. */ + return 0; +} + +/* + * Note: this function assumes there is no overlap with the default LPC device's + * claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER. + */ +static void sc_add_io_resource(device_t dev, int base, int size, int index) +{ + struct resource *res; + + if (io_range_in_default(base, size)) + return; + + res = new_resource(dev, index); + res->base = base; + res->size = size; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +static void sc_add_io_resources(device_t dev) +{ + struct resource *res; + + /* Add the default claimed IO range for the LPC device. */ + res = new_resource(dev, 0); + res->base = LPC_DEFAULT_IO_RANGE_LOWER; + res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + + /* GPIO */ + sc_add_io_resource(dev, GPIO_BASE_ADDRESS, 256, GBASE); + + /* ACPI */ + sc_add_io_resource(dev, ACPI_BASE_ADDRESS, 128, ABASE); +} + +static void sc_read_resources(device_t dev) +{ + /* Get the normal PCI resources of this device. */ + pci_dev_read_resources(dev); + + /* Add non-standard MMIO resources. */ + sc_add_mmio_resources(dev); + + /* Add IO resources. */ + sc_add_io_resources(dev); +} + +static struct device_operations device_ops = { + .read_resources = sc_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = NULL, + .init = NULL, + .enable = NULL, + .scan_bus = NULL, + .ops_pci = &soc_pci_ops, +}; + +static const struct pci_driver southcluster __pci_driver = { + .ops = &device_ops, + .vendor = PCI_VENDOR_ID_INTEL, + .device = LPC_DEVID, +};