blob: 3e559ea7c0cc839e18079ddeefcbd20e56e72ffd [file] [log] [blame]
Eric Biedermane9a271e32003-09-02 03:36:25 +00001#include <console/console.h>
2#include <device/device.h>
3#include <device/pci.h>
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00004#include <part/hard_reset.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +00005
6/**
7 * Read the resources for the root device,
Li-Ta Lo9782f752004-05-05 21:15:42 +00008 * that encompass the resources for the entire system.
Eric Biedermane9a271e32003-09-02 03:36:25 +00009 * @param root Pointer to the device structure for the system root device
10 */
11void root_dev_read_resources(device_t root)
12{
Eric Biederman03acab62004-10-14 21:25:53 +000013 struct resource *resource;
Eric Biedermane9a271e32003-09-02 03:36:25 +000014
15 /* Initialize the system wide io space constraints */
Eric Biederman03acab62004-10-14 21:25:53 +000016 resource = new_resource(root, 0);
17 resource->base = 0x400;
18 resource->size = 0;
19 resource->align = 0;
20 resource->gran = 0;
21 resource->limit = 0xffffUL;
22 resource->flags = IORESOURCE_IO;
23 compute_allocate_resource(&root->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +000024 IORESOURCE_IO, IORESOURCE_IO);
Eric Biedermane9a271e32003-09-02 03:36:25 +000025
26 /* Initialize the system wide memory resources constraints */
Eric Biederman03acab62004-10-14 21:25:53 +000027 resource = new_resource(root, 1);
28 resource->base = 0;
29 resource->size = 0;
30 resource->align = 0;
31 resource->gran = 0;
32 resource->limit = 0xffffffffUL;
33 resource->flags = IORESOURCE_MEM;
34 compute_allocate_resource(&root->link[0], resource,
Eric Biedermanb78c1972004-10-14 20:54:17 +000035 IORESOURCE_MEM, IORESOURCE_MEM);
Eric Biedermane9a271e32003-09-02 03:36:25 +000036}
37
38/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000039 * @brief Write the resources for every device
Li-Ta Lo04930692004-11-25 17:37:19 +000040 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000041 * Write the resources for the root device,
Eric Biedermane9a271e32003-09-02 03:36:25 +000042 * and every device under it which are all of the devices.
43 * @param root Pointer to the device structure for the system root device
44 */
45void root_dev_set_resources(device_t root)
46{
Eric Biedermanb78c1972004-10-14 20:54:17 +000047 struct bus *bus;
Li-Ta Loe5266692004-03-23 21:28:05 +000048
Eric Biedermanb78c1972004-10-14 20:54:17 +000049 bus = &root->link[0];
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000050 compute_allocate_resource(bus,
51 &root->resource[0], IORESOURCE_IO, IORESOURCE_IO);
52 compute_allocate_resource(bus,
53 &root->resource[1], IORESOURCE_MEM, IORESOURCE_MEM);
Eric Biedermane9a271e32003-09-02 03:36:25 +000054 assign_resources(bus);
55}
56
57/**
Li-Ta Lofb4c50f2004-05-07 21:52:47 +000058 * @brief Scan devices on static buses.
59 *
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +000060 * The enumeration of certain buses is purely static. The existence of
61 * devices on those buses can be completely determined at compile time
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000062 * and is specified in the config file. Typical examples are the 'PNP'
63 * devices on a legacy ISA/LPC bus. There is no need of probing of any kind,
64 * the only thing we have to do is to walk through the bus and
Li-Ta Lo04930692004-11-25 17:37:19 +000065 * enable or disable devices as indicated in the config file.
Li-Ta Lofb4c50f2004-05-07 21:52:47 +000066 *
Li-Ta Lo04930692004-11-25 17:37:19 +000067 * On the other hand, some devices are virtual and their existence is
68 * artificial. They can not be probed at run time. One example is the
69 * debug device. Those virtual devices have to be listed in the config
70 * file under some static bus in order to be enumerated at run time.
Li-Ta Lofb4c50f2004-05-07 21:52:47 +000071 *
Li-Ta Lo04930692004-11-25 17:37:19 +000072 * This function is the default scan_bus() method for the root device and
73 * LPC bridges.
74 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000075 * @param bus Pointer to the device structure which the static buses are attached
Li-Ta Lo04930692004-11-25 17:37:19 +000076 * @param max Maximum bus number currently used before scanning.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000077 * @return Largest bus number used.
Eric Biedermane9a271e32003-09-02 03:36:25 +000078 */
arch import user (historical)98d0d302005-07-06 17:13:46 +000079static int smbus_max = 0;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000080unsigned int scan_static_bus(device_t bus, unsigned int max)
Eric Biedermane9a271e32003-09-02 03:36:25 +000081{
82 device_t child;
83 unsigned link;
Li-Ta Loe5266692004-03-23 21:28:05 +000084
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000085 printk_spew("%s for %s\n", __func__, dev_path(bus));
Li-Ta Lo04930692004-11-25 17:37:19 +000086
Yinghai Lu13f1c2a2005-07-08 02:49:49 +000087 for(link = 0; link < bus->links; link++) {
88 /* for smbus bus enumerate */
89 child = bus->link[link].children;
90 if(child && child->path.type == DEVICE_PATH_I2C) {
91 bus->link[link].secondary = ++smbus_max;
92 }
93 for(child = bus->link[link].children; child; child = child->sibling) {
Eric Biederman7003ba42004-10-16 06:20:29 +000094 if (child->chip_ops && child->chip_ops->enable_dev) {
95 child->chip_ops->enable_dev(child);
96 }
Eric Biedermane9a271e32003-09-02 03:36:25 +000097 if (child->ops && child->ops->enable) {
98 child->ops->enable(child);
99 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000100 if (child->path.type == DEVICE_PATH_I2C) {
101 printk_debug("smbus: %s[%d]->",
102 dev_path(child->bus->dev), child->bus->link );
103 }
104 printk_debug("%s %s\n",
105 dev_path(child),
106 child->enabled?"enabled": "disabled");
Eric Biedermane9a271e32003-09-02 03:36:25 +0000107 }
108 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000109 for(link = 0; link < bus->links; link++) {
110 for(child = bus->link[link].children; child; child = child->sibling) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000111 if (!child->ops || !child->ops->scan_bus)
112 continue;
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000113 printk_spew("%s scanning...\n", dev_path(child));
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000114 max = scan_bus(child, max);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000115 }
116 }
Li-Ta Lofb4c50f2004-05-07 21:52:47 +0000117
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000118 printk_spew("%s for %s done\n", __func__, dev_path(bus));
Li-Ta Lofb4c50f2004-05-07 21:52:47 +0000119
Eric Biedermane9a271e32003-09-02 03:36:25 +0000120 return max;
121}
122
Li-Ta Lo9782f752004-05-05 21:15:42 +0000123/**
124 * @brief Enable resources for children devices
125 *
Li-Ta Lofb4c50f2004-05-07 21:52:47 +0000126 * @param dev the device whos children's resources are to be enabled
Li-Ta Lo9782f752004-05-05 21:15:42 +0000127 *
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000128 * This function is called by the global enable_resource() indirectly via the
Li-Ta Lo04930692004-11-25 17:37:19 +0000129 * device_operation::enable_resources() method of devices.
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000130 *
131 * Indirect mutual recursion:
Li-Ta Lo04930692004-11-25 17:37:19 +0000132 * enable_childrens_resources() -> enable_resources()
133 * enable_resources() -> device_operation::enable_resources()
134 * device_operation::enable_resources() -> enable_children_resources()
Li-Ta Lo9782f752004-05-05 21:15:42 +0000135 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000136void enable_childrens_resources(device_t dev)
137{
138 unsigned link;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000139 for(link = 0; link < dev->links; link++) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000140 device_t child;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000141 for(child = dev->link[link].children; child; child = child->sibling) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000142 enable_resources(child);
143 }
144 }
145}
146
Eric Biederman03acab62004-10-14 21:25:53 +0000147void root_dev_enable_resources(device_t dev)
148{
149 enable_childrens_resources(dev);
150}
151
Li-Ta Lo9782f752004-05-05 21:15:42 +0000152/**
Eric Biederman03acab62004-10-14 21:25:53 +0000153 * @brief Scan root bus for generic systems
Li-Ta Lo9782f752004-05-05 21:15:42 +0000154 *
Li-Ta Lofb4c50f2004-05-07 21:52:47 +0000155 * @param root The root device structure
Li-Ta Lo04930692004-11-25 17:37:19 +0000156 * @param max The current bus number scanned so far, usually 0x00
Li-Ta Lo9782f752004-05-05 21:15:42 +0000157 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000158 * This function is the default scan_bus() method of the root device.
Li-Ta Lo9782f752004-05-05 21:15:42 +0000159 */
Eric Biederman03acab62004-10-14 21:25:53 +0000160unsigned int root_dev_scan_bus(device_t root, unsigned int max)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000161{
Eric Biederman03acab62004-10-14 21:25:53 +0000162 return scan_static_bus(root, max);
163}
164
165void root_dev_init(device_t root)
166{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000167}
168
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000169void root_dev_reset(struct bus *bus)
170{
171 printk_info("Reseting board...\n");
172 hard_reset();
173}
174
Li-Ta Lo9782f752004-05-05 21:15:42 +0000175/**
176 * @brief Default device operation for root device
177 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000178 * This is the default device operation for root devices. These operations
179 * should be fully usable as is. However the chip_operations::enable_dev()
180 * of a motherboard can override this if you want non-default behavior.
Li-Ta Lo9782f752004-05-05 21:15:42 +0000181 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000182struct device_operations default_dev_ops_root = {
183 .read_resources = root_dev_read_resources,
184 .set_resources = root_dev_set_resources,
Eric Biederman03acab62004-10-14 21:25:53 +0000185 .enable_resources = root_dev_enable_resources,
186 .init = root_dev_init,
187 .scan_bus = root_dev_scan_bus,
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000188 .reset_bus = root_dev_reset,
Eric Biedermane9a271e32003-09-02 03:36:25 +0000189};
190
191/**
Li-Ta Lo04930692004-11-25 17:37:19 +0000192 * @brief The root of device tree.
Li-Ta Lofb4c50f2004-05-07 21:52:47 +0000193 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000194 * This is the root of the device tree. The device tree is defined in the
195 * static.c file and is generated by config tool during compile time.
Eric Biedermane9a271e32003-09-02 03:36:25 +0000196 */
Eric Biederman7003ba42004-10-16 06:20:29 +0000197extern struct device dev_root;