blob: 617e6634720af8137ddc8cd96bf9dd2d8a855caa [file] [log] [blame]
Duncan Laurie8a14c392016-06-07 13:40:11 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2009 Vipin Kumar, ST Microelectronics
Chris Chingb8dc63b2017-12-06 14:26:15 -07005 * Copyright 2017 Google Inc.
6 * Copyright 2017 Intel Corporation.
Duncan Laurie8a14c392016-06-07 13:40:11 -07007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
Duncan Laurie88a1f142016-06-13 10:28:36 -070018#include <arch/acpigen.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020019#include <device/mmio.h>
Duncan Laurie8a14c392016-06-07 13:40:11 -070020#include <console/console.h>
21#include <device/device.h>
Aaron Durbinb7d79cd2018-01-22 21:31:48 -070022#include <device/i2c_bus.h>
Nico Huber0f2dd1e2017-08-01 14:02:40 +020023#include <device/i2c_simple.h>
Duncan Laurie222381e2016-06-21 10:41:19 -070024#include <string.h>
Duncan Laurie8a14c392016-06-07 13:40:11 -070025#include <timer.h>
Chris Chingb8dc63b2017-12-06 14:26:15 -070026#include "dw_i2c.h"
Duncan Laurie8a14c392016-06-07 13:40:11 -070027
Duncan Lauriea87170b2016-11-03 10:43:14 -070028/* Use a ~10ms timeout for various operations */
Chris Chingb8dc63b2017-12-06 14:26:15 -070029#define DW_I2C_TIMEOUT_US 10000
Duncan Laurie8a14c392016-06-07 13:40:11 -070030
31/* High and low times in different speed modes (in ns) */
32enum {
Duncan Laurie88a1f142016-06-13 10:28:36 -070033 /* SDA Hold Time */
34 DEFAULT_SDA_HOLD_TIME = 300,
Duncan Laurie8a14c392016-06-07 13:40:11 -070035 /* Standard Speed */
36 MIN_SS_SCL_HIGHTIME = 4000,
37 MIN_SS_SCL_LOWTIME = 4700,
Duncan Laurie88a1f142016-06-13 10:28:36 -070038 /* Fast Speed */
Duncan Laurie8a14c392016-06-07 13:40:11 -070039 MIN_FS_SCL_HIGHTIME = 600,
40 MIN_FS_SCL_LOWTIME = 1300,
Duncan Laurie88a1f142016-06-13 10:28:36 -070041 /* Fast Plus Speed */
42 MIN_FP_SCL_HIGHTIME = 260,
43 MIN_FP_SCL_LOWTIME = 500,
Duncan Laurie8a14c392016-06-07 13:40:11 -070044 /* High Speed */
45 MIN_HS_SCL_HIGHTIME = 60,
46 MIN_HS_SCL_LOWTIME = 160,
47};
48
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -060049/* Frequency represented as ticks per ns. Can also be used to calculate
50 * the number of ticks to meet a time target or the period. */
51struct freq {
52 uint32_t ticks;
53 uint32_t ns;
54};
55
Rizwan Qureshiae6a4b62017-04-26 21:06:35 +053056/* Control register definitions */
57enum {
58 CONTROL_MASTER_MODE = (1 << 0),
59 CONTROL_SPEED_SS = (1 << 1),
60 CONTROL_SPEED_FS = (1 << 2),
61 CONTROL_SPEED_HS = (3 << 1),
62 CONTROL_SPEED_MASK = (3 << 1),
63 CONTROL_10BIT_SLAVE = (1 << 3),
64 CONTROL_10BIT_MASTER = (1 << 4),
65 CONTROL_RESTART_ENABLE = (1 << 5),
66 CONTROL_SLAVE_DISABLE = (1 << 6),
67};
68
69/* Command/Data register definitions */
70enum {
71 CMD_DATA_CMD = (1 << 8),
72 CMD_DATA_STOP = (1 << 9),
73};
74
75/* Status register definitions */
76enum {
77 STATUS_ACTIVITY = (1 << 0),
78 STATUS_TX_FIFO_NOT_FULL = (1 << 1),
79 STATUS_TX_FIFO_EMPTY = (1 << 2),
80 STATUS_RX_FIFO_NOT_EMPTY = (1 << 3),
81 STATUS_RX_FIFO_FULL = (1 << 4),
82 STATUS_MASTER_ACTIVITY = (1 << 5),
83 STATUS_SLAVE_ACTIVITY = (1 << 6),
84};
85
86/* Enable register definitions */
87enum {
88 ENABLE_CONTROLLER = (1 << 0),
89};
90
91/* Interrupt status register definitions */
92enum {
93 INTR_STAT_RX_UNDER = (1 << 0),
94 INTR_STAT_RX_OVER = (1 << 1),
95 INTR_STAT_RX_FULL = (1 << 2),
96 INTR_STAT_TX_OVER = (1 << 3),
97 INTR_STAT_TX_EMPTY = (1 << 4),
98 INTR_STAT_RD_REQ = (1 << 5),
99 INTR_STAT_TX_ABORT = (1 << 6),
100 INTR_STAT_RX_DONE = (1 << 7),
101 INTR_STAT_ACTIVITY = (1 << 8),
102 INTR_STAT_STOP_DET = (1 << 9),
103 INTR_STAT_START_DET = (1 << 10),
104 INTR_STAT_GEN_CALL = (1 << 11),
105};
106
Chris Chingb8dc63b2017-12-06 14:26:15 -0700107/* I2C Controller MMIO register space */
108struct dw_i2c_regs {
109 uint32_t control;
110 uint32_t target_addr;
111 uint32_t slave_addr;
112 uint32_t master_addr;
113 uint32_t cmd_data;
114 uint32_t ss_scl_hcnt;
115 uint32_t ss_scl_lcnt;
116 uint32_t fs_scl_hcnt;
117 uint32_t fs_scl_lcnt;
118 uint32_t hs_scl_hcnt;
119 uint32_t hs_scl_lcnt;
120 uint32_t intr_stat;
121 uint32_t intr_mask;
122 uint32_t raw_intr_stat;
123 uint32_t rx_thresh;
124 uint32_t tx_thresh;
125 uint32_t clear_intr;
126 uint32_t clear_rx_under_intr;
127 uint32_t clear_rx_over_intr;
128 uint32_t clear_tx_over_intr;
129 uint32_t clear_rd_req_intr;
130 uint32_t clear_tx_abrt_intr;
131 uint32_t clear_rx_done_intr;
132 uint32_t clear_activity_intr;
133 uint32_t clear_stop_det_intr;
134 uint32_t clear_start_det_intr;
135 uint32_t clear_gen_call_intr;
136 uint32_t enable;
137 uint32_t status;
138 uint32_t tx_level;
139 uint32_t rx_level;
140 uint32_t sda_hold;
141 uint32_t tx_abort_source;
142 uint32_t slv_data_nak_only;
143 uint32_t dma_cr;
144 uint32_t dma_tdlr;
145 uint32_t dma_rdlr;
146 uint32_t sda_setup;
147 uint32_t ack_general_call;
148 uint32_t enable_status;
149 uint32_t fs_spklen;
150 uint32_t hs_spklen;
151 uint32_t clr_restart_det;
152 uint32_t comp_param1;
153 uint32_t comp_version;
154 uint32_t comp_type;
155} __packed;
156
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600157static const struct i2c_descriptor {
158 enum i2c_speed speed;
159 struct freq freq;
160 int min_thigh_ns;
161 int min_tlow_ns;
162} speed_descriptors[] = {
163 {
164 .speed = I2C_SPEED_STANDARD,
165 .freq = {
166 .ticks = 100,
167 .ns = 1000*1000,
168 },
169 .min_thigh_ns = MIN_SS_SCL_HIGHTIME,
170 .min_tlow_ns = MIN_SS_SCL_LOWTIME,
171 },
172 {
173 .speed = I2C_SPEED_FAST,
174 .freq = {
175 .ticks = 400,
176 .ns = 1000*1000,
177 },
178 .min_thigh_ns = MIN_FS_SCL_HIGHTIME,
179 .min_tlow_ns = MIN_FS_SCL_LOWTIME,
180 },
181 {
182 .speed = I2C_SPEED_FAST_PLUS,
183 .freq = {
184 .ticks = 1,
185 .ns = 1000,
186 },
187 .min_thigh_ns = MIN_FP_SCL_HIGHTIME,
188 .min_tlow_ns = MIN_FP_SCL_LOWTIME,
189 },
190 {
191 /* 100pF max capacitance */
192 .speed = I2C_SPEED_HIGH,
193 .freq = {
194 .ticks = 3400,
195 .ns = 1000*1000,
196 },
197 .min_thigh_ns = MIN_HS_SCL_HIGHTIME,
198 .min_tlow_ns = MIN_HS_SCL_LOWTIME,
199 },
200};
201
202static const struct soc_clock {
203 int clk_speed_mhz;
204 struct freq freq;
205} soc_clocks[] = {
206 {
207 .clk_speed_mhz = 120,
208 .freq = {
209 .ticks = 120,
210 .ns = 1000,
211 },
212 },
213 {
214 .clk_speed_mhz = 133,
215 .freq = {
216 .ticks = 400,
217 .ns = 3000,
218 },
219 },
Duncan Laurie4afefd62018-12-05 15:38:13 -0800220 {
221 .clk_speed_mhz = 216,
222 .freq = {
223 .ticks = 1080,
224 .ns = 5000,
225 },
226 },
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600227};
228
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600229static const struct i2c_descriptor *get_bus_descriptor(enum i2c_speed speed)
230{
231 size_t i;
232
233 for (i = 0; i < ARRAY_SIZE(speed_descriptors); i++)
234 if (speed == speed_descriptors[i].speed)
235 return &speed_descriptors[i];
236
237 return NULL;
238}
239
240static const struct soc_clock *get_soc_descriptor(int ic_clk)
241{
242 size_t i;
243
244 for (i = 0; i < ARRAY_SIZE(soc_clocks); i++)
245 if (ic_clk == soc_clocks[i].clk_speed_mhz)
246 return &soc_clocks[i];
247
248 return NULL;
249}
250
251static int counts_from_time(const struct freq *f, int ns)
252{
253 return DIV_ROUND_UP(f->ticks * ns, f->ns);
254}
255
256static int counts_from_freq(const struct freq *fast, const struct freq *slow)
257{
258 return DIV_ROUND_UP(fast->ticks * slow->ns, fast->ns * slow->ticks);
259}
260
Duncan Laurie8a14c392016-06-07 13:40:11 -0700261/* Enable this I2C controller */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700262static void dw_i2c_enable(struct dw_i2c_regs *regs)
Duncan Laurie8a14c392016-06-07 13:40:11 -0700263{
264 uint32_t enable = read32(&regs->enable);
265
266 if (!(enable & ENABLE_CONTROLLER))
267 write32(&regs->enable, enable | ENABLE_CONTROLLER);
268}
269
270/* Disable this I2C controller */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700271static int dw_i2c_disable(struct dw_i2c_regs *regs)
Duncan Laurie8a14c392016-06-07 13:40:11 -0700272{
273 uint32_t enable = read32(&regs->enable);
274
275 if (enable & ENABLE_CONTROLLER) {
276 struct stopwatch sw;
277
278 write32(&regs->enable, enable & ~ENABLE_CONTROLLER);
279
280 /* Wait for enable bit to clear */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700281 stopwatch_init_usecs_expire(&sw, DW_I2C_TIMEOUT_US);
Duncan Laurie772555a22016-09-12 11:20:27 -0700282 while (read32(&regs->enable_status) & ENABLE_CONTROLLER)
Duncan Laurie8a14c392016-06-07 13:40:11 -0700283 if (stopwatch_expired(&sw))
284 return -1;
285 }
286
287 return 0;
288}
289
290/* Wait for this I2C controller to go idle for transmit */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700291static int dw_i2c_wait_for_bus_idle(struct dw_i2c_regs *regs)
Duncan Laurie8a14c392016-06-07 13:40:11 -0700292{
293 struct stopwatch sw;
294
295 /* Start timeout for up to 16 bytes in FIFO */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700296 stopwatch_init_usecs_expire(&sw, 16 * DW_I2C_TIMEOUT_US);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700297
298 while (!stopwatch_expired(&sw)) {
299 uint32_t status = read32(&regs->status);
300
301 /* Check for master activity and keep waiting */
302 if (status & STATUS_MASTER_ACTIVITY)
303 continue;
304
305 /* Check for TX FIFO empty to indicate TX idle */
306 if (status & STATUS_TX_FIFO_EMPTY)
307 return 0;
308 }
309
310 /* Timed out while waiting for bus to go idle */
311 return -1;
312}
313
314/* Transfer one byte of one segment, sending stop bit if requested */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700315static int dw_i2c_transfer_byte(struct dw_i2c_regs *regs,
Nico Huber58173862017-08-01 17:09:35 +0200316 const struct i2c_msg *segment,
Duncan Laurie8a14c392016-06-07 13:40:11 -0700317 size_t byte, int send_stop)
318{
319 struct stopwatch sw;
320 uint32_t cmd = CMD_DATA_CMD; /* Read op */
321
Chris Chingb8dc63b2017-12-06 14:26:15 -0700322 stopwatch_init_usecs_expire(&sw, DW_I2C_TIMEOUT_US);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700323
Nico Huber029dfff2017-07-12 17:59:16 +0200324 if (!(segment->flags & I2C_M_RD)) {
Duncan Laurie8a14c392016-06-07 13:40:11 -0700325 /* Write op only: Wait for FIFO not full */
326 while (!(read32(&regs->status) & STATUS_TX_FIFO_NOT_FULL)) {
327 if (stopwatch_expired(&sw)) {
328 printk(BIOS_ERR, "I2C transmit timeout\n");
329 return -1;
330 }
331 }
332 cmd = segment->buf[byte];
333 }
334
335 /* Send stop on last byte, if desired */
336 if (send_stop && byte == segment->len - 1)
337 cmd |= CMD_DATA_STOP;
338
339 write32(&regs->cmd_data, cmd);
340
Nico Huber029dfff2017-07-12 17:59:16 +0200341 if (segment->flags & I2C_M_RD) {
Duncan Laurie8a14c392016-06-07 13:40:11 -0700342 /* Read op only: Wait for FIFO data and store it */
343 while (!(read32(&regs->status) & STATUS_RX_FIFO_NOT_EMPTY)) {
344 if (stopwatch_expired(&sw)) {
345 printk(BIOS_ERR, "I2C receive timeout\n");
346 return -1;
347 }
348 }
349 segment->buf[byte] = read32(&regs->cmd_data);
350 }
351
352 return 0;
353}
354
Aaron Durbin97d58bc2018-01-30 17:29:08 -0700355static int _dw_i2c_transfer(unsigned int bus, const struct i2c_msg *segments,
356 size_t count)
Duncan Laurie8a14c392016-06-07 13:40:11 -0700357{
358 struct stopwatch sw;
Chris Chingb8dc63b2017-12-06 14:26:15 -0700359 struct dw_i2c_regs *regs;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700360 size_t byte;
Duncan Laurie772555a22016-09-12 11:20:27 -0700361 int ret = -1;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700362
Chris Chingb8dc63b2017-12-06 14:26:15 -0700363 regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700364 if (!regs) {
365 printk(BIOS_ERR, "I2C bus %u base address not found\n", bus);
366 return -1;
367 }
368
Aaron Durbin97d58bc2018-01-30 17:29:08 -0700369 /* The assumption is that the host controller is disabled -- either
Elyes HAOUAS18958382018-08-07 12:23:16 +0200370 after running this function or from performing the initialization
Aaron Durbin97d58bc2018-01-30 17:29:08 -0700371 sequence in dw_i2c_init(). */
Duncan Laurie8a14c392016-06-07 13:40:11 -0700372
Aaron Durbin97d58bc2018-01-30 17:29:08 -0700373 /* Set target slave address */
374 write32(&regs->target_addr, segments->slave);
375
376 dw_i2c_enable(regs);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700377
378 /* Process each segment */
379 while (count--) {
Chris Chingb8dc63b2017-12-06 14:26:15 -0700380 if (IS_ENABLED(CONFIG_DRIVERS_I2C_DESIGNWARE_DEBUG)) {
Duncan Laurief8a7b2c2016-09-12 11:21:40 -0700381 printk(BIOS_DEBUG, "i2c %u:%02x %s %d bytes : ",
Nico Huber029dfff2017-07-12 17:59:16 +0200382 bus, segments->slave,
383 (segments->flags & I2C_M_RD) ? "R" : "W",
Duncan Laurief8a7b2c2016-09-12 11:21:40 -0700384 segments->len);
Chris Chingb8dc63b2017-12-06 14:26:15 -0700385 }
Duncan Laurief8a7b2c2016-09-12 11:21:40 -0700386
Duncan Laurie8a14c392016-06-07 13:40:11 -0700387 /* Read or write each byte in segment */
388 for (byte = 0; byte < segments->len; byte++) {
389 /*
390 * Set stop condition on final segment only.
391 * Repeated start will be automatically generated
392 * by the controller on R->W or W->R switch.
393 */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700394 if (dw_i2c_transfer_byte(regs, segments, byte,
Duncan Laurie8a14c392016-06-07 13:40:11 -0700395 count == 0) < 0) {
396 printk(BIOS_ERR, "I2C %s failed: bus %u "
Nico Huber029dfff2017-07-12 17:59:16 +0200397 "addr 0x%02x\n",
398 (segments->flags & I2C_M_RD) ?
399 "read" : "write", bus, segments->slave);
Duncan Laurie772555a22016-09-12 11:20:27 -0700400 goto out;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700401 }
402 }
Duncan Laurief8a7b2c2016-09-12 11:21:40 -0700403
Chris Chingb8dc63b2017-12-06 14:26:15 -0700404 if (IS_ENABLED(CONFIG_DRIVERS_I2C_DESIGNWARE_DEBUG)) {
Duncan Laurief8a7b2c2016-09-12 11:21:40 -0700405 int j;
406 for (j = 0; j < segments->len; j++)
407 printk(BIOS_DEBUG, "%02x ", segments->buf[j]);
Maulik V Vaghela794d0972018-03-20 16:52:00 +0530408 printk(BIOS_DEBUG, "\n");
Duncan Laurief8a7b2c2016-09-12 11:21:40 -0700409 }
410
Duncan Laurie8a14c392016-06-07 13:40:11 -0700411 segments++;
412 }
413
414 /* Wait for interrupt status to indicate transfer is complete */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700415 stopwatch_init_usecs_expire(&sw, DW_I2C_TIMEOUT_US);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700416 while (!(read32(&regs->raw_intr_stat) & INTR_STAT_STOP_DET)) {
417 if (stopwatch_expired(&sw)) {
418 printk(BIOS_ERR, "I2C stop bit not received\n");
Duncan Laurie772555a22016-09-12 11:20:27 -0700419 goto out;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700420 }
421 }
422
423 /* Read to clear INTR_STAT_STOP_DET */
424 read32(&regs->clear_stop_det_intr);
425
426 /* Wait for the bus to go idle */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700427 if (dw_i2c_wait_for_bus_idle(regs)) {
Duncan Laurie8a14c392016-06-07 13:40:11 -0700428 printk(BIOS_ERR, "I2C timeout waiting for bus %u idle\n", bus);
Duncan Laurie772555a22016-09-12 11:20:27 -0700429 goto out;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700430 }
431
432 /* Flush the RX FIFO in case it is not empty */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700433 stopwatch_init_usecs_expire(&sw, 16 * DW_I2C_TIMEOUT_US);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700434 while (read32(&regs->status) & STATUS_RX_FIFO_NOT_EMPTY) {
435 if (stopwatch_expired(&sw)) {
436 printk(BIOS_ERR, "I2C timeout flushing RX FIFO\n");
Duncan Laurie772555a22016-09-12 11:20:27 -0700437 goto out;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700438 }
439 read32(&regs->cmd_data);
440 }
441
Duncan Laurie772555a22016-09-12 11:20:27 -0700442 ret = 0;
443
444out:
445 read32(&regs->clear_intr);
Chris Chingb8dc63b2017-12-06 14:26:15 -0700446 dw_i2c_disable(regs);
Duncan Laurie772555a22016-09-12 11:20:27 -0700447 return ret;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700448}
449
Aaron Durbin97d58bc2018-01-30 17:29:08 -0700450int dw_i2c_transfer(unsigned int bus, const struct i2c_msg *msg, size_t count)
451{
452 const struct i2c_msg *orig_msg = msg;
453 size_t i;
454 size_t start;
455 uint16_t addr;
456
457 if (count == 0 || !msg)
458 return -1;
459
460 /* Break up the transfers at the differing slave address boundary. */
461 addr = orig_msg->slave;
462
463 for (i = 0, start = 0; i < count; i++, msg++) {
464 if (addr != msg->slave) {
465 if (_dw_i2c_transfer(bus, &orig_msg[start], i - start))
466 return -1;
467 start = i;
468 addr = msg->slave;
469 }
470 }
471
472 return _dw_i2c_transfer(bus, &orig_msg[start], count - start);
473}
474
Nico Huber58173862017-08-01 17:09:35 +0200475/* Global I2C bus handler, defined in include/device/i2c_simple.h */
476int platform_i2c_transfer(unsigned int bus, struct i2c_msg *msg, int count)
477{
Chris Chingb8dc63b2017-12-06 14:26:15 -0700478 return dw_i2c_transfer(bus, msg, count < 0 ? 0 : count);
Nico Huber58173862017-08-01 17:09:35 +0200479}
480
Chris Chingb8dc63b2017-12-06 14:26:15 -0700481static int dw_i2c_set_speed_config(unsigned int bus,
482 const struct dw_i2c_speed_config *config)
Duncan Laurie88a1f142016-06-13 10:28:36 -0700483{
Chris Chingb8dc63b2017-12-06 14:26:15 -0700484 struct dw_i2c_regs *regs;
Duncan Laurie88a1f142016-06-13 10:28:36 -0700485 void *hcnt_reg, *lcnt_reg;
486
Chris Chingb8dc63b2017-12-06 14:26:15 -0700487 regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
Duncan Laurie88a1f142016-06-13 10:28:36 -0700488 if (!regs || !config)
489 return -1;
490
491 /* Nothing to do if no values are set */
492 if (!config->scl_lcnt && !config->scl_hcnt && !config->sda_hold)
493 return 0;
494
Naresh G Solanki14deaee2017-07-19 17:14:33 +0530495 if (config->speed >= I2C_SPEED_HIGH) {
496 /* High and Fast Ultra speed */
Duncan Laurie8a14c392016-06-07 13:40:11 -0700497 hcnt_reg = &regs->hs_scl_hcnt;
498 lcnt_reg = &regs->hs_scl_lcnt;
Duncan Laurie88a1f142016-06-13 10:28:36 -0700499 } else if (config->speed >= I2C_SPEED_FAST) {
Naresh G Solanki14deaee2017-07-19 17:14:33 +0530500 /* Fast and Fast-Plus speed */
Duncan Laurie8a14c392016-06-07 13:40:11 -0700501 hcnt_reg = &regs->fs_scl_hcnt;
502 lcnt_reg = &regs->fs_scl_lcnt;
Duncan Laurie88a1f142016-06-13 10:28:36 -0700503 } else {
504 /* Standard speed */
505 hcnt_reg = &regs->ss_scl_hcnt;
506 lcnt_reg = &regs->ss_scl_lcnt;
507 }
508
509 /* SCL count must be set after the speed is selected */
510 if (config->scl_hcnt)
511 write32(hcnt_reg, config->scl_hcnt);
512 if (config->scl_lcnt)
513 write32(lcnt_reg, config->scl_lcnt);
514
515 /* Set SDA Hold Time register */
516 if (config->sda_hold)
517 write32(&regs->sda_hold, config->sda_hold);
518
519 return 0;
520}
521
Chris Chingb8dc63b2017-12-06 14:26:15 -0700522static int dw_i2c_gen_config_rise_fall_time(struct dw_i2c_regs *regs,
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600523 enum i2c_speed speed,
Chris Chingb8dc63b2017-12-06 14:26:15 -0700524 const struct dw_i2c_bus_config *bcfg,
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600525 int ic_clk,
Chris Chingb8dc63b2017-12-06 14:26:15 -0700526 struct dw_i2c_speed_config *config)
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600527{
528 const struct i2c_descriptor *bus;
529 const struct soc_clock *soc;
530 int fall_cnt, rise_cnt, min_tlow_cnt, min_thigh_cnt, spk_cnt;
531 int hcnt, lcnt, period_cnt, diff, tot;
Aaron Durbinc5f10f92017-03-31 14:46:26 -0500532 int data_hold_time_ns;
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600533
534 bus = get_bus_descriptor(speed);
535 soc = get_soc_descriptor(ic_clk);
536
537 if (bus == NULL) {
Chris Chingb8dc63b2017-12-06 14:26:15 -0700538 printk(BIOS_ERR, "dw_i2c: invalid bus speed %d\n", speed);
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600539 return -1;
540 }
541
542 if (soc == NULL) {
Chris Chingb8dc63b2017-12-06 14:26:15 -0700543 printk(BIOS_ERR, "dw_i2c: invalid SoC clock speed %d MHz\n",
Aaron Durbinbff8c5ec2016-11-18 08:10:35 -0600544 ic_clk);
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600545 return -1;
546 }
547
548 /* Get the proper spike suppression count based on target speed. */
549 if (speed >= I2C_SPEED_HIGH)
550 spk_cnt = read32(&regs->hs_spklen);
551 else
552 spk_cnt = read32(&regs->fs_spklen);
553
554 /* Find the period, rise, fall, min tlow, and min thigh in terms of
555 * counts of SoC clock. */
556 period_cnt = counts_from_freq(&soc->freq, &bus->freq);
557 rise_cnt = counts_from_time(&soc->freq, bcfg->rise_time_ns);
558 fall_cnt = counts_from_time(&soc->freq, bcfg->fall_time_ns);
559 min_tlow_cnt = counts_from_time(&soc->freq, bus->min_tlow_ns);
560 min_thigh_cnt = counts_from_time(&soc->freq, bus->min_thigh_ns);
561
Chris Chingb8dc63b2017-12-06 14:26:15 -0700562 printk(DW_I2C_DEBUG, "dw_i2c: SoC %d/%d ns Bus: %d/%d ns\n",
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600563 soc->freq.ticks, soc->freq.ns, bus->freq.ticks, bus->freq.ns);
Chris Chingb8dc63b2017-12-06 14:26:15 -0700564 printk(DW_I2C_DEBUG,
565" dw_i2c: period %d rise %d fall %d tlow %d thigh %d spk %d\n",
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600566 period_cnt, rise_cnt, fall_cnt, min_tlow_cnt, min_thigh_cnt,
567 spk_cnt);
568
569 /*
570 * Back solve for hcnt and lcnt according to the following equations.
571 * SCL_High_time = [(HCNT + IC_*_SPKLEN + 7) * ic_clk] + SCL_Fall_time
572 * SCL_Low_time = [(LCNT + 1) * ic_clk] - SCL_Fall_time + SCL_Rise_time
573 */
574 hcnt = min_thigh_cnt - fall_cnt - 7 - spk_cnt;
575 lcnt = min_tlow_cnt - rise_cnt + fall_cnt - 1;
576
577 if (hcnt < 0 || lcnt < 0) {
Chris Chingb8dc63b2017-12-06 14:26:15 -0700578 printk(BIOS_ERR, "dw_i2c: bad counts. hcnt = %d lcnt = %d\n",
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600579 hcnt, lcnt);
580 return -1;
581 }
582
583 /* Now add things back up to ensure the period is hit. If off,
584 * split the difference and bias to lcnt for remainder. */
585 tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
586
587 if (tot < period_cnt) {
588 diff = (period_cnt - tot) / 2;
589 hcnt += diff;
590 lcnt += diff;
591 tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
592 lcnt += period_cnt - tot;
593 }
594
595 config->speed = speed;
596 config->scl_lcnt = lcnt;
597 config->scl_hcnt = hcnt;
Aaron Durbinc5f10f92017-03-31 14:46:26 -0500598
599 /* Use internal default unless other value is specified. */
600 data_hold_time_ns = DEFAULT_SDA_HOLD_TIME;
601 if (bcfg->data_hold_time_ns)
602 data_hold_time_ns = bcfg->data_hold_time_ns;
603
604 config->sda_hold = counts_from_time(&soc->freq, data_hold_time_ns);
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600605
Chris Chingb8dc63b2017-12-06 14:26:15 -0700606 printk(DW_I2C_DEBUG, "dw_i2c: hcnt = %d lcnt = %d sda hold = %d\n",
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600607 hcnt, lcnt, config->sda_hold);
608
609 return 0;
610}
611
Chris Chingb8dc63b2017-12-06 14:26:15 -0700612int dw_i2c_gen_speed_config(uintptr_t dw_i2c_addr,
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600613 enum i2c_speed speed,
Chris Chingb8dc63b2017-12-06 14:26:15 -0700614 const struct dw_i2c_bus_config *bcfg,
615 struct dw_i2c_speed_config *config)
Duncan Laurie88a1f142016-06-13 10:28:36 -0700616{
Chris Chingb8dc63b2017-12-06 14:26:15 -0700617 const int ic_clk = CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ;
618 struct dw_i2c_regs *regs;
Duncan Laurie88a1f142016-06-13 10:28:36 -0700619 uint16_t hcnt_min, lcnt_min;
Aaron Durbin4668ba72016-11-09 17:09:40 -0600620 int i;
Duncan Laurie88a1f142016-06-13 10:28:36 -0700621
Chris Chingb8dc63b2017-12-06 14:26:15 -0700622 regs = (struct dw_i2c_regs *)dw_i2c_addr;
623
624 _Static_assert(CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ != 0,
625 "DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ can't be zero!");
Duncan Laurie88a1f142016-06-13 10:28:36 -0700626
Aaron Durbin4668ba72016-11-09 17:09:40 -0600627 /* Apply board specific override for this speed if found */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700628 for (i = 0; i < DW_I2C_SPEED_CONFIG_COUNT; i++) {
Aaron Durbin4668ba72016-11-09 17:09:40 -0600629 if (bcfg->speed_config[i].speed != speed)
630 continue;
631 memcpy(config, &bcfg->speed_config[i], sizeof(*config));
632 return 0;
633 }
634
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600635 /* If rise time is set use the time calculation. */
636 if (bcfg->rise_time_ns)
Chris Chingb8dc63b2017-12-06 14:26:15 -0700637 return dw_i2c_gen_config_rise_fall_time(regs, speed, bcfg,
Aaron Durbin2b3e0cd2016-11-09 23:20:30 -0600638 ic_clk, config);
639
Duncan Laurie88a1f142016-06-13 10:28:36 -0700640 if (speed >= I2C_SPEED_HIGH) {
641 /* High speed */
642 hcnt_min = MIN_HS_SCL_HIGHTIME;
643 lcnt_min = MIN_HS_SCL_LOWTIME;
644 } else if (speed >= I2C_SPEED_FAST_PLUS) {
645 /* Fast-Plus speed */
646 hcnt_min = MIN_FP_SCL_HIGHTIME;
647 lcnt_min = MIN_FP_SCL_LOWTIME;
648 } else if (speed >= I2C_SPEED_FAST) {
649 /* Fast speed */
Duncan Laurie8a14c392016-06-07 13:40:11 -0700650 hcnt_min = MIN_FS_SCL_HIGHTIME;
651 lcnt_min = MIN_FS_SCL_LOWTIME;
652 } else {
Duncan Laurie88a1f142016-06-13 10:28:36 -0700653 /* Standard speed */
Duncan Laurie8a14c392016-06-07 13:40:11 -0700654 hcnt_min = MIN_SS_SCL_HIGHTIME;
655 lcnt_min = MIN_SS_SCL_LOWTIME;
656 }
657
Duncan Laurie88a1f142016-06-13 10:28:36 -0700658 config->speed = speed;
659 config->scl_hcnt = ic_clk * hcnt_min / KHz;
660 config->scl_lcnt = ic_clk * lcnt_min / KHz;
661 config->sda_hold = ic_clk * DEFAULT_SDA_HOLD_TIME / KHz;
662
663 return 0;
664}
665
Chris Chingb8dc63b2017-12-06 14:26:15 -0700666static int dw_i2c_set_speed(unsigned int bus, enum i2c_speed speed,
667 const struct dw_i2c_bus_config *bcfg)
Duncan Laurie88a1f142016-06-13 10:28:36 -0700668{
Chris Chingb8dc63b2017-12-06 14:26:15 -0700669 struct dw_i2c_regs *regs;
670 struct dw_i2c_speed_config config;
Duncan Laurie88a1f142016-06-13 10:28:36 -0700671 uint32_t control;
672
673 /* Clock must be provided by Kconfig */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700674 regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
Duncan Laurie88a1f142016-06-13 10:28:36 -0700675 if (!regs || !speed)
676 return -1;
677
678 control = read32(&regs->control);
679 control &= ~CONTROL_SPEED_MASK;
680
Naresh G Solanki14deaee2017-07-19 17:14:33 +0530681 if (speed >= I2C_SPEED_HIGH) {
682 /* High and Fast-Ultra speed share config registers */
Duncan Laurie88a1f142016-06-13 10:28:36 -0700683 control |= CONTROL_SPEED_HS;
684 } else if (speed >= I2C_SPEED_FAST) {
Naresh G Solanki14deaee2017-07-19 17:14:33 +0530685 /* Fast speed and Fast-Plus */
Duncan Laurie88a1f142016-06-13 10:28:36 -0700686 control |= CONTROL_SPEED_FS;
687 } else {
688 /* Standard speed */
689 control |= CONTROL_SPEED_SS;
690 }
691
692 /* Generate speed config based on clock */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700693 if (dw_i2c_gen_speed_config((uintptr_t)regs, speed, bcfg, &config) < 0)
Duncan Laurie88a1f142016-06-13 10:28:36 -0700694 return -1;
695
Duncan Laurie8a14c392016-06-07 13:40:11 -0700696 /* Select this speed in the control register */
697 write32(&regs->control, control);
698
Duncan Laurie88a1f142016-06-13 10:28:36 -0700699 /* Write the speed config that was generated earlier */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700700 dw_i2c_set_speed_config(bus, &config);
Duncan Laurie88a1f142016-06-13 10:28:36 -0700701
702 return 0;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700703}
704
Aaron Durbin4668ba72016-11-09 17:09:40 -0600705
Rizwan Qureshiae6a4b62017-04-26 21:06:35 +0530706/*
707 * Initialize this bus controller and set the speed.
708 *
709 * The bus speed can be passed in Hz or using values from device/i2c.h and
710 * will default to I2C_SPEED_FAST if it is not provided.
711 */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700712int dw_i2c_init(unsigned int bus, const struct dw_i2c_bus_config *bcfg)
Duncan Laurie8a14c392016-06-07 13:40:11 -0700713{
Chris Chingb8dc63b2017-12-06 14:26:15 -0700714 struct dw_i2c_regs *regs;
Aaron Durbin4668ba72016-11-09 17:09:40 -0600715 enum i2c_speed speed;
716
717 if (!bcfg)
718 return -1;
719
720 speed = bcfg->speed ? : I2C_SPEED_FAST;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700721
Chris Chingb8dc63b2017-12-06 14:26:15 -0700722 regs = (struct dw_i2c_regs *)dw_i2c_base_address(bus);
Duncan Laurie8a14c392016-06-07 13:40:11 -0700723 if (!regs) {
724 printk(BIOS_ERR, "I2C bus %u base address not found\n", bus);
Duncan Laurie88a1f142016-06-13 10:28:36 -0700725 return -1;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700726 }
727
Chris Chingb8dc63b2017-12-06 14:26:15 -0700728 if (dw_i2c_disable(regs) < 0) {
Duncan Laurie8a14c392016-06-07 13:40:11 -0700729 printk(BIOS_ERR, "I2C timeout disabling bus %u\n", bus);
Duncan Laurie88a1f142016-06-13 10:28:36 -0700730 return -1;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700731 }
732
733 /* Put controller in master mode with restart enabled */
734 write32(&regs->control, CONTROL_MASTER_MODE | CONTROL_SLAVE_DISABLE |
735 CONTROL_RESTART_ENABLE);
736
737 /* Set bus speed to FAST by default */
Chris Chingb8dc63b2017-12-06 14:26:15 -0700738 if (dw_i2c_set_speed(bus, speed, bcfg) < 0) {
Duncan Laurie88a1f142016-06-13 10:28:36 -0700739 printk(BIOS_ERR, "I2C failed to set speed for bus %u\n", bus);
740 return -1;
741 }
Duncan Laurie8a14c392016-06-07 13:40:11 -0700742
743 /* Set RX/TX thresholds to smallest values */
744 write32(&regs->rx_thresh, 0);
745 write32(&regs->tx_thresh, 0);
746
747 /* Enable stop detection interrupt */
748 write32(&regs->intr_mask, INTR_STAT_STOP_DET);
749
Chris Chingb8dc63b2017-12-06 14:26:15 -0700750 printk(BIOS_INFO, "DW I2C bus %u at 0x%p (%u KHz)\n",
Aaron Durbin4668ba72016-11-09 17:09:40 -0600751 bus, regs, speed / KHz);
Duncan Laurie88a1f142016-06-13 10:28:36 -0700752
753 return 0;
Duncan Laurie8a14c392016-06-07 13:40:11 -0700754}
Aaron Durbinb7d79cd2018-01-22 21:31:48 -0700755
756/*
757 * Write ACPI object to describe speed configuration.
758 *
759 * ACPI Object: Name ("xxxx", Package () { scl_lcnt, scl_hcnt, sda_hold }
760 *
761 * SSCN: I2C_SPEED_STANDARD
762 * FMCN: I2C_SPEED_FAST
763 * FPCN: I2C_SPEED_FAST_PLUS
764 * HSCN: I2C_SPEED_HIGH
765 */
766static void dw_i2c_acpi_write_speed_config(
767 const struct dw_i2c_speed_config *config)
768{
769 if (!config)
770 return;
771 if (!config->scl_lcnt && !config->scl_hcnt && !config->sda_hold)
772 return;
773
774 if (config->speed >= I2C_SPEED_HIGH)
775 acpigen_write_name("HSCN");
776 else if (config->speed >= I2C_SPEED_FAST_PLUS)
777 acpigen_write_name("FPCN");
778 else if (config->speed >= I2C_SPEED_FAST)
779 acpigen_write_name("FMCN");
780 else
781 acpigen_write_name("SSCN");
782
783 /* Package () { scl_lcnt, scl_hcnt, sda_hold } */
784 acpigen_write_package(3);
785 acpigen_write_word(config->scl_hcnt);
786 acpigen_write_word(config->scl_lcnt);
787 acpigen_write_dword(config->sda_hold);
788 acpigen_pop_len();
789}
790
791/*
792 * The device should already be enabled and out of reset,
793 * either from early init in coreboot or SiliconInit in FSP.
794 */
795void dw_i2c_dev_init(struct device *dev)
796{
797 const struct dw_i2c_bus_config *config;
798 int bus = dw_i2c_soc_dev_to_bus(dev);
799
800 if (bus < 0)
801 return;
802
Aaron Durbinb94a2752018-01-24 16:58:18 -0700803 config = dw_i2c_get_soc_cfg(bus);
Aaron Durbinb7d79cd2018-01-22 21:31:48 -0700804
805 if (!config)
806 return;
807
808 dw_i2c_init(bus, config);
809}
810
811/*
812 * Generate I2C timing information into the SSDT for the OS driver to consume,
813 * optionally applying override values provided by the caller.
814 */
815void dw_i2c_acpi_fill_ssdt(struct device *dev)
816{
817 const struct dw_i2c_bus_config *bcfg;
818 uintptr_t dw_i2c_addr;
819 struct dw_i2c_speed_config sgen;
820 enum i2c_speed speeds[DW_I2C_SPEED_CONFIG_COUNT] = {
821 I2C_SPEED_STANDARD,
822 I2C_SPEED_FAST,
823 I2C_SPEED_FAST_PLUS,
824 I2C_SPEED_HIGH,
825 };
826 int i, bus;
827 const char *path;
828
829 if (!dev->enabled)
830 return;
831
832 bus = dw_i2c_soc_dev_to_bus(dev);
833
834 if (bus < 0)
835 return;
836
Aaron Durbinb94a2752018-01-24 16:58:18 -0700837 bcfg = dw_i2c_get_soc_cfg(bus);
Aaron Durbinb7d79cd2018-01-22 21:31:48 -0700838
839 if (!bcfg)
840 return;
841
842 dw_i2c_addr = dw_i2c_base_address(bus);
843 if (!dw_i2c_addr)
844 return;
845
846 path = acpi_device_path(dev);
847 if (!path)
848 return;
849
850 acpigen_write_scope(path);
851
852 /* Report timing values for the OS driver */
853 for (i = 0; i < DW_I2C_SPEED_CONFIG_COUNT; i++) {
854 /* Generate speed config. */
855 if (dw_i2c_gen_speed_config(dw_i2c_addr, speeds[i], bcfg,
856 &sgen) < 0)
857 continue;
858
859 /* Generate ACPI based on selected speed config */
860 dw_i2c_acpi_write_speed_config(&sgen);
861 }
862
863 acpigen_pop_len();
864}
865
866static int dw_i2c_dev_transfer(struct device *dev,
867 const struct i2c_msg *msg, size_t count)
868{
869 return dw_i2c_transfer(dw_i2c_soc_dev_to_bus(dev), msg, count);
870}
871
872const struct i2c_bus_operations dw_i2c_bus_ops = {
873 .transfer = dw_i2c_dev_transfer,
874};