Various cosmetic and coding style fixes in src/devices.
[coreboot.git] / src / devices / cardbus_device.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2005 Linux Networx
5  * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
6  * Copyright (C) 2005 Ronald G. Minnich <rminnich@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20  */
21
22 #include <console/console.h>
23 #include <device/device.h>
24 #include <device/pci.h>
25 #include <device/pci_ids.h>
26 #include <device/cardbus.h>
27
28 /*
29  * I don't think this code is quite correct but it is close.
30  * Anyone with a cardbus bridge and a little time should be able
31  * to make it usable quickly. -- Eric Biederman 24 March 2005
32  */
33
34 /*
35  * IO should be max 256 bytes. However, since we may have a P2P bridge below
36  * a cardbus bridge, we need 4K.
37  */
38 #define CARDBUS_IO_SIZE         4096
39 #define CARDBUS_MEM_SIZE        (32 * 1024 * 1024)
40
41 static void cardbus_record_bridge_resource(device_t dev, resource_t moving,
42                 resource_t min_size, unsigned int index, unsigned long type)
43 {
44         struct resource *resource;
45         unsigned long gran;
46         resource_t step;
47
48         /* Initialize the constraints on the current bus. */
49         resource = NULL;
50         if (!moving)
51                 return;
52
53         resource = new_resource(dev, index);
54         resource->size = 0;
55         gran = 0;
56         step = 1;
57         while ((moving & step) == 0) {
58                 gran += 1;
59                 step <<= 1;
60         }
61         resource->gran = gran;
62         resource->align = gran;
63         resource->limit = moving | (step - 1);
64         resource->flags = type;
65
66         /* Don't let the minimum size exceed what we can put in the resource. */
67         if ((min_size - 1) > resource->limit)
68                 min_size = resource->limit + 1;
69
70         resource->size = min_size;
71 }
72
73 static void cardbus_size_bridge_resource(device_t dev, unsigned int index)
74 {
75         struct resource *resource;
76         resource_t min_size;
77
78         resource = find_resource(dev, index);
79         if (resource) {
80                 min_size = resource->size;
81                 /*
82                  * Always allocate at least the miniumum size to a
83                  * cardbus bridge in case a new card is plugged in.
84                  */
85                 if (resource->size < min_size)
86                         resource->size = min_size;
87         }
88 }
89
90 void cardbus_read_resources(device_t dev)
91 {
92         resource_t moving_base, moving_limit, moving;
93         unsigned long type;
94         u16 ctl;
95
96         /* See if needs a card control registers base address. */
97
98         pci_get_resource(dev, PCI_BASE_ADDRESS_0);
99
100         compact_resources(dev);
101
102         /* See which bridge I/O resources are implemented. */
103         moving_base = pci_moving_config32(dev, PCI_CB_IO_BASE_0);
104         moving_limit = pci_moving_config32(dev, PCI_CB_IO_LIMIT_0);
105         moving = moving_base & moving_limit;
106
107         /* Initialize the I/O space constraints on the current bus. */
108         cardbus_record_bridge_resource(dev, moving, CARDBUS_IO_SIZE,
109                                        PCI_CB_IO_BASE_0, IORESOURCE_IO);
110         cardbus_size_bridge_resource(dev, PCI_CB_IO_BASE_0);
111
112         /* See which bridge I/O resources are implemented. */
113         moving_base = pci_moving_config32(dev, PCI_CB_IO_BASE_1);
114         moving_limit = pci_moving_config32(dev, PCI_CB_IO_LIMIT_1);
115         moving = moving_base & moving_limit;
116
117         /* Initialize the I/O space constraints on the current bus. */
118         cardbus_record_bridge_resource(dev, moving, CARDBUS_IO_SIZE,
119                                        PCI_CB_IO_BASE_1, IORESOURCE_IO);
120
121         /* If I can, enable prefetch for mem0. */
122         ctl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL);
123         ctl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
124         ctl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
125         ctl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
126         pci_write_config16(dev, PCI_CB_BRIDGE_CONTROL, ctl);
127         ctl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL);
128
129         /* See which bridge memory resources are implemented. */
130         moving_base = pci_moving_config32(dev, PCI_CB_MEMORY_BASE_0);
131         moving_limit = pci_moving_config32(dev, PCI_CB_MEMORY_LIMIT_0);
132         moving = moving_base & moving_limit;
133
134         /* Initialize the memory space constraints on the current bus. */
135         type = IORESOURCE_MEM;
136         if (ctl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)
137                 type |= IORESOURCE_PREFETCH;
138         cardbus_record_bridge_resource(dev, moving, CARDBUS_MEM_SIZE,
139                                        PCI_CB_MEMORY_BASE_0, type);
140         if (type & IORESOURCE_PREFETCH)
141                 cardbus_size_bridge_resource(dev, PCI_CB_MEMORY_BASE_0);
142
143         /* See which bridge memory resources are implemented. */
144         moving_base = pci_moving_config32(dev, PCI_CB_MEMORY_BASE_1);
145         moving_limit = pci_moving_config32(dev, PCI_CB_MEMORY_LIMIT_1);
146         moving = moving_base & moving_limit;
147
148         /* Initialize the memory space constraints on the current bus. */
149         cardbus_record_bridge_resource(dev, moving, CARDBUS_MEM_SIZE,
150                                        PCI_CB_MEMORY_BASE_1, IORESOURCE_MEM);
151         cardbus_size_bridge_resource(dev, PCI_CB_MEMORY_BASE_1);
152
153         compact_resources(dev);
154 }
155
156 void cardbus_enable_resources(device_t dev)
157 {
158         u16 ctrl;
159
160         ctrl = pci_read_config16(dev, PCI_CB_BRIDGE_CONTROL);
161         ctrl |= (dev->link_list->bridge_ctrl & (
162                         PCI_BRIDGE_CTL_PARITY |
163                         PCI_BRIDGE_CTL_SERR |
164                         PCI_BRIDGE_CTL_NO_ISA |
165                         PCI_BRIDGE_CTL_VGA |
166                         PCI_BRIDGE_CTL_MASTER_ABORT |
167                         PCI_BRIDGE_CTL_BUS_RESET));
168         /* Error check */
169         ctrl |= (PCI_CB_BRIDGE_CTL_PARITY + PCI_CB_BRIDGE_CTL_SERR);
170         printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
171         pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
172
173         pci_dev_enable_resources(dev);
174 }
175
176 struct device_operations default_cardbus_ops_bus = {
177         .read_resources   = cardbus_read_resources,
178         .set_resources    = pci_dev_set_resources,
179         .enable_resources = cardbus_enable_resources,
180         .init             = 0,
181         .scan_bus         = pci_scan_bridge,
182         .enable           = 0,
183         .reset_bus        = pci_bus_reset,
184 };