blob: fe14000ce9ce5273d8c3a3bf61b6710d760b0231 [file] [log] [blame]
Daisuke Nojiria6712f32015-01-23 10:06:19 -08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2015 Google 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.
Daisuke Nojiria6712f32015-01-23 10:06:19 -080014 */
15
Anatol Pomazaud9af30b2015-02-04 10:09:27 -080016#include <arch/io.h>
17#include <assert.h>
Daisuke Nojiria6712f32015-01-23 10:06:19 -080018#include <console/console.h>
Anatol Pomazaud9af30b2015-02-04 10:09:27 -080019#include <delay.h>
Daisuke Nojiria6712f32015-01-23 10:06:19 -080020#include <device/i2c.h>
21#include <soc/i2c.h>
22
Anatol Pomazaud9af30b2015-02-04 10:09:27 -080023struct cygnus_i2c_regs {
24 u32 i2c_con;
25 u32 i2c_timing_con;
26 u32 i2c_addr;
27 u32 i2c_fifo_master;
28 u32 i2c_fifo_slave;
29 u32 i2c_bit_bang;
30 u32 reserved0[(0x30 - 0x18) / 4];
31 u32 i2c_master_comm;
32 u32 i2c_slave_comm;
33 u32 i2c_int_en;
34 u32 i2c_int_status;
35 u32 i2c_master_data_wr;
36 u32 i2c_master_data_rd;
37 u32 i2c_slave_data_wr;
38 u32 i2c_slave_data_rd;
39 u32 reserved1[(0xb0 - 0x50) / 4];
40 u32 i2c_timing_con2;
41};
42
43static struct cygnus_i2c_regs *i2c_bus[] = {
44 (struct cygnus_i2c_regs *)0x18008000,
45 (struct cygnus_i2c_regs *)0x1800b000,
46};
47
48#define I2C_TIMEOUT_US 100000 /* 100ms */
49#define I2C_FIFO_MAX_SIZE 64
50
51#define ETIMEDOUT 1
52#define EINVAL 2
53#define EBUSY 3
54
55/* Configuration (0x0) */
56#define I2C_SMB_RESET (1 << 31)
57#define I2C_SMB_EN (1 << 30)
58
59/* Timing configuration (0x4) */
60#define I2C_MODE_400 (1 << 31)
61
62/* Master FIFO control (0xc) */
63#define I2C_MASTER_RX_FIFO_FLUSH (1 << 31)
64#define I2C_MASTER_TX_FIFO_FLUSH (1 << 30)
65
66/* Master command (0x30) */
67#define I2C_MASTER_START_BUSY (1 << 31)
68#define I2C_MASTER_STATUS_SFT 25
69#define I2C_MASTER_STATUS_MASK (0x7 << I2C_MASTER_STATUS_SFT)
70#define I2C_MASTER_PROT_SFT 9
71#define I2C_MASTER_PROT_BLK_WR (0x7 << I2C_MASTER_PROT_SFT)
72#define I2C_MASTER_PROT_BLK_RD (0x8 << I2C_MASTER_PROT_SFT)
73
74/* Master data write (0x40) */
75#define I2C_MASTER_WR_STATUS (1 << 31)
76
77/* Master data read (0x44) */
78#define I2C_MASTER_RD_DATA_MASK 0xff
79
80static unsigned int i2c_bus_busy(struct cygnus_i2c_regs *reg_addr)
81{
82 return read32(&reg_addr->i2c_master_comm) & I2C_MASTER_START_BUSY;
83}
84
85static int i2c_wait_bus_busy(struct cygnus_i2c_regs *reg_addr)
86{
87 int timeout = I2C_TIMEOUT_US;
88 while (timeout--) {
89 if (!i2c_bus_busy(reg_addr))
90 break;
91 udelay(1);
92 }
93
94 if (timeout <= 0)
95 return ETIMEDOUT;
96
97 return 0;
98}
99
100static void i2c_flush_fifo(struct cygnus_i2c_regs *reg_addr)
101{
102 write32(&reg_addr->i2c_fifo_master,
103 I2C_MASTER_RX_FIFO_FLUSH | I2C_MASTER_TX_FIFO_FLUSH);
104}
105
106static int i2c_write(struct cygnus_i2c_regs *reg_addr, struct i2c_seg *segment)
107{
108 uint8_t *data = segment->buf;
109 unsigned int val, status;
110 int i, ret;
111
112 write32(&reg_addr->i2c_master_data_wr, segment->chip << 1);
113
114 for (i = 0; i < segment->len; i++) {
115 val = data[i];
116
117 /* mark the last byte */
118 if (i == segment->len - 1)
119 val |= I2C_MASTER_WR_STATUS;
120
121 write32(&reg_addr->i2c_master_data_wr, val);
122 }
123 if (segment->len == 0)
124 write32(&reg_addr->i2c_master_data_wr, I2C_MASTER_WR_STATUS);
125
126 /*
127 * Now we can activate the transfer.
128 */
129 write32(&reg_addr->i2c_master_comm,
130 I2C_MASTER_START_BUSY | I2C_MASTER_PROT_BLK_WR);
131
132 ret = i2c_wait_bus_busy(reg_addr);
133 if (ret) {
134 printk(BIOS_ERR, "I2C bus timeout\n");
135 goto flush_fifo;
136 }
137
138 /* check transaction successful */
139 status = read32(&reg_addr->i2c_master_comm);
140 ret = (status & I2C_MASTER_STATUS_MASK) >> I2C_MASTER_STATUS_SFT;
141 if (ret) {
142 printk(BIOS_ERR, "I2C write error %u\n", status);
143 goto flush_fifo;
144 }
145
146 return 0;
147
148flush_fifo:
149 i2c_flush_fifo(reg_addr);
150 return ret;
151}
152
153static int i2c_read(struct cygnus_i2c_regs *reg_addr, struct i2c_seg *segment)
154{
155 uint8_t *data = segment->buf;
156 int i, ret;
157 unsigned int status;
158
159 write32(&reg_addr->i2c_master_data_wr, segment->chip << 1 | 1);
160
161 /*
162 * Now we can activate the transfer. Specify the number of bytes to read
163 */
164 write32(&reg_addr->i2c_master_comm,
165 I2C_MASTER_START_BUSY | I2C_MASTER_PROT_BLK_RD | segment->len);
166
167 ret = i2c_wait_bus_busy(reg_addr);
168 if (ret) {
169 printk(BIOS_ERR, "I2C bus timeout\n");
170 goto flush_fifo;
171 }
172
173 /* check transaction successful */
174 status = read32(&reg_addr->i2c_master_comm);
175 ret = (status & I2C_MASTER_STATUS_MASK) >> I2C_MASTER_STATUS_SFT;
176 if (ret) {
177 printk(BIOS_ERR, "I2C read error %u\n", status);
178 goto flush_fifo;
179 }
180
181 for (i = 0; i < segment->len; i++)
182 data[i] = read32(&reg_addr->i2c_master_data_rd) &
183 I2C_MASTER_RD_DATA_MASK;
184
185 return 0;
186
187flush_fifo:
188 i2c_flush_fifo(reg_addr);
189 return ret;
190}
191
192static int i2c_do_xfer(struct cygnus_i2c_regs *reg_addr,
193 struct i2c_seg *segment)
194{
195 int ret;
196
197 if (segment->len > I2C_FIFO_MAX_SIZE - 1) {
198 printk(BIOS_ERR,
199 "I2C transfer error: segment size (%d) is larger than limit (%d)\n",
200 segment->len, I2C_FIFO_MAX_SIZE);
201 return EINVAL;
202 }
203
204 if (i2c_bus_busy(reg_addr)) {
205 printk(BIOS_WARNING, "I2C transfer error: bus is busy\n");
206 return EBUSY;
207 }
208
209 if (segment->read)
210 ret = i2c_read(reg_addr, segment);
211 else
212 ret = i2c_write(reg_addr, segment);
213
214 return ret;
215}
216
Daisuke Nojiria6712f32015-01-23 10:06:19 -0800217int platform_i2c_transfer(unsigned bus, struct i2c_seg *segments, int seg_count)
218{
Anatol Pomazaud9af30b2015-02-04 10:09:27 -0800219 int i;
220 int res = 0;
221 struct cygnus_i2c_regs *regs = i2c_bus[bus];
222 struct i2c_seg *seg = segments;
223
224 for (i = 0; i < seg_count; i++, seg++) {
225 res = i2c_do_xfer(regs, seg);
226 if (res)
227 break;
228 }
229 return res;
Daisuke Nojiria6712f32015-01-23 10:06:19 -0800230}
231
232void i2c_init(unsigned int bus, unsigned int hz)
233{
Anatol Pomazaud9af30b2015-02-04 10:09:27 -0800234 struct cygnus_i2c_regs *regs = i2c_bus[bus];
235
236 assert(bus >= 0 && bus <= 1);
237
238 setbits_le32(&regs->i2c_con, I2C_SMB_RESET);
239 udelay(100); /* wait 100 usec per spec */
240 clrbits_le32(&regs->i2c_con, I2C_SMB_RESET);
241
242 switch (hz) {
243 case 100000:
244 clrbits_le32(&regs->i2c_timing_con, I2C_MODE_400);
245 break;
246 case 400000:
247 setbits_le32(&regs->i2c_timing_con, I2C_MODE_400);
248 break;
249 default:
250 printk(BIOS_ERR, "I2C bus does not support frequency %d Hz\n",
251 hz);
252 break;
253 }
254
255 i2c_flush_fifo(regs);
256
257 /* disable all interrupts */
258 write32(&regs->i2c_int_en, 0);
259
260 /* clear all pending interrupts */
261 write32(&regs->i2c_int_status, 0xffffffff);
262
263 write32(&regs->i2c_con, I2C_SMB_EN);
Daisuke Nojiria6712f32015-01-23 10:06:19 -0800264}