1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "qemu/bitops.h"
23#include "qemu/timer.h"
24#include "hw/sysbus.h"
25#include "hw/i2c/i2c.h"
26#include "qemu/fifo.h"
27#include "qemu/log.h"
28
29#define TYPE_CADENCE_I2C "cdns.i2c-r1p10"
30#define CADENCE_I2C(obj) \
31 OBJECT_CHECK(CadenceI2CState, (obj), TYPE_CADENCE_I2C)
32
33
34#define R_CONTROL (0x00 / 4)
35#define CONTROL_DIV_A_SHIFT 14
36#define CONTROL_DIV_A_WIDTH 2
37#define CONTROL_DIV_B_SHIFT 8
38#define CONTROL_DIV_B_WIDTH 6
39#define CONTROL_CLR_FIFO (1 << 6)
40#define CONTROL_SLVMON (1 << 5)
41#define CONTROL_HOLD (1 << 4)
42#define CONTROL_ACKEN (1 << 3)
43#define CONTROL_NEA (1 << 2)
44#define CONTROL_MS (1 << 1)
45#define CONTROL_RW (1 << 0)
46#define R_STATUS (0x04 / 4)
47#define STATUS_BA (1 << 8)
48#define STATUS_RXOVF (1 << 7)
49#define STATUS_TXDV (1 << 6)
50#define STATUS_RXDV (1 << 5)
51#define STATUS_RXRW (1 << 3)
52#define R_ADDRESS (0x08 / 4)
53#define R_DATA (0x0C / 4)
54#define R_ISR (0x10 / 4)
55#define ISR_RX_UNF (1 << 7)
56#define ISR_TX_OVF (1 << 6)
57#define ISR_RX_OVF (1 << 5)
58#define ISR_SLV_RDY (1 << 4)
59#define ISR_TO (1 << 3)
60#define ISR_NACK (1 << 2)
61#define ISR_DATA (1 << 1)
62#define ISR_COMP (1 << 0)
63#define R_TRANSFER_SIZE (0x14 / 4)
64#define R_SLAVE_MON_PAUSE (0x18 / 4)
65#define R_TIME_OUT (0x1c / 4)
66#define R_INTRPT_MASK (0x20 / 4)
67#define R_INTRPT_ENABLE (0x24 / 4)
68#define R_INTRPT_DISABLE (0x28 / 4)
69#define R_MAX (R_INTRPT_DISABLE + 1)
70
71
72
73#define NS_PER_PCLK 10ull
74
75
76
77
78
79typedef struct CadenceI2CRegInfo {
80 const char *name;
81 uint32_t ro;
82 uint32_t wtc;
83 uint32_t reset;
84 int width;
85} CadenceI2CRegInfo;
86
87static const CadenceI2CRegInfo cadence_i2c_reg_info[] = {
88 [R_CONTROL] = {.name = "CONTROL", .width = 16,
89 .ro = CONTROL_CLR_FIFO | (1 << 7) },
90 [R_STATUS] = {.name = "STATUS", .width = 9, .ro = ~0 },
91 [R_ADDRESS] = {.name = "ADDRESS", .width = 10 },
92 [R_DATA] = {.name = "DATA", .width = 8 },
93 [R_ISR] = {.name = "ISR", .width = 10, .wtc = 0x2FF,
94 .ro = 0x100 },
95 [R_TRANSFER_SIZE] = {.name = "TRANSFER_SIZE", .width = 8 },
96 [R_SLAVE_MON_PAUSE] = {.name = "SLAVE_MON_PAUSE", .width = 8 },
97 [R_TIME_OUT] = {.name = "TIME_OUT", .width = 8},
98 [R_INTRPT_MASK] = {.name = "INTRPT_MASK", .width = 10, .ro = ~0,
99 .reset = 0x2FF },
100 [R_INTRPT_ENABLE] = {.name = "INTRPT_ENABLE", .width = 10, .wtc = ~0 },
101 [R_INTRPT_DISABLE] = {.name = "INTRPT_DISABLE", .width = 10, .wtc = ~0 },
102};
103
104#ifndef CADENCE_I2C_DEBUG
105#define CADENCE_I2C_DEBUG 0
106#endif
107#define DB_PRINT(fmt, args...) do {\
108 if (CADENCE_I2C_DEBUG) {\
109 fprintf(stderr, "CADENCE_I2C: %s:" fmt, __func__, ## args);\
110 } \
111} while (0);
112
113#define FIFO_WIDTH 16
114
115typedef struct CadenceI2CState {
116 SysBusDevice busdev;
117 MemoryRegion iomem;
118 I2CBus *bus;
119 qemu_irq irq;
120
121 QEMUTimer *transfer_timer;
122
123 bool rw;
124
125 Fifo fifo;
126 uint32_t regs[R_MAX];
127} CadenceI2CState;
128
129static inline bool cadence_i2c_has_work(CadenceI2CState *s)
130{
131 if (!(s->regs[R_STATUS] & STATUS_BA)) {
132 return false;
133 }
134
135 if (!(s->regs[R_CONTROL] & CONTROL_RW)) {
136 if (!(s->regs[R_CONTROL] & CONTROL_HOLD)) {
137 return true;
138 }
139 return !fifo_is_empty(&s->fifo);
140 } else {
141 if ((s->regs[R_CONTROL] & CONTROL_HOLD)) {
142 return !fifo_is_full(&s->fifo) && s->regs[R_TRANSFER_SIZE];
143 }
144 return true;
145 }
146}
147
148static inline void cadence_i2c_update_status(CadenceI2CState *s)
149{
150 if (cadence_i2c_has_work(s)) {
151 uint64_t delay = NS_PER_PCLK;
152 delay *= extract32(s->regs[R_CONTROL], CONTROL_DIV_A_SHIFT,
153 CONTROL_DIV_A_WIDTH) + 1;
154 delay *= extract32(s->regs[R_CONTROL], CONTROL_DIV_B_SHIFT,
155 CONTROL_DIV_B_WIDTH) + 1;
156 delay *= 10;
157 DB_PRINT("scheduling transfer operation with delay of %lldns\n",
158 (unsigned long long)delay);
159 timer_mod(s->transfer_timer,
160 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delay);
161 }
162
163 DB_PRINT("irq state: %d\n", !!(s->regs[R_ISR] & ~s->regs[R_INTRPT_MASK]));
164 qemu_set_irq(s->irq, !!(s->regs[R_ISR] & ~s->regs[R_INTRPT_MASK]));
165}
166
167static void cadence_i2c_do_stop(CadenceI2CState *s)
168{
169 if (!(s->regs[R_CONTROL] & CONTROL_HOLD) &&
170 (s->regs[R_STATUS] & STATUS_BA)) {
171 DB_PRINT("sending stop condition\n");
172 i2c_end_transfer(s->bus);
173 s->regs[R_STATUS] &= ~STATUS_BA;
174 }
175}
176
177static void cadence_i2c_do_txrx(void *opaque)
178{
179 CadenceI2CState *s = opaque;
180
181 if (!!(s->regs[R_CONTROL] & CONTROL_RW) != s->rw) {
182 return;
183 }
184
185 DB_PRINT("doing transfer at time %llx\n",
186 (unsigned long long)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
187 if (!(s->regs[R_CONTROL] & CONTROL_RW)) {
188 if (fifo_is_empty(&s->fifo)) {
189 cadence_i2c_do_stop(s);
190 } else {
191 uint8_t t = fifo_pop8(&s->fifo);
192 if (i2c_send(s->bus, t)) {
193 s->regs[R_ISR] |= ISR_NACK;
194 }
195 if (fifo_is_empty(&s->fifo)) {
196 s->regs[R_ISR] |= ISR_COMP;
197 }
198 if (s->regs[R_TRANSFER_SIZE]) {
199 s->regs[R_TRANSFER_SIZE]--;
200 }
201 if (s->fifo.num <= 2) {
202 s->regs[R_ISR] |= ISR_DATA;
203 }
204 }
205 } else {
206
207 if (!s->regs[R_TRANSFER_SIZE]) {
208 cadence_i2c_do_stop(s);
209 DB_PRINT("stopping read transfer\n");
210
211 } else if (fifo_is_full(&s->fifo) &&
212 !(s->regs[R_CONTROL] & CONTROL_HOLD)) {
213 i2c_recv(s->bus);
214 s->regs[R_ISR] |= ISR_RX_OVF;
215 s->regs[R_STATUS] |= STATUS_RXOVF;
216 DB_PRINT("nacking becuase the fifo is full!\n");
217 i2c_nack(s->bus);
218 cadence_i2c_do_stop(s);
219
220 } else if (!fifo_is_full(&s->fifo)) {
221 uint8_t r = i2c_recv(s->bus);
222 DB_PRINT("receiving from I2C bus: %02x\n", r);
223 fifo_push8(&s->fifo, r);
224 s->regs[R_STATUS] |= STATUS_RXDV;
225 if (s->fifo.num >= FIFO_WIDTH - 2) {
226 s->regs[R_ISR] |= ISR_DATA;
227 }
228 if (!(s->regs[R_CONTROL] & CONTROL_ACKEN)) {
229 i2c_nack(s->bus);
230 }
231 s->regs[R_TRANSFER_SIZE]--;
232 if (!s->regs[R_TRANSFER_SIZE]) {
233 DB_PRINT("Nacking last byte of read transaction\n");
234 i2c_nack(s->bus);
235 s->regs[R_ISR] |= ISR_COMP;
236 }
237 }
238
239 }
240
241 cadence_i2c_update_status(s);
242}
243
244static inline void cadence_i2c_check_reg_access(hwaddr offset, uint32_t val,
245 bool rnw)
246{
247 if (!cadence_i2c_reg_info[offset >> 2].name) {
248 qemu_log_mask(LOG_UNIMP, "cadence i2c: %s offset %x\n",
249 rnw ? "read from" : "write to", (unsigned)offset);
250 DB_PRINT("%s offset %x\n",
251 rnw ? "read from" : "write to", (unsigned)offset);
252 } else {
253 DB_PRINT("%s %s [%#02x] %s %#08x\n", rnw ? "read" : "write",
254 cadence_i2c_reg_info[offset >> 2].name, (unsigned) offset,
255 rnw ? "->" : "<-", val);
256 }
257}
258
259static uint64_t cadence_i2c_read(void *opaque, hwaddr offset,
260 unsigned size)
261{
262 CadenceI2CState *s = (CadenceI2CState *)opaque;
263 const CadenceI2CRegInfo *info = &cadence_i2c_reg_info[offset >> 2];
264 uint32_t ret = s->regs[offset >> 2];
265
266 cadence_i2c_check_reg_access(offset, ret, true);
267 if (!info->name) {
268 return 0;
269 }
270 ret &= (1ull << info->width) - 1;
271
272 if (offset >> 2 == R_DATA) {
273 if (fifo_is_empty(&s->fifo)) {
274 s->regs[R_ISR] |= ISR_RX_UNF;
275 } else {
276 s->regs[R_STATUS] &= ~STATUS_RXOVF;
277 ret = fifo_pop8(&s->fifo);
278 if (fifo_is_empty(&s->fifo)) {
279 s->regs[R_STATUS] &= ~STATUS_RXDV;
280 }
281 }
282 cadence_i2c_update_status(s);
283 }
284 return ret;
285}
286
287static void cadence_i2c_write(void *opaque, hwaddr offset,
288 uint64_t value, unsigned size)
289{
290 CadenceI2CState *s = (CadenceI2CState *)opaque;
291 const CadenceI2CRegInfo *info = &cadence_i2c_reg_info[offset >> 2];
292 uint32_t new_value = value;
293 uint32_t ro_mask;
294
295 cadence_i2c_check_reg_access(offset, value, false);
296 if (!info->name) {
297 return;
298 }
299 offset >>= 2;
300 assert(!(info->wtc & info->ro));
301
302 ro_mask = info->ro | info->wtc | ~((1ull << info->width) - 1);
303 new_value &= ~ro_mask;
304 new_value |= ro_mask & s->regs[offset];
305
306 new_value &= ~(value & info->wtc);
307 s->regs[offset] = new_value;
308
309 switch (offset) {
310 case R_CONTROL:
311 if (value & CONTROL_CLR_FIFO) {
312 DB_PRINT("clearing fifo\n");
313 s->regs[R_TRANSFER_SIZE] = 0;
314 s->regs[R_STATUS] &= ~STATUS_RXOVF;
315 fifo_reset(&s->fifo);
316 }
317 if (!(value & CONTROL_HOLD)) {
318 bool idle = s->regs[R_CONTROL] & CONTROL_RW ?
319 !s->regs[R_TRANSFER_SIZE] : fifo_is_empty(&s->fifo);
320 if (idle) {
321 cadence_i2c_do_stop(s);
322 }
323 }
324 break;
325 case R_ADDRESS:
326 s->rw = s->regs[R_CONTROL] & CONTROL_RW;
327 if (!(s->regs[R_CONTROL] & CONTROL_NEA)) {
328 qemu_log_mask(LOG_UNIMP, "cadence i2c: 10 bit addressing selected "
329 "(unimplmented)");
330 }
331 if (i2c_start_transfer(s->bus, new_value & 0x7f,
332 s->regs[R_CONTROL] & CONTROL_RW)) {
333 DB_PRINT("No match for device 0x%x\n", new_value);
334 } else {
335 DB_PRINT("device 0x%x probe success\n", new_value);
336 if (s->regs[R_CONTROL] & CONTROL_SLVMON) {
337
338 s->regs[R_ISR] |= ISR_SLV_RDY;
339 } else {
340 s->regs[R_STATUS] |= STATUS_BA;
341 }
342 }
343 break;
344 case R_DATA:
345 if (fifo_is_full(&s->fifo)) {
346 s->regs[R_ISR] |= ISR_TX_OVF;
347 } else {
348 s->regs[R_TRANSFER_SIZE]++;
349 fifo_push8(&s->fifo, new_value);
350 }
351 break;
352 case R_INTRPT_ENABLE:
353 s->regs[R_INTRPT_MASK] &= ~value;
354 break;
355 case R_INTRPT_DISABLE:
356 s->regs[R_INTRPT_MASK] |= value;
357 break;
358 }
359 cadence_i2c_update_status(s);
360}
361
362static const MemoryRegionOps cadence_i2c_ops = {
363 .read = cadence_i2c_read,
364 .write = cadence_i2c_write,
365 .endianness = DEVICE_NATIVE_ENDIAN,
366};
367
368static const VMStateDescription cadence_i2c_vmstate = {
369 .name = TYPE_CADENCE_I2C,
370 .version_id = 1,
371 .minimum_version_id = 1,
372 .fields = (VMStateField[]) {
373 VMSTATE_FIFO(fifo, CadenceI2CState),
374 VMSTATE_UINT32_ARRAY(regs, CadenceI2CState, R_MAX),
375 VMSTATE_TIMER_PTR(transfer_timer, CadenceI2CState),
376 VMSTATE_END_OF_LIST()
377 }
378};
379
380static void cadence_i2c_reset(DeviceState *d)
381{
382 CadenceI2CState *s = CADENCE_I2C(d);
383 int i;
384
385 timer_del(s->transfer_timer);
386 for (i = 0; i < R_MAX; ++i) {
387 s->regs[i] = cadence_i2c_reg_info[i].name ?
388 cadence_i2c_reg_info[i].reset : 0;
389 }
390 fifo_reset(&s->fifo);
391}
392
393static void cadence_i2c_realize(DeviceState *dev, Error **errp)
394{
395 CadenceI2CState *s = CADENCE_I2C(dev);
396 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
397
398 memory_region_init_io(&s->iomem, OBJECT(dev), &cadence_i2c_ops, s,
399 TYPE_CADENCE_I2C, R_MAX * 4);
400 sysbus_init_mmio(sbd, &s->iomem);
401 sysbus_init_irq(sbd, &s->irq);
402
403 s->bus = i2c_init_bus(dev, "i2c");
404
405 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cadence_i2c_do_txrx,
406 s);
407
408 fifo_create8(&s->fifo, FIFO_WIDTH);
409}
410
411static void cadence_i2c_class_init(ObjectClass *klass, void *data)
412{
413 DeviceClass *dc = DEVICE_CLASS(klass);
414
415 dc->vmsd = &cadence_i2c_vmstate;
416 dc->reset = cadence_i2c_reset;
417 dc->realize = cadence_i2c_realize;
418}
419
420static const TypeInfo cadence_i2c_type_info = {
421 .name = TYPE_CADENCE_I2C,
422 .parent = TYPE_SYS_BUS_DEVICE,
423 .instance_size = sizeof(CadenceI2CState),
424 .class_init = cadence_i2c_class_init,
425};
426
427static void cadence_i2c_register_types(void)
428{
429 type_register_static(&cadence_i2c_type_info);
430}
431
432type_init(cadence_i2c_register_types)
433