e71bb5cbee84f6a2f58884949fef36a1c4ca7bfa
[coreboot.git] / src / southbridge / broadcom / bcm5785 / bcm5785_smbus.h
1 /*
2  * Copyright 2005 AMD
3  *  by yinghai.lu@amd.com
4  */
5 #include <device/smbus_def.h>
6
7 #define SMBHSTSTAT 0x0
8 #define SMBSLVSTAT 0x1
9 #define SMBHSTCTRL 0x2
10 #define SMBHSTCMD  0x3
11 #define SMBHSTADDR 0x4
12 #define SMBHSTDAT0 0x5
13 #define SMBHSTDAT1 0x6
14 #define SMBHSTBLKDAT 0x7
15
16 #define SMBSLVCTRL 0x8
17 #define SMBSLVCMD_SHADOW 0x9
18 #define SMBSLVEVT 0xa
19 #define SMBSLVDAT 0xc
20
21
22 /* Between 1-10 seconds, We should never timeout normally
23  * Longer than this is just painful when a timeout condition occurs.
24  */
25 #define SMBUS_TIMEOUT (100*1000*10)
26
27 static inline void smbus_delay(void)
28 {
29         outb(0x80, 0x80);
30 }
31
32 static int smbus_wait_until_ready(unsigned smbus_io_base)
33 {
34         unsigned long loops;
35         loops = SMBUS_TIMEOUT;
36         do {
37                 unsigned char val;
38                 val = inb(smbus_io_base + SMBHSTSTAT);
39                 val &= 0x1f;
40                 if (val == 0) { // ready now
41                         return 0;
42                 }
43                 outb(val, smbus_io_base + SMBHSTSTAT);
44         } while(--loops);
45         return -2; // time out
46 }
47
48 static int smbus_wait_until_done(unsigned smbus_io_base)
49 {
50         unsigned long loops;
51         loops = SMBUS_TIMEOUT;
52         do {
53                 unsigned char val;
54
55                 val = inb(smbus_io_base + SMBHSTSTAT);
56                 val &= 0x1f; // mask off reserved bits
57                 if ( val & 0x1c) {
58                         return -5; // error
59                 }
60                 if ( val == 0x02) {
61                         outb(val, smbus_io_base + SMBHSTSTAT); // clear status
62                         return 0; //
63                 }
64         } while(--loops);
65         return -3; // timeout
66 }
67
68 static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
69 {
70         uint8_t byte;
71
72         if (smbus_wait_until_ready(smbus_io_base) < 0) {
73                 return -2; // not ready
74         }
75
76         /* set the device I'm talking too */
77         outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
78
79         byte = inb(smbus_io_base + SMBHSTCTRL);
80         byte &= 0xe3; // Clear [4:2]
81         byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
82         outb(byte, smbus_io_base + SMBHSTCTRL);
83
84         /* poll for transaction completion */
85         if (smbus_wait_until_done(smbus_io_base) < 0) {
86                 return -3; // timeout or error
87         }
88
89         /* read results of transaction */
90         byte = inb(smbus_io_base + SMBHSTCMD);
91
92         return byte;
93
94 }
95 static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
96 {
97         uint8_t byte;
98
99         if (smbus_wait_until_ready(smbus_io_base) < 0) {
100                 return -2; // not ready
101         }
102
103         /* set the command... */
104         outb(val, smbus_io_base + SMBHSTCMD);
105
106         /* set the device I'm talking too */
107         outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
108
109         byte = inb(smbus_io_base + SMBHSTCTRL);
110         byte &= 0xe3; // Clear [4:2]
111         byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
112         outb(byte, smbus_io_base + SMBHSTCTRL);
113
114         /* poll for transaction completion */
115         if (smbus_wait_until_done(smbus_io_base) < 0) {
116                 return -3; // timeout or error
117         }
118
119         return 0;
120
121 }
122
123
124 static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
125 {
126         uint8_t byte;
127
128         if (smbus_wait_until_ready(smbus_io_base) < 0) {
129                 return -2; // not ready
130         }
131
132         /* set the command/address... */
133         outb(address & 0xff, smbus_io_base + SMBHSTCMD);
134
135         /* set the device I'm talking too */
136         outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
137
138         byte = inb(smbus_io_base + SMBHSTCTRL);
139         byte &= 0xe3; // Clear [4:2]
140         byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
141         outb(byte, smbus_io_base + SMBHSTCTRL);
142
143         /* poll for transaction completion */
144         if (smbus_wait_until_done(smbus_io_base) < 0) {
145                 return -3; // timeout or error
146         }
147
148         /* read results of transaction */
149         byte = inb(smbus_io_base + SMBHSTDAT0);
150
151         return byte;
152 }
153 static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
154 {
155         uint8_t byte;
156
157         if (smbus_wait_until_ready(smbus_io_base) < 0) {
158                 return -2; // not ready
159         }
160
161         /* set the command/address... */
162         outb(address & 0xff, smbus_io_base + SMBHSTCMD);
163
164         /* set the device I'm talking too */
165         outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
166
167         /* output value */
168         outb(val, smbus_io_base + SMBHSTDAT0);
169
170         byte = inb(smbus_io_base + SMBHSTCTRL);
171         byte &= 0xe3; // Clear [4:2]
172         byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
173         outb(byte, smbus_io_base + SMBHSTCTRL);
174
175         /* poll for transaction completion */
176         if (smbus_wait_until_done(smbus_io_base) < 0) {
177                 return -3; // timeout or error
178         }
179
180         return 0;
181
182 }
183
184