blob: 856b8b32eba13e3dd69c09cf0c5b4e9e35984fbd [file] [log] [blame]
Frank Vibrans63e62b02011-02-14 18:38:14 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2011 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
Kerry Shefeed3292011-08-18 18:03:44 +080020#include <console/console.h>
Frank Vibrans63e62b02011-02-14 18:38:14 +000021#include <device/pci.h>
Patrick Georgi2c2e78d2012-02-16 18:54:37 +010022#include <arch/ioapic.h>
Frank Vibrans63e62b02011-02-14 18:38:14 +000023#include "lpc.h"
24
25
26void lpc_read_resources(device_t dev)
27{
28 struct resource *res;
29
Kerry Shefeed3292011-08-18 18:03:44 +080030 printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_read_resources - Start.\n");
Frank Vibrans63e62b02011-02-14 18:38:14 +000031 /* Get the normal pci resources of this device */
32 pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
33
34 pci_get_resource(dev, SPIROM_BASE_ADDRESS); /* SPI ROM base address */
35
36 /* Add an extra subtractive resource for both memory and I/O. */
37 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
38 res->base = 0;
39 res->size = 0x1000;
40 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
41 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
42
43 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
44 res->base = 0xff800000;
45 res->size = 0x00800000; /* 8 MB for flash */
46 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
47 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
48
Patrick Georgi2c2e78d2012-02-16 18:54:37 +010049 res = new_resource(dev, 3);
50 res->base = IO_APIC_ADDR;
Frank Vibrans63e62b02011-02-14 18:38:14 +000051 res->size = 0x00001000;
52 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
53
54 compact_resources(dev);
Kerry Shefeed3292011-08-18 18:03:44 +080055 printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_read_resources - End.\n");
Frank Vibrans63e62b02011-02-14 18:38:14 +000056}
57
58void lpc_set_resources(struct device *dev)
59{
60 struct resource *res;
61
Kerry Shefeed3292011-08-18 18:03:44 +080062 printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_set_resources - Start.\n");
Frank Vibrans63e62b02011-02-14 18:38:14 +000063 pci_dev_set_resources(dev);
64
65 /* Specical case. SPI Base Address. The SpiRomEnable should be set. */
66 res = find_resource(dev, SPIROM_BASE_ADDRESS);
67 pci_write_config32(dev, SPIROM_BASE_ADDRESS, res->base | 1 << 1);
Kerry Shefeed3292011-08-18 18:03:44 +080068 printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_set_resources - End.\n");
Frank Vibrans63e62b02011-02-14 18:38:14 +000069}
70
71/**
72 * @brief Enable resources for children devices
73 *
74 * @param dev the device whos children's resources are to be enabled
75 *
76 */
77void lpc_enable_childrens_resources(device_t dev)
78{
79 struct bus *link;
80 u32 reg, reg_x;
81 int var_num = 0;
82 u16 reg_var[3];
83
Kerry Shefeed3292011-08-18 18:03:44 +080084 printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_enable_childrens_resources - Start.\n");
Frank Vibrans63e62b02011-02-14 18:38:14 +000085 reg = pci_read_config32(dev, 0x44);
86 reg_x = pci_read_config32(dev, 0x48);
87
88 for (link = dev->link_list; link; link = link->next) {
89 device_t child;
90 for (child = link->children; child;
91 child = child->sibling) {
92 if (child->enabled
93 && (child->path.type == DEVICE_PATH_PNP)) {
94 struct resource *res;
95 for (res = child->resource_list; res; res = res->next) {
96 u32 base, end; /* don't need long long */
97 if (!(res->flags & IORESOURCE_IO))
98 continue;
99 base = res->base;
100 end = resource_end(res);
101/*
102 printk(BIOS_DEBUG, "sb800 lpc decode:%s, base=0x%08x, end=0x%08x\n",
103 dev_path(child), base, end);
104*/
105 switch (base) {
106 case 0x60: /* KB */
107 case 0x64: /* MS */
108 reg |= (1 << 29);
109 break;
110 case 0x3f8: /* COM1 */
111 reg |= (1 << 6);
112 break;
113 case 0x2f8: /* COM2 */
114 reg |= (1 << 7);
115 break;
116 case 0x378: /* Parallal 1 */
117 reg |= (1 << 0);
118 break;
119 case 0x3f0: /* FD0 */
120 reg |= (1 << 26);
121 break;
122 case 0x220: /* Aduio 0 */
123 reg |= (1 << 8);
124 break;
125 case 0x300: /* Midi 0 */
126 reg |= (1 << 18);
127 break;
128 case 0x400:
129 reg_x |= (1 << 16);
130 break;
131 case 0x480:
132 reg_x |= (1 << 17);
133 break;
134 case 0x500:
135 reg_x |= (1 << 18);
136 break;
137 case 0x580:
138 reg_x |= (1 << 19);
139 break;
140 case 0x4700:
141 reg_x |= (1 << 22);
142 break;
143 case 0xfd60:
144 reg_x |= (1 << 23);
145 break;
146 default:
147 if (var_num >= 3)
148 continue; /* only 3 var ; compact them ? */
149 switch (var_num) {
150 case 0:
151 reg_x |= (1 << 2);
152 break;
153 case 1:
154 reg_x |= (1 << 24);
155 break;
156 case 2:
157 reg_x |= (1 << 25);
158 break;
159 }
160 reg_var[var_num++] =
161 base & 0xffff;
162 }
163 }
164 }
165 }
166 }
167 pci_write_config32(dev, 0x44, reg);
168 pci_write_config32(dev, 0x48, reg_x);
169 /* Set WideIO for as many IOs found (fall through is on purpose) */
170 switch (var_num) {
171 case 2:
172 pci_write_config16(dev, 0x90, reg_var[2]);
173 case 1:
174 pci_write_config16(dev, 0x66, reg_var[1]);
175 case 0:
176 //pci_write_config16(dev, 0x64, reg_var[0]); //cause filo can not find sata
177 break;
178 }
Kerry Shefeed3292011-08-18 18:03:44 +0800179 printk(BIOS_DEBUG, "SB800 - Lpc.c - lpc_enable_childrens_resources - End.\n");
Frank Vibrans63e62b02011-02-14 18:38:14 +0000180}