blob: 49505a0782afd38147a1cb06b59f1abca5c72ac4 [file] [log] [blame]
Angel Pons1ddb8942020-04-04 18:51:26 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Gabe Black607c0b62013-05-16 05:45:57 -07002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Gabe Blackcdb61a62014-04-07 18:45:14 -07004#include <assert.h>
Gabe Black607c0b62013-05-16 05:45:57 -07005#include <console/console.h>
6#include <delay.h>
Nico Huber0f2dd1e2017-08-01 14:02:40 +02007#include <device/i2c_simple.h>
Julius Werner80af4422014-10-20 13:18:56 -07008#include <soc/clk.h>
9#include <soc/i2c.h>
10#include <soc/periph.h>
11#include <soc/pinmux.h>
Julius Werner80af4422014-10-20 13:18:56 -070012#include <timer.h>
Gabe Black607c0b62013-05-16 05:45:57 -070013
Jes Klinke19baa9d2022-02-22 16:00:09 -080014#define I2C_TIMEOUT_US (1000 * USECS_PER_MSEC)
15
Stefan Reinauer6a001132017-07-13 02:20:27 +020016struct __packed i2c_regs
Gabe Blackcdb61a62014-04-07 18:45:14 -070017{
18 uint8_t con;
19 uint8_t _1[3];
20 uint8_t stat;
21 uint8_t _2[3];
22 uint8_t add;
23 uint8_t _3[3];
24 uint8_t ds;
25 uint8_t _4[3];
26 uint8_t lc;
27 uint8_t _5[3];
Gabe Black607c0b62013-05-16 05:45:57 -070028};
29
Stefan Reinauer6a001132017-07-13 02:20:27 +020030struct __packed hsi2c_regs
Gabe Blackcdb61a62014-04-07 18:45:14 -070031{
32 uint32_t usi_ctl;
33 uint32_t usi_fifo_ctl;
34 uint32_t usi_trailing_ctl;
35 uint32_t usi_clk_ctl;
36 uint32_t usi_clk_slot;
37 uint32_t spi_ctl;
38 uint32_t uart_ctl;
39 uint32_t res1;
40 uint32_t usi_int_en;
41 uint32_t usi_int_stat;
42 uint32_t modem_stat;
43 uint32_t error_stat;
44 uint32_t usi_fifo_stat;
45 uint32_t usi_txdata;
46 uint32_t usi_rxdata;
47 uint32_t res2;
48 uint32_t i2c_conf;
49 uint32_t i2c_auto_conf;
50 uint32_t i2c_timeout;
51 uint32_t i2c_manual_cmd;
52 uint32_t i2c_trans_status;
53 uint32_t i2c_timing_hs1;
54 uint32_t i2c_timing_hs2;
55 uint32_t i2c_timing_hs3;
56 uint32_t i2c_timing_fs1;
57 uint32_t i2c_timing_fs2;
58 uint32_t i2c_timing_fs3;
59 uint32_t i2c_timing_sla;
60 uint32_t i2c_addr;
61};
62check_member(hsi2c_regs, i2c_addr, 0x70);
63
64struct i2c_bus
65{
66 int bus_num;
67 struct i2c_regs *regs;
68 enum periph_id periph_id;
69 struct hsi2c_regs *hsregs;
70 int is_highspeed; /* High speed type, rather than I2C */
71 int id;
Martin Roth57e89092019-10-23 21:45:23 -060072 unsigned int clk_cycle;
73 unsigned int clk_div;
Gabe Blackcdb61a62014-04-07 18:45:14 -070074};
75
Gabe Blackcdb61a62014-04-07 18:45:14 -070076static struct i2c_bus i2c_busses[] = {
Gabe Black607c0b62013-05-16 05:45:57 -070077 {
78 .bus_num = 0,
Gabe Blackcdb61a62014-04-07 18:45:14 -070079 .regs = (void *)0x12c60000,
Gabe Black607c0b62013-05-16 05:45:57 -070080 .periph_id = PERIPH_ID_I2C0,
81 },
82 {
83 .bus_num = 1,
Gabe Blackcdb61a62014-04-07 18:45:14 -070084 .regs = (void *)0x12c70000,
Gabe Black607c0b62013-05-16 05:45:57 -070085 .periph_id = PERIPH_ID_I2C1,
86 },
87 {
88 .bus_num = 2,
Gabe Blackcdb61a62014-04-07 18:45:14 -070089 .regs = (void *)0x12c80000,
Gabe Black607c0b62013-05-16 05:45:57 -070090 .periph_id = PERIPH_ID_I2C2,
91 },
92 {
93 .bus_num = 3,
Gabe Blackcdb61a62014-04-07 18:45:14 -070094 .regs = (void *)0x12c90000,
Gabe Black607c0b62013-05-16 05:45:57 -070095 .periph_id = PERIPH_ID_I2C3,
96 },
David Hendricks83fd2392013-06-14 19:16:56 -070097 /* I2C4-I2C10 are part of the USI block */
Gabe Black607c0b62013-05-16 05:45:57 -070098 {
99 .bus_num = 4,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700100 .hsregs = (void *)0x12ca0000,
Gabe Black607c0b62013-05-16 05:45:57 -0700101 .periph_id = PERIPH_ID_I2C4,
David Hendricks83fd2392013-06-14 19:16:56 -0700102 .is_highspeed = 1,
Gabe Black607c0b62013-05-16 05:45:57 -0700103 },
104 {
105 .bus_num = 5,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700106 .hsregs = (void *)0x12cb0000,
Gabe Black607c0b62013-05-16 05:45:57 -0700107 .periph_id = PERIPH_ID_I2C5,
David Hendricks83fd2392013-06-14 19:16:56 -0700108 .is_highspeed = 1,
Gabe Black607c0b62013-05-16 05:45:57 -0700109 },
110 {
111 .bus_num = 6,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700112 .hsregs = (void *)0x12cc0000,
Gabe Black607c0b62013-05-16 05:45:57 -0700113 .periph_id = PERIPH_ID_I2C6,
David Hendricks83fd2392013-06-14 19:16:56 -0700114 .is_highspeed = 1,
Gabe Black607c0b62013-05-16 05:45:57 -0700115 },
116 {
117 .bus_num = 7,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700118 .hsregs = (void *)0x12cd0000,
Gabe Black607c0b62013-05-16 05:45:57 -0700119 .periph_id = PERIPH_ID_I2C7,
David Hendricks83fd2392013-06-14 19:16:56 -0700120 .is_highspeed = 1,
121 },
122 {
123 .bus_num = 8,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700124 .hsregs = (void *)0x12e00000,
David Hendricks83fd2392013-06-14 19:16:56 -0700125 .periph_id = PERIPH_ID_I2C8,
126 .is_highspeed = 1,
127 },
128 {
129 .bus_num = 9,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700130 .hsregs = (void *)0x12e10000,
David Hendricks83fd2392013-06-14 19:16:56 -0700131 .periph_id = PERIPH_ID_I2C9,
132 .is_highspeed = 1,
133 },
134 {
135 .bus_num = 10,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700136 .hsregs = (void *)0x12e20000,
David Hendricks83fd2392013-06-14 19:16:56 -0700137 .periph_id = PERIPH_ID_I2C10,
138 .is_highspeed = 1,
Gabe Black607c0b62013-05-16 05:45:57 -0700139 },
140};
141
Gabe Blackcdb61a62014-04-07 18:45:14 -0700142// I2C_CTL
143enum {
144 Hsi2cFuncModeI2c = 1 << 0,
145 Hsi2cMaster = 1 << 3,
146 Hsi2cRxchon = 1 << 6,
147 Hsi2cTxchon = 1 << 7,
148 Hsi2cSwRst = 1 << 31
149};
David Hendricks83fd2392013-06-14 19:16:56 -0700150
Gabe Blackcdb61a62014-04-07 18:45:14 -0700151// I2C_FIFO_STAT
152enum {
153 Hsi2cTxFifoLevel = 0x7f << 0,
154 Hsi2cTxFifoFull = 1 << 7,
155 Hsi2cTxFifoEmpty = 1 << 8,
156 Hsi2cRxFifoLevel = 0x7f << 16,
157 Hsi2cRxFifoFull = 1 << 23,
158 Hsi2cRxFifoEmpty = 1 << 24
159};
160
161// I2C_FIFO_CTL
162enum {
163 Hsi2cRxfifoEn = 1 << 0,
164 Hsi2cTxfifoEn = 1 << 1,
165 Hsi2cTxfifoTriggerLevel = 0x20 << 16,
166 Hsi2cRxfifoTriggerLevel = 0x20 << 4
167};
168
169// I2C_TRAILING_CTL
170enum {
171 Hsi2cTrailingCount = 0xff
172};
173
174// I2C_INT_EN
175enum {
176 Hsi2cIntTxAlmostemptyEn = 1 << 0,
177 Hsi2cIntRxAlmostfullEn = 1 << 1,
178 Hsi2cIntTrailingEn = 1 << 6,
179 Hsi2cIntI2cEn = 1 << 9
180};
181
182// I2C_CONF
183enum {
184 Hsi2cAutoMode = 1 << 31,
185 Hsi2c10bitAddrMode = 1 << 30,
186 Hsi2cHsMode = 1 << 29
187};
188
189// I2C_AUTO_CONF
190enum {
191 Hsi2cReadWrite = 1 << 16,
192 Hsi2cStopAfterTrans = 1 << 17,
193 Hsi2cMasterRun = 1 << 31
194};
195
196// I2C_TIMEOUT
197enum {
198 Hsi2cTimeoutEn = 1 << 31
199};
200
201// I2C_TRANS_STATUS
202enum {
203 Hsi2cMasterBusy = 1 << 17,
204 Hsi2cSlaveBusy = 1 << 16,
205 Hsi2cTimeoutAuto = 1 << 4,
206 Hsi2cNoDev = 1 << 3,
207 Hsi2cNoDevAck = 1 << 2,
208 Hsi2cTransAbort = 1 << 1,
209 Hsi2cTransDone = 1 << 0
210};
211
212#define HSI2C_SLV_ADDR_MAS(x) ((x & 0x3ff) << 10)
213
214enum {
215 Hsi2cTimeout = 100
216};
217
218enum {
219 I2cConIntPending = 0x1 << 4,
220 I2cConIntEn = 0x1 << 5,
221 I2cConAckGen = 0x1 << 7
222};
223
224enum {
225 I2cStatAck = 0x1 << 0,
226 I2cStatAddrZero = 0x1 << 1,
227 I2cStatAddrSlave = 0x1 << 2,
228 I2cStatArb = 0x1 << 3,
229 I2cStatEnable = 0x1 << 4,
230 I2cStatStartStop = 0x1 << 5,
231 I2cStatBusy = 0x1 << 5,
232
233 I2cStatModeMask = 0x3 << 6,
234 I2cStatSlaveRecv = 0x0 << 6,
235 I2cStatSlaveXmit = 0x1 << 6,
236 I2cStatMasterRecv = 0x2 << 6,
237 I2cStatMasterXmit = 0x3 << 6
238};
239
Gabe Blackcdb61a62014-04-07 18:45:14 -0700240static int hsi2c_get_clk_details(struct i2c_bus *i2c, int *div, int *cycle,
Martin Roth57e89092019-10-23 21:45:23 -0600241 unsigned int op_clk)
Gabe Black607c0b62013-05-16 05:45:57 -0700242{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700243 struct hsi2c_regs *regs = i2c->hsregs;
244 unsigned long clkin = clock_get_periph_rate(i2c->periph_id);
Gabe Black607c0b62013-05-16 05:45:57 -0700245
Gabe Blackcdb61a62014-04-07 18:45:14 -0700246 /*
247 * FPCLK / FI2C =
248 * (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2) + 8 + 2 * FLT_CYCLE
249 * temp0 = (CLK_DIV + 1) * (TSCLK_L + TSCLK_H + 2)
250 * temp1 = (TSCLK_L + TSCLK_H + 2)
251 */
Julius Werner2f37bd62015-02-19 14:51:15 -0800252 uint32_t flt_cycle = (read32(&regs->i2c_conf) >> 16) & 0x7;
Gabe Blackcdb61a62014-04-07 18:45:14 -0700253 int temp = (clkin / op_clk) - 8 - 2 * flt_cycle;
Gabe Black607c0b62013-05-16 05:45:57 -0700254
Gabe Blackcdb61a62014-04-07 18:45:14 -0700255 // CLK_DIV max is 256.
256 int i;
257 for (i = 0; i < 256; i++) {
258 int period = temp / (i + 1) - 2;
259 if (period < 512 && period >= 2) {
260 *cycle = period;
261 *div = i;
262 return 0;
263 }
264 }
265 printk(BIOS_ERR, "%s: Failed to find timing parameters.\n", __func__);
266 return -1;
Gabe Black607c0b62013-05-16 05:45:57 -0700267}
268
Gabe Blackcdb61a62014-04-07 18:45:14 -0700269static void hsi2c_ch_init(struct i2c_bus *i2c, unsigned int frequency)
Gabe Black607c0b62013-05-16 05:45:57 -0700270{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700271 struct hsi2c_regs *regs = i2c->hsregs;
272
273 int div, cycle;
274 if (hsi2c_get_clk_details(i2c, &div, &cycle, frequency))
275 return;
276
277 uint32_t sr_release;
278 sr_release = cycle;
279
280 uint32_t scl_l, scl_h, start_su, start_hd, stop_su;
281 scl_l = scl_h = start_su = start_hd = stop_su = cycle / 2;
282
283 uint32_t data_su, data_hd;
284 data_su = data_hd = cycle / 4;
285
286 uint32_t timing_fs1 = start_su << 24 | start_hd << 16 | stop_su << 8;
287 uint32_t timing_fs2 = data_su << 24 | scl_l << 8 | scl_h << 0;
288 uint32_t timing_fs3 = div << 16 | sr_release << 0;
289 uint32_t timing_sla = data_hd << 0;
290
291 // Currently operating in fast speed mode.
Julius Werner2f37bd62015-02-19 14:51:15 -0800292 write32(&regs->i2c_timing_fs1, timing_fs1);
293 write32(&regs->i2c_timing_fs2, timing_fs2);
294 write32(&regs->i2c_timing_fs3, timing_fs3);
295 write32(&regs->i2c_timing_sla, timing_sla);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700296
297 // Clear to enable timeout.
Julius Werner2f37bd62015-02-19 14:51:15 -0800298 write32(&regs->i2c_timeout,
299 read32(&regs->i2c_timeout) & ~Hsi2cTimeoutEn);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700300
Julius Werner2f37bd62015-02-19 14:51:15 -0800301 write32(&regs->usi_trailing_ctl, Hsi2cTrailingCount);
302 write32(&regs->usi_fifo_ctl, Hsi2cRxfifoEn | Hsi2cTxfifoEn);
303 write32(&regs->i2c_conf, read32(&regs->i2c_conf) | Hsi2cAutoMode);
David Hendricks83fd2392013-06-14 19:16:56 -0700304}
Gabe Black607c0b62013-05-16 05:45:57 -0700305
Gabe Blackcdb61a62014-04-07 18:45:14 -0700306static void hsi2c_reset(struct i2c_bus *i2c)
Gabe Black607c0b62013-05-16 05:45:57 -0700307{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700308 struct hsi2c_regs *regs = i2c->hsregs;
309
310 // Set and clear the bit for reset.
Julius Werner2f37bd62015-02-19 14:51:15 -0800311 write32(&regs->usi_ctl, read32(&regs->usi_ctl) | Hsi2cSwRst);
312 write32(&regs->usi_ctl, read32(&regs->usi_ctl) & ~Hsi2cSwRst);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700313
314 /* FIXME: This just assumes 100KHz as a default bus freq */
315 hsi2c_ch_init(i2c, 100000);
316}
317
318static void i2c_ch_init(struct i2c_bus *i2c, int speed)
319{
320 struct i2c_regs *regs = i2c->regs;
321
Gabe Black607c0b62013-05-16 05:45:57 -0700322 unsigned long freq, pres = 16, div;
323 unsigned long val;
324
Gabe Blackcdb61a62014-04-07 18:45:14 -0700325 freq = clock_get_periph_rate(i2c->periph_id);
326 // Calculate prescaler and divisor values.
Gabe Black607c0b62013-05-16 05:45:57 -0700327 if ((freq / pres / (16 + 1)) > speed)
328 /* set prescaler to 512 */
329 pres = 512;
330
331 div = 0;
Gabe Blackcdb61a62014-04-07 18:45:14 -0700332
Gabe Black607c0b62013-05-16 05:45:57 -0700333 while ((freq / pres / (div + 1)) > speed)
334 div++;
335
Gabe Blackcdb61a62014-04-07 18:45:14 -0700336 // Set prescaler, divisor according to freq, also set ACKGEN, IRQ.
337 val = (div & 0x0f) | 0xa0 | ((pres == 512) ? 0x40 : 0);
Julius Werner2f37bd62015-02-19 14:51:15 -0800338 write32(&regs->con, val);
Gabe Black607c0b62013-05-16 05:45:57 -0700339
Gabe Blackcdb61a62014-04-07 18:45:14 -0700340 // Init to SLAVE RECEIVE mode and clear I2CADDn.
Julius Werner2f37bd62015-02-19 14:51:15 -0800341 write32(&regs->stat, 0);
342 write32(&regs->add, 0);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700343 // program Master Transmit (and implicit STOP).
Julius Werner2f37bd62015-02-19 14:51:15 -0800344 write32(&regs->stat, I2cStatMasterXmit | I2cStatEnable);
Gabe Black607c0b62013-05-16 05:45:57 -0700345}
346
Martin Roth57e89092019-10-23 21:45:23 -0600347void i2c_init(unsigned int bus, int speed, int slaveadd)
Gabe Black607c0b62013-05-16 05:45:57 -0700348{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700349 struct i2c_bus *i2c = &i2c_busses[bus];
Gabe Black607c0b62013-05-16 05:45:57 -0700350
Gabe Blackcdb61a62014-04-07 18:45:14 -0700351 if (i2c->is_highspeed) {
352 hsi2c_reset(i2c);
David Hendricksbe582782013-06-22 19:40:43 -0700353 hsi2c_ch_init(i2c, speed);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700354 } else {
355 i2c_ch_init(i2c, speed);
356 }
Gabe Black607c0b62013-05-16 05:45:57 -0700357}
358
359/*
Gabe Blackbecb3f62013-06-19 01:23:50 -0700360 * Check whether the transfer is complete.
Gabe Blackf396ad52013-06-24 03:20:22 -0700361 * Return values:
362 * 0 - transfer not done
363 * 1 - transfer finished successfully
364 * -1 - transfer failed
Gabe Black607c0b62013-05-16 05:45:57 -0700365 */
Gabe Blackcdb61a62014-04-07 18:45:14 -0700366static int hsi2c_check_transfer(struct hsi2c_regs *regs)
Gabe Black607c0b62013-05-16 05:45:57 -0700367{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700368 uint32_t status = read32(&regs->i2c_trans_status);
369 if (status & (Hsi2cTransAbort | Hsi2cNoDevAck |
370 Hsi2cNoDev | Hsi2cTimeoutAuto)) {
371 if (status & Hsi2cTransAbort)
Gabe Blackf396ad52013-06-24 03:20:22 -0700372 printk(BIOS_ERR,
373 "%s: Transaction aborted.\n", __func__);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700374 if (status & Hsi2cNoDevAck)
Gabe Blackf396ad52013-06-24 03:20:22 -0700375 printk(BIOS_ERR,
376 "%s: No ack from device.\n", __func__);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700377 if (status & Hsi2cNoDev)
Gabe Blackf396ad52013-06-24 03:20:22 -0700378 printk(BIOS_ERR,
379 "%s: No response from device.\n", __func__);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700380 if (status & Hsi2cTimeoutAuto)
Gabe Blackf396ad52013-06-24 03:20:22 -0700381 printk(BIOS_ERR,
382 "%s: Transaction time out.\n", __func__);
383 return -1;
384 }
Gabe Blackcdb61a62014-04-07 18:45:14 -0700385 return !(status & Hsi2cMasterBusy);
Gabe Blackbecb3f62013-06-19 01:23:50 -0700386}
387
388/*
389 * Wait for the transfer to finish.
Gabe Blackf396ad52013-06-24 03:20:22 -0700390 * Return values:
391 * 0 - transfer not done
392 * 1 - transfer finished successfully
393 * -1 - transfer failed
Gabe Blackbecb3f62013-06-19 01:23:50 -0700394 */
Gabe Blackcdb61a62014-04-07 18:45:14 -0700395static int hsi2c_wait_for_transfer(struct hsi2c_regs *i2c)
Gabe Blackbecb3f62013-06-19 01:23:50 -0700396{
Aaron Durbin43933462014-09-24 10:27:29 -0500397 struct stopwatch sw;
Gabe Black607c0b62013-05-16 05:45:57 -0700398
Aaron Durbin43933462014-09-24 10:27:29 -0500399 stopwatch_init_msecs_expire(&sw, Hsi2cTimeout);
400 while (!stopwatch_expired(&sw)) {
Gabe Blackf396ad52013-06-24 03:20:22 -0700401 int ret = hsi2c_check_transfer(i2c);
402 if (ret)
403 return ret;
David Hendricks83fd2392013-06-14 19:16:56 -0700404 }
Gabe Blackf396ad52013-06-24 03:20:22 -0700405 return 0;
Gabe Blackbecb3f62013-06-19 01:23:50 -0700406}
David Hendricks83fd2392013-06-14 19:16:56 -0700407
Gabe Blackcdb61a62014-04-07 18:45:14 -0700408static int hsi2c_senddata(struct hsi2c_regs *regs, const uint8_t *data, int len)
Gabe Blackbecb3f62013-06-19 01:23:50 -0700409{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700410 while (!hsi2c_check_transfer(regs) && len) {
411 if (!(read32(&regs->usi_fifo_stat) & Hsi2cTxFifoFull)) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800412 write32(&regs->usi_txdata, *data++);
Gabe Blackbecb3f62013-06-19 01:23:50 -0700413 len--;
414 }
415 }
416 return len ? -1 : 0;
417}
418
Gabe Blackcdb61a62014-04-07 18:45:14 -0700419static int hsi2c_recvdata(struct hsi2c_regs *regs, uint8_t *data, int len)
Gabe Blackbecb3f62013-06-19 01:23:50 -0700420{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700421 while (!hsi2c_check_transfer(regs) && len) {
422 if (!(read32(&regs->usi_fifo_stat) & Hsi2cRxFifoEmpty)) {
423 *data++ = read32(&regs->usi_rxdata);
Gabe Blackbecb3f62013-06-19 01:23:50 -0700424 len--;
425 }
426 }
427 return len ? -1 : 0;
David Hendricks83fd2392013-06-14 19:16:56 -0700428}
429
Nico Huber029dfff2017-07-12 17:59:16 +0200430static int hsi2c_segment(struct i2c_msg *seg, struct hsi2c_regs *regs,
431 int stop)
David Hendricks83fd2392013-06-14 19:16:56 -0700432{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700433 const uint32_t usi_ctl = Hsi2cFuncModeI2c | Hsi2cMaster;
David Hendricks83fd2392013-06-14 19:16:56 -0700434
Nico Huber029dfff2017-07-12 17:59:16 +0200435 write32(&regs->i2c_addr, HSI2C_SLV_ADDR_MAS(seg->slave));
David Hendricks83fd2392013-06-14 19:16:56 -0700436
Gabe Blackcdb61a62014-04-07 18:45:14 -0700437 /*
438 * We really only want to stop after this transaction (I think) if the
439 * "stop" parameter is true. I'm assuming that's supposed to make the
440 * controller issue a repeated start, but the documentation isn't very
441 * clear. We may need to switch to manual mode to really get the
442 * behavior we want.
443 */
444 uint32_t autoconf =
445 seg->len | Hsi2cMasterRun | Hsi2cStopAfterTrans;
David Hendricks83fd2392013-06-14 19:16:56 -0700446
Nico Huber029dfff2017-07-12 17:59:16 +0200447 if (seg->flags & I2C_M_RD) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800448 write32(&regs->usi_ctl, usi_ctl | Hsi2cRxchon);
449 write32(&regs->i2c_auto_conf, autoconf | Hsi2cReadWrite);
David Hendricks83fd2392013-06-14 19:16:56 -0700450
Gabe Blackcdb61a62014-04-07 18:45:14 -0700451 if (hsi2c_recvdata(regs, seg->buf, seg->len))
452 return -1;
453 } else {
Julius Werner2f37bd62015-02-19 14:51:15 -0800454 write32(&regs->usi_ctl, usi_ctl | Hsi2cTxchon);
455 write32(&regs->i2c_auto_conf, autoconf);
David Hendricks83fd2392013-06-14 19:16:56 -0700456
Gabe Blackcdb61a62014-04-07 18:45:14 -0700457 if (hsi2c_senddata(regs, seg->buf, seg->len))
458 return -1;
David Hendricks83fd2392013-06-14 19:16:56 -0700459 }
460
Gabe Blackcdb61a62014-04-07 18:45:14 -0700461 if (hsi2c_wait_for_transfer(regs) != 1)
462 return -1;
463
Julius Werner2f37bd62015-02-19 14:51:15 -0800464 write32(&regs->usi_ctl, Hsi2cFuncModeI2c);
Gabe Blackbecb3f62013-06-19 01:23:50 -0700465 return 0;
David Hendricks83fd2392013-06-14 19:16:56 -0700466}
467
Nico Huber029dfff2017-07-12 17:59:16 +0200468static int hsi2c_transfer(struct i2c_bus *i2c, struct i2c_msg *segments,
Gabe Blackcdb61a62014-04-07 18:45:14 -0700469 int count)
David Hendricks83fd2392013-06-14 19:16:56 -0700470{
Gabe Blackcdb61a62014-04-07 18:45:14 -0700471 struct hsi2c_regs *regs = i2c->hsregs;
472 if (hsi2c_wait_for_transfer(regs) != 1) {
473 hsi2c_reset(i2c);
Gabe Blackbecb3f62013-06-19 01:23:50 -0700474 return -1;
Gabe Blackcdb61a62014-04-07 18:45:14 -0700475 }
David Hendricks83fd2392013-06-14 19:16:56 -0700476
Gabe Blackcdb61a62014-04-07 18:45:14 -0700477 int i;
478 for (i = 0; i < count; i++) {
479 if (hsi2c_segment(&segments[i], regs, i == count - 1)) {
480 hsi2c_reset(i2c);
Gabe Blackdda0e662013-11-06 11:21:48 -0800481 return -1;
482 }
Gabe Blackbecb3f62013-06-19 01:23:50 -0700483 }
David Hendricks83fd2392013-06-14 19:16:56 -0700484
Gabe Blackbecb3f62013-06-19 01:23:50 -0700485 return 0;
Gabe Black607c0b62013-05-16 05:45:57 -0700486}
487
Gabe Blackcdb61a62014-04-07 18:45:14 -0700488static int i2c_int_pending(struct i2c_regs *regs)
Gabe Black607c0b62013-05-16 05:45:57 -0700489{
Julius Werner2f37bd62015-02-19 14:51:15 -0800490 return read8(&regs->con) & I2cConIntPending;
Gabe Black607c0b62013-05-16 05:45:57 -0700491}
492
Gabe Blackcdb61a62014-04-07 18:45:14 -0700493static void i2c_clear_int(struct i2c_regs *regs)
Gabe Black607c0b62013-05-16 05:45:57 -0700494{
Julius Werner2f37bd62015-02-19 14:51:15 -0800495 write8(&regs->con, read8(&regs->con) & ~I2cConIntPending);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700496}
Gabe Black607c0b62013-05-16 05:45:57 -0700497
Gabe Blackcdb61a62014-04-07 18:45:14 -0700498static void i2c_ack_enable(struct i2c_regs *regs)
499{
Julius Werner2f37bd62015-02-19 14:51:15 -0800500 write8(&regs->con, read8(&regs->con) | I2cConAckGen);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700501}
502
503static void i2c_ack_disable(struct i2c_regs *regs)
504{
Julius Werner2f37bd62015-02-19 14:51:15 -0800505 write8(&regs->con, read8(&regs->con) & ~I2cConAckGen);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700506}
507
508static int i2c_got_ack(struct i2c_regs *regs)
509{
Julius Werner2f37bd62015-02-19 14:51:15 -0800510 return !(read8(&regs->stat) & I2cStatAck);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700511}
512
Jes Klinke19baa9d2022-02-22 16:00:09 -0800513static int i2c_wait_for_idle(struct i2c_regs *regs, int timeout_us)
Gabe Blackcdb61a62014-04-07 18:45:14 -0700514{
Jes Klinke19baa9d2022-02-22 16:00:09 -0800515 int timeout = timeout_us / 10;
Gabe Blackcdb61a62014-04-07 18:45:14 -0700516 while (timeout--) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800517 if (!(read8(&regs->stat) & I2cStatBusy))
Gabe Blackcdb61a62014-04-07 18:45:14 -0700518 return 0;
519 udelay(10);
520 }
521 printk(BIOS_ERR, "I2C timeout waiting for idle.\n");
522 return 1;
523}
524
Jes Klinke19baa9d2022-02-22 16:00:09 -0800525static int i2c_wait_for_int(struct i2c_regs *regs, int timeout_us)
Gabe Blackcdb61a62014-04-07 18:45:14 -0700526{
Jes Klinke19baa9d2022-02-22 16:00:09 -0800527 int timeout = timeout_us / 10;
Gabe Blackcdb61a62014-04-07 18:45:14 -0700528 while (timeout--) {
529 if (i2c_int_pending(regs))
530 return 0;
531 udelay(10);
532 }
533 printk(BIOS_ERR, "I2C timeout waiting for I2C interrupt.\n");
534 return 1;
535}
536
Gabe Blackcdb61a62014-04-07 18:45:14 -0700537static int i2c_send_stop(struct i2c_regs *regs)
538{
Julius Werner2f37bd62015-02-19 14:51:15 -0800539 uint8_t mode = read8(&regs->stat) & (I2cStatModeMask);
540 write8(&regs->stat, mode | I2cStatEnable);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700541 i2c_clear_int(regs);
Jes Klinke19baa9d2022-02-22 16:00:09 -0800542 return i2c_wait_for_idle(regs, I2C_TIMEOUT_US);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700543}
544
545static int i2c_send_start(struct i2c_regs *regs, int read, int chip)
546{
Julius Werner2f37bd62015-02-19 14:51:15 -0800547 write8(&regs->ds, chip << 1);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700548 uint8_t mode = read ? I2cStatMasterRecv : I2cStatMasterXmit;
Julius Werner2f37bd62015-02-19 14:51:15 -0800549 write8(&regs->stat, mode | I2cStatStartStop | I2cStatEnable);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700550 i2c_clear_int(regs);
551
Jes Klinke19baa9d2022-02-22 16:00:09 -0800552 if (i2c_wait_for_int(regs, I2C_TIMEOUT_US))
Gabe Blackcdb61a62014-04-07 18:45:14 -0700553 return 1;
554
555 if (!i2c_got_ack(regs)) {
556 // Nobody home, but they may just be asleep.
Gabe Black607c0b62013-05-16 05:45:57 -0700557 return 1;
558 }
559
Gabe Blackcdb61a62014-04-07 18:45:14 -0700560 return 0;
561}
562
563static int i2c_xmit_buf(struct i2c_regs *regs, uint8_t *data, int len)
564{
565 ASSERT(len);
566
567 i2c_ack_enable(regs);
568
569 int i;
570 for (i = 0; i < len; i++) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800571 write8(&regs->ds, data[i]);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700572
573 i2c_clear_int(regs);
Jes Klinke19baa9d2022-02-22 16:00:09 -0800574 if (i2c_wait_for_int(regs, CONFIG_I2C_TRANSFER_TIMEOUT_US))
Gabe Blackcdb61a62014-04-07 18:45:14 -0700575 return 1;
576
577 if (!i2c_got_ack(regs)) {
578 printk(BIOS_INFO, "I2c nacked.\n");
579 return 1;
580 }
Gabe Black607c0b62013-05-16 05:45:57 -0700581 }
582
Gabe Blackcdb61a62014-04-07 18:45:14 -0700583 return 0;
584}
585
586static int i2c_recv_buf(struct i2c_regs *regs, uint8_t *data, int len)
587{
588 ASSERT(len);
589
590 i2c_ack_enable(regs);
591
592 int i;
593 for (i = 0; i < len; i++) {
594 if (i == len - 1)
595 i2c_ack_disable(regs);
596
597 i2c_clear_int(regs);
Jes Klinke19baa9d2022-02-22 16:00:09 -0800598 if (i2c_wait_for_int(regs, CONFIG_I2C_TRANSFER_TIMEOUT_US))
Gabe Blackcdb61a62014-04-07 18:45:14 -0700599 return 1;
600
Julius Werner2f37bd62015-02-19 14:51:15 -0800601 data[i] = read8(&regs->ds);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700602 }
603
604 return 0;
605}
606
Martin Roth57e89092019-10-23 21:45:23 -0600607int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
Gabe Blackcdb61a62014-04-07 18:45:14 -0700608{
609 struct i2c_bus *i2c = &i2c_busses[bus];
David Hendricks83fd2392013-06-14 19:16:56 -0700610 if (i2c->is_highspeed)
Gabe Blackcdb61a62014-04-07 18:45:14 -0700611 return hsi2c_transfer(i2c, segments, count);
612
613 struct i2c_regs *regs = i2c->regs;
614 int res = 0;
615
Jes Klinke19baa9d2022-02-22 16:00:09 -0800616 if (!regs || i2c_wait_for_idle(regs, I2C_TIMEOUT_US))
Gabe Black607c0b62013-05-16 05:45:57 -0700617 return 1;
Gabe Black607c0b62013-05-16 05:45:57 -0700618
Julius Werner2f37bd62015-02-19 14:51:15 -0800619 write8(&regs->stat, I2cStatMasterXmit | I2cStatEnable);
Gabe Black607c0b62013-05-16 05:45:57 -0700620
Gabe Blackcdb61a62014-04-07 18:45:14 -0700621 int i;
622 for (i = 0; i < count; i++) {
Nico Huber029dfff2017-07-12 17:59:16 +0200623 struct i2c_msg *seg = &segments[i];
Gabe Blackcdb61a62014-04-07 18:45:14 -0700624
Nico Huber029dfff2017-07-12 17:59:16 +0200625 res = i2c_send_start(regs, seg->flags & I2C_M_RD, seg->slave);
Gabe Blackcdb61a62014-04-07 18:45:14 -0700626 if (res)
627 break;
Nico Huber029dfff2017-07-12 17:59:16 +0200628 if (seg->flags & I2C_M_RD)
Gabe Blackcdb61a62014-04-07 18:45:14 -0700629 res = i2c_recv_buf(regs, seg->buf, seg->len);
630 else
631 res = i2c_xmit_buf(regs, seg->buf, seg->len);
632 if (res)
633 break;
Gabe Black607c0b62013-05-16 05:45:57 -0700634 }
635
Gabe Blackcdb61a62014-04-07 18:45:14 -0700636 return i2c_send_stop(regs) || res;
Gabe Black607c0b62013-05-16 05:45:57 -0700637}