Uwe Hermann | b80dbf0 | 2007-04-22 19:08:13 +0000 | [diff] [blame] | 1 | /* |
Stefan Reinauer | 7e61e45 | 2008-01-18 10:35:56 +0000 | [diff] [blame] | 2 | * This file is part of the coreboot project. |
Uwe Hermann | b80dbf0 | 2007-04-22 19:08:13 +0000 | [diff] [blame] | 3 | * |
| 4 | * Copyright (C) 2003-2004 Linux Networx |
| 5 | * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx) |
| 6 | * Copyright (C) 2003 Ronald G. Minnich <rminnich@gmail.com> |
| 7 | * Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov> |
| 8 | * Copyright (C) 2005 Tyan |
| 9 | * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan) |
| 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by |
| 13 | * the Free Software Foundation; version 2 of the License. |
| 14 | * |
| 15 | * This program is distributed in the hope that it will be useful, |
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | * GNU General Public License for more details. |
| 19 | * |
| 20 | * You should have received a copy of the GNU General Public License |
| 21 | * along with this program; if not, write to the Free Software |
Paul Menzel | a46a712 | 2013-02-23 18:37:27 +0100 | [diff] [blame] | 22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
Uwe Hermann | b80dbf0 | 2007-04-22 19:08:13 +0000 | [diff] [blame] | 23 | */ |
| 24 | |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 25 | #include <console/console.h> |
| 26 | #include <device/device.h> |
| 27 | #include <device/pci.h> |
Stefan Reinauer | de3206a | 2010-02-22 06:09:43 +0000 | [diff] [blame] | 28 | #include <reset.h> |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 29 | |
Kyösti Mälkki | a93c3fe | 2012-10-09 22:28:56 +0300 | [diff] [blame] | 30 | const char mainboard_name[] = CONFIG_MAINBOARD_VENDOR " " CONFIG_MAINBOARD_PART_NUMBER; |
| 31 | |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 32 | /** |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 33 | * Read the resources for the root device, that encompass the resources for |
| 34 | * the entire system. |
| 35 | * |
| 36 | * @param root Pointer to the device structure for the system root device. |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 37 | */ |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 38 | static void root_dev_read_resources(device_t root) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 39 | { |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 40 | printk(BIOS_ERR, "%s should never be called.\n", __func__); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | /** |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 44 | * Write the resources for every device. |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 45 | * |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 46 | * Write the resources for the root device, and every device under it which |
| 47 | * are all of the devices. |
| 48 | * |
| 49 | * @param root Pointer to the device structure for the system root device. |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 50 | */ |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 51 | static void root_dev_set_resources(device_t root) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 52 | { |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 53 | printk(BIOS_ERR, "%s should never be called.\n", __func__); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | /** |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 57 | * Scan devices on static buses. |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 58 | * |
Li-Ta Lo | 9f0d0f9 | 2004-05-10 16:05:16 +0000 | [diff] [blame] | 59 | * The enumeration of certain buses is purely static. The existence of |
| 60 | * devices on those buses can be completely determined at compile time |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 61 | * and is specified in the config file. Typical examples are the 'PNP' |
| 62 | * devices on a legacy ISA/LPC bus. There is no need of probing of any kind, |
| 63 | * the only thing we have to do is to walk through the bus and |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 64 | * enable or disable devices as indicated in the config file. |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 65 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 66 | * On the other hand, some devices are virtual and their existence is |
| 67 | * artificial. They can not be probed at run time. One example is the |
| 68 | * debug device. Those virtual devices have to be listed in the config |
| 69 | * file under some static bus in order to be enumerated at run time. |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 70 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 71 | * This function is the default scan_bus() method for the root device and |
| 72 | * LPC bridges. |
| 73 | * |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 74 | * @param bus Pointer to the device to which the static buses are attached to. |
| 75 | * @param max Maximum bus number currently used before scanning. |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 76 | * @return The largest bus number used. |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 77 | */ |
arch import user (historical) | 98d0d30 | 2005-07-06 17:13:46 +0000 | [diff] [blame] | 78 | static int smbus_max = 0; |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 79 | unsigned int scan_static_bus(device_t bus, unsigned int max) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 80 | { |
| 81 | device_t child; |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 82 | struct bus *link; |
Li-Ta Lo | e526669 | 2004-03-23 21:28:05 +0000 | [diff] [blame] | 83 | |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 84 | printk(BIOS_SPEW, "%s for %s\n", __func__, dev_path(bus)); |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 85 | |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 86 | for (link = bus->link_list; link; link = link->next) { |
| 87 | /* For SMBus bus enumerate. */ |
Myles Watson | 894a347 | 2010-06-09 22:41:35 +0000 | [diff] [blame] | 88 | child = link->children; |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 89 | |
| 90 | if (child && child->path.type == DEVICE_PATH_I2C) |
Myles Watson | 894a347 | 2010-06-09 22:41:35 +0000 | [diff] [blame] | 91 | link->secondary = ++smbus_max; |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 92 | |
| 93 | for (child = link->children; child; child = child->sibling) { |
| 94 | if (child->chip_ops && child->chip_ops->enable_dev) |
Eric Biederman | 7003ba4 | 2004-10-16 06:20:29 +0000 | [diff] [blame] | 95 | child->chip_ops->enable_dev(child); |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 96 | |
| 97 | if (child->ops && child->ops->enable) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 98 | child->ops->enable(child); |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 99 | |
| 100 | if (child->path.type == DEVICE_PATH_I2C) { |
| 101 | printk(BIOS_DEBUG, "smbus: %s[%d]->", |
| 102 | dev_path(child->bus->dev), |
| 103 | child->bus->link_num); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 104 | } |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 105 | printk(BIOS_DEBUG, "%s %s\n", dev_path(child), |
| 106 | child->enabled ? "enabled" : "disabled"); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 107 | } |
| 108 | } |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 109 | |
| 110 | for (link = bus->link_list; link; link = link->next) { |
| 111 | for (child = link->children; child; child = child->sibling) { |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 112 | if (!child->ops || !child->ops->scan_bus) |
| 113 | continue; |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 114 | printk(BIOS_SPEW, "%s scanning...\n", dev_path(child)); |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 115 | max = scan_bus(child, max); |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 116 | } |
| 117 | } |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 118 | |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 119 | printk(BIOS_SPEW, "%s for %s done\n", __func__, dev_path(bus)); |
Li-Ta Lo | fb4c50f | 2004-05-07 21:52:47 +0000 | [diff] [blame] | 120 | |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 121 | return max; |
| 122 | } |
| 123 | |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 124 | static void root_dev_enable_resources(device_t dev) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 125 | { |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 126 | } |
| 127 | |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 128 | /** |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 129 | * Scan root bus for generic systems. |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 130 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 131 | * This function is the default scan_bus() method of the root device. |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 132 | * |
| 133 | * @param root The root device structure. |
| 134 | * @param max The current bus number scanned so far, usually 0x00. |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 135 | * @return The largest bus number used. |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 136 | */ |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 137 | static unsigned int root_dev_scan_bus(device_t root, unsigned int max) |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 138 | { |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 139 | return scan_static_bus(root, max); |
| 140 | } |
| 141 | |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 142 | static void root_dev_init(device_t root) |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 143 | { |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 144 | } |
| 145 | |
Myles Watson | 7eac445 | 2010-06-17 16:16:56 +0000 | [diff] [blame] | 146 | static void root_dev_reset(struct bus *bus) |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 147 | { |
Uwe Hermann | d453dd0 | 2010-10-18 00:00:57 +0000 | [diff] [blame] | 148 | printk(BIOS_INFO, "Resetting board...\n"); |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 149 | hard_reset(); |
| 150 | } |
| 151 | |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 152 | /** |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 153 | * Default device operation for root device. |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 154 | * |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 155 | * This is the default device operation for root devices. These operations |
Uwe Hermann | c1ee429 | 2010-10-17 19:01:48 +0000 | [diff] [blame] | 156 | * should be fully usable as is. However the chip_operations::enable_dev() |
Li-Ta Lo | 0493069 | 2004-11-25 17:37:19 +0000 | [diff] [blame] | 157 | * of a motherboard can override this if you want non-default behavior. |
Li-Ta Lo | 9782f75 | 2004-05-05 21:15:42 +0000 | [diff] [blame] | 158 | */ |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 159 | struct device_operations default_dev_ops_root = { |
| 160 | .read_resources = root_dev_read_resources, |
| 161 | .set_resources = root_dev_set_resources, |
Eric Biederman | 03acab6 | 2004-10-14 21:25:53 +0000 | [diff] [blame] | 162 | .enable_resources = root_dev_enable_resources, |
| 163 | .init = root_dev_init, |
| 164 | .scan_bus = root_dev_scan_bus, |
Yinghai Lu | 13f1c2a | 2005-07-08 02:49:49 +0000 | [diff] [blame] | 165 | .reset_bus = root_dev_reset, |
Eric Biederman | e9a271e3 | 2003-09-02 03:36:25 +0000 | [diff] [blame] | 166 | }; |