2 * This file is part of the coreboot project.
4 * Copyright (C) 2010 Advanced Micro Devices, Inc.
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.
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.
16 #ifndef _HUDSON_SMBUS_C_
17 #define _HUDSON_SMBUS_C_
23 static int smbus_wait_until_ready(u32 smbus_io_base
)
26 loops
= SMBUS_TIMEOUT
;
29 val
= inb(smbus_io_base
+ SMBHSTSTAT
);
31 if (val
== 0) { /* ready now */
34 outb(val
, smbus_io_base
+ SMBHSTSTAT
);
36 return -2; /* time out */
39 static int smbus_wait_until_done(u32 smbus_io_base
)
42 loops
= SMBUS_TIMEOUT
;
46 val
= inb(smbus_io_base
+ SMBHSTSTAT
);
47 val
&= 0x1f; /* mask off reserved bits */
49 return -5; /* error */
52 outb(val
, smbus_io_base
+ SMBHSTSTAT
); /* clear status */
56 return -3; /* timeout */
59 int do_smbus_recv_byte(u32 smbus_io_base
, u32 device
)
63 if (smbus_wait_until_ready(smbus_io_base
) < 0) {
64 return -2; /* not ready */
67 /* set the device I'm talking too */
68 outb(((device
& 0x7f) << 1) | 1, smbus_io_base
+ SMBHSTADDR
);
70 byte
= inb(smbus_io_base
+ SMBHSTCTRL
);
71 byte
&= 0xe3; /* Clear [4:2] */
72 byte
|= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
73 outb(byte
, smbus_io_base
+ SMBHSTCTRL
);
75 /* poll for transaction completion */
76 if (smbus_wait_until_done(smbus_io_base
) < 0) {
77 return -3; /* timeout or error */
80 /* read results of transaction */
81 byte
= inb(smbus_io_base
+ SMBHSTCMD
);
86 int do_smbus_send_byte(u32 smbus_io_base
, u32 device
, u8 val
)
90 if (smbus_wait_until_ready(smbus_io_base
) < 0) {
91 return -2; /* not ready */
94 /* set the command... */
95 outb(val
, smbus_io_base
+ SMBHSTCMD
);
97 /* set the device I'm talking too */
98 outb(((device
& 0x7f) << 1) | 0, smbus_io_base
+ SMBHSTADDR
);
100 byte
= inb(smbus_io_base
+ SMBHSTCTRL
);
101 byte
&= 0xe3; /* Clear [4:2] */
102 byte
|= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
103 outb(byte
, smbus_io_base
+ SMBHSTCTRL
);
105 /* poll for transaction completion */
106 if (smbus_wait_until_done(smbus_io_base
) < 0) {
107 return -3; /* timeout or error */
113 int do_smbus_read_byte(u32 smbus_io_base
, u32 device
,
118 if (smbus_wait_until_ready(smbus_io_base
) < 0) {
119 return -2; /* not ready */
122 /* set the command/address... */
123 outb(address
& 0xff, smbus_io_base
+ SMBHSTCMD
);
125 /* set the device I'm talking too */
126 outb(((device
& 0x7f) << 1) | 1, smbus_io_base
+ SMBHSTADDR
);
128 byte
= inb(smbus_io_base
+ SMBHSTCTRL
);
129 byte
&= 0xe3; /* Clear [4:2] */
130 byte
|= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
131 outb(byte
, smbus_io_base
+ SMBHSTCTRL
);
133 /* poll for transaction completion */
134 if (smbus_wait_until_done(smbus_io_base
) < 0) {
135 return -3; /* timeout or error */
138 /* read results of transaction */
139 byte
= inb(smbus_io_base
+ SMBHSTDAT0
);
144 int do_smbus_write_byte(u32 smbus_io_base
, u32 device
,
149 if (smbus_wait_until_ready(smbus_io_base
) < 0) {
150 return -2; /* not ready */
153 /* set the command/address... */
154 outb(address
& 0xff, smbus_io_base
+ SMBHSTCMD
);
156 /* set the device I'm talking too */
157 outb(((device
& 0x7f) << 1) | 0, smbus_io_base
+ SMBHSTADDR
);
160 outb(val
, smbus_io_base
+ SMBHSTDAT0
);
162 byte
= inb(smbus_io_base
+ SMBHSTCTRL
);
163 byte
&= 0xe3; /* Clear [4:2] */
164 byte
|= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
165 outb(byte
, smbus_io_base
+ SMBHSTCTRL
);
167 /* poll for transaction completion */
168 if (smbus_wait_until_done(smbus_io_base
) < 0) {
169 return -3; /* timeout or error */
175 void alink_ab_indx(u32 reg_space
, u32 reg_addr
,
180 outl((reg_space
& 0x7) << 29 | reg_addr
, AB_INDX
);
183 * For certain revisions of the chip, the ABCFG registers,
184 * with an address of 0x100NN (where 'N' is any hexadecimal
185 * number), require an extra programming step.*/
191 /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<29 | reg_addr); */
192 outl((reg_space
& 0x7) << 29 | reg_addr
, AB_INDX
); /* probably we dont have to do it again. */
197 void alink_rc_indx(u32 reg_space
, u32 reg_addr
, u32 port
,
202 outl((reg_space
& 0x7) << 29 | (port
& 3) << 24 | reg_addr
, AB_INDX
);
205 * For certain revisions of the chip, the ABCFG registers,
206 * with an address of 0x100NN (where 'N' is any hexadecimal
207 * number), require an extra programming step.*/
213 //printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<29 | (port&3) << 24 | reg_addr);
214 outl((reg_space
& 0x7) << 29 | (port
& 3) << 24 | reg_addr
, AB_INDX
); /* probably we dont have to do it again. */
219 /* space = 0: AX_INDXC, AX_DATAC
220 * space = 1: AX_INDXP, AX_DATAP
222 void alink_ax_indx(u32 space
/*c or p? */ , u32 axindc
,
227 /* read axindc to tmp */
228 outl(space
<< 29 | space
<< 3 | 0x30, AB_INDX
);
229 outl(axindc
, AB_DATA
);
231 outl(space
<< 29 | space
<< 3 | 0x34, AB_INDX
);
239 outl(space
<< 29 | space
<< 3 | 0x30, AB_INDX
);
240 outl(axindc
, AB_DATA
);
242 outl(space
<< 29 | space
<< 3 | 0x34, AB_INDX
);