/* * 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, };