diff options
author | Stefan Reinauer <reinauer@chromium.org> | 2012-11-30 12:34:04 -0800 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2012-11-30 23:59:58 +0100 |
commit | 8d7115560d469f901d7d8ccb242d0b437e7394aa (patch) | |
tree | 0f1b4bd63c48a233c49d5a9ca15f08a1675d1ff4 /src/device/cardbus_device.c | |
parent | 4b6be985aae8bff84ae442e7be7669e93694fa1e (diff) | |
download | coreboot-8d7115560d469f901d7d8ccb242d0b437e7394aa.tar.xz |
Rename devices -> device
to match src/include/device
Change-Id: I5d0e5b4361c34881a3b81347aac48738cb5b9af0
Signed-off-by: Stefan Reinauer <reinauer@google.com>
Reviewed-on: http://review.coreboot.org/1960
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
Diffstat (limited to 'src/device/cardbus_device.c')
-rw-r--r-- | src/device/cardbus_device.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/device/cardbus_device.c b/src/device/cardbus_device.c new file mode 100644 index 0000000000..0b07e3458f --- /dev/null +++ b/src/device/cardbus_device.c @@ -0,0 +1,184 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Linux Networx + * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx) + * Copyright (C) 2005 Ronald G. Minnich <rminnich@gmail.com> + * + * 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 <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/cardbus.h> + +/* + * I don't think this code is quite correct but it is close. + * Anyone with a cardbus bridge and a little time should be able + * to make it usable quickly. -- Eric Biederman 24 March 2005 + */ + +/* + * IO should be max 256 bytes. However, since we may have a P2P bridge below + * a cardbus bridge, we need 4K. + */ +#define CARDBUS_IO_SIZE 4096 +#define CARDBUS_MEM_SIZE (32 * 1024 * 1024) + +static void cardbus_record_bridge_resource(device_t dev, resource_t moving, + resource_t min_size, unsigned int index, unsigned long type) +{ + struct resource *resource; + unsigned long gran; + resource_t step; + + /* Initialize the constraints on the current bus. */ + resource = NULL; + if (!moving) + return; + + resource = new_resource(dev, index); + resource->size = 0; + gran = 0; + step = 1; + while ((moving & step) == 0) { + gran += 1; + step <<= 1; + } + resource->gran = gran; + resource->align = gran; + resource->limit = moving | (step - 1); + resource->flags = type; + + /* Don't let the minimum size exceed what we can put in the resource. */ + if ((min_size - 1) > resource->limit) + min_size = resource->limit + 1; + + resource->size = min_size; +} + +static void cardbus_size_bridge_resource(device_t dev, unsigned int index) +{ + struct resource *resource; + resource_t min_size; + + resource = find_resource(dev, index); + if (resource) { + min_size = resource->size; + /* + * Always allocate at least the miniumum size to a + * cardbus bridge in case a new card is plugged in. + */ + if (resource->size < min_size) + resource->size = min_size; + } +} + +void cardbus_read_resources(device_t dev) +{ + resource_t moving_base, moving_limit, moving; + unsigned long type; + u16 ctl; + + /* See if needs a card control registers base address. */ + + pci_get_resource(dev, PCI_BASE_ADDRESS_0); + + compact_resources(dev); + + /* See which bridge I/O resources are implemented. */ + moving_base = pci_moving_config32(dev, PCI_CB_IO_BASE_0); + moving_limit = pci_moving_config32(dev, PCI_CB_IO_LIMIT_0); + moving = moving_base & moving_limit; + + /* Initialize the I/O space constraints on the current bus. */ + cardbus_record_bridge_resource(dev, moving, CARDBUS_IO_SIZE, + PCI_CB_IO_BASE_0, IORESOURCE_IO); + cardbus_size_bridge_resource(dev, PCI_CB_IO_BASE_0); + + /* See which bridge I/O resources are implemented. */ + moving_base = pci_moving_config32(dev, PCI_CB_IO_BASE_1); + moving_limit = pci_moving_config32(dev, PCI_CB_IO_LIMIT_1); + moving = moving_base & moving_limit; + + /* Initialize the I/O space constraints on the current bus. */ + cardbus_record_bridge_resource(dev, moving, CARDBUS_IO_SIZE, + PCI_CB_IO_BASE_1, IORESOURCE_IO); + + /* If I can, enable prefetch for mem0. */ + ctl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL); + ctl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; + ctl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; + ctl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; + pci_write_config16(dev, PCI_CB_BRIDGE_CONTROL, ctl); + ctl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL); + + /* See which bridge memory resources are implemented. */ + moving_base = pci_moving_config32(dev, PCI_CB_MEMORY_BASE_0); + moving_limit = pci_moving_config32(dev, PCI_CB_MEMORY_LIMIT_0); + moving = moving_base & moving_limit; + + /* Initialize the memory space constraints on the current bus. */ + type = IORESOURCE_MEM; + if (ctl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) + type |= IORESOURCE_PREFETCH; + cardbus_record_bridge_resource(dev, moving, CARDBUS_MEM_SIZE, + PCI_CB_MEMORY_BASE_0, type); + if (type & IORESOURCE_PREFETCH) + cardbus_size_bridge_resource(dev, PCI_CB_MEMORY_BASE_0); + + /* See which bridge memory resources are implemented. */ + moving_base = pci_moving_config32(dev, PCI_CB_MEMORY_BASE_1); + moving_limit = pci_moving_config32(dev, PCI_CB_MEMORY_LIMIT_1); + moving = moving_base & moving_limit; + + /* Initialize the memory space constraints on the current bus. */ + cardbus_record_bridge_resource(dev, moving, CARDBUS_MEM_SIZE, + PCI_CB_MEMORY_BASE_1, IORESOURCE_MEM); + cardbus_size_bridge_resource(dev, PCI_CB_MEMORY_BASE_1); + + compact_resources(dev); +} + +void cardbus_enable_resources(device_t dev) +{ + u16 ctrl; + + ctrl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL); + ctrl |= (dev->link_list->bridge_ctrl & ( + PCI_BRIDGE_CTL_PARITY | + PCI_BRIDGE_CTL_SERR | + PCI_BRIDGE_CTL_NO_ISA | + PCI_BRIDGE_CTL_VGA | + PCI_BRIDGE_CTL_MASTER_ABORT | + PCI_BRIDGE_CTL_BUS_RESET)); + /* Error check */ + ctrl |= (PCI_CB_BRIDGE_CTL_PARITY + PCI_CB_BRIDGE_CTL_SERR); + printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl); + pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); + + pci_dev_enable_resources(dev); +} + +struct device_operations default_cardbus_ops_bus = { + .read_resources = cardbus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = cardbus_enable_resources, + .init = 0, + .scan_bus = pci_scan_bridge, + .enable = 0, + .reset_bus = pci_bus_reset, +}; |