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