1 #include <console/console.h>
2 #include <device/device.h>
3 #include <device/pci.h>
4 #include <device/pci_ids.h>
5 #include <device/pci_ops.h>
6 #include <cpu/p6/msr.h>
9 #include <device/chip.h>
10 #include "../../../northbridge/amd/amdk8/northbridge.h"
13 #include "pc80/mc146818rtc.h"
17 unsigned long initial_apicid[CONFIG_MAX_CPUS] =
22 #define SMBGSTATUS 0xe0
24 #define SMBHSTADDR 0xe4
25 #define SMBHSTDAT 0xe6
26 #define SMBHSTCMD 0xe8
27 #define SMBHSTFIFO 0xe9
29 #define SMBUS_TIMEOUT (100*1000*10)
31 static inline void smbus_delay(void)
36 static int smbus_wait_until_ready(unsigned smbus_io_base)
39 loops = SMBUS_TIMEOUT;
43 val = inw(smbus_io_base + SMBGSTATUS);
44 if ((val & 0x800) == 0) {
47 if(loops == (SMBUS_TIMEOUT / 2)) {
48 outw(inw(smbus_io_base + SMBGSTATUS),
49 smbus_io_base + SMBGSTATUS);
55 static int smbus_wait_until_done(unsigned smbus_io_base)
58 loops = SMBUS_TIMEOUT;
63 val = inw(smbus_io_base + SMBGSTATUS);
64 if (((val & 0x8) == 0) | ((val & 0x437) != 0)) {
71 static int smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned value)
73 unsigned char global_status_register;
75 if (smbus_wait_until_ready(smbus_io_base) < 0) {
79 /* setup transaction */
80 /* disable interrupts */
81 outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
82 /* set the device I'm talking too */
83 outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
84 /* set the command/address... */
85 outb(0, smbus_io_base + SMBHSTCMD);
86 /* set up for a send byte */
87 outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
89 /* clear any lingering errors, so the transaction will run */
90 /* Do I need to write the bits to a 1 to clear an error? */
91 outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
93 /* set the data word...*/
94 outw(value, smbus_io_base + SMBHSTDAT);
96 /* start the command */
97 outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
100 /* poll for transaction completion */
101 if (smbus_wait_until_done(smbus_io_base) < 0) {
104 global_status_register = inw(smbus_io_base + SMBGSTATUS);
106 if (global_status_register != (1 << 4)) {
112 static int smbus_recv_byte(unsigned smbus_io_base, unsigned device)
114 unsigned char global_status_register;
117 if (smbus_wait_until_ready(smbus_io_base) < 0) {
121 /* setup transaction */
122 /* disable interrupts */
123 outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
124 /* set the device I'm talking too */
125 outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
126 /* set the command/address... */
127 outb(0, smbus_io_base + SMBHSTCMD);
128 /* set up for a send byte */
129 outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
131 /* clear any lingering errors, so the transaction will run */
132 /* Do I need to write the bits to a 1 to clear an error? */
133 outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
135 /* set the data word...*/
136 outw(0, smbus_io_base + SMBHSTDAT);
138 /* start the command */
139 outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
142 /* poll for transaction completion */
143 if (smbus_wait_until_done(smbus_io_base) < 0) {
147 global_status_register = inw(smbus_io_base + SMBGSTATUS);
149 /* read results of transaction */
150 byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
152 if (global_status_register != (1 << 4)) {
159 static int smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
161 unsigned char global_status_register;
164 if (smbus_wait_until_ready(smbus_io_base) < 0) {
168 /* setup transaction */
169 /* disable interrupts */
170 outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)), smbus_io_base + SMBGCTL);
171 /* set the device I'm talking too */
172 outw(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
173 /* set the command/address... */
174 outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
175 /* set up for a byte data read */
176 outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x2), smbus_io_base + SMBGCTL);
178 /* clear any lingering errors, so the transaction will run */
179 /* Do I need to write the bits to a 1 to clear an error? */
180 outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
182 /* clear the data word...*/
183 outw(0, smbus_io_base + SMBHSTDAT);
185 /* start the command */
186 outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
189 /* poll for transaction completion */
190 if (smbus_wait_until_done(smbus_io_base) < 0) {
194 global_status_register = inw(smbus_io_base + SMBGSTATUS);
196 /* read results of transaction */
197 byte = inw(smbus_io_base + SMBHSTDAT) & 0xff;
199 if (global_status_register != (1 << 4)) {
205 static int smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
207 if (smbus_wait_until_ready(smbus_io_base) < 0) {
211 /* setup transaction */
212 /* disable interrupts */
213 outw(inw(smbus_io_base + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)),
214 smbus_io_base + SMBGCTL);
215 /* set the device I'm talking too */
216 outw(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
217 outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
218 /* set up for a byte data write */ /* FIXME */
219 outw((inw(smbus_io_base + SMBGCTL) & ~7) | (0x1), smbus_io_base + SMBGCTL);
220 /* clear any lingering errors, so the transaction will run */
221 /* Do I need to write the bits to a 1 to clear an error? */
222 outw(inw(smbus_io_base + SMBGSTATUS), smbus_io_base + SMBGSTATUS);
224 /* clear the data word...*/
225 outw(val, smbus_io_base + SMBHSTDAT);
227 /* start the command */
228 outw((inw(smbus_io_base + SMBGCTL) | (1 << 3)), smbus_io_base + SMBGCTL);
230 /* poll for transaction completion */
231 if (smbus_wait_until_done(smbus_io_base) < 0) {
238 #define SMBUS_MUX 0x70
239 static void mainboard_init(device_t dev)
241 /* Set the mux to see the temperature sensors */
242 dev = dev_find_device(0x1022, 0x746b, 0);
244 unsigned smbus_io_base;
250 smbus_io_base = pci_read_config32(dev, 0x58) & ~1;;
251 result = smbus_send_byte(smbus_io_base, device, mux_setting);
253 (smbus_recv_byte(smbus_io_base, device) != mux_setting)) {
254 printk_err("SMBUS mux would not set to %d\n", mux_setting);
259 printk_err("SMBUS_controller not found\n");
263 static struct device_operations mainboard_operations = {
264 .read_resources = root_dev_read_resources,
265 .set_resources = root_dev_set_resources,
266 .enable_resources = enable_childrens_resources,
267 .init = mainboard_init,
268 .scan_bus = amdk8_scan_root_bus,
272 static void enumerate(struct chip *chip)
275 dev_root.ops = &mainboard_operations;
276 chip->dev = &dev_root;
278 for(child = chip->children; child; child = child->next) {
279 child->bus = &dev_root.link[0];
282 struct chip_control mainboard_arima_hdama_control = {
283 .enumerate = enumerate,
284 .name = "Arima HDAMA mainboard ",